27届大模型面试准备(十六):后训练全攻略——SFT、RLHF、DPO、PPO 一次讲透

27届大模型面试准备(十六):后训练全攻略------SFT、RLHF、DPO、PPO 一次讲透

上一篇《高效推理全攻略》讲的是"怎么让模型推理又快又省",属于部署侧。这一篇回到训练侧,把"预训练之后的所有事"------也就是后训练(Post-Training)------一次性讲透。覆盖 SFT、Reward Model、RLHF(PPO)、DPO 四条主线,外加一条工程副线(数据配方、课程学习、拒绝采样)。每节都给:原理 → 数学/算法骨架 → 代码片段 → 面试速答 + 高频追问。配合《LoRA/PEFT》(候选 A18)一起看,刚好串成"对齐怎么做、怎么省显存做"。


一、先理清"预训练"和"后训练"的职责边界

很多面试者把二者混为一谈,第一句就露怯。一句话区分:

  • 预训练(Pre-training):在海量无标注语料上做 next-token prediction,给模型"通识知识"和"语言流畅度"。此时模型像一本读过的百科全书,但不会按你的指令办事。

  • 后训练(Post-training):在预训练之后,用"指令 / 对话 / 偏好"数据把模型对齐(alignment)到"人类想要的回答方式"。包括 SFT、RLHF、DPO、安全对齐等。

    复制代码
                      预训练                      后训练
          ┌───────────────────────┐   ┌──────────────────────────────┐
          │ 8B~万亿 token 语料      │   │ SFT(指令) → RM(偏好)           │
          │ next-token 预测         │──▶│   → RLHF(PPO) / DPO(直接偏好)  │
          │ 产出: 基座模型 base      │   │ 产出: 对话模型 chat / instruct │
          └───────────────────────┘   └──────────────────────────────┘
                   通识 + 流畅                  有用 + 无害 + 听指令

面试常问:"为什么不直接用预训练模型上线?" 答案是:base 模型只会"续写",不会"对话"------你给它"请写一首诗",它可能接着写"请写一首诗的步骤如下"。SFT 就是把"续写者"变成"对话者"。


二、SFT:后训练的第一块基石

2.1 SFT 在做什么

SFT(Supervised Fine-Tuning,监督微调)用"指令-回答"配对数据,继续做 next-token prediction,但数据从"网页语料"换成"高质量对话/任务样本"。目标函数和预训练一致,只是数据分布变了:

复制代码
预训练损失:  L_pt = -Σ log P(x_t | x_<t)        # x 是网页文本
SFT 损失:    L_sft = -Σ log P(a_t | a_<t, q)     # q 是指令, a 是理想回答

注意:通常只在 answer 部分算 loss,instruction/prompt 部分 mask 掉(label 置 -100),否则模型会学"怎么复述问题"而不是"怎么回答"。

2.2 一个最小 SFT 数据样本

复制代码
{
  "instruction": "把下面这句话翻译成英文:今天天气真好。",
  "input": "",
  "output": "The weather is really nice today."
}

多轮对话则组织成 messages 列表:

复制代码
{
  "messages": [
    {"role": "system", "content": "你是一个严谨的翻译助手。"},
    {"role": "user",   "content": "把'今天天气真好'翻译成英文。"},
    {"role": "assistant", "content": "The weather is really nice today."}
  ]
}

2.3 SFT 质量的三个关键点

维度 常见错误 正确做法
数据量 认为越多越好,堆几百万条噪声 几万条高质量远胜几百万条低质;质量 > 数量
多样性 单一任务(全是翻译) 覆盖推理/创作/代码/安全拒答等多题型
格式 混入系统 prompt 噪声 prompt 部分 mask 掉 loss,只训回答

用 HuggingFace TRL 跑 SFT 的最小骨架:

复制代码
from trl import SFTTrainer, SFTConfig
from datasets import load_dataset

dataset = load_dataset("json", data_files="sft_data.jsonl")["train"]

