环境声明

  • Python版本:Python 3.10+
  • PyTorch版本:PyTorch 2.0+
  • Transformers库:transformers 4.35+
  • 开发工具:PyCharm / VS Code / Jupyter Notebook
  • 硬件建议:NVIDIA GPU (显存8GB以上) 或 使用云端GPU服务

学习目标和摘要

学习目标

  1. 理解大语言模型的核心原理与Scaling Laws
  2. 掌握GPT系列与LLaMA系列的技术演进
  3. 学习指令微调(SFT)与人类反馈强化学习(RLHF)
  4. 了解模型量化与高效推理技术
  5. 能够使用开源框架部署和微调大语言模型

文章摘要:本章深入解析大语言模型(LLM)的核心技术,从GPT-3的涌现能力到GPT-4的多模态突破,从LLaMA的开源生态到2025年最新的MoE架构。我们将探讨Scaling Laws、上下文学习、思维链、RLHF对齐等关键技术,并提供完整的代码实践。


1. 大语言模型概述

1.1 什么是大语言模型

大语言模型(Large Language Model, LLM)是指参数量巨大(通常数十亿到数千亿)、在海量文本数据上训练的自然语言处理模型。它们基于Transformer架构,通过自监督学习掌握语言的统计规律和语义表示。

一句话总结:大语言模型就像是一位读过人类所有书籍的学者,能够理解和生成自然语言。

1.2 Scaling Laws:规模法则

Scaling Laws是OpenAI在2020年提出的重要发现,揭示了模型性能与三个关键因素之间的幂律关系:

性能公式

L(N) = (N_c / N)^alpha_N
L(D) = (D_c / D)^alpha_D
L(C) = (C_c / C)^alpha_C

其中:

  • N:模型参数量
  • D:训练数据量
  • C:计算量(FLOPs)
  • alpha:经验指数(约0.05-0.1)

核心结论

  1. 模型性能随规模可预测地提升
  2. 参数量、数据量、计算量需要同步增长
  3. 存在一个最优的计算效率边界

1.3 涌现能力(Emergent Abilities)

涌现能力是指模型在达到一定规模后突然展现出的新能力,这些能力在小模型中不存在。

主要涌现能力

能力名称 描述 典型规模
上下文学习(In-context Learning) 通过示例学习新任务 约100B参数
思维链(Chain-of-Thought) 逐步推理复杂问题 约100B参数
指令遵循(Instruction Following) 理解并执行自然语言指令 约68B参数
多语言翻译 零样本跨语言翻译 约50B参数

2. GPT系列技术解析

2.1 GPT-3:开启大模型时代

GPT-3(Generative Pre-trained Transformer 3)于2020年发布,拥有1750亿参数,首次展示了强大的上下文学习能力。

技术特点

  • 架构:Decoder-only Transformer
  • 参数量:175B
  • 上下文长度:2048 tokens
  • 训练数据:300B tokens (Common Crawl, WebText等)

上下文学习示例

# GPT-3上下文学习示例
prompt = """
将以下中文翻译成英文:
中文:今天天气很好。
英文:The weather is nice today.

中文:我喜欢学习Python。
英文:I enjoy learning Python.

中文:深度学习很有趣。
英文:"""

# GPT-3会根据前面的示例,自动完成翻译
# 输出:Deep learning is very interesting.

2.2 GPT-4:多模态与推理突破

GPT-4于2023年发布,是OpenAI的多模态大模型,支持文本和图像输入。

技术突破

  1. 多模态能力:理解图像内容并生成文本描述
  2. 更强的推理:在复杂数学和逻辑问题上表现优异
  3. 更长的上下文:支持32K tokens的上下文窗口
  4. 更好的对齐:通过RLHF减少有害输出

思维链(Chain-of-Thought)示例

# 思维链提示
prompt = """
问题:一个农场有鸡和兔子,共有35个头和94只脚。鸡和兔子各有多少只?

让我们一步一步思考:

步骤1:设鸡有x只,兔子有y只。
步骤2:根据头的数量:x + y = 35
步骤3:根据脚的数量:2x + 4y = 94
步骤4:从步骤2得:x = 35 - y
步骤5:代入步骤3:2(35 - y) + 4y = 94
步骤6:70 - 2y + 4y = 94
步骤7:2y = 24
步骤8:y = 12
步骤9:x = 35 - 12 = 23

答案:鸡有23只,兔子有12只。
"""

2.3 GPT-4o:原生多模态

GPT-4o("o"代表omni,全能)于2024年发布,是首个原生多模态模型,统一处理文本、音频、图像。


3. LLaMA与开源大模型生态

3.1 LLaMA系列演进

