从0训练LLM · 现代大模型体系 阅读 + 实验 ≈ 45 分钟 页内实验 ×5
C12 后训练:从续写到听话、推理、做事 第 2 课

好回答写不出来,但能比较:怎么把「比较」变成训练信号?

RLHF:把「比较」变成训练信号
SFT 只有正例,它分不清「另一个好回答」和「一个差回答」。人写不出最好的回答,却能说出两个里哪个更好:把成对比较拟合成一个打分(Bradley-Terry 奖励模型),再用 PPO 让策略往高分推,逐 token 的 KL 拴住它别跑远。代价是显存里同时放 4 个模型。
❓

本课一问:对贯穿提问,「在小王手里。」和「在小王手里:「给了」说明……」都是好回答,「我不确定。」是差回答。SFT 只会模仿示范,它知道「好」,不知道「差」。人很难写出最好的回答,却能轻松说出两个回答里哪个更好——怎么把这种「比较」变成模型能优化的信号?

这一课先不碰:不训奖励模型的做法(第 3 课 DPO);去掉 value 模型(第 4 课 GRPO);奖励被钻空子(第 5 课)。

从已有出发

上一课的 SFT 模型已经会按格式作答了。从这一课起,我们用一个教学世界把后面几课串起来:同一个贯穿提问,6 个候选回答——

回答Qwen3.8 token 数这是什么
A在小王手里。4直接作答
B在小王手里:「给了」说明苹果从小明转到了小王。15作答并说明理由
C在小明手里。4答错
D小明和小王都有可能。5两头下注
E小明把苹果给了小王,小王又把苹果给了小红,小红把苹果给了小李。18接着往下编(续写)
F我不确定。3拒答

一个只有 6 个 logit 的玩具策略代表「SFT 之后的模型」,初始概率 A 0.30、B 0.10、C 0.20、D 0.15、E 0.15、F 0.10。回答、初始概率和后面的偏好对都是手写的教学数据(不是任何模型的输出);token 数是 Qwen3.8 真 tokenizer 切的;之后的每一个数都由真算法在浏览器里算出。

从已有出发 · 后训练流水线 点已学的站看数据、损失与模型数
演进图 · 每一代都是被上一代的失败逼出来的本课高亮
  1. 第一代 SFT:用示范教格式 FLAN 2021 · LIMA 2023
  2. 第二代 RLHF:奖励模型 + PPO Christiano 2017 → Ziegler 2019 → InstructGPT 2022 你在这里
    解决了人只需比较两个回答;InstructGPT 的 1.3B 模型胜过 175B GPT-3,175B 版对 GPT-3 的胜率 85 ± 3%。
    卡在显存里同时放 4 个模型:按 Qwen3.8-27B 规模,policy 与 value 各 444.5 GB、RM 与参考模型各 55.6 GB,合计1000.1 GB。
  3. 第三代 · 离线 DPO:不训奖励模型 Rafailov et al. 2023(Stanford)
  4. 第三代 · 在线 GRPO 系:去掉 value model DeepSeekMath 2024-02 → DAPO / Dr. GRPO / GSPO 2025
  5. 奖励来源 RLVR:可验证的奖励 Tülu 3 2024-11 命名 · DeepSeek-R1 2025-01 规模化
  6. 岔路 RL 扩展了能力,还是重排? Yue 2025 vs ProRL 2025
  7. 第四代 思考模型:想更久,也能控 o1 2024-09 · R1 2025-01 · Qwen3 2025-05
  8. 第五代 蒸馏:小模型直接继承 Hinton 2015 → GKD 2023 → Qwen3 2025
  9. 第六代 Agentic RL:在环境里做事 SWE-RL 2025-02 · Kimi K2 · GLM-4.5 slime · DeepSeek-V3.2

先自己设计:再多给点示范,接着 SFT

最直接的想法:SFT 学得不够好,那就多写示范、接着训。示范只有「好回答」——比如只示范 A:

  1. ① 朴素方案
  2. ② 它在哪失败
  3. ③ 改进方案