trainer = SFTTrainer(
    model="Qwen/Qwen2.5-7B",
    args=SFTConfig(
        per_device_train_batch_size=4,
        max_seq_length=2048,
        num_train_epochs=3,
        learning_rate=2e-5,
        packing=True,          # 把短样本拼接到一条,提升吞吐
    ),
    train_dataset=dataset,
)
trainer.train()

面试速答:SFT 为什么只用 answer 算 loss?因为 instruction 是"已知条件",模型在推理时已经知道;我们要优化的是"给定问题后生成好回答"的概率,prompt 部分的预测不需要学。

高频追问

  1. packing 和 padding 的区别?packing 把多条样本拼接避免浪费,padding 用 0 补齐到相同长度(浪费算力)。

  2. SFT 学习率一般比预训练大还是小?更大(如 1e-5~3e-5),因为数据少、要快速适配指令分布。

  3. 全量 SFT 和 LoRA-SFT 怎么选?数据少/防灾难性遗忘选 LoRA;要深度改变行为选全量。


三、Reward Model:RLHF 的"裁判"

RLHF 需要一个人来打分,这个"人"就是 Reward Model(RM)。它把"回答质量"映射成一个标量分数。

3.1 RM 的训练数据:成对偏好

RM 不用绝对分数,而用成对比较数据(人类标注"回答 A 比回答 B 好"):

复制代码
{
  "chosen":   "北京是中国的首都。",
  "rejected": "北京是美国的一个城市。"
}

3.2 RM 的损失函数(Bradley-Terry 模型)

把 RM 记作 r(x, y),希望 chosen 分数高于 rejected:

复制代码
L_RM = -E[ log σ( r(x, y_chosen) - r(x, y_rejected) ) ]

σ 是 sigmoid。直观:差距越大、符号越对,损失越小。RM 通常就是"基座模型 + 一个回归头(把 hidden 压成 1 维)"。

复制代码
# RM 头:取最后一个 token 的 hidden 投射到标量
class RewardModel(nn.Module):
    def __init__(self, base):
        self.base = base
        self.value_head = nn.Linear(base.config.hidden_size, 1)
    def forward(self, input_ids, attention_mask):
        out = self.base(input_ids, attention_mask).last_hidden_state
        # 取每个序列最后一个非 pad token
        scores = self.value_head(out[:, -1, :])
        return scores.squeeze(-1)

面试速答:为什么用成对比较而不是绝对打分?因为人类对"绝对分数"标定很不一致,但对"哪个更好"的相对判断稳定得多,标注成本低、信噪比高。

高频追问

  1. RM 过优化(reward hacking)是什么?模型找到骗 RM 拿高分的捷径(比如啰嗦、拍马屁),而非真正变好。

  2. 怎么缓解?加 KL 惩罚、定期用新模型数据重训 RM、做 RM 集成。


四、RLHF 的核心:PPO 算法

PPO(Proximal Policy Optimization)是 RLHF 经典算法。把"生成回答"看成强化学习:策略 π 是待训练的语言模型,奖励来自 RM,约束是不偏离原始 SFT 模型太远(防崩)。

4.1 总目标

复制代码
L_PPO = E[ r_t(θ) * A_t ]  -  β * KL( π_θ(y|x) || π_ref(y|x) )
其中:
  r_t(θ) = π_θ(y_t|y_<t, x) / π_old(y_t|y_<t, x)   # 概率比
  A_t     = 来自 GAE 的优势估计(由 RM 打分驱动)
  KL 项   = 防止模型跑太偏,β 是系数

4.2 PPO 四件套

复制代码
┌────────────┐   ┌────────────┐   ┌────────────┐   ┌────────────┐
│ Actor (π)  │   │ Critic (V) │   │ Reward(RM) │   │ Reference  │
│ 待更新策略 │   │ 价值估计   │   │ 打分裁判   │   │ 初始锚点   │
└─────┬──────┘   └─────┬──────┘   └─────┬──────┘   └─────┬──────┘
      │ 生成 y          │ 估 V           │ 打 r           │ 算 KL 锚
      └────────────────┴─────── 共同计算 PPO loss ────────┘

