PPO 最容易被误解成一个简单的 clip 技巧。 真正的问题不是把公式背下来,而是理解为什么策略梯度在复用同一批轨迹做多轮 minibatch 更新时会突然变得危险。
这篇文章从 TRPO 的信任域出发,推到 PPO 的重要性采样比率与裁剪目标,再落到代码里的 value clipping、优势归一化、KL 到参考模型惩罚和学习率退火。 读完你应该能看懂一份 PPO/RLHF 训练日志里哪些信号代表正常探索,哪些信号代表策略正在被训坏。
一、从策略梯度到信任域问题
上一篇讨论 Actor-Critic 和 GAE 时,策略更新的核心形式是用优势函数给采样动作加权。 若 \(\theta_{old}\) 是采样轨迹时的策略参数,朴素做法会把这些轨迹当成当前策略的数据反复训练。
问题在于策略梯度是 on-policy 方法。 数据来自旧策略,梯度却作用在新策略上;当新旧策略差距变大,估计偏差会迅速扩大。
PPO 要解决的不是“让更新更大”,而是“在仍然利用 minibatch 多轮训练的情况下,不让策略一步跨出可信范围”。
策略优化的局部目标可以写成:
\[ L^{PG}(\theta)=\mathbb{E}_t[\log \pi_\theta(a_t|s_t)\hat A_t] \]
TRPO 把这件事表述成带约束优化。 它最大化代理目标,同时限制新旧策略的平均 KL 散度不超过一个小半径。
\[ \max_\theta \ \mathbb{E}_t\left[\frac{\pi_\theta(a_t|s_t)}{\pi_{\theta_{old}}(a_t|s_t)}\hat A_t\right] \quad \text{s.t.}\quad \mathbb{E}_t[D_{KL}(\pi_{\theta_{old}}(\cdot|s_t)\|\pi_\theta(\cdot|s_t))]\le \delta \]
Schulman et al. 2015 的 TRPO 用二阶近似和共轭梯度来解这个信任域问题。 它给出了重要思想,但实现复杂,对深度网络和大规模分布式训练不够友好。
二、重要性采样比率是 PPO 的入口
PPO 的第一个关键量是重要性采样比率。 它衡量同一个动作在新策略和旧策略下概率的相对变化。
\[ r_t(\theta)=\frac{\pi_\theta(a_t|s_t)}{\pi_{\theta_{old}}(a_t|s_t)} \]
如果 \(r_t(\theta)=1\),说明新旧策略对这个动作给出的概率相同。 若 \(r_t(\theta)=1.2\),说明新策略把该动作概率提高了 20%。 若 \(r_t(\theta)=0.7\),说明新策略把该动作概率降低到旧策略的 70%。
带比率的代理目标是:
\[ L^{CPI}(\theta)=\mathbb{E}_t[r_t(\theta)\hat A_t] \]
这个目标看似自然,但没有约束。 若 \(\hat A_t>0\),优化器会不断增大 \(r_t\);若 \(\hat A_t<0\),优化器会不断压低 \(r_t\)。 在神经网络参数空间里,这种局部收益可能对应全局分布的大幅漂移。
三、裁剪目标为什么是悲观下界
PPO-Clip 把比率限制在一个局部窗口内。 常见窗口是 \([1-\epsilon,1+\epsilon]\),例如 \(\epsilon=0.2\)。
\[ L^{CLIP}(\theta)=\mathbb{E}_t\left[\min\left(r_t(\theta)\hat A_t,\ \mathrm{clip}(r_t(\theta),1-\epsilon,1+\epsilon)\hat A_t\right)\right] \]
这个 min 不是为了数值好看,而是构造一个悲观目标。 它保留对保守更新的奖励,但截断会让目标函数对“过度改变概率”的方向不再继续给梯度收益。
分两种情况看最清楚:
- 当 \(\hat A_t>0\) 时,动作比平均更好,策略应该提高它的概率;但 \(r_t>1+\epsilon\) 后,裁剪项固定为 \((1+\epsilon)\hat A_t\),继续提高概率不会增加目标。
- 当 \(\hat A_t<0\) 时,动作比平均更差,策略应该降低它的概率;但 \(r_t<1-\epsilon\) 后,裁剪项固定为 \((1-\epsilon)\hat A_t\),继续降低概率不会增加目标。
- 因此 clip 阻止的是破坏性更新:把好动作概率推得过高,或把坏动作概率压得过低,都会让新策略远离采样数据所覆盖的分布。
- 裁剪不是硬约束。它不保证 KL 一定小,只是让多数样本上的目标函数在危险方向变平。
PPO 的直觉可以浓缩成一句话:
同一批轨迹只可信到一个局部邻域;PPO 用裁剪代理目标把“看似有利但跨出邻域”的梯度收益拿掉。
四、完整目标:策略、价值与熵
实际 PPO 不是只优化 \(L^{CLIP}\)。 Actor-Critic 版本还要同时训练价值函数,并用熵奖励延缓策略过早塌缩。
\[ L_t(\theta)=\mathbb{E}_t\left[L_t^{CLIP}(\theta)-c_1L_t^{VF}(\theta)+c_2S[\pi_\theta](s_t)\right] \]
这里 \(L_t^{VF}\) 是 value loss,\(S[\pi_\theta]\) 是策略熵,\(c_1\) 和 \(c_2\) 控制两项权重。 实现里通常把 actor loss、critic loss、entropy bonus 分开记录,而不是只看一个总 loss。
| 组成 | 作用 | 常见日志名 | 失败信号 |
|---|---|---|---|
| policy loss | 推动策略提高高优势动作概率 | policy_loss |
clip fraction 长期接近 1 或 KL 突增 |
| value loss | 让 critic 拟合回报或 GAE 目标 | value_loss |
值函数解释不了 reward,优势方差很大 |
| entropy bonus | 保持探索,避免过早确定 | entropy |
熵快速归零,输出模式单一 |
| approx KL | 监控新旧策略距离 | approx_kl |
超过目标 KL 多倍仍继续训练 |
value clipping 是 PPO 实现里常见但容易漏掉的细节。 它限制新 value 相对旧 value 的变化幅度,防止 critic 在多轮 minibatch 训练里追着噪声回报大幅摆动。
五、KL penalty 版本与自适应系数
PPO 论文同时讨论了 clipped surrogate 和 KL penalty 变体。 KL penalty 版本不直接裁剪 \(r_t\),而是在目标里加入新旧策略的 KL 惩罚。
\[ L^{KLPEN}(\theta)=\mathbb{E}_t\left[r_t(\theta)\hat A_t-\beta D_{KL}(\pi_{\theta_{old}}(\cdot|s_t)\|\pi_\theta(\cdot|s_t))\right] \]
固定 \(\beta\) 简单,但不同任务、不同训练阶段的合适 KL 强度不同。 自适应 KL 方案会根据当前 KL 是否高于目标来增减 \(\beta\)。
一个简化控制逻辑如下:
note = "示意:自适应 KL 系数,不是论文或框架源码"
if measured_kl > 1.5 * target_kl:
beta *= 2.0
elif measured_kl < target_kl / 1.5:
beta /= 2.0在 RLHF 里还会出现另一种 KL:policy 到 reference model 的 KL。 它不是 PPO 新旧策略 KL,而是防止模型远离 SFT/reference 分布的奖励惩罚项。
\[ R(x,y)=r_\phi(x,y)-\beta\sum_t\left(\log \pi_\theta(y_t|x,y_{<t})-\log \pi_{ref}(y_t|x,y_{<t})\right) \]
这项 KL-to-reference 在语言模型后训练里至关重要。 它把“让奖励模型给高分”和“不要偏离可读、可控、原有能力分布太远”绑在一起。
六、PPO 更新循环
flowchart TD
A[收集轨迹] --> B[冻结 old policy logprob]
B --> C[计算 reward 与 value]
C --> D[GAE 得到 advantage]
D --> E[优势归一化]
E --> F[多轮 minibatch 更新]
F --> G[计算 ratio 与 clipped loss]
G --> H[更新 actor critic]
H --> I{KL 或 clip fraction 过高?}
I -- 是 --> J[提前停止或降低步长]
I -- 否 --> K[进入下一批采样]
J --> K
图里的关键是 old logprob 必须来自采样时的策略,并在整轮 PPO epoch 内保持不变。 若边采样边覆盖旧 logprob,ratio 的含义会被破坏。
七、代码级实现陷阱
Engstrom et al. 2020 的核心提醒是:深度策略梯度的结果很大程度取决于实现细节。 PPO 论文公式只定义了主目标,真正决定训练是否稳定的是一串小开关。
Huang et al. 2024 针对 RLHF with PPO 系统整理了大量实现细节。 语言模型场景比 MuJoCo 更敏感,因为动作空间是词表,轨迹长度可变,reward 来自代理模型,KL 惩罚又改变了每个 token 的回报。
八、逐项实现核对清单
1. 优势归一化
- 核对点:每个 batch 或 minibatch 内把 advantage 做零均值、单位方差,避免 reward 尺度直接决定策略步长。
- 常见失败:不同 worker 的 reward 尺度漂移,导致同一学习率下有时不动、有时爆炸。
- 观测信号:
adv_mean、adv_std、policy gradient norm。 - 边界条件:小 batch 场景下归一化统计本身有噪声,需和 batch size 一起看。
2. value clipping
- 核对点:把新 value 相对旧 value 的变化限制在裁剪窗口,降低 critic 过拟合短期噪声的风险。
- 常见失败:critic loss 很快变小,但策略 KL 变大,优势估计方向开始抖动。
- 观测信号:
value_loss、explained variance、return/value scatter。 - 边界条件:奖励尺度变化后 value clip 范围也要重新审视。
3. 奖励缩放
- 核对点:把环境奖励、RM 分数或规则奖励变成适合优化器的尺度。
- 常见失败:RM 分数绝对值很大,KL 惩罚被淹没,模型迅速学会刷奖励。
- 观测信号:reward mean/std、non-score reward、KL reward。
- 边界条件:不要把缩放后的分数误当成人类偏好强度。
4. 观测或输入归一化
- 核对点:在传统连续控制里常见,在 LLM 里对应 prompt 长度、位置、mask 和 padding 处理。
- 常见失败:padding token 参与 loss 或 reward,长短样本统计不一致。
- 观测信号:有效 token 数、attention mask 覆盖率。
- 边界条件:语言模型一般不做连续观测归一化,但必须正确处理 mask。
5. 学习率退火
- 核对点:PPO 常用线性退火,让后期更新更保守。
- 常见失败:固定大学习率在 reward 上升后继续推,KL 后期失控。
- 观测信号:learning rate、approx KL、clip fraction。
- 边界条件:过早退火会让策略还没学到偏好就停止移动。
6. GAE 的 \(\lambda\)
- 核对点:在 bias 和 variance 之间折中,决定优势估计看多远。
- 常见失败:\(\lambda\) 太低只看短期,太高把 noisy reward 传播到整段序列。
- 观测信号:advantage variance、return variance。
- 边界条件:LLM 中 token 级 reward shaping 会改变合适的 \(\lambda\)。
7. minibatch epochs
- 核对点:同一批 on-policy 数据可复用几轮,但复用越多越 off-policy。
- 常见失败:epoch 多时训练 loss 下降,真实采样 reward 不升反降。
- 观测信号:epoch 内 approx KL 曲线、early stop 次数。
- 边界条件:大模型 RLHF 往往受 KL 和采样成本共同约束。
8. ratio 计算
- 核对点:用 logprob 差值再 exponentiate,避免直接概率下溢。
- 常见失败:直接除概率出现 0、inf 或 NaN。
- 观测信号:ratio min/max、NaN 计数。
- 边界条件:需要在相同 tokenization 和相同 mask 上比较。
9. mask 处理
- 核对点:只在有效动作 token 上计算 ratio、KL、entropy 和 advantage。
- 常见失败:prompt token 被当成动作优化,模型学会改变用户输入分布的假象。
- 观测信号:response mask token count。
- 边界条件:对话模板变化会改变 mask 边界。
10. KL 到参考模型
- 核对点:RLHF 中把参考模型作为行为锚点,通常按 token 加到 reward。
- 常见失败:奖励模型高分但输出啰嗦、重复、偏离指令。
- 观测信号:
objective/kl、non_score_reward、长度分布。 - 边界条件:reference 应与 SFT 初始化一致或明确说明差异。
11. 熵奖励
- 核对点:延缓策略塌缩,尤其在探索空间很大时有用。
- 常见失败:熵太低导致固定模板输出,熵太高导致 reward 学不动。
- 观测信号:entropy、distinct n-gram、采样温度。
- 边界条件:LLM 中采样温度也会影响表观熵。
12. 梯度裁剪
- 核对点:限制异常 batch 对参数的破坏。
- 常见失败:单个高 reward 或异常长样本造成梯度爆炸。
- 观测信号:global grad norm、optimizer skipped step。
- 边界条件:裁剪不能替代 reward 和 mask 修复。
13. early stopping
- 核对点:当 minibatch 内 KL 超过阈值,提前停止本批 PPO epoch。
- 常见失败:明知 KL 超标仍继续训练,下一轮采样分布突变。
- 观测信号:early stop rate、target KL。
- 边界条件:阈值过低会让训练几乎不更新。
14. 随机种子
- 核对点:采样、数据打乱、dropout 与分布式归约都会影响结果。
- 常见失败:复现实验时 reward 曲线形状完全不同。
- 观测信号:seed、rank-level sample count。
- 边界条件:种子只保证可诊断,不保证结论普适。
15. 分布式同步
- 核对点:old logprob、value、reward、advantage 的统计必须跨 worker 一致。
- 常见失败:每张卡看到的优势尺度不同,更新方向互相抵消。
- 观测信号:all-reduce 后的统计量。
- 边界条件:异步采样系统要记录策略版本号。
16. 长度偏置
- 核对点:RM 和 KL 都可能让模型偏爱更长或更短回答。
- 常见失败:reward 上升主要来自长度增长,而非质量提升。
- 观测信号:response length、reward per token、KL per token。
- 边界条件:后续第 16 篇会专门讨论奖励黑客。
九、PPO 在 RLHF 中的特殊性
传统 PPO 面对的是环境给出的 reward。 RLHF PPO 面对的是 reward model、KL-to-reference、长度规范和采样温度共同构成的奖励。
这意味着 PPO 只是优化器,后训练质量还取决于偏好数据、奖励模型校准、reference 选择和评测闭环。 第 09 篇会把这些组件串成完整 RLHF 链路。
十、训练日志判读清单
1. KL 突然升高
- 观察:对比当前 batch 的 approx KL、reference KL 与响应长度。
- 风险:策略可能正在利用 reward 或 minibatch 复用导致 off-policy 偏移。
- 处置:先触发 early stop,再降低学习率或 KL target。
2. clip fraction 过高
- 观察:检查被裁剪样本占比是否长期接近上限。
- 风险:大部分梯度来自被压平区域,继续训练只会制造噪声。
- 处置:减少 epoch 或 batch 学习率,并复核 advantage 尺度。
3. reward 上升但人评下降
- 观察:抽样查看高 reward 输出是否重复、冗长或迎合。
- 风险:RM 被策略 exploit,代理目标与真实偏好分离。
- 处置:增加人工重评,调高 reference KL,补充反例偏好。
4. value loss 不降
- 观察:比较 return、value 和 advantage 的尺度。
- 风险:critic 不稳会把策略更新方向放大成噪声。
- 处置:调整 reward normalization、value coef 和 value clip。
5. entropy 过快下降
- 观察:查看采样温度与 token-level entropy。
- 风险:模型过早锁定模板,探索空间变窄。
- 处置:降低 KL 压力或增加 entropy bonus,但不要掩盖 reward 问题。
6. 优势均值偏离零
- 观察:确认 advantage normalization 是按有效 token 和正确 batch 执行。
- 风险:未归一化优势会改变实际步长。
- 处置:在日志中同时记录归一化前后统计。
7. ratio 出现极端值
- 观察:检查 old logprob 是否来自采样时冻结策略。
- 风险:新旧 logprob 对不上会让 ratio 失去概率比意义。
- 处置:保存 policy version,并按 mask 计算 logprob 差。
8. 长度分布漂移
- 观察:比较 response length 与 reward、KL 的相关性。
- 风险:策略可能把变长当成刷分捷径。
- 处置:按 token 归一化部分指标,并加入长度诊断集。
9. 多卡结果不一致
- 观察:检查 reward、advantage、KL 统计是否 all-reduce。
- 风险:各 rank 用不同尺度更新会互相干扰。
- 处置:统一统计窗口,记录 rank-level 指标。
10. 学习率退火过慢
- 观察:观察后期 KL 是否继续上升而评测停滞。
- 风险:优化器还在推动已饱和的代理目标。
- 处置:使用线性退火或按 KL 自适应缩放。
11. GAE 方差过大
- 观察:查看不同长度样本的 advantage 分布。
- 风险:长序列噪声被传播到大量 token。
- 处置:调整 \(\lambda\)、reward shaping 和终止处理。
12. reference 不匹配
- 观察:确认 reference 权重、tokenizer、模板与 SFT 初始化一致。
- 风险:KL 惩罚约束到错误分布。
- 处置:把 reference artifact 固化并写入实验记录。
13. RM 延迟过高
- 观察:区分 rollout、RM 打分、训练三段吞吐。
- 风险:采样队列空转会让 GPU 利用率下降。
- 处置:缓存 reference logprob,批量化 RM 推理。
14. padding 参与损失
- 观察:检查 mask 后有效 token 数是否等于响应 token 数。
- 风险:pad token 的 logprob 会污染 loss 和 KL。
- 处置:为每个 batch 断言 mask 边界。
15. reward 尺度换版
- 观察:比较 RM 版本切换前后的均值和方差。
- 风险:同一 KL 系数对应不同真实惩罚强度。
- 处置:对新 RM 重新标定 reward normalization。
16. 样本复用过度
- 观察:看一个 rollout batch 被训练多少 minibatch epoch。
- 风险:on-policy 假设被削弱。
- 处置:降低 epoch 或增大新采样频率。
17. 梯度爆炸
- 观察:定位是否来自少数高 reward 或长样本。
- 风险:单个异常样本会破坏大模型权重。
- 处置:启用 grad clipping,并排查 reward outlier。
18. 评测回归
- 观察:分任务看通用能力、数学、代码和安全。
- 风险:总体 reward 掩盖局部能力退化。
- 处置:建立 release gate,不让 PPO 单指标决定发布。
19. 日志命名混乱
- 观察:区分 policy KL、reference KL、objective KL。
- 风险:团队讨论同名指标时含义不同。
- 处置:在 dashboard 写清每个 KL 的计算对象。
20. 采样温度变化
- 观察:记录 rollout temperature、top-p 和 stop token。
- 风险:采样分布变化被误认为算法改进。
- 处置:把采样配置纳入实验不可变参数。
十一、参考资料
- John Schulman, Sergey Levine, Philipp Moritz, Michael I. Jordan, Pieter Abbeel. “Trust Region Policy Optimization”. ICML 2015.
- John Schulman, Filip Wolski, Prafulla Dhariwal, Alec Radford, Oleg Klimov. “Proximal Policy Optimization Algorithms”. arXiv 2017.
- Logan Engstrom, Andrew Ilyas, Shibani Santurkar, Dimitris Tsipras, Firdaus Janoos, Larry Rudolph, Aleksander Madry. “Implementation Matters in Deep RL: A Case Study on PPO and TRPO”. ICLR 2020.
- Long Ouyang et al. “Training language models to follow instructions with human feedback”. NeurIPS 2022.
- Shengyi Costa Huang et al. “The N+ Implementation Details of RLHF with PPO: A Case Study on TL;DR Summarization”. ICLR Blog Track 2024.
← 上一篇:04|Actor-Critic 与优势函数、GAE | 下一篇:06|后训练全景 →
同主题继续阅读
把当前热点继续串成多页阅读,而不是停在单篇消费。
【强化学习与大模型后训练】09|RLHF 全链路:用 PPO 对齐语言模型
从 SFT 初始化、奖励模型、参考策略 KL 到 PPO 更新,串起 RLHF 的四模型训练闭环,并解释稳定性与工程成本。
【强化学习与大模型后训练】04|Actor-Critic 与优势函数、GAE
解释 Actor-Critic 架构、优势估计和 GAE 的偏差—方差取舍,并映射到 LLM 后训练中的 value head 与 per-token advantage。
【强化学习与大模型后训练】03|策略梯度与 REINFORCE
从期望回报出发推导策略梯度与 REINFORCE,解释 log-derivative trick、基线降方差,以及它们在语言模型后训练中的含义。
【强化学习与大模型后训练】17|RL 训练基础设施:采样-训练分离与 PPO 编排
从 rollout、奖励计算、价值估计到策略更新,拆解 LLM 在线 RL 的系统拓扑、资源瓶颈和同步边界。