Meta发布的LLaMA(Large Language Model Meta AI)系列推动了开源大模型的发展。

LLaMA 1(2023年2月)

  • 参数量:7B, 13B, 33B, 65B
  • 训练数据:1.4T tokens
  • 仅用于研究用途

LLaMA 2(2023年7月)

  • 参数量:7B, 13B, 70B
  • 上下文长度:4096 tokens
  • 可商用
  • 发布了Chat版本

LLaMA 3(2024年4月)

  • 参数量:8B, 70B
  • 训练数据:15T tokens
  • 上下文长度:8K tokens
  • 性能大幅提升

LLaMA 4(2025年4月)

  • 采用MoE(混合专家)架构
  • 支持千万Token超长上下文
  • 多模态融合能力

3.2 开源模型对比

模型 发布方 参数量 上下文 许可证 特点
LLaMA 3 Meta 8B/70B 8K 商业可用 开源生态最活跃
Mistral Mistral AI 7B 32K Apache 2.0 性能优异,效率高
Qwen 阿里 7B-110B 32K-128K 商业可用 中文优化好
ChatGLM 清华 6B 8K 商业可用 中英双语
DeepSeek DeepSeek 7B-67B 4K-128K 开源 推理能力强

3.3 使用Transformers加载LLaMA

from transformers import AutoTokenizer, AutoModelForCausalLM
import torch

# 加载LLaMA 3模型
model_name = "meta-llama/Meta-Llama-3-8B-Instruct"

# 加载tokenizer和模型
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(
    model_name,
    torch_dtype=torch.float16,
    device_map="auto"
)

# 准备对话消息
messages = [
    {"role": "system", "content": "你是一个 helpful AI助手。"},
    {"role": "user", "content": "请介绍一下深度学习的基本概念。"}
]

# 应用对话模板
input_text = tokenizer.apply_chat_template(
    messages,
    tokenize=False,
    add_generation_prompt=True
)

# 生成回复
inputs = tokenizer(input_text, return_tensors="pt").to(model.device)
outputs = model.generate(
    **inputs,
    max_new_tokens=256,
    do_sample=True,
    temperature=0.7,
    top_p=0.9
)

response = tokenizer.decode(outputs[0], skip_special_tokens=True)
print(response)

4. 指令微调与对齐

4.1 监督微调(SFT)

监督微调(Supervised Fine-Tuning)是在预训练模型基础上,使用指令-回复对进行微调。

数据格式示例

{
    "instruction": "将以下中文翻译成英文",
    "input": "深度学习是机器学习的一个分支。",
    "output": "Deep learning is a branch of machine learning."
}

SFT代码实现

from transformers import (
    AutoModelForCausalLM,
    AutoTokenizer,
    TrainingArguments,
    Trainer
)
from datasets import load_dataset
import torch

# 加载模型和tokenizer
model_name = "meta-llama/Llama-2-7b-hf"
model = AutoModelForCausalLM.from_pretrained(
    model_name,
    torch_dtype=torch.float16,
    device_map="auto"
)
tokenizer = AutoTokenizer.from_pretrained(model_name)
tokenizer.pad_token = tokenizer.eos_token

# 加载指令数据集
dataset = load_dataset("tatsu-lab/alpaca", split="train")

def format_prompt(example):
    """格式化指令数据"""
    if example["input"]:
        prompt = f"### Instruction:\n{example['instruction']}\n\n### Input:\n{example['input']}\n\n### Response:\n{example['output']}"
    else:
        prompt = f"### Instruction:\n{example['instruction']}\n\n### Response:\n{example['output']}"
    return {"text": prompt}

# 格式化数据集
formatted_dataset = dataset.map(format_prompt)

# 定义训练参数
training_args = TrainingArguments(
    output_dir="./sft_llama",
    num_train_epochs=3,
    per_device_train_batch_size=4,
    gradient_accumulation_steps=4,
    learning_rate=2e-5,
    warmup_steps=100,
    logging_steps=10,
    save_steps=500,
    fp16=True,
    optim="adamw_torch"
)

# 创建Trainer
trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=formatted_dataset,
    tokenizer=tokenizer
)

# 开始训练
trainer.train()

4.2 RLHF:人类反馈强化学习

RLHF(Reinforcement Learning from Human Feedback)通过人类反馈来优化模型输出,使其更符合人类偏好。

RLHF三阶段流程

阶段1:预训练 -> 基础模型
阶段2:SFT -> 指令模型
阶段3:RLHF -> 对齐模型
    3.1 训练奖励模型(Reward Model)
    3.2 使用PPO算法优化策略

奖励模型训练

import torch
import torch.nn as nn
from transformers import AutoModel, AutoTokenizer