4.3 TRL 跑 PPO 的最小骨架

复制代码
from trl import PPOTrainer, PPOConfig, AutoModelForCausalLMWithValueHead
from transformers import AutoTokenizer

model = AutoModelForCausalLMWithValueHead.from_pretrained("sft-model")
ref_model = AutoModelForCausalLMWithValueHead.from_pretrained("sft-model")
tokenizer = AutoTokenizer.from_pretrained("sft-model")

config = PPOConfig(batch_size=16, learning_rate=1e-6,
                   kl_penalty="kl", init_kl_coef=0.02)
ppo = PPOTrainer(config, model, ref_model, tokenizer)

for batch in dataloader:
    query = tokenizer(batch["prompt"], return_tensors="pt")
    response = model.generate(**query, max_new_tokens=128)
    reward = rm_score(query, response)          # RM 打分
    stats = ppo.step(query["input_ids"], response, reward)

面试速答:RLHF 里 KL 惩罚的作用?防止策略为了骗 RM 而偏离 SFT 模型太远导致语言崩坏(满嘴乱码)。它是"有用"和"不像人话"之间的安全绳。

高频追问

  1. Critic 和 RM 的区别?RM 给整句打分(外部裁判),Critic 预估每步价值(内部基线,降低方差)。

  2. 为什么 PPO 比普通 policy gradient 稳?用了 clip 把概率比限制在一定范围,避免一步更新过猛。


五、DPO:绕开 RM 和 PPO 的直接偏好优化

PPO 又贵又脆(要四个模型同时在线)。2023 年提出的 DPO(Direct Preference Optimization)证明:在 KL 约束下,最优策略和 RM 有闭式关系,于是可以直接在偏好数据上用分类损失训,不需要显式 RM、不需要 RL 循环。

5.1 DPO 损失

复制代码
L_DPO = -E[ log σ( β * ( log π_θ(y_w|x)/π_ref(y_w|x)
                         - log π_θ(y_l|x)/π_ref(y_l|x) ) ) ]
        y_w = chosen,  y_l = rejected

关键点:它把"奖励差"隐式编码进策略比里,β 控制偏离 ref 的强度。

5.2 DPO vs PPO 对比

维度 PPO/RLHF DPO
需要 RM 是(单独训练) 否(隐式)
在线采样 需要(rollout) 不需要,离线
显存/算力 高(4 模型) 低(2 模型)
训练稳定性 较脆,超参敏感 较稳
动态探索 弱(依赖静态数据)

5.3 TRL 跑 DPO 的最小骨架

复制代码
from trl import DPOTrainer, DPOConfig

dpo = DPOTrainer(
    model="sft-model",
    ref_model="sft-model",           # 固定参考
    args=DPOConfig(beta=0.1, learning_rate=5e-6,
                   per_device_train_batch_size=4),
    train_dataset=pref_dataset,      # 含 chosen / rejected 字段
)
dpo.train()

面试速答:DPO 为什么不需要 reward model?因为 Bradley-Terry + KL 约束下,最优策略的奖励可以写成"策略比 ref 的对数概率差",这个量在训练时直接可算,于是 RM 被消掉了。

高频追问

  1. DPO 的弱点?数据静态,模型只能从已有 chosen/rejected 学,缺乏 PPO 的在线探索,容易被数据分布限制。

  2. β 太大或太小会怎样?太大→几乎不更新(贴近 ref);太小→可能过拟合偏好、语言退化。

  3. 线上该选哪个?资源紧/求稳选 DPO;要最强效果且有 RL 工程能力选 PPO。


六、工程副线:数据配方与课程学习

面试高阶题常考"后训练怎么排兵布阵",这里给一个可落地配方:

