PPO理论解析

RLHF中的PPO算法

1.动机

PPO算法是后续很多RLHF/RLVR强化学习微调算法的基础,因此了解它的底层原理。对于后续理解很多RL算法乃至在这个基础上改进算法是很重要的。本篇博客希望能够记录PPO算法的学习过程,并提供一个较为全面的分析视角。

2.RLHF-PPO数学结构

为了方便下面的数学建模,我们需要先定义强化学习中的几个基本要素也就是:状态空间(State Space)、动作空间(Action Space)、奖励(Reward)、策略(Policy)

2.1 基础建模

LLM研究领域中的强化学习,这几个要素定义如下:

  • **状态空间(State $s_t$)**:Prompt + 当前已生成的 Token 序列 $[x_1, x_2, ..., x_{t-1}]$
  • **动作空间(Action $a_t$)**:词表(Vocabulary)中的下一个 Token $x_t$
  • **奖励(Reward)**:由训练好的奖励模型给出(通常是SFT模型基础上继续训练得到)
  • **策略(Policy $\pi_\theta$)**:当前正在训练的 Actor 网络。

预备知识(强化学习基础)

**累积折扣奖励**

对于一个有限步数的强化学习环境,其累积奖励序列为
\[G_t = \sum_{l=0}^{T-t} \gamma^l r_{t+l} = r_t + \gamma r_{t+1} + \gamma^2 r_{t+2} + \dots + \gamma^{T-t} r_{T}\]
$T$:整个 Token 序列的结束位置(通常是 [EOS] 或者是设定的最大长度)。
$\gamma$:折扣因子(Discount Factor),取值范围在 $[0, 1]$ 之间。
$r_{t+l}$:第 $t+l$ 步的即时奖励(Step Reward)。

**状态价值函数**

一个状态的期望回报(即从这个状态出发的未来累积奖励的期望)被称为这个状态的价值(value)。所有状态的价值就组成了价值函数(value function),价值函数的输入为某个状态,输出为这个状态的价值。我们将基于策略 $\pi$ 的状态价值函数写成 $V_{\pi}(s)=\mathbb{E}_{\pi}[G_t|S_t=s]$,展开为

\[ V_{\pi}(s) = \mathbb{E}_{\pi}[G_t|s_t=s] = \mathbb{E}_{\pi}[\sum_{k=0}^{\infty} \gamma^k r_{t+k+1}|s_t=s], 对于所有的s \in S \]
**动作价值函数**