class RewardModel(nn.Module):
    """奖励模型:给模型输出打分"""
    
    def __init__(self, base_model_name):
        super().__init__()
        self.base_model = AutoModel.from_pretrained(base_model_name)
        self.reward_head = nn.Linear(self.base_model.config.hidden_size, 1)
    
    def forward(self, input_ids, attention_mask):
        outputs = self.base_model(input_ids, attention_mask=attention_mask)
        # 取最后一个token的隐藏状态
        last_hidden = outputs.last_hidden_state[:, -1, :]
        reward = self.reward_head(last_hidden)
        return reward

# 训练奖励模型
def train_reward_model(
    model,
    tokenizer,
    preference_data,
    num_epochs=3,
    lr=1e-5
):
    """
    preference_data格式:
    {
        "prompt": "问题...",
        "chosen": "更好的回答...",
        "rejected": "较差的回答..."
    }
    """
    optimizer = torch.optim.AdamW(model.parameters(), lr=lr)
    
    for epoch in range(num_epochs):
        for batch in preference_data:
            # 编码prompt + chosen
            chosen_text = batch["prompt"] + batch["chosen"]
            rejected_text = batch["prompt"] + batch["rejected"]
            
            chosen_inputs = tokenizer(
                chosen_text,
                return_tensors="pt",
                truncation=True,
                max_length=512
            )
            rejected_inputs = tokenizer(
                rejected_text,
                return_tensors="pt",
                truncation=True,
                max_length=512
            )
            
            # 计算奖励
            chosen_reward = model(**chosen_inputs)
            rejected_reward = model(**rejected_inputs)
            
            # Bradley-Terry损失:希望chosen的奖励高于rejected
            loss = -torch.log(torch.sigmoid(chosen_reward - rejected_reward)).mean()
            
            loss.backward()
            optimizer.step()
            optimizer.zero_grad()

4.3 PPO算法实现

PPO(Proximal Policy Optimization)是RLHF中常用的强化学习算法。

from trl import PPOTrainer, PPOConfig, AutoModelForCausalLMWithValueHead
from transformers import AutoTokenizer
import torch

# 配置PPO
config = PPOConfig(
    model_name="gpt2",  # 示例使用gpt2
    learning_rate=1.41e-5,
    batch_size=256,
    mini_batch_size=64,
    gradient_accumulation_steps=1,
    optimize_cuda_cache=True,
    early_stopping=False,
    target_kl=0.1,
    ppo_epochs=4,
    seed=0,
    init_kl_coef=0.2,
    adap_kl_ctrl=True,
    use_score_scaling=True,
    use_score_norm=True,
    score_clip=None
)

# 加载模型
model = AutoModelForCausalLMWithValueHead.from_pretrained(config.model_name)
ref_model = AutoModelForCausalLMWithValueHead.from_pretrained(config.model_name)
tokenizer = AutoTokenizer.from_pretrained(config.model_name)
tokenizer.pad_token = tokenizer.eos_token

# 创建PPO训练器
ppo_trainer = PPOTrainer(
    config=config,
    model=model,
    ref_model=ref_model,
    tokenizer=tokenizer,
    dataset=None,  # 这里传入你的数据集
    data_collator=None
)

# PPO训练循环
for epoch in range(num_epochs):
    for batch in dataloader:
        queries = batch["query"]
        query_tensors = [tokenizer.encode(q, return_tensors="pt")[0] for q in queries]
        
        # 生成回复
        response_tensors = ppo_trainer.generate(query_tensors)
        
        # 解码回复
        responses = [tokenizer.decode(r.squeeze()) for r in response_tensors]
        
        # 使用奖励模型打分
        rewards = reward_model.score(queries, responses)
        
        # PPO更新
        stats = ppo_trainer.step(query_tensors, response_tensors, rewards)
        
        print(f"Epoch {epoch}, Reward: {rewards.mean().item():.4f}")

4.4 DPO:直接偏好优化

DPO(Direct Preference Optimization)是2023年提出的新方法,无需显式训练奖励模型,直接用偏好数据优化策略。

import torch
import torch.nn.functional as F
from transformers import AutoModelForCausalLM, AutoTokenizer