朴素方案只用示范做 SFT(只示范 A)
问题:「小明把苹果给了小王。」苹果现在在谁手里?(标准答案:小王)

教学世界:候选回答、初始概率、偏好对是手写的教学数据(不是任何模型的输出或真实标注);token 数来自 Qwen3.8 真 tokenizer;其余数字由浏览器按真算法现算。

这不是因为示范写得不够多:SFT 的交叉熵梯度 p − onehot(A) 里,任何两个不是 A 的回答,只要当前概率相同,收到的梯度就完全相同 。示范能告诉模型「往哪去」,不能告诉它「别去哪」;而且示范的天花板是写示范的人。

改进一:让人比较,用 Bradley-Terry 把比较变成分数

为什么是比较而不是打分? 让标注者直接给回答打 1–7 分,每个人的尺度不一样;比较「哪个更好」要可靠得多——即便如此,InstructGPT 的训练标注者之间也只有 72.6 ± 1.5% 的一致率 ,所以要用概率模型去拟合,而不是当成确定的标签。这个思路不是 LLM 时代发明的:Christiano et al. 2017 在 Atari 和机器人任务上,只对不到 1% 的交互收集人类的成对偏好,就学会了复杂的行为 。

对齐的原料因此是一堆 (问题, 更好的回答, 更差的回答) 三元组。Bradley-Terry 模型假设每个回答有一个隐含分数 r,人选中 yw 的概率只取决于分差:

奖励模型的训练损失 · InstructGPT 式 (1)
loss(θ) = −E − )
👆 公式里带下划线的每一项都可以点——点哪项,讲哪项。
教学世界里:r_w − r_l = 1 时 P = σ(1) = 0.731,这一对的 loss = −ln 0.731 = 0.313;RM 刚初始化时所有分差都是 0,每一对的 loss 都是 ln 2 = 0.693。

上面「改进方案」一侧的奖励模型就是按这个式子在 9 对偏好上训出来的(4 个表面特征的线性模型:提到「小王」、长度、「在…手里」格式、含「可能 / 不确定」)。回到那个组件留意两件事:平均 loss 从 0.6931 一路降到 0.0834;而 E 这个续写式回答从没出现在标注里,却拿到了最高分 6.900——奖励模型只能按「提到小王、写得长」去外推它。这个伏笔在第 5 课兑现。

🔍 Bradley-Terry 与国际象棋的 Elo 是同一个公式

Elo 写作 P = 1 / (1 + 10−Δ/400),展开就是 σ(Δ · ln10 / 400):一个 β = ln10/400 ≈ 0.00576 的 Bradley-Terry。奖励模型的分数和棋手的 Elo 一样,单看一个数没有意义,只有差值有意义。奖励模型训练和第 3 课的 DPO 损失,本质上都在拟合这个 Bradley-Terry 概率;DPO 正是把它反解出了闭式最优策略。

rl
rw
−50+5
横轴 = 实力差 Δ = rw − rl,纵轴 = P(chosen 胜) = σ(Δ)。整条曲线只认差值——两个分一起平移,点纹丝不动。

把同一个 Δ 交给 DPO:σ(β·Δ)

DPO 说:隐式奖励 r = β·log πθ/πref。所以上面那个 Δ 换个读法——它是模型相对参考模型的对数比之差,要先乘 β 才是实力差,再进同一个 sigmoid。β 于是成了曲线的陡峭度旋钮:

灰色是 β=0.05 / 0.5 / 1.0 的参照曲线,紫色是你当前的 β。β 越大曲线越陡:偏离参考模型一点点,sigmoid 就到顶了。

🎯

试三件事:① 把两个实力分拖到差 6 分以上——胜率冲进 99% 的饱和区,曲线贴平、梯度几乎消失,这就是「已经分得很开的偏好对学不到东西」;② 点「整体 +2」,两个分一起右移而胜率一位小数都不动——只有差值进 sigmoid,所以奖励模型的绝对分数(和棋手的 Elo 绝对值一样)本身没有意义;③ 调 β:调大 → 曲线变陡 → 模型只要偏离参考模型一点点损失就到底、梯度归零 = 强锚定;调小 → 曲线变平 → 必须把对数比拉开很多才算达标 = 允许大幅偏离(β 这部分是给第 3 课 DPO 预备的)。

