📑 本页目录(点开跳转)
12 · RLHF 全流程
⏱ 44 分钟 | ⭐⭐ 前 11 章的零件在这里全部就位
🎯 一句话
RLHF 解决一个具体的困难:有些"好"你写不出评分函数。 「这个回答有帮助吗」「这段话礼貌吗」—— 没法写成损失函数。 那就让人来比较,用比较训一个模型来打分,再用 RL 去优化那个分数。
🤔 一、为什么需要它
预训练教会模型「下一个词是什么」
微调(SFT)教会模型「按指令回答」
⚠️ 但两者都是【模仿】—— 模型只能学到示范里有的东西
⭐ 而人类对"好回答"的判断有三个特点:
├─ 说不清标准(但一比就知道哪个好)
├─ 和上下文强相关
└─ 写不出可微的评分函数
→ 监督学习卡在这里
💡 关键的转念:
「让人【写】一个满分答案」很难、很贵、且一个人写不出多样性
「让人【比较】两个答案哪个好」容易、便宜、一致性还高得多 ⭐
→ RLHF 的全部起点就是这个观察
🏗️ 二、三个阶段
- 数据:人写的(指令, 优质回答)
- 产出:一个会听指令的基础模型 π_SFT
- 数据:人对同一提示的多个回答【排序】
- 产出:一个能给回答【打分】的模型
- 做法:用 RM 当奖励,用 PPO 更新语言模型
- 产出:对齐后的模型
↓ 三个阶段严格按顺序进行:上一阶段的产出,就是下一阶段的输入。
🏆 三、阶段 2:奖励模型怎么训
数据长这样:
提示:"解释一下量子纠缠"
回答 A:(清晰、有类比、承认了简化)
回答 B:(堆砌术语、没有解释)
标注者:A > B ⭐ 只需要比较,不需要打分
损失函数(Bradley–Terry 模型):
$$L = -\log\sigma\big(r(x, y_{win}) - r(x, y_{lose})\big)$$
💡 人话翻译:
让"好回答的分"减去"差回答的分"尽量大。 注意它只关心分数的差,不关心绝对值 —— 所以打出来的分数没有绝对含义。
# 奖励模型的训练核心就这两行
import torch.nn.functional as F
r_win, r_lose = rm(prompt, chosen), rm(prompt, rejected)
loss = -F.logsigmoid(r_win - r_lose).mean()
⚠️ 奖励模型的三个真实问题
| 问题 | 说明 |
|---|---|
| 标注噪声 | 人类之间一致率通常只有 70~80% —— 这是奖励模型精度的天花板 ⭐ |
| 长度偏好 ⭐ | 标注者倾向于选更长的回答 → RM 学会"越长越好" → 模型变得啰嗦 |
| 分布漂移 | RM 在 SFT 模型的输出上训练,但 PPO 会把模型推到 RM 没见过的区域 ⭐ |
🔑 第三点是 RLHF 最本质的困难: 奖励模型只在它见过的分布上准。 PPO 优化得越狠,模型越会跑到 RM 的盲区, 那里的分数是不可信的 —— 这直接导致下面的奖励攻击。
💀 四、奖励攻击(Reward Hacking)
模型不是在"变好",而是在【钻奖励模型的漏洞】
真实观察到的现象:
├─ 回答越来越长(RM 有长度偏好)⭐
├─ 疯狂使用列表和 Markdown 格式
├─ 开头必说"这是一个很好的问题!"
├─ 过度谨慎、什么都不敢回答(因为"安全"得分高)
└─ 在特定短语上过拟合
三道防线:
① KL 惩罚 ⭐(第 11 章)
r = RM分数 − β·KL(π ‖ π_SFT)
→ 把模型拴在 SFT 附近,不让它跑到 RM 的盲区
② 早停:盯着【KL 散度】而不是奖励分数
→ 奖励还在涨但 KL 已经很大 = 正在钻漏洞 ⭐
③ 迭代式 RLHF:用新模型的输出重新标注、重训 RM
→ 把 RM 的有效范围扩展到新分布上
💡 第 ② 条是实践中最有用的一条经验: 奖励分数上涨不代表模型变好。 真正该监控的是 「KL 散度」和「人工抽样评估」 —— 前者告诉你跑多远了,后者告诉你是不是真的更好。
🔧 五、阶段 3 的工程现实
PPO 训练时【同时要装下四个模型】:
├─ 策略模型 π (在训练,要梯度)
├─ 参考模型 π_SFT (冻结,算 KL)
├─ 奖励模型 RM (冻结,打分)
└─ 价值模型 Critic (在训练,要梯度)
⭐ 显存约为 SFT 阶段的 4 倍以上 —— 这是 RLHF 昂贵的直接原因
几个关键的工程细节:
| 细节 | 说明 |
|---|---|
| 奖励只在最后一个 token 给 | 中间 token 的奖励只有 KL 项 |
| Critic 通常和策略共享 backbone | 加一个价值头,省显存 |
| γ 常设为 1.0 | 文本生成的回合很短,不需要折扣 |
| 优势用 GAE(λ=0.95) | 第 10 章 |
| KL 系数 β 可自适应 | KL 超标就调大 β |
🌱 六、变体与后续路线
| 方法 | 关键区别 |
|---|---|
| RLAIF | 用 AI 代替人做偏好标注(Constitutional AI)→ 便宜、可扩展 ⭐ |
| DPO ⭐ | 完全跳过 RM 和 PPO,直接用偏好数据优化 → 第 13 章 |
| GRPO | 去掉 Critic,用一组采样的相对排名当优势 → 省显存,DeepSeek 用它 ⭐ |
| 过程监督 PRM | 给推理的每一步打分而不只是最终答案 → 数学/代码任务上明显更好 ⭐ |
| RLVR | 用可验证的奖励(代码能否跑通、数学答案对不对)→ 没有奖励攻击问题 ⭐⭐ |
🔑 RLVR 值得特别注意: 当奖励是可自动验证的客观事实(单元测试通过、数学答案正确)时, 奖励模型的所有问题都消失了 —— 没有标注噪声、没有长度偏好、无法钻漏洞。 这就是近年推理模型训练的主流方向。
🧮 GRPO 展开:把 Critic 换成「同组同学的平均分」
表格里 GRPO 那一行值得单独展开 —— 因为跑 RLVR 的那个算法通常就是 GRPO(DeepSeek-R1 正是这个组合)。
组内优势:不训 Critic 也能算「比预期好多少」
先回忆 Critic 在干什么(第 10 章):它是一个基线,回答「这个状态本来大概能拿多少分」, 用实际回报减掉它得到优势 A,目的是降方差。
GRPO 的做法直接得多:
对同一个 prompt,采样 G 个回答(常见 G = 8 ~ 64)
逐个打分,得到 r₁ … r_G
⭐ 组内标准化,结果直接当优势用:
A_i = (r_i − mean(r)) / std(r)
💡 为什么这样就能替代 Critic:优势的本质是「减掉一个与当前动作无关的基线」。 Critic 是「学」出来的基线,组内均值是「采」出来的基线。 ⭐ 关键前提:这 G 个回答来自同一个 prompt,所以它们的"预期得分"确实是同一个数 —— 这个基线才合法。
除以 std 是在拉平题目难度:简单题一组都在 0.9 附近、难题都在 0.1 附近,减完均值差异都只有 ±0.03; 不除 std,梯度会被"难度适中"的那批 prompt 主导,除完之后每个 prompt 的贡献才相当。
⚠️ 一个必须处理的边界:一组回答全对或全错时 std = 0 → 优势全是 0(或除零成 NaN),这个 prompt 白采了 G 次。 实现里要么加 eps,要么整组丢弃。⭐ 这条使 GRPO 对题目难度分布很敏感:题太简单或太难,大量组是"零梯度组",采样算力全打水漂。
KL 的位置和 PPO 不一样
| PPO / 标准 RLHF | GRPO | |
|---|---|---|
| KL 放在哪 | 进 reward:r_total = RM分数 − β·KL |
⭐ 直接加进损失函数,reward 里不含 KL |
| 后果 | KL 要经过 GAE、折扣、Critic 一路传播,被"搅拌"过一遍 | 优势 A 是纯粹的"这个回答好不好",不掺"跑了多远";KL 梯度直接落到每个 token |
$$L_{GRPO} \;=\; -\,\mathbb{E}\big[\text{裁剪过的策略比}\times\text{组内优势}\big] \;+\; \beta\, D_{KL}(\pi_\theta \,\|\, \pi_{ref})$$
⭐ 而且它的 KL 估计式也不是朴素那个:$-\log(\pi_{ref}/\pi_\theta)$ 的单样本估计会取到负值、方差还大,GRPO 改用
$$\hat D_{KL} = \frac{\pi_{ref}}{\pi_\theta} - \log\frac{\pi_{ref}}{\pi_\theta} - 1 \;\;\ge\; 0$$
恒非负、且仍然无偏 —— 小改动,但让 KL 直接进损失时稳定得多。
🔗 KL 散度本身(定义、为什么不对称、和交叉熵/最大似然的关系)在 数学原理 01b · KL 散度。 ⭐ 那一章还解释了一件和本章直接相关的事:KL 惩罚是反向 KL,所以它拴得住模型别跑飞,却拦不住 mode collapse。
省了多少:一笔显存账
去掉 Critic,省的不是"四分之一",而是四个模型里最贵的那一类 —— 一个要训练的、和策略同尺寸的模型。
每参数:要训练的 ≈ 16 字节(fp16 参数2 + 梯度2 + fp32 主权重4 + Adam m4 + v4)
冻结的 ≈ 2 字节 ⭐ 差 8 倍
7B 粗算(不含激活值与采样时的 KV Cache):
PPO :策略112 + Critic112 + 参考14 + RM14 ≈ 252 GB
GRPO:策略112 + 参考14 + RM14 ≈ 140 GB ⭐ 接近腰斩
🔗 这些数字的来历见 AI基础设施 03 · 显存与带宽墙(16 字节/参数怎么拆出来的、7B → 112 GB 就是那条经验公式); 怎么把它省下来见 09 · 显存优化全家桶、11 · ZeRO 与 FSDP。
⚖️ PPO / DPO / GRPO 三方对比
| PPO | DPO | GRPO | |
|---|---|---|---|
| 要几个模型 | 4 个(策略·Critic·参考·RM),2 个在训练 | 2 个(策略·参考),1 个在训练 | 3 个(策略·参考·RM 或验证器),1 个在训练 |
| 优势从哪来 | Critic 学出来的价值基线 + GAE | 不需要优势,直接对偏好对做分类 | ⭐ 同一 prompt 采 G 个,组内均值当基线 |
| 要不要在线采样 | 要 | 不要(吃离线偏好数据) | 要,而且一个 prompt 要采 G 次 |
| KL 在哪 | 加进 reward | 隐含在 β·log(π/π_ref) 里,是推导的出发点 | 直接加在损失上 |
| 采样成本 | 1× | 0 | ⚠️ G×(G 常取 8~64) |
| 最适合 | 通用偏好对齐,且有人能调 RL | 偏好对齐,团队小、要快 | ⭐ 有可验证奖励的任务(数学、代码) |
| 典型代表 | InstructGPT / ChatGPT | Zephyr 及大量开源对齐模型 | DeepSeek-R1 |
🔑 一句话选型: 有现成偏好对、只想调风格和有帮助性 → DPO(第 13 章;先试拒绝采样更省)。 答案能自动验证(单元测试跑通、数学答案对) → GRPO + RLVR:奖励免费、没有 RM 可钻,组内标准化还天然处理了"题目难度不一"。 必须在线探索、而奖励只能靠 RM → PPO。
💡 GRPO 省的是显存,花的是采样:G=16 意味着每一步要多生成 15 份回答。 ⭐ 它把「训一个 Critic」的成本换成了「多采 15 份样本」的成本 —— 在推理吞吐便宜、而 Critic 又难训(长序列上的价值估计本来就很不准)的场景下,这笔交易划算。
🧩 七、前 11 章的零件在这里的位置
| 零件 | 来自哪章 | 在 RLHF 里是什么 |
|---|---|---|
| MDP 建模 | 02 | 状态=已生成序列,动作=下一个 token |
| 回报与折扣 | 03 | γ 通常设 1.0 |
| 价值函数 | 03 | Critic 头 |
| TD / GAE | 05、10 | 优势估计 |
| 探索 | 07 | 采样温度、熵 |
| 策略梯度 | 09 | 更新的基本形式 |
| Actor-Critic | 10 | 整体架构 |
| PPO + KL | 11 | 优化算法 ⭐ |
🔑 这就是把 RL 放进这套教程的理由: RLHF 不是一个新算法,是前 11 章零件的一次组装。
🔗 这一章连到哪里
| 去哪 | 为什么 |
|---|---|
| 全景导论 04 | 这一章在大模型全流程里的位置:预训练 → SFT → 你现在读的这步 |
| AI基础设施 11 | ⭐ 第五节「工程现实」的解法:四个模型同时装进显存,靠的是 ZeRO 分片 + offload |
| 上线之后 15 | ⭐ 奖励攻击不是 RL 独有的 —— 它就是古德哈特定律,代理指标被优化坏的通用形态 |
| 数学原理 01b · KL 散度 | ⭐ 本章反复在用的 KL 散度,定义在那里:它到底在量什么、为什么不对称,以及为什么 KL 惩罚拴得住模型不跑飞、却拦不住 mode collapse |
| AI基础设施 03 · 显存与带宽墙 | ⭐ GRPO 那笔显存账的数字来历:训练态 16 字节/参数(fp32 主权重 4 + Adam m 4 + v 4 + BF16 参数 2 + 梯度 2)、冻结态 2 字节(BF16),以及 训练显存 ≈ 16 × 参数量(B) 那条经验公式(7B → 112 GB,正是上面「策略 112」的出处) |
| AI基础设施 09 | 省不动的时候还能怎么省:七件武器(梯度检查点、ZeRO、LoRA…)和 8-bit Adam 把优化器状态从 12 字节压到 4 |
✅ 检查点
- 为什么监督学习解决不了"对齐"?关键的转念是什么?
- RLHF 的三个阶段分别产出什么?
- 奖励模型的损失函数是什么?它只关心什么?
- 奖励模型的三个真实问题?哪个最本质?
- 奖励攻击有哪些典型表现?
- 三道防线是什么?实践中最有用的监控指标是什么?
- PPO 阶段要装几个模型?分别是什么?
- GRPO 相比标准 PPO 省了什么?
- GRPO 的组内优势怎么算?为什么"组内均值"可以当基线用?为什么还要除以 std?
- GRPO 的 KL 放在哪,和 PPO 有什么不同?这样做有什么好处?
- PPO / DPO / GRPO 各要几个模型、各要采几次样?什么时候该选哪个?
- RLVR 为什么能消除奖励攻击?
👀 答案
- 因为人类对"好回答"的判断说不清标准、和上下文强相关、写不出可微的评分函数。关键转念:"让人写一个满分答案"很难很贵,"让人比较两个答案哪个好"容易便宜且一致性高。
- ①SFT:产出会听指令的基础模型 ②奖励模型:产出能给回答打分的模型 ③PPO:产出对齐后的模型。
- L = −log σ(r(win) − r(lose))(Bradley–Terry)。只关心分数的差,不关心绝对值——所以打出来的分没有绝对含义。
- ①标注噪声(人类一致率仅 70~80%,是精度天花板)②长度偏好(标注者倾向选长的 → 模型变啰嗦)③⭐分布漂移——最本质:RM 只在它见过的分布上准,PPO 优化越狠模型越跑到 RM 盲区,那里的分数不可信。
- 回答越来越长、疯狂用列表和 Markdown、开头必说"这是个好问题"、过度谨慎什么都不敢答、在特定短语上过拟合。
- ①KL 惩罚(拴在 SFT 附近)②盯 KL 散度早停 ③迭代式 RLHF(重新标注重训 RM)。⭐最有用的监控:KL 散度 + 人工抽样评估——奖励分数上涨不代表模型变好。
- 四个:策略模型(训练)、参考模型 π_SFT(冻结,算 KL)、奖励模型(冻结,打分)、Critic(训练)。显存约 SFT 的 4 倍,这是 RLHF 昂贵的直接原因。
- 省掉了 Critic——用一组采样的相对排名当优势。省的不是"四分之一",而是四个模型里最贵的那一类:一个要训练的、和策略同尺寸的模型(训练态约 16 字节/参数,冻结态只要 2 字节,差 8 倍)。7B 粗算:PPO ≈ 252 GB → GRPO ≈ 140 GB,接近腰斩。DeepSeek-R1 用它。
- A_i = (r_i − mean(r)) / std(r):同一 prompt 采 G 个回答(常见 8~64),打分后做组内标准化。⭐ 组内均值能当基线,是因为优势的本质就是"减掉一个与当前动作无关的基线"——Critic 是"学"出来的,组内均值是"采"出来的;前提是这 G 个回答来自同一个 prompt,预期得分才是同一个数。除以 std 是把不同难度的题拉到同一尺度(简单题都 0.9、难题都 0.1,减完均值差异都只有 ±0.03)。⚠️ 一组全对或全错时 std=0、优势全为 0,这个 prompt 白采 G 次——加 eps 或整组丢弃。
- PPO 把 KL 加进 reward,GRPO 直接加在损失函数上。好处:①优势 A 是纯粹的"这个回答好不好",不掺"跑了多远",不用再过一遍 GAE/折扣/Critic ②KL 梯度直接落到每个 token。⭐ 估计式用的是 π_ref/π_θ − log(π_ref/π_θ) − 1,恒非负且无偏(朴素的 −log(π_ref/π_θ) 单样本估计会取负值、方差还大)。
- PPO 4 个模型(2 个在训练)、采样 1×;DPO 2 个(1 个在训练)、采样 0;GRPO 3 个(1 个在训练)、采样 G×。选型:调风格和有帮助性 → DPO;答案能自动验证(单测、数学)→ GRPO + RLVR;必须在线探索而奖励只能靠 RM → PPO。⭐ GRPO 省的是显存、花的是采样——把"训一个 Critic"换成了"多采 15 份样本"。
- 因为奖励是可自动验证的客观事实(单元测试通过、数学答案正确),没有标注噪声、没有长度偏好、无法钻漏洞——奖励模型的所有问题都消失了。
🛑 可以停在这里
⚡ 走神救援
⭐RLHF 解决"有些好你写不出评分函数"(有帮助吗、礼貌吗)。⭐关键转念:让人"写"满分答案难且贵,让人"比较"两个答案哪个好容易便宜且一致性高。三阶段:SFT(会听指令)→ ⭐奖励模型(人排序 → L = −logσ(r_win − r_lose),Bradley-Terry,只关心分数差不关心绝对值)→ ⭐⭐PPO 优化。RM 的三个问题:标注噪声(人类一致率仅70~80%,这是精度天花板)、⭐长度偏好(标注者爱选长的 → 模型变啰嗦)、⭐⭐分布漂移(RM 只在见过的分布上准,PPO 优化越狠越跑到盲区,那里分数不可信)→ 💀奖励攻击:回答越来越长、疯狂用列表、开头必说"这是个好问题"、过度谨慎。三道防线:KL 惩罚(拴在 SFT 附近)、⭐盯 KL 散度而不是奖励分数来早停(奖励涨不代表模型变好,真正该看 KL + 人工抽样)、迭代式重训 RM。工程现实:PPO 阶段要同时装四个模型(策略/参考/奖励/Critic)→ 显存约 SFT 的 4 倍,这是 RLHF 昂贵的直接原因;奖励只在最后一个 token 给、Critic 共享 backbone、γ 常设 1.0。变体:RLAIF(AI 标注)、DPO(跳过 RM 和 PPO)、⭐GRPO(去掉 Critic)、过程监督 PRM、⭐⭐RLVR(用可验证的奖励——单元测试通过、数学答案正确——奖励模型的所有问题全部消失,无法钻漏洞,近年推理模型训练的主流方向)。⭐RLHF 不是新算法,是前 11 章零件的一次组装。 ⭐⭐GRPO 展开(跑 RLVR 的通常就是它,DeepSeek-R1 = GRPO + RLVR):同一个 prompt 采 G 个回答(常见 8~64),打分后组内标准化直接当优势:A_i = (r_i − mean(r)) / std(r)。能替代 Critic 是因为优势的本质就是"减掉一个与动作无关的基线"——Critic 是"学"出来的,组内均值是"采"出来的;⭐前提是这 G 个回答来自同一个 prompt,预期得分才是同一个数。除以 std 把难度不同的题拉到同一尺度;⚠️一组全对或全错时 std=0、优势全为 0,这个 prompt 白采 G 次(加 eps 或整组丢弃)。⭐KL 位置不同:PPO 把 KL 加进 reward(要经 GAE 搅拌),GRPO 直接加在损失上 → 优势 A 是纯粹的"回答好不好",KL 梯度直接落到每个 token;估计用 π_ref/π_θ − log(π_ref/π_θ) − 1,恒非负且无偏。显存账(训练态约 16 字节/参数、冻结态 2 字节,差 8 倍):7B 时 PPO ≈ 252 GB → GRPO ≈ 140 GB,接近腰斩。⭐三方:PPO 4 模型/2 个在训练/采样 1×、DPO 2 模型/1 个在训练/采样 0、GRPO 3 模型/1 个在训练/采样 G×。选型:调风格和有帮助性 → DPO;答案能自动验证(单测、数学)→ GRPO + RLVR;必须在线探索而奖励只能靠 RM → PPO。💡GRPO 省的是显存、花的是采样——把"训一个 Critic"换成了"多采 15 份样本"。
下一节 👉 13-DPO与免RL对齐.md