复制代码
阶段1  SFT(通用指令)      ------ 让模型学会按指令办事
阶段2  SFT(领域/硬任务)   ------ 注入代码、数学、安全拒答等硬能力
阶段3  DPO / RLHF(偏好)   ------ 对齐"风格、无害、有用"
阶段4  安全对齐 + 红蓝对抗 ------ 专门修越狱、补拒答

课程学习(curriculum):先易后难、先广后专。常见坑:

  • 灾难性遗忘:后训练把预训练知识冲掉。缓解:混入少量预训练续写数据(replay)、用 LoRA 而非全量。
  • 长度崩坏:RL 阶段模型学会"越长分越高"。缓解:RM 加长度惩罚、KL 约束。
  • 分布漂移:偏好数据来自少数标注员,模型被窄化。缓解:多源标注、定期重采。

面试速答:为什么后训练要分阶段而不是一把梭?不同阶段目标冲突(通用性 vs 专业性 vs 偏好),一把梭会让梯度互相打架;分阶段能让每阶段专注一类能力,且便于单独 debug。


七、面试速答 + 高频追问清单(汇总)

速答 TOP 8:

  1. 预训练给知识,后训练给对齐(指令遵循 + 偏好)。

  2. SFT 只在 answer 算 loss,prompt 部分 mask。

  3. RM 用成对比较训练,输出标量奖励。

  4. PPO 四件套:Actor / Critic / Reward / Reference,KL 防崩。

  5. DPO 用偏好数据直接训,隐式消去 RM。

  6. DPO 省算力但缺在线探索;PPO 效果好但脆。

  7. β 控制偏离 ref 的强度。

  8. 后训练分阶段是为避免目标冲突与遗忘。

追问清单:

  • 为什么 RM 用 Bradley-Terry 而不是 MSE?

  • reward hacking 有哪些典型表现,怎么发现?

  • 多轮对话的 RLHF 怎么处理?

  • DPO 的隐式奖励公式推导一遍。

  • 全量微调 vs LoRA 在后训练各阶段怎么搭配?


八、下一篇预告

后训练讲完"对齐怎么做",下一篇(候选 A17)可以深入分布式训练 DeepSpeed / FSDP / Megatron ------把"训练一个大模型"的工程底座讲明白;或者 A18 的 LoRA/QLoRA/PEFT 省显存全家桶。如果你更想听推理侧,A15 的高效推理已经就位。评论区告诉我你想先啃哪个。

相关推荐
四六的六2 小时前
端侧模型多端部署实战:从格式转换到灰度发布,Web 和移动端统一部署流水线
前端·人工智能·大模型·ai编程·ai模型·ai产品·端侧ai
thesky1234569 小时前
智能体面试准备(十八):Function Calling 全链路——Agent 真正动手的最后一公里
函数调用·智能体·工具调用·functioncalling·面试准备
@Mr_LiuYang10 小时前
《深入理解 AI Agent:设计原理与工程实践 》实验2-1 本地大模型服务部署与工具调用
人工智能·大模型·本地化部署·深入理解ai agent
aqi0012 小时前
15天学会AI应用开发(十九)使用LangGraph实现持久记忆功能
人工智能·python·大模型·ai编程·ai应用
云卷云舒___________12 小时前
传OpenAI将发Astra新一代模型、谷歌Gemini3.5Pro现身后端、字节欲练5万亿参数大模型 | 8月7日 AI日报
大模型·openai·谷歌·字节跳动·astra·ai日报·gemini35pro
绵满13 小时前
"AgentX: Towards Agent-Driven Self-Iteration of Industrial Recommender Systems" 论文笔记
大模型·推荐系统·多智能体
熊猫钓鱼>_>1 天前
用Seed Evolving+高德地图做城市旅行规划Agent
大模型·agent·规划·智能体·豆包·火山·seed evolving
hoaxxcj1 天前
多智能体把云可靠性工程自动化:NeurIPS 2025 的 STRATUS 比 SOTA 强 1.5 倍,还顺手定了条“安全规范“
运维·安全·自动化·大模型·ai论文·前沿解读