理解 RLHF 与对齐训练(四):PPO——用强化学习微调语言模型的艺术与苦难
PPO:用强化学习微调语言模型的艺术与苦难
PPO 原本是为 Atari 游戏和机器人设计的。把它搬到语言模型上,就像把赛车引擎装到自行车上——强大但需要极其精细的调校才不会翻车。
为什么需要强化学习?
在前面的文章中,我们建好了一个”评委”——奖励模型。它能对任何 (问题, 回答) 打分。
现在的问题是:怎么用这个分数来改进模型?
直觉上你可能想:”对高分的回答做更多 SFT 不就行了?” 这叫 Best-of-N 或 Rejection Sampling——生成 N 个回答,选分最高的那个,用它做 SFT。这确实有效,但效率极低:大部分生成都被丢弃了,而且你无法利用”失败尝试”中的信息。
强化学习的优势在于:它不只奖励好的行为,还能从坏的行为中学习。PPO 在每一步生成时都获得梯度信号——不只是”最终答案好不好”,而是”每一步选择的方向对不对”。
PPO 的核心思想:高速公路上的护栏
PPO(Proximal Policy Optimization)的核心创新可以用一个比喻来理解:
想象你在一条高速公路上开车。你的目标是尽快到达终点(最大化奖励),但高速公路两侧有护栏。护栏不会减慢你的速度,但它们防止你因为转向过猛而冲出路面。
在传统的策略梯度方法(如 REINFORCE)中,没有护栏。每一步更新可能很大,如果方向稍微偏了,模型会突然崩溃——输出变成乱码、无限重复、或退化为固定模板。
PPO 的护栏就是 clipping 机制。
Clipping 机制的数学
PPO 计算新旧策略之间的概率比:
\[r(\theta) = \frac{\pi_\theta(a_t|s_t)}{\pi_{\text{old}}(a_t|s_t)}\]当 $r(\theta) = 1$ 时,新旧策略完全一样。$r(\theta) > 1$ 意味着新策略对这个 action 更自信,$r(\theta) < 1$ 意味着新策略更不看好这个 action。
PPO 的目标函数限制了 $r(\theta)$ 的变化范围:
\[L^{\text{CLIP}} = \mathbb{E}\left[\min\left(r(\theta) \cdot A_t, \; \text{clip}(r(\theta), 1-\epsilon, 1+\epsilon) \cdot A_t\right)\right]\]其中 $\epsilon$ 通常是 0.1-0.2,$A_t$ 是优势函数(advantage,衡量这个 action 比平均水平好多少)。
直觉解释:
- 如果一个 action 是好的($A_t > 0$),PPO 允许增加它的概率,但增幅上限是 $(1+\epsilon)$ 倍——不能一步到位全压上去
- 如果一个 action 是坏的($A_t < 0$),PPO 允许降低它的概率,但降幅下限是 $(1-\epsilon)$ 倍——不能一步就完全排除
这就是护栏:你可以在正确的方向加速,但每一步的转向幅度有限。
RLHF 中的四模型系统
PPO 在 RLHF 中的完整实现需要同时维护四个模型:
| 模型 | 作用 | 是否更新 |
|---|---|---|
| 策略模型 (Actor) | 生成回答 | ✓ 持续训练 |
| 参考模型 (Reference) | 计算 KL 惩罚 | ✗ 冻结的 SFT 模型 |
| 奖励模型 (Reward) | 给回答打分 | ✗ 已训练好,冻结 |
| 价值模型 (Critic) | 估计期望奖励 | ✓ 持续训练 |
为什么需要价值模型(Critic)?
策略梯度的一个基本问题是方差太大。如果一个回答得了 8 分,你怎么知道这是好还是坏?如果平均水平是 3 分,8 分就很好;如果平均水平是 9 分,8 分就是失败。
价值模型 $V(s)$ 就是用来估计”平均水平”的。它预测从当前状态开始,未来能获得的期望奖励。有了它,你可以计算优势(Advantage):
\[A_t = R_t - V(s_t)\]“这个行为比我预期的好多少”——这才是策略应该关注的信号。
KL 惩罚:保险绳
除了 clipping 护栏,RLHF-PPO 还有第二道安全机制:KL 散度惩罚。
\[R_{\text{total}} = R_{\text{reward}}(x, y) - \beta \cdot \text{KL}(\pi_\theta \| \pi_{\text{ref}})\]KL 散度衡量新策略和参考模型(冻结的 SFT 模型)之间的”距离”。如果新策略开始生成和原模型完全不同的东西,KL 惩罚会拉住它。
比喻: Clipping 是每一步的护栏(限制单步更新幅度),KL 惩罚是全局的保险绳(限制累计偏离程度)。两者配合,确保模型在追求高奖励的同时不会”迷失自我”。
$\beta$ 通常设为 0.05-0.2。太小了,模型会 reward hack;太大了,模型完全不学习。
为什么 PPO 在 LLM 上是”调参地狱”?
问题 1:训练不稳定
四个模型必须同步训练。策略改进 → 价值函数跟不上 → 优势估计不准 → 策略更新方向错误 → 训练崩溃。
超参数之间的相互耦合也很严重:
- 学习率影响 clipping 是否被触发
- KL 系数影响策略能探索多远
- PPO epoch 数影响每 batch 数据的利用率
- GAE λ 影响长期 vs 短期信号的权重
改动任何一个,其他参数的最优值都会变化。
问题 2:奖励黑客
PPO 是一个强大的优化器。如果给它足够多的步数和足够小的 KL 约束,它一定会找到奖励模型的漏洞。典型症状:
- 训练初期:奖励上升,回答质量确实在改善
- 中期:奖励继续上升,但人类评估分数开始停滞
- 后期:奖励飙升,但回答变得冗长、谄媚、格式化——RM 给高分,人类觉得恶心
这就是那条著名的”overoptimization 曲线”:proxy reward 持续上升,但 gold reward(真实人类偏好)先升后降。
问题 3:模式坍塌
如果 KL 约束太弱,模型会收敛到一个狭窄的输出分布——对所有问题都用类似的模板回答。多样性和创造力消失,模型变成一个只会说”八股文”的应试机器。
问题 4:计算成本
对一个 70B 参数的模型做 PPO,需要同时在 GPU 上维护:
- 70B 策略模型
- 70B 参考模型(冻结但占内存)
- 70B 价值模型
- 6-70B 奖励模型
总计 200-300B 参数的显存占用。即使用混合精度和梯度累积,这也需要数百张 GPU 和数周的训练时间。
PPO 的训练循环
每一步 PPO 更新的完整流程:
for each batch of prompts:
1. 策略模型生成回答 (rollout)
2. 奖励模型给回答打分
3. 参考模型计算 KL 散度
4. 计算总奖励 = RM 分数 - β·KL
5. 价值模型估计每个 token 位置的 V(s)
6. 用 GAE 计算 Advantage
7. 做 K 轮 PPO 更新(通常 K=1-4):
- 计算概率比 r(θ)
- 计算 clipped 目标
- 更新策略模型
- 更新价值模型
成功的 PPO 训练是什么样的
一个健康的 RLHF-PPO 训练曲线通常表现为:
- 奖励分数:稳步上升,然后趋于平稳(不是飙升)
- KL 散度:缓慢增长,稳定在 5-15 nats 之间
- 人类偏好胜率:持续提升(vs SFT baseline)
- 回答长度:微增但不爆炸
- 困惑度(PPL):轻微上升但不崩溃
如果你看到奖励飙升但 KL 爆炸,或者奖励上升但回答长度翻倍——都是 reward hacking 的信号。
实践中的关键超参数
| 参数 | 典型值 | 含义 |
|---|---|---|
| ε (clip) | 0.1-0.2 | 单步更新幅度限制 |
| β (KL) | 0.05-0.2 | 偏离参考模型的惩罚强度 |
| 学习率 | 1e-6 ~ 5e-6 | 比 SFT 更小 |
| PPO epochs | 1-4 | 每批数据重复利用次数 |
| Batch size | 32-512 prompts | 越大越稳定 |
| GAE λ | 0.95 | 优势估计的时间折扣 |
| 生成长度 | 256-2048 tokens | 回答的最大长度 |
下一篇预告
PPO 强大但复杂:四个模型、大量超参数、训练不稳定、计算成本高昂。自然的问题是:能不能更简单?
2023 年,一篇论文给出了惊人的回答:不需要奖励模型,不需要 PPO,不需要价值函数——只用一个简单的分类损失,就能达到几乎相同的效果。这就是 DPO(Direct Preference Optimization)。而 2024 年 DeepSeek 更进一步:保留 RL 的探索能力,但砍掉价值函数——这就是 GRPO。下一篇,我们看看这些”后 PPO”时代的方法如何优雅地简化对齐训练。