PPO(Proximal Policy Optimization)是 RLHF(Reinforcement Learning from Human Feedback)流水线里最常用的强化学习算法:ChatGPT、Claude 早期的对齐训练都用它把一个已经会说话的模型,调教成一个”说人话更讨喜”的模型。这篇文章按”为什么需要它 → 它怎么推导出来 → 怎么落到 LLM 训练里”的顺序讲清楚 PPO,重点放在它在 LLM RLHF 场景下的具体形态,而不是经典的 Atari/MuJoCo 场景。
1. RLHF 全景与 MDP 建模
一个典型的 RLHF 流程分三步:SFT——用人工标注的高质量问答对,对预训练模型做监督微调,得到一个”听得懂指令”的基础策略;训练 Reward Model(RM)——让标注员对同一个 prompt 的多个模型输出排序,训练一个打分模型 ,输入 prompt 和回复 ,输出一个标量分数,代表”人类有多喜欢这个回复”;PPO 阶段——把 SFT 模型当作初始策略,用 RM 的打分作为强化学习的 reward 信号,继续优化这个策略。PPO 只负责第三步,但效果很大程度上取决于前两步的质量——RM 学得不准,PPO 会很忠实地把策略优化到 RM 的漏洞上(这就是后面要讲的 reward hacking)。
要用 RL 的框架处理语言生成,首先要把生成过程翻译成 MDP(马尔可夫决策过程)的语言:状态 是 prompt 加上目前已经生成的 token,即 ;动作 是下一个要生成的 token,动作空间就是整个词表(通常几万到十几万);策略 就是 LLM 本身, 是模型在给定上下文时对下一个 token 的概率分布;一个 episode 是一次完整的生成,从 prompt 开始到 EOS 或截断为止。reward 是和经典 RL 最不一样的地方:RM 通常只在整个回复生成完毕后对完整序列打一个分,中间每个 token 没有”环境”给出的即时奖励,原始 reward 是序列级、稀疏的,只落在最后一个 token 上。这个”每个 token 是一步决策,但奖励只在最后才出现”的结构,决定了后面 GAE 和 KL 惩罚要怎么设计。
2. 从策略梯度到 Clipped Objective
强化学习最直接的做法是策略梯度:直接对期望回报 求梯度,REINFORCE 给出的估计是:
直觉很简单:某次采样的轨迹回报 是正的就调高这次采样到的动作的概率,是负的就调低。问题在于 是蒙特卡洛采样得到的,方差很大,尤其在长序列(LLM 生成动辄几百个 token)和巨大动作空间(几万词表)下会被进一步放大。标准做法是引入一个 baseline(通常是状态价值函数 ),用优势函数 替代原始回报——它衡量”这个动作比这个状态下的平均水平好多少”,均值为零,方差显著更小:
策略梯度还有一个更棘手的问题:更新幅度不好控制。学习率稍大,一次梯度更新就可能让策略的输出分布剧烈偏移——对 LLM 来说,意味着模型可能几步之内就开始输出乱码,或坍缩到能骗过 RM 但语言质量很差的退化模式,而且这种偏移一旦发生很难恢复,因为下一批 rollout 已经是从被破坏的策略里采出来的。TRPO(Trust Region Policy Optimization)的方案是显式约束新旧策略之间的 KL 散度,把每一步更新限制在一个”信赖域”内,但这需要求解带约束的二阶优化问题,实现复杂、代价高。PPO 的出发点是:能不能用一个更简单的一阶方法,达到类似的效果?
PPO 的答案是用一个概率比来衡量新旧策略的差异:。如果直接优化 ,当 很大时优化过程会疯狂拉高 ,导致策略一步走出信赖域。PPO 的 clipped objective 把这个比值夹在一个区间内:
通常取 0.1~0.2。当 (这个动作比平均水平好)时, 一旦超过 ,clip 后的项就不再增长,梯度也就没有动力继续把 推得更高;当 时同理, 一旦跌破 ,目标就不再因为继续降低 而变得更”好”。取 而不是直接用 clip 后的值,是为了保证这个目标始终是真实目标的一个悲观下界——无论 正负,最终优化的都是更保守的那个估计,防止模型基于单次采样的优势估计做出过度自信、不可逆的更新。这就是”proximal”(邻近)这个名字的来源:用一个廉价的一阶方法,达到和 TRPO 类似的”每步更新幅度受限”的效果。
3. GAE 与完整损失函数
Clipped objective 里的 需要一个价值函数 来估计。PPO 通常配合 GAE(Generalized Advantage Estimation)计算优势:
是单步 TD 误差, 控制”往后看多远”: 时 GAE 退化成只用单步 TD 误差(低方差、高偏差), 时退化成蒙特卡洛优势估计(高方差、无偏),常见取值在 0.9~0.97 之间权衡。在 LLM RLHF 场景里,由于原始 reward 只落在序列最后一个 token, 需要学会”预测从当前生成到结尾最终能拿到的 RM 分数”,这也是为什么需要单独训练一个 Critic(价值模型),通常从 SFT 模型或 RM 初始化,输出维度改成每个 token 位置一个标量。
实际实现中,PPO 的总损失是三项的组合:
是上面推导的 clipped policy objective,训练 Actor; 是 Critic 的回归损失(); 是策略的熵,加一个熵奖励鼓励策略保持一定的随机性,防止过早收敛到确定性输出。 分别控制价值损失和熵奖励的权重。
4. LLM RLHF 里的 PPO:四个模型与 KL 惩罚
经典 RL 场景(比如 MuJoCo)里 PPO 只需要 Actor 和 Critic 两个网络。LLM RLHF 的 PPO 阶段要同时在显存里放四个模型,这是它区别于经典 PPO 最大的工程挑战:
| 模型 | 是否训练 | 作用 |
|---|---|---|
| Policy / Actor | 训练 | 当前正在优化的 LLM,从 SFT 模型初始化,负责生成回复 |
| Reference Model | 冻结 | SFT 模型的一份只读副本,只用来计算 KL 惩罚,防止 Policy 跑得太远 |
| Reward Model | 冻结 | 单独训练好的打分模型,只在序列末尾给一个标量分数 |
| Critic / Value Model | 训练 | 预测每个 token 位置的价值 ,为 GAE 提供优势估计 |
四个模型往往参数规模相近(Critic 和 Reward Model 有时共享底座,只是输出头不同),意味着 PPO 阶段的显存和计算开销大约是纯推理的数倍——这也是后面 GRPO 等变体想要砍掉 Critic 的直接动机。
只靠 RM 的打分做 reward,策略很容易朝着 RM 的漏洞优化过去,而不是真正变得更好。RLHF 的标准做法是把 Policy 和 Reference Model 之间的 KL 散度作为惩罚项加进 reward:
这个 KL 惩罚是逐 token计算并加到每一步的 reward 上,而 RM 的分数只在最后一个 token 出现——GAE 会自动把末尾的 RM 分数按时间差分传播回前面的 token(credit assignment),每一步自身的 KL 偏移也被实时计入 reward,两件事互不冲突。 的取值很敏感:太小则约束不住策略,容易 reward hacking;太大则策略几乎不敢偏离 SFT 模型,学不到 RM 想要的偏好。InstructGPT 等工作采用自适应 KL 控制:持续监控实际 KL 值和目标 KL 的偏差,用一个简单的比例控制器动态调整 ,而不是固定一个常数。
5. 实践中的坑、PPO 之外的变体
工程实践里几个常见的坑:Reward hacking——策略找到 RM 打分函数里的漏洞而不是真正提升质量,常见表现是回复异常啰嗦(RM 对长回复有偏好)、堆砌 RM 喜欢的措辞,缓解手段包括 KL 惩罚、RM 集成、定期用新数据重新训练 RM;PPO epoch 数不能太多——同一批 rollout 数据重复做太多次梯度更新会让策略过拟合到这批样本、KL 迅速失控,LLM RLHF 里通常只做 1~2 个 epoch,比经典 RL 场景保守得多;Value Model 训练不稳定——Critic 从头学习预测最终 RM 分数本身很难,训练早期价值估计噪声大会污染优势估计,一些实践会先单独 warm-up Critic;Reward 归一化——不同 batch 之间 RM 分数尺度可能漂移,常用 running mean/std 归一化(whitening);采样参数——rollout 阶段的 temperature/top-p 直接决定探索到的动作分布,进而影响优势估计的方差,是个容易被忽略但影响很大的超参数。
PPO 的主要代价是”重”:需要单独训练 RM、维护 Critic、同时跑四个模型。近两年的变体分别砍掉了一部分复杂度:**DPO(Direct Preference Optimization)**跳过显式的 RM 和 PPO 采样-更新循环,直接从人类偏好对 构造对比式损失函数,用监督学习的方式优化策略,代价是假设了 Bradley-Terry 偏好模型,且失去了在线探索的灵活性;**GRPO(Group Relative Policy Optimization,DeepSeekMath 提出)**保留 PPO 的 clipped objective 和在线 rollout,但去掉 Critic——对同一个 prompt 采样一组输出,用组内奖励的均值和方差把每个输出的优势标准化,直接省掉一个和 Policy 同等规模的模型,是目前 LLM 推理能力训练中很受欢迎的简化方向。这两者都是在”PPO 的通用性”和”更少的模型、更简单的流程”之间做取舍——PPO 仍是最成熟、最通用的基线,但如果偏好数据结构足够规整,或能接受组内相对奖励的近似,更轻量的变体往往性价比更高。
归根结底,PPO 在 LLM RLHF 里做的事情,是把”用 RM 的打分改进模型”这件事,约束在”每一步更新都不能偏离参考模型太远”的框架里完成:clipped surrogate objective 保证单次更新幅度有界,GAE 把稀疏的序列级奖励合理分摊到每个 token 上,KL 惩罚从 reward 层面再加一道防线。理解这三件事分别在解决什么问题,比记住最终的目标函数公式更重要。