改进二:用 RL 让策略往高分推——PPO 的数据流

有了打分,就能让策略自己生成回答、拿分、往高分的方向改。RLHF 的完整配方是三段:① SFT;② 用偏好数据训奖励模型(RM);③ 用 PPO 优化策略,同时加 KL 惩罚防止它跑到奖励模型没见过的地方。出处要分清:Christiano 2017 用于 Atari 与机器人;第一次用于语言模型的是 Ziegler et al. 2019——风格续写只用了 5,000 条人类比较,摘要任务用了 60,000 条 ;Stiennon 2020 做摘要;InstructGPT 2022 把它做成了通用助手的配方。

一条回答走一遍 PPO,看每个数从哪来(回答 A 的 5 个 token 来自 Qwen3.8 真 tokenizer;奖励模型分来自上面训出的 RM):

🎯

试三件事:① 按顺序点 ①→⑦,盯住「奖励模型分」那一行:只有最后一个 token 有分,前面 4 个 token 的奖励只有 −β·KL;② 把 β 拖到 0,每个 token 的 KL 惩罚消失,r_t 只剩最后一格——这时没有任何东西把策略拴在 SFT 模型附近;③ 在步骤 ⑦ 把 ratio 从 1.3 拖回 1.1:第 1 个 token 的优势为正,ratio 超过 1.2 时「已裁剪,梯度 0」,回到 1.2 以内梯度恢复。

PPO 目标函数(InstructGPT 用法:裁剪目标 + 逐 token KL)
L(θ) = E[ min( , ) ] −
👆 公式里带下划线的每一项都可以点——点哪项,讲哪项。
min(未裁剪, 已裁剪) 取悲观的那个:占便宜的方向按裁剪后的算(防激进),吃亏的方向按更狠的算(不护短)。而 Â 从哪来?PPO 用一个和策略一样大的 value 模型估基线,再用 GAE 算——这正是第 4 课要砍的。
这个回答的优势:

🎯

三件事:① 把 ρ 从 1 往右拖过 1+ε,看曲线变平、梯度归零——这个好回答提得够多了,这一项不再推它;② 切到 Â = −1 往左拖过 1−ε——压差回答同样有这道闸;③ 注意反方向没有闸(虚线继续陡降):min 的「悲观取小」只防占便宜、不防吃亏。

⚠

常见误解一:「PPO 的 clip 让单次更新最多把概率提高 / 压低 20%。」(旧版课程的写法)

clip 只把「超出范围之后继续推」的那部分梯度去掉,不是硬上限。一批 rollout 之后要连续做好几次梯度更新(InstructGPT 把每批拆成 8 个 minibatch 依次更新,DAPO 每批 16 次,Tülu 3 有的设置每批重复 4 轮),一个 token 自己那一项被裁剪之后,别的样本的更新仍然会通过 softmax 归一化把它的概率推得更高。下面把教学世界的 6 个回答各采一次、在同一批上连续更新:

A 在第 20 次更新时 ratio 第一次超过 1.2(1.207),之后它自己不再贡献梯度,最后却停在 1.330。

常见误解二:「RLHF 是 InstructGPT 发明的。」 Christiano 2017 提出从人类偏好学奖励,Ziegler 2019 第一次用到语言模型上;InstructGPT 的贡献是把它做成了通用助手的配方,并证明了它的效果。

常见误解三:「PPO 天生是为 LLM 设计的。」 PPO 原文(Schulman 2017)是给 Atari 和 MuJoCo 设计的通用算法,里面没有语言模型、没有奖励模型、也没有 KL 锚点。复杂度是被搬过来的——理解这一点,才懂后面为什么要拼命简化。

代价:显存里同时放 4 个模型

