PPO 算法详解:RLHF 中的核心优化器

RLHF/对齐PPO 算法详解openstarry.com

PPO 算法详解:RLHF 中的核心优化器

PPO(Proximal Policy Optimization)是目前 RLHF 中最常用的强化学习算法。它的核心创新是通过裁剪机制限制策略更新幅度,让训练过程既高效又稳定。

从策略梯度说起

PPO 属于策略梯度(Policy Gradient)家族。理解 PPO 需要先理解策略梯度的基本思想:

策略梯度的核心思路:
1. 用当前策略生成一批动作(在 RLHF 中是生成回答)
2. 环境给出奖励(在 RLHF 中是奖励模型打分)
3. 让"好动作"的概率增大,"坏动作"的概率减小

参数更新方向:
  ∇J(θ) = E[∇log π_θ(a|s) · A(s,a)]
  
  π_θ(a|s):策略在状态 s 下选择动作 a 的概率
  A(s,a):优势函数(这个动作比平均好多少)

问题在于:步子迈太大,策略可能崩溃。


为什么需要裁剪?

普通策略梯度有一个致命缺陷:如果某次更新步幅过大,新策略可能比旧策略差很多,而且无法恢复。

灾难性更新示例:
旧策略: P("好回答") = 0.7
某次更新后: P("好回答") = 0.1  ← 一步跨太大,策略崩溃

后果:
- 生成的回答质量暴跌
- 奖励信号变得不可靠
- 后续训练全部失效

PPO 的裁剪机制

PPO 通过裁剪比率 r(θ) 来限制更新幅度:

import numpy as np

def ppo_loss(ratio, advantages, clip_epsilon=0.2):
    """
    ratio: 新策略概率 / 旧策略概率 = π_new(a|s) / π_old(a|s)
    advantages: 优势函数值 A(s,a)
    clip_epsilon: 裁剪范围(通常 0.2)
    """
    # 裁剪后的目标函数
    clipped = np.clip(ratio, 1 - clip_epsilon, 1 + clip_epsilon)
    
    # 取两者中较小的(保守估计)
    loss = -np.minimum(ratio * advantages, clipped * advantages)
    
    return loss.mean()

直觉解释:当 ratio 偏离 1 超过 0.2 时,裁剪会阻止进一步的更新,防止步幅过大。


PPO 的完整算法流程

PPO 训练循环:

1. 用当前策略收集一批数据(状态、动作、奖励)
2. 计算优势函数 A(s,a)(用 GAE 广义优势估计)
3. 迭代 K 轮(通常 K=3~10):
   for each mini-batch:
     计算新旧策略比率 r(θ) = π_new / π_old
     计算裁剪目标: L = min(r*A, clip(r, 1-ε, 1+ε)*A)
     反向传播更新 θ
4. 回到步骤 1,用新策略收集新数据

PPO 在 RLHF 中的角色

在 RLHF 流程中,PPO 是第三阶段的核心算法:

RLHF 组件 PPO 中的对应
语言模型策略网络 π_θ
生成的回答动作 a
当前上下文状态 s
奖励模型打分奖励 r
SFT 模型参考策略 π_ref(用于 KL 惩罚)
RLHF 中的奖励设计:
总奖励 = 奖励模型分数 - β × KL散度(π_θ || π_ref)

β × KL散度 项的作用:
  防止模型偏离 SFT 模型太远
  避免"钻空子":模型不会为了获得高分而生成奇怪文本

PPO 的稳定性优势

对比其他策略梯度算法:

算法 步幅控制 样本效率 稳定性
REINFORCE
TRPO信赖域约束好(但计算复杂)
PPO裁剪机制好(且计算简单)

实践中的注意事项


总结

PPO 通过简洁的裁剪机制解决了策略梯度训练不稳定的问题。在 RLHF 中,PPO 负责根据奖励模型的反馈优化语言模型的生成策略,同时通过 KL 惩罚确保模型不会偏离原始能力太远。它的高效和稳定使其成为当前 RLHF 的默认选择。

延伸阅读DPO:跳过奖励模型的直接偏好优化

以 AI 之力,筑未来之境

现在注册,立即免费获赠 200 次大模型调用权益

免费注册 →