当前状态s的动作价值函数是遵循策略 $\pi$ ,在当前状态s下执行动作a得到的期望回报
\[Q_{\pi}(s,a)=\mathbb{E}_{\pi}[G_t|S_t=s, A_t=a] = \mathbb{E}_{\pi}[\sum_{k=0}^{\infty} \gamma^k r_{t+k+1}|s_t=s, a_t=a]\]
联系上面说的状态价值函数,可以得到二者的关系式 \[V_\pi(s) = \sum_{a \in A} \pi(a \mid s) Q_\pi(s, a) = \mathbb{E}_{a \sim \pi} [Q_\pi(s, a)]\]
\[Q_\pi(s, a) = R(s, a) + \gamma \sum_{s' \in S} P(s' \mid s, a) V_\pi(s') = R(s, a) + \gamma \mathbb{E}_{s' \sim P} [V_\pi(s')]\]

强化学习的目标是最大化期望奖励:
\[\max_\theta \mathbb{E}_{\tau \sim \pi_\theta} [R(\tau)]\]
其中:

  • $\tau = (s_0, a_0, s_1, a_1, \dots, s_T)$ 表示策略网络 $\pi_\theta$ 与环境交互产生的一条轨迹(Trajectory)。在大语言模型(LLM)的对齐语境下,这条轨迹 $\tau$ 精准地对应着模型针对某个 Prompt 生成的一整个 Token 序列。
  • $R(\tau)$ 则是这条轨迹所获得的累积回报。为了在工程中通过梯度下降(或梯度上升)来更新大模型的参数 $\theta$
  • 我们需要对这个基于概率分布的期望目标求导。对于有限步数的环境,根据经典的策略梯度定理(Policy Gradient Theorem)目标函数对参数 $\theta$ 的梯度可以展开为Reinforce算法形式(详细证明可以见附录):
    \[\nabla_\theta J(\theta) = \mathbb{E}_{\tau \sim \pi_\theta} \left[ \sum_{t=0}^T \nabla_\theta \log \pi_\theta(a_t | s_t) \cdot G_t \right]\]

这里的 $G_t$ 是从时间步 $t$ 开始直到序列结束的实际折扣累积回报。从绝对值到相对值的演进在传统的 REINFORCE 算法中,直接将 $G_t$ 作为梯度更新的权重。但这会带来灾难性的工程痛点:方差极高,因为每一步reward都有两个随机源策略随机和环境转移概率随机。具体来说LLM 自回归采样的随机性非常大,同一句 Prompt 稍微换一个词,最后的得分可能天差地别。为了降低方差、稳定训练,PPO 算法引入了基准线(Baseline)——即由 Critic 网络预测的状态价值 $V_\phi(s_t)$。通过用实际回报 $G_t$ 减去这个平均基准,我们得到了优势函数(Advantage Function, $A_t$)。最终的策略梯度公式被改写为:\[\nabla_\theta J(\theta) = \mathbb{E}_{\tau \sim \pi_\theta} \left[ \sum_{t=0}^T \nabla_\theta \log \pi_\theta(a_t | s_t) \cdot A_t \right]\]

2.2 PPO网络结构

RLHF中PPO算法使用4个网络,分别是Actor model,Critic model,Reward model,Reference model

**Actor model**

Actor model是策略网络,也就是公式中得 $\pi_\theta$ 决定当前状态下的动作,在LLM中也就是决定当前状态下,这一阶段也被称为rollout,下一个采样的token(这里还涉及到一些采样算法暂时不展开)在训练时需要更新其中的网络参数 $\theta$

**Critic model**

用于评估当前状态的期望累积回报(Expected Cumulative Return),也就是数学公式中的状态价值函数 $V_\phi(s)$。在LLM语境下,它负责预测在当前已生成的 Prompt + Token 序列下,一直到生成结束,预期能拿到的总得分。它提供了一个“平均基准线(Baseline)”,用来和 Actor 实际走出的表现做对比,从而计算出优势函数(Advantage)。在训练时,需要更新其中的网络参数 $\phi$

为了让整个 PPO 闭环运行起来,除了 Actor 和 Critic,经典的 RLHF 流程中还必须包含另外两个参数冻结(不参与更新)的核心网络:

**Reference model**

Reference model 是策略网络的一个冻结备份,通常直接使用刚完成监督微调(SFT)后的模型 $\pi_{ref}$。它在 PPO 阶段不更新参数,唯一的职责是防止策略被训飞导致Reward Hacking和LLM底座模型训练到的知识丢失。通过计算当前训练的 Actor 网络与 Reference 网络在 Token 输出概率上的 KL 散度(KL Divergence),来约束 Actor 不要为了迎合打分而疯狂放飞自我,从而有效防止模型为了钻空子而吐出失去逻辑的废话(即防止 Reward Hacking)。

**Reward model**

Reward model 是偏好评价网络(在 PPO 阶段同样冻结参数),通常表示为 $R$。它是利用人类或强模型对成对数据(Chosen / Rejected)的偏好排序预先训练好的。负责在 Actor 模型吐完整个回答(或者在生成每个 Token 时)进行质量评估,Reward model并给出一个绝对的偏好分数。通过它和 KL 惩罚相减,最终转化为 Critic 和 Actor 所需的奖惩信号。

2.3 PPO损失函数

PPO模型实际上是在Actor-Critic网络架构基础上发展而来,将Actor-Critic模型中的奖励函数换成奖励模型,然后为了约束策略的更新辅导又引入原始的reference模型,通过KL散度约束策略更新,所以主体上PPO的Pipeline和AC没有很大区别,其损失函数也与AC模型类似,分为Actor策略模型的损失函数和Critic模型的损失函数组成

总损失函数
\[ \mathcal{L}_{total}(\theta, \phi) = \mathcal{L}_{actor}(\theta) + c_1 \mathcal{L}_{critic}(\phi) + c_2 \mathcal{L}_{PT}(\theta) \]

  • $\mathcal{L}_{actor}(\theta)$:Actor(策略网络)的裁剪代理损失(加入了负号,变最大化为最小化)。
  • $\mathcal{L}_{critic}(\phi)$:Critic(价值网络)的均方误差损失。
  • $\mathcal{L}_{PT}(\theta)$:预训练语言模型损失(Pre-training Loss), 用于防止模型在强化学习期间变傻(alignment tax)。
  • $c_1, c_2$:调节这三者权重的超参数。

**策略模型损失函数**
策略模型损失函数有两种,一种是KL Penalty的形式显示约束,另外一种是clip形式的隐式约束,一般在RLHF-PPO中常用的是后者。

**KL Penalty形式策略模型损失(显示约束)**
\[ \mathcal{L}_{Pen}(\theta) = \mathbb{E}_t \left[ r_t(\theta) A_t^{GAE(\gamma, \lambda)} - \beta \mathbb{D}_{KL}\left( \pi_{\theta_{\text{old}}}(\cdot|s_t) \parallel \pi_{\theta}(\cdot|s_t) \right) \right]\]

其中:

  • $r_t(\theta) = \frac{\pi_\theta(a_t|s_t)}{\pi_old(a_t|s_t)}$ 是新旧策略的概率比值
  • $A_t^{GAE}$ 是优势估计,这里引入GAE来平衡方差(Varience)和偏差(Bias)
  • $\beta$ 是惩罚系数,控制KL散度对目标函数的影响。

整个过程采用梯度上升法来进行策略优化

下面分析分析一下PPO-Penalty在不同case下的影响,首先我们要明确PPO-Penalty通过在优化过程中监控KL散度,通过实际调整 $\beta$ 的大小,实现对策略更新的幅度的动态控制:

  • 首先,我们对 $D_{KL}$ 设置threshold,分别记成 $D_{max}$$D_{min}$
  • $D_{KL} \geq D_{max}$ 时,说明当期策略已经偏离旧策略比较远了,这时我们应该增大 $\beta$ 把分布拉回来。
  • $D_{KL} \leq D_{min}$ 时,说明当前策略可能找到了捷径,即它过度拟合优化KL散度一项,而很可能忽视了前面优势相关的项,这时我们应该减小 $\beta$ 参数,降低惩罚项的影响。

**Clip形式隐式约束**

由于上面对于KL散度的超参数动态调整比较麻烦,所以一般采用下面的clip形式的隐式约束,它可以直接对概率比率 $ r_t(\theta)$ 对梯度进行裁剪,避免了引入二阶导数或 KL 散度计算。整个过程采用梯度上升法来进行策略优化

\[ \mathcal{L}_{Clip}(\theta) = \mathbb{E}_t \left[ \min \left( r_t(\theta)\hat{A}_t,  \text{clip}(r_t(\theta), 1-\epsilon, 1+\epsilon)\hat{A}_t \right) \right] \]

  • $\hat{A}_t$:时序 Token 级别的优势函数(通常由 GAE 算得)。这里的优势函数内部其实已经隐式包含了 Reference Model 带来的 KL 惩罚。
  • $\epsilon$:裁剪超参数(通常取 0.1 或 0.2)。
  • $\text{clip}(r_t, 1-\epsilon, 1+\epsilon)$:将比率强行截断在 $[1-\epsilon, 1+\epsilon]$ 区间内。
  • min(*)操作实现了在优势为正的时候,仅对 $1+\epsilon$ 裁剪;在优势为负时,仅对 $1-\epsilon$ 裁剪。

我们针对这个表达式的几种情况进行一下分析一下:
$A_t > 0 $ 优势为正时,我们倾向于让 $\pi_\theta(a_t|s_t)$ 变大, 因此 $r_t(\theta)$ 也会增大:

  • 如果新旧策略分布相同,则 $r_t(\theta) = 1$,此时训练稳定,不会产生裁剪。
  • 如果 $\pi_\theta(a_t|s_t)$ 在之前更新过程中已经变大,则 $r_t(\theta) > 1$ ,那我们可能需要进行裁剪,将其限制在 $1+\epsilon$ 内防止策略分布越来越大,越偏越远。
  • 如果 $\pi_\theta(a_t|s_t)$ 在之前更新过程中已经变得很小,则$r_t(\theta) < 1$,此时更新策略,由于 $A_t > 0 $,所以下一次更新新策略增大,导致 $r_t(\theta) \to 1$,这是希望看到的,于是我们不再对其进行裁剪。

对于 $A_t < 0$ 的情况分析也类似,但是分析结果是前一种情况的相反方向。

2.4 Actor Loss

大多数策略网络使用PPO算法时都会采用PPO-Clip形式,也就是目标函数为:
\[ \mathcal{L}_{Clip}(\theta) = \mathbb{E}_t \left[ \min \left( r_t(\theta)\hat{A}_t,  \text{clip}(r_t(\theta), 1-\epsilon, 1+\epsilon)\hat{A}_t \right) \right] \]
然后使用梯度上升法进行更新。

2.5 Critic Loss

价值函数的目标是要满足贝尔曼方程:
\[ V_\pi(s_t)=\mathbb{E}_t\left[r_t+\gamma V_\pi(s_{t+1})\right] \]
实际应用中为了提高训练效率,减少轨迹采样中的等待,提高采样效率。常用一步估计法近似目标值,这是可以通过不断迭代收敛的,具体过程可以参考TD算法和Robbins-Monro 算法。也就是目标值 $V_{target}$ 可以近似为:
\[V_{target}(s_t)=r_t+\gamma V_{\phi_{old}}(s_{t+1})\]
其中 $\phi_{old}$ 是旧的critic网络,也就是在生成经验时使用的模型,这种设计类似于 DQN 中的目标网络机制:通过分离新旧网络(延迟副本)来稳定训练。


PPO理论解析
https://www.jarodleo.top/2026/06/17/2026-06-17-ppo理论解析/
作者
Jarod Leo
发布于
2026年6月17日
许可协议
CC BY-NC-SA 4.0