def dpo_loss(
    policy_model,
    ref_model,
    tokenizer,
    batch,
    beta=0.1
):
    """
    DPO损失函数
    
    batch格式:
    {
        "prompt": ["问题1", "问题2", ...],
        "chosen": ["好回答1", "好回答2", ...],
        "rejected": ["差回答1", "差回答2", ...]
    }
    """
    # 编码输入
    chosen_texts = [p + c for p, c in zip(batch["prompt"], batch["chosen"])]
    rejected_texts = [p + r for p, r in zip(batch["prompt"], batch["rejected"])]
    
    chosen_inputs = tokenizer(
        chosen_texts,
        return_tensors="pt",
        padding=True,
        truncation=True
    )
    rejected_inputs = tokenizer(
        rejected_texts,
        return_tensors="pt",
        padding=True,
        truncation=True
    )
    
    # 策略模型log概率
    policy_chosen_logits = policy_model(**chosen_inputs).logits
    policy_rejected_logits = policy_model(**rejected_inputs).logits
    
    # 参考模型log概率
    with torch.no_grad():
        ref_chosen_logits = ref_model(**chosen_inputs).logits
        ref_rejected_logits = ref_model(**rejected_inputs).logits
    
    # 计算log概率(简化版,实际需要对齐token)
    policy_chosen_logps = F.log_softmax(policy_chosen_logits, dim=-1)
    policy_rejected_logps = F.log_softmax(policy_rejected_logits, dim=-1)
    ref_chosen_logps = F.log_softmax(ref_chosen_logits, dim=-1)
    ref_rejected_logps = F.log_softmax(ref_rejected_logits, dim=-1)
    
    # DPO损失
    pi_ratio = policy_chosen_logps - policy_rejected_logps
    ref_ratio = ref_chosen_logps - ref_rejected_logps
    
    logits = beta * (pi_ratio - ref_ratio)
    loss = -F.logsigmoid(logits).mean()
    
    return loss

# DPO训练循环
def train_dpo(
    policy_model,
    ref_model,
    tokenizer,
    preference_dataset,
    num_epochs=3,
    lr=5e-7,
    beta=0.1
):
    optimizer = torch.optim.AdamW(policy_model.parameters(), lr=lr)
    
    for epoch in range(num_epochs):
        total_loss = 0
        for batch in preference_dataset:
            loss = dpo_loss(policy_model, ref_model, tokenizer, batch, beta)
            
            loss.backward()
            optimizer.step()
            optimizer.zero_grad()
            
            total_loss += loss.item()
        
        avg_loss = total_loss / len(preference_dataset)
        print(f"Epoch {epoch+1}/{num_epochs}, Loss: {avg_loss:.4f}")

5. 上下文学习与涌现能力

5.1 In-context Learning原理

上下文学习(In-context Learning)是指大模型仅通过提示中的几个示例就能学会新任务,无需梯度更新。

三种上下文学习形式

类型 描述 示例数量
Zero-shot 直接给出指令,无示例 0个
One-shot 提供1个示例 1个
Few-shot 提供多个示例 2-10个

Few-shot Prompting示例

# Few-shot情感分析
few_shot_prompt = """
判断以下评论的情感倾向(正面/负面/中性):

评论:这部电影太精彩了,强烈推荐!
情感:正面

评论:完全浪费时间,剧情无聊透顶。
情感:负面

评论:一般般吧,没什么特别的。
情感:中性

评论:演员演技出色,画面也很美。
情感:"""

# 模型会输出:正面

5.2 Chain-of-Thought思维链

思维链(Chain-of-Thought, CoT)通过引导模型展示推理过程,显著提升复杂任务的性能。

标准Prompt vs CoT Prompt

# 标准Prompt(直接问)
standard_prompt = """
问题:Roger有5个网球,又买了2罐,每罐3个。他现在有几个?
答案:11
"""

# CoT Prompt(展示推理过程)
cot_prompt = """
问题:Roger有5个网球,又买了2罐,每罐3个。他现在有几个?

思考过程:
Roger最初有5个网球。
他买了2罐,每罐3个,所以买了 2 * 3 = 6 个网球。
总共:5 + 6 = 11 个网球。

答案:11
"""

自动CoT(Auto-CoT)实现

import openai
import numpy as np
from sklearn.cluster import KMeans

def auto_cot(
    questions,
    num_demonstrations=8,
    api_key=None
):
    """
    自动构建思维链示例
    
    步骤:
    1. 对问题进行聚类
    2. 从每个聚类中选择代表性问题
    3. 使用Zero-shot-CoT生成推理链
    4. 组合成Few-shot-CoT提示
    """
    # 步骤1:获取问题嵌入并聚类
    embeddings = get_embeddings(questions)  # 使用文本嵌入模型
    kmeans = KMeans(n_clusters=num_demonstrations, random_state=42)
    clusters = kmeans.fit_predict(embeddings)
    
    # 步骤2:从每个聚类中选择最接近中心的问题
    demonstrations = []
    for i in range(num_demonstrations):
        cluster_indices = np.where(clusters == i)[0]
        center = kmeans.cluster_centers_[i]
        
        # 找到最接近中心的样本
        distances = np.linalg.norm(
            embeddings[cluster_indices] - center,
            axis=1
        )
        closest_idx = cluster_indices[np.argmin(distances)]
        demonstrations.append(questions[closest_idx])
    
    # 步骤3:为每个示例生成思维链
    cot_examples = []
    for q in demonstrations:
        # 使用Zero-shot-CoT生成推理
        zero_shot_prompt = f"Q: {q}\nA: Let's think step by step."
        response = openai.Completion.create(
            engine="text-davinci-003",
            prompt=zero_shot_prompt,
            max_tokens=256,
            temperature=0.0
        )
        reasoning = response.choices[0].text.strip()
        cot_examples.append((q, reasoning))
    
    return cot_examples