PPO-RLHF 训练时要同时放 policy(在训)、value(在训)、奖励模型(冻结)、参考模型(冻结)。按锚点 Qwen3.8-27B 的规模(27,781,427,952 个参数)算:训练中的模型按混合精度 AdamW 每参数 16 字节(C9),policy 和 value 各 444.5 GB;冻结模型按 BF16 每参数 2 字节,RM 和参考模型各 55.6 GB,合计 1000.1 GB,还不算激活和生成用的 KV cache。下面这张图里的计算器可以自己换组合:

两条轴 · 优化器 × 信号来源(不是一条「砍法线」)
信号来源 ↓ / 优化器 →模仿交叉熵(SFT、拒绝采样 SFT)PPOcritic + GAE + clip离线偏好损失DPO 系,不采样组内基线GRPO / DAPO / GSPO蒸馏对老师分布的 KL
人写的示范
FLAN · LIMA2021 · 2023 显存里 1 个模型
人类偏好(学出的 RM)
Ziegler 20192019 显存里 4 个模型
InstructGPT2022 显存里 4 个模型
Llama 3 · Tülu 3 偏好阶段2024 显存里 2 个模型
DeepSeekMath2024-02 显存里 3 个模型
可验证规则
Tülu 3 RLVR2024-11 显存里 3 个模型
DeepSeek-R1-Zero2025-01 显存里 2 个模型
DAPO2025-03 显存里 1 个模型
SWE-RL2025-02 显存里 2 个模型
GLM-5 推理 RL2026-02 显存里 1 个模型
环境反馈
GLM-5.2 / 5.3 SAO2026-07 模型数:未全部披露
DeepSeek-V3.2 agent RL2025-12 模型数:未全部披露
老师模型的分布
Qwen3 strong-to-weak2025-05 显存里 2 个模型
V4 OPD · K3 MOPD2026 模型数:未全部披露

橙框两格是旧课讲错的地方:Tülu 3 的 RLVR 用的是 PPO,DeepSeekMath 的 GRPO 用的是学出来的奖励模型。「RLVR」说的是奖励从哪来,「GRPO」说的是梯度怎么算,两件事可以任意组合。悬停格子里的系统看出处要点。

自己组合:显存里要放几个模型?(Qwen3.8-27B 规模,27,781,427,952 个参数)

InstructGPT 实际用的是 6B 的 RM 和 6B 的 value 模型,配 1.3B、6B、175B 三种 policy(附录 C)。效果是真的:在他们的提示分布上,1.3B 的 InstructGPT 比 175B 的 GPT-3 更受偏好;175B 的 InstructGPT 对 GPT-3 的胜率是 85 ± 3%,对加了 few-shot 提示的 GPT-3 也有 71 ± 4% 。

证据三问

问本课的回答
① 它解决什么问题?SFT 只有正例、天花板是标注者;比较比示范便宜、能表达「差」
② 数学上为什么可能有效?Bradley-Terry 只依赖分差,是二分类交叉熵 ;KL 惩罚把策略限制在 RM 可信的区域里,是理论动机
③ 实验上为什么选了它?Ziegler 2019 的风格续写与摘要;InstructGPT 1.3B 胜 175B GPT-3

一句话

📌

人写不出最好的回答,但能说出两个里哪个更好:把「更好」拟合成一个打分,再用 RL 把策略往高分推,KL 拴住它别跑偏。

🚦

先停在这里:记住「Bradley-Terry 只看分差;PPO 只有最后一个 token 拿到 RM 分;clip 去掉的是激励不是上限;显存里 4 个模型」。
再深一层:在 PPO 数据流组件里改 value 那一行,看 critic 估得准不准如何改变前面 token 的优势;再去读 InstructGPT 附录 C 的超参。

下一个缺口

显存里 4 个模型,奖励模型还得先单独训一遍,PPO 的超参(β、γ、λ、ε、value 学习率)又多又敏感。能不能不训奖励模型,直接用偏好数据训策略? → 第 3 课:DPO

回扣:value 模型和 GAE 的 λ 为什么难调,第 4 课兑现;E 这个没被标注过的回答拿了最高分会怎样,第 5 课兑现。

你可能会问