# 使用Auto-CoT进行推理
def inference_with_auto_cot(test_question, demonstrations):
    """使用Auto-CoT生成的示例进行推理"""
    prompt = ""
    for q, r in demonstrations:
        prompt += f"Q: {q}\nA: {r}\n\n"
    
    prompt += f"Q: {test_question}\nA: Let's think step by step."
    
    response = openai.Completion.create(
        engine="text-davinci-003",
        prompt=prompt,
        max_tokens=256,
        temperature=0.0
    )
    return response.choices[0].text.strip()

6. 模型量化与高效推理

6.1 量化技术概述

模型量化通过降低参数精度(如FP32->INT8)来减少模型大小和推理延迟。

量化类型对比

量化类型 精度 压缩比 适用场景
FP32 32位 1x 训练
FP16 16位 2x 推理
INT8 8位 4x 生产部署
INT4 4位 8x 边缘设备
NF4 4位(非对称) 8x 大模型量化

6.2 INT8动态量化

import torch
from transformers import AutoModelForCausalLM, AutoTokenizer

# 加载模型
model_name = "meta-llama/Llama-2-7b-hf"
model = AutoModelForCausalLM.from_pretrained(
    model_name,
    torch_dtype=torch.float16,
    device_map="auto"
)
tokenizer = AutoTokenizer.from_pretrained(model_name)

# 应用动态量化
quantized_model = torch.quantization.quantize_dynamic(
    model,
    {torch.nn.Linear},  # 量化线性层
    dtype=torch.qint8
)

# 保存量化模型
torch.save(quantized_model.state_dict(), "quantized_model.pth")

# 量化前后对比
print(f"原始模型大小: ~14GB (FP16)")
print(f"量化后模型大小: ~7GB (INT8)")

6.3 GPTQ量化

GPTQ(General-purpose Post-Training Quantization)是目前最流行的4-bit量化方法。

from transformers import AutoModelForCausalLM, AutoTokenizer, GPTQConfig

# GPTQ 4-bit量化
model_name = "meta-llama/Llama-2-7b-hf"

quantization_config = GPTQConfig(
    bits=4,
    group_size=128,
    dataset="c4",
    desc_act=False,  # 是否激活降序排序
)

# 加载量化模型
model = AutoModelForCausalLM.from_pretrained(
    model_name,
    quantization_config=quantization_config,
    device_map="auto"
)
tokenizer = AutoTokenizer.from_pretrained(model_name)

# 推理
text = "深度学习是"
inputs = tokenizer(text, return_tensors="pt").to(model.device)
outputs = model.generate(**inputs, max_new_tokens=50)
print(tokenizer.decode(outputs[0]))

6.4 使用bitsandbytes进行高效加载

from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
import torch

# 配置4-bit量化
bnb_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_use_double_quant=True,  # 嵌套量化
    bnb_4bit_quant_type="nf4",       # 4-bit归一化浮点
    bnb_4bit_compute_dtype=torch.bfloat16
)

# 加载量化模型
model_name = "meta-llama/Llama-2-13b-hf"
model = AutoModelForCausalLM.from_pretrained(
    model_name,
    quantization_config=bnb_config,
    device_map="auto",
    trust_remote_code=True
)
tokenizer = AutoTokenizer.from_pretrained(model_name)

# 计算显存占用
print(f"模型加载完成")
print(f"4-bit量化后,13B模型约占用显存: ~7-8GB")

6.5 vLLM加速推理

vLLM是一个高吞吐量的LLM推理引擎,使用PagedAttention算法。

from vllm import LLM, SamplingParams

# 加载模型
llm = LLM(
    model="meta-llama/Llama-2-7b-hf",
    tensor_parallel_size=1,  # GPU数量
    dtype="half"
)

# 设置采样参数
sampling_params = SamplingParams(
    temperature=0.8,
    top_p=0.95,
    max_tokens=256
)

# 批量推理
prompts = [
    "人工智能的未来发展",
    "深度学习的基本原理",
    "自然语言处理的应用"
]

outputs = llm.generate(prompts, sampling_params)

for output in outputs:
    prompt = output.prompt
    generated_text = output.outputs[0].text
    print(f"Prompt: {prompt}")
    print(f"Generated: {generated_text}")
    print("-" * 50)

7. 2025年最新进展

7.1 MoE:混合专家架构

MoE(Mixture of Experts)通过稀疏激活机制,在不增加推理成本的情况下扩大模型容量。

MoE架构原理

输入 -> 路由网络 -> 选择Top-K专家 -> 专家网络计算 -> 加权聚合 -> 输出

LLaMA 4 MoE特点(2025年)

  • 总参数量:万亿级别
  • 激活参数量:数百亿级别
  • 支持千万Token超长上下文
  • 多模态融合能力

7.2 长上下文技术

长上下文(Long Context)是2024-2025年的重要突破方向。

关键技术

技术 描述 代表模型
RoPE外推 扩展位置编码范围 LLaMA
ALiBi 线性偏置注意力 BLOOM
NTK-aware 非线性位置编码扩展 各种社区方案
Ring Attention 环形注意力计算 研究阶段

长上下文实现示例

from transformers import AutoModelForCausalLM, AutoTokenizer
import torch

# 加载支持长上下文的模型
model_name = "togethercomputer/LLaMA-2-7B-32K"

model = AutoModelForCausalLM.from_pretrained(
    model_name,
    torch_dtype=torch.float16,
    device_map="auto"
)
tokenizer = AutoTokenizer.from_pretrained(model_name)

# 处理长文档
long_document = "..." * 10000  # 长文本

# 使用滑动窗口处理超长文本
max_chunk_size = 4096
stride = 2048

def sliding_window_inference(text, model, tokenizer, max_length=4096, stride=2048):
    """滑动窗口处理长文本"""
    tokens = tokenizer.encode(text)
    
    results = []
    for i in range(0, len(tokens), stride):
        chunk = tokens[i:i + max_length]
        inputs = torch.tensor([chunk]).to(model.device)
        
        with torch.no_grad():
            outputs = model(inputs)
            # 处理输出...
            results.append(outputs)
    
    return results

7.3 多模态大模型

2025年的大模型趋向多模态统一。

GPT-4o多模态示例

import base64
from openai import OpenAI

client = OpenAI()

# 读取图像
with open("image.jpg", "rb") as f:
    image_data = base64.b64encode(f.read()).decode()

# 多模态对话
response = client.chat.completions.create(
    model="gpt-4o",
    messages=[
        {
            "role": "user",
            "content": [
                {"type": "text", "text": "描述这张图片的内容"},
                {
                    "type": "image_url",
                    "image_url": {
                        "url": f"data:image/jpeg;base64,{image_data}"
                    }
                }
            ]
        }
    ],
    max_tokens=300
)

print(response.choices[0].message.content)

8. LLM应用开发实战

8.1 构建智能问答系统

from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
from langchain import OpenAI, LLMChain, PromptTemplate
from langchain.memory import ConversationBufferMemory
import torch

class LLMQASystem:
    """基于LLM的智能问答系统"""
    
    def __init__(self, model_name="meta-llama/Llama-2-7b-chat-hf"):
        self.tokenizer = AutoTokenizer.from_pretrained(model_name)
        self.model = AutoModelForCausalLM.from_pretrained(
            model_name,
            torch_dtype=torch.float16,
            device_map="auto"
        )
        self.memory = ConversationBufferMemory()
    
    def generate_response(self, question, context=None):
        """生成回答"""
        # 构建提示
        if context:
            prompt = f"""基于以下上下文回答问题:

上下文:
{context}

问题:{question}

回答:"""
        else:
            prompt = f"问题:{question}\n回答:"
        
        # 生成
        inputs = self.tokenizer(prompt, return_tensors="pt").to(self.model.device)
        
        outputs = self.model.generate(
            **inputs,
            max_new_tokens=256,
            do_sample=True,
            temperature=0.7,
            top_p=0.9,
            repetition_penalty=1.1
        )
        
        response = self.tokenizer.decode(
            outputs[0][inputs.input_ids.shape[1]:],
            skip_special_tokens=True
        )
        
        return response.strip()
    
    def chat(self, message):
        """多轮对话"""
        # 获取历史
        history = self.memory.load_memory_variables({})
        
        # 构建对话提示
        prompt = f"""以下是友好的对话:

{history.get('history', '')}
用户:{message}
助手:"""
        
        # 生成回复
        inputs = self.tokenizer(prompt, return_tensors="pt").to(self.model.device)
        outputs = self.model.generate(
            **inputs,
            max_new_tokens=128,
            do_sample=True,
            temperature=0.7
        )
        
        response = self.tokenizer.decode(
            outputs[0][inputs.input_ids.shape[1]:],
            skip_special_tokens=True
        ).strip()
        
        # 保存对话
        self.memory.save_context(
            {"input": message},
            {"output": response}
        )
        
        return response

# 使用示例
qa_system = LLMQASystem()

# 单轮问答
context = """
深度学习是机器学习的一个分支,它使用多层神经网络来学习数据的层次化表示。
深度学习的核心思想是通过多层非线性变换,从原始数据中提取高层次的抽象特征。
"""
answer = qa_system.generate_response("什么是深度学习?", context)
print(answer)

# 多轮对话
print(qa_system.chat("你好!"))
print(qa_system.chat("你能做什么?"))

8.2 RAG检索增强生成

from langchain.embeddings import HuggingFaceEmbeddings
from langchain.vectorstores import FAISS
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.document_loaders import TextLoader
from langchain.chains import RetrievalQA
import torch

class RAGSystem:
    """检索增强生成系统"""
    
    def __init__(self, llm_model_name="meta-llama/Llama-2-7b-chat-hf"):
        # 初始化嵌入模型
        self.embeddings = HuggingFaceEmbeddings(
            model_name="sentence-transformers/all-MiniLM-L6-v2"
        )
        
        # 初始化LLM
        from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
        
        tokenizer = AutoTokenizer.from_pretrained(llm_model_name)
        model = AutoModelForCausalLM.from_pretrained(
            llm_model_name,
            torch_dtype=torch.float16,
            device_map="auto"
        )
        
        self.llm = pipeline(
            "text-generation",
            model=model,
            tokenizer=tokenizer,
            max_new_tokens=512,
            temperature=0.7
        )
        
        self.vector_store = None
    
    def load_documents(self, file_paths):
        """加载文档"""
        documents = []
        for path in file_paths:
            loader = TextLoader(path, encoding="utf-8")
            documents.extend(loader.load())
        
        # 分割文档
        text_splitter = RecursiveCharacterTextSplitter(
            chunk_size=500,
            chunk_overlap=50
        )
        texts = text_splitter.split_documents(documents)
        
        # 创建向量库
        self.vector_store = FAISS.from_documents(texts, self.embeddings)
        
        print(f"已加载 {len(texts)} 个文档片段")
    
    def query(self, question, k=3):
        """检索并生成回答"""
        if not self.vector_store:
            return "请先加载文档"
        
        # 检索相关文档
        docs = self.vector_store.similarity_search(question, k=k)
        context = "\n\n".join([doc.page_content for doc in docs])
        
        # 构建提示
        prompt = f"""基于以下信息回答问题。如果信息不足,请说明。

相关信息:
{context}

问题:{question}

回答:"""
        
        # 生成回答
        response = self.llm(prompt)[0]["generated_text"]
        
        # 提取生成的部分
        answer = response[len(prompt):].strip()
        
        return {
            "answer": answer,
            "sources": [doc.page_content[:200] + "..." for doc in docs]
        }

# 使用示例
rag = RAGSystem()

# 加载文档
rag.load_documents(["document1.txt", "document2.txt"])

# 查询
result = rag.query("深度学习的应用场景有哪些?")
print("回答:", result["answer"])
print("来源:", result["sources"])

8.3 模型微调完整流程

from transformers import (
    AutoModelForCausalLM,
    AutoTokenizer,
    TrainingArguments,
    Trainer,
    DataCollatorForLanguageModeling
)
from peft import LoraConfig, get_peft_model, TaskType
from datasets import load_dataset
import torch

def finetune_llm(
    model_name="meta-llama/Llama-2-7b-hf",
    dataset_name="tatsu-lab/alpaca",
    output_dir="./finetuned_model"
):
    """
    使用LoRA微调大语言模型
    """
    
    # 1. 加载模型和tokenizer
    print("加载模型...")
    tokenizer = AutoTokenizer.from_pretrained(model_name)
    tokenizer.pad_token = tokenizer.eos_token
    
    model = AutoModelForCausalLM.from_pretrained(
        model_name,
        torch_dtype=torch.float16,
        device_map="auto"
    )
    
    # 2. 配置LoRA
    print("配置LoRA...")
    lora_config = LoraConfig(
        r=16,                    # LoRA秩
        lora_alpha=32,           # 缩放参数
        target_modules=[         # 目标模块
            "q_proj",
            "k_proj",
            "v_proj",
            "o_proj"
        ],
        lora_dropout=0.05,
        bias="none",
        task_type=TaskType.CAUSAL_LM
    )
    
    model = get_peft_model(model, lora_config)
    model.print_trainable_parameters()
    
    # 3. 准备数据集
    print("准备数据集...")
    dataset = load_dataset(dataset_name, split="train[:1000]")
    
    def format_prompt(example):
        if example["input"]:
            text = f"### Instruction:\n{example['instruction']}\n\n### Input:\n{example['input']}\n\n### Response:\n{example['output']}"
        else:
            text = f"### Instruction:\n{example['instruction']}\n\n### Response:\n{example['output']}"
        return {"text": text}
    
    dataset = dataset.map(format_prompt)
    
    # 分词
    def tokenize_function(examples):
        return tokenizer(
            examples["text"],
            truncation=True,
            max_length=512,
            padding="max_length"
        )
    
    tokenized_dataset = dataset.map(
        tokenize_function,
        batched=True,
        remove_columns=dataset.column_names
    )
    
    # 4. 配置训练参数
    print("配置训练...")
    training_args = TrainingArguments(
        output_dir=output_dir,
        num_train_epochs=3,
        per_device_train_batch_size=4,
        gradient_accumulation_steps=4,
        learning_rate=2e-4,
        warmup_steps=100,
        logging_steps=10,
        save_steps=500,
        save_total_limit=2,
        fp16=True,
        optim="adamw_torch",
        lr_scheduler_type="cosine"
    )
    
    # 5. 创建Trainer
    data_collator = DataCollatorForLanguageModeling(
        tokenizer=tokenizer,
        mlm=False
    )
    
    trainer = Trainer(
        model=model,
        args=training_args,
        train_dataset=tokenized_dataset,
        data_collator=data_collator
    )
    
    # 6. 开始训练
    print("开始训练...")
    trainer.train()
    
    # 7. 保存模型
    print("保存模型...")
    model.save_pretrained(f"{output_dir}/final")
    tokenizer.save_pretrained(f"{output_dir}/final")
    
    print("训练完成!")
    return model, tokenizer

# 运行微调
if __name__ == "__main__":
    model, tokenizer = finetune_llm()

9. 避坑小贴士

9.1 训练阶段常见陷阱

  1. 显存溢出(OOM)

    • 解决方案:使用梯度累积、减小batch size、启用梯度检查点
    • 使用DeepSpeed ZeRO优化器状态分片
  2. 灾难性遗忘

    • 解决方案:混合原始数据与微调数据、使用更小的学习率
    • 采用LoRA等参数高效微调方法
  3. 过拟合

    • 解决方案:增加正则化、早停、使用更大的数据集
    • 监控验证集loss

9.2 推理阶段注意事项

  1. 温度参数选择

    • 创意写作:temperature=0.8-1.0
    • 事实问答:temperature=0.1-0.3
    • 代码生成:temperature=0.2-0.5
  2. 上下文长度限制

    • 预留足够的token给生成内容
    • 使用滑动窗口处理长文档
  3. 输出格式化

    • 使用stop sequences控制生成结束
    • 后处理去除重复内容

9.3 部署优化建议

  1. 模型量化

    • 生产环境建议使用INT8或INT4量化
    • 使用vLLM或TensorRT-LLM加速推理
  2. 批处理

    • 尽可能使用动态批处理(dynamic batching)
    • 合理设置最大等待时间
  3. 缓存策略

    • 对常见查询使用KV Cache
    • 实现提示模板缓存

10. 本章小结

核心知识点回顾

  1. Scaling Laws:模型性能随规模可预测增长,参数量、数据量、计算量需同步扩展

  2. GPT系列演进:从GPT-3的上下文学习到GPT-4的多模态能力,展现了大模型的强大潜力

  3. 开源生态:LLaMA系列推动了开源大模型发展,Mistral、Qwen等模型提供了多样化选择

  4. 对齐技术:SFT、RLHF、DPO等方法使模型输出更符合人类偏好和价值观

  5. 高效推理:量化(INT8/INT4)、vLLM等技术使大模型部署更加高效

  6. 2025年趋势:MoE架构、长上下文、多模态融合成为主要发展方向

关键公式总结

  • Scaling Law:L(N) = (N_c / N)^alpha
  • PPO目标函数:L^{CLIP}(theta) = E[min(r_t * A_t, clip(r_t) * A_t)]
  • DPO损失:L_DPO = -log(sigmoid(beta * (log pi(y_w|x) - log pi(y_l|x))))

本教程为《深度学习精通》系列的一部分,欢迎关注专栏获取更多内容。

版权声明:本文为原创内容,转载请注明出处。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