参考文献
PPO算法执行流程
场景设定
Prompt:
"如何提高学习效率?"
当前策略(policy LM):( π θ \pi_\theta πθ)
旧策略: π old \pi_{\text{old}} πold
参考模型: π ref \pi_{\text{ref}} πref
奖励模型: r ϕ ( x , y ) r_\phi(x,y) rϕ(x,y)
超参数:
- ( ϵ \epsilon ϵ = 0.2)
- ( γ \gamma γ = 1)
- ( λ \lambda λ = 1)(为简化)
- ( β \beta β = 0.1)(KL 系数)
Step 1:Rollout(采样)
模型生成 3 个 token 的回答:
a1 = "制定"
a2 = "计划"
a3 = "坚持"
我们记录旧策略的 logprob:
| t | token | l o g π o l d log π_{old} logπold |
|---|---|---|
| 1 | 制定 | -1.0 |
| 2 | 计划 | -0.5 |
| 3 | 坚持 | -0.2 |
Step 2:奖励 + KL shaping
- 奖励模型给整条回答一个分数:
r ϕ ( x , y ) = 2.0 r_\phi(x,y) = 2.0 rϕ(x,y)=2.0 - 我们只把主奖励给最后一个 token:
r 3 m a i n = 2.0 , r 1 = r 2 = 0 r_3^{main} = 2.0,\quad r_1=r_2=0 r3main=2.0,r1=r2=0
2.1 计算 KL penalty
当前策略的新 logprob:
| t | l o g π θ logπ_{\theta} logπθ | l o g π r e f logπ_{ref} logπref |
|---|---|---|
| 1 | -0.8 | -0.9 |
| 2 | -0.4 | -0.6 |
| 3 | -0.1 | -0.3 |
计算 token-level KL shaping,为每个token的奖励加正则,防止分布变化过大
r t K L − β ( log π θ − log π r e f ) r_t^{KL} -\beta(\log \pi_\theta - \log \pi_{ref}) rtKL−β(logπθ−logπref)
- t=1
r 1 K L = − 0.1 ( − 0.8 + 0.9 ) = − 0.1 ( 0.1 ) = − 0.01 r_1^{KL}=-0.1(-0.8+0.9)=-0.1(0.1)=-0.01 r1KL=−0.1(−0.8+0.9)=−0.1(0.1)=−0.01 - t=2
r 2 K L = − 0.1 ( − 0.4 + 0.6 ) = − 0.1 ( 0.2 ) = − 0.02 r_2^{KL}=-0.1(-0.4+0.6)=-0.1(0.2)=-0.02 r2KL=−0.1(−0.4+0.6)=−0.1(0.2)=−0.02 - t=3
r 3 K L = − 0.1 ( − 0.1 + 0.3 ) = − 0.1 ( 0.2 ) = − 0.02 r_3^{KL}=-0.1(-0.1+0.3)=-0.1(0.2)=-0.02 r3KL=−0.1(−0.1+0.3)=−0.1(0.2)=−0.02
2.2 最终 reward
| t | main reward | KL | total r_t |
|---|---|---|---|
| 1 | 0 | -0.01 | -0.01 |
| 2 | 0 | -0.02 | -0.02 |
| 3 | 2.0 | -0.02 | 1.98 |
Step 3:Value 预测 + Advantage
假设 value head 预测:
| t | V(s_t) |
|---|---|
| 1 | 0.5 |
| 2 | 0.6 |
| 3 | 0.7 |
| terminal | 0 |
3.1 计算 TD residual
这几步用于更新value head
δ t = r t + V ( s t + 1 ) − V ( s t ) \delta_t = r_t + V(s_{t+1}) - V(s_t) δt=rt+V(st+1)−V(st)
- t=3
δ 3 = 1.98 + 0 − 0.7 = 1.28 \delta_3 = 1.98 + 0 - 0.7 = 1.28 δ3=1.98+0−0.7=1.28 - t=2
δ 2 = − 0.02 + 0.7 − 0.6 = 0.08 \delta_2 = -0.02 + 0.7 - 0.6 = 0.08 δ2=−0.02+0.7−0.6=0.08 - t=1
δ 1 = − 0.01 + 0.6 − 0.5 = 0.09 \delta_1 = -0.01 + 0.6 - 0.5 = 0.09 δ1=−0.01+0.6−0.5=0.09
3.2 GAE(λ=1 简化)
A t = ∑ l = 0 δ t + l A_t = \sum_{l=0} \delta_{t+l} At=l=0∑δt+l
- t=3
A 3 = 1.28 A_3 = 1.28 A3=1.28 - t=2
A 2 = 0.08 + 1.28 = 1.36 A_2 = 0.08 + 1.28 = 1.36 A2=0.08+1.28=1.36 - t=1
A 1 = 0.09 + 0.08 + 1.28 = 1.45 A_1 = 0.09 + 0.08 + 1.28 = 1.45 A1=0.09+0.08+1.28=1.45
Step 4:计算 PPO ratio
损失函数之一项
ρ t = exp ( log π θ − log π o l d ) \rho_t = \exp(\log \pi_\theta - \log \pi_{old}) ρt=exp(logπθ−logπold)
- t=1
ρ 1 = e − 0.8 − ( − 1.0 ) = e 0.2 ≈ 1.22 \rho_1 = e^{-0.8 - (-1.0)} = e^{0.2} ≈ 1.22 ρ1=e−0.8−(−1.0)=e0.2≈1.22 - t=2
ρ 2 = e − 0.4 − ( − 0.5 ) = e 0.1 ≈ 1.105 \rho_2 = e^{-0.4 - (-0.5)} = e^{0.1} ≈ 1.105 ρ2=e−0.4−(−0.5)=e0.1≈1.105 - t=3
ρ 3 = e − 0.1 − ( − 0.2 ) = e 0.1 ≈ 1.105 \rho_3 = e^{-0.1 - (-0.2)} = e^{0.1} ≈ 1.105 ρ3=e−0.1−(−0.2)=e0.1≈1.105
Step 5:Clipped objective
L t = min ( ρ t A t , c l i p ( ρ t , 1 − ϵ , 1 + ϵ ) A t ) L_t = \min(\rho_t A_t, clip(\rho_t,1-\epsilon,1+\epsilon)A_t) Lt=min(ρtAt,clip(ρt,1−ϵ,1+ϵ)At)
( ϵ \epsilon ϵ=0.2)
clip 区间:
0.8 , 1.2 \] \[0.8,1.2\] \[0.8,1.2
- t=1:\rho_1=1.22 > 1.2
clip后=1.2
\\rho_1A_1=1.22×1.45=1.769
clip×A=1.2×1.45=1.74
取 min → 1.74
t=2
\\rho_2=1.105
在区间内
1.105×1.36=1.50
t=3
1.105×1.28=1.414
总 policy objective
L = 1.74 + 1.50 + 1.414 = 4.654 L = 1.74 + 1.50 + 1.414 = 4.654 L=1.74+1.50+1.414=4.654
训练时我们最大化 L
(实现中最小化 -L)
Step 6:Value loss
目标 return:
R t = A t + V ( s t ) R_t = A_t + V(s_t) Rt=At+V(st)
例如:
R_3 = 1.28 + 0.7 = 1.98
正好接近真实奖励。
value loss:
(V - R)\^2
Step 7:参数更新
对同一批 rollout 数据:
- 做 K 个 epoch
- 每次随机 minibatch
- 用 Adam 更新参数
直观解释这次更新发生了什么?
- 所有 token advantage 都是正的 → 模型认为整句话是"好回答"
- ratio > 1 → 新模型比旧模型更倾向这些 token
- clip 防止过度放大概率
- KL penalty 轻微拉回 reference
整体流程总结(LM 对齐视角)
- 生成回答
- 奖励模型打分
- 加 KL penalty
- 计算 GAE
- PPO clipped 更新
- 重复
本质
PPO 在 LM 中等价于:
轻微提高好回答中 token 的概率
轻微降低坏回答中 token 的概率
同时保持分布不偏离 reference 太远
DPO算法原理
显然,PPO 的算法存在的主要一个缺陷就是所需的内存过多:我们需要保存:
- Policy:和 LM 一样大的模型
- Reference Policy:和 LM 一样大的模型
- Value Model:和 LM 一样大的模型
- Reward Model:和 LM 差不多大的模型
并且,在训练过程中,还需要保存大量的中间激活(activations)用于反向传播(backpropagation)。
这对于动辄几个 B 的 LM 模型来说,消耗是巨大的,因此,提出了 DPO 的算法。
DPO(Direct Preference Optimization)(Rafailov et al. 2024)可以把 "RLHF + PPO" 那套 采样→训练 reward→RL 更新,简化成一个纯监督式的偏好学习:直接用偏好数据更新策略模型。一句话总结就是:让模型对 preferred 回答的概率比 rejected 更大,同时用参考模型 (\pi_{\mathrm{ref}}) 约束别偏太远。
接下来,我们来具体看看 DPO 算法:假设 policy 不是神经网络,而是任意分布(nonparametric)。在这个假设下,这个优化问题有解析解:
π r ( y ∣ x ) = 1 Z ( x ) , π r e f ( y ∣ x ) , exp ! ( 1 β , r ( x , y ) ) \pi_r(y\mid x)=\frac{1}{Z(x)},\pi_{\mathrm{ref}}(y\mid x),\exp!\left(\frac{1}{\beta},r(x,y)\right) πr(y∣x)=Z(x)1,πref(y∣x),exp!(β1,r(x,y))
这其实就是一个 Boltzmann / energy-based reweighting:
- 参考分布 (\pi_{\mathrm{ref}}) 提供"先验"
- reward 越高,(\exp(r/\beta)) 越把概率往上推
- (Z(x)) 是归一化常数(partition function)
2.5 反解"得到 implied reward:reward ≈ log-ratio(差一个常数)
把上式取 log 并整理,得到图里最后一行:
r ( x , y ) = β log π r ( y ∣ x ) π r e f ( y ∣ x ) + β log Z ( x ) r(x,y)=\beta\log\frac{\pi_r(y\mid x)}{\pi_{\mathrm{ref}}(y\mid x)}+\beta\log Z(x) r(x,y)=βlogπref(y∣x)πr(y∣x)+βlogZ(x)
关键点:
- (\beta\log Z(x)) 只依赖 (x),不依赖 (y) → 在"比较 (y^+) vs (y^-)"时会相消
所以在偏好学习里,你可以把 reward 的差写成:
r ( x , y + ) − r ( x , y − ) = β ( log π ( y + ∣ x ) π r e f ( y + ∣ x ) log π ( y − ∣ x ) π r e f ( y − ∣ x ) ) r(x,y^+)-r(x,y^-)= \beta\left( \log\frac{\pi(y^+\mid x)}{\pi_{\mathrm{ref}}(y^+\mid x)} \log\frac{\pi(y^-\mid x)}{\pi_{\mathrm{ref}}(y^-\mid x)} \right) r(x,y+)−r(x,y−)=β(logπref(y+∣x)π(y+∣x)logπref(y−∣x)π(y−∣x))
这一步就是 DPO 的核心:不显式训练 reward model,而是用 policy 的 logprob(相对 ref 的差)
把上面差值写得更紧凑一点:
Δ θ ( x ) = ( log π θ ( y + ∣ x ) − log π θ ( y − ∣ x ) ) − ( log π r e f ( y + ∣ x ) − log π r e f ( y − ∣ x ) ) \Delta_\theta(x)= \big(\log\pi_\theta(y^+\mid x)-\log\pi_\theta(y^-\mid x)\big)-\big(\log\pi_{\mathrm{ref}}(y^+\mid x)-\log\pi_{\mathrm{ref}}(y^-\mid x)\big) Δθ(x)=(logπθ(y+∣x)−logπθ(y−∣x))−(logπref(y+∣x)−logπref(y−∣x))
于是
代回偏好似然:
L D P O ( θ ) − E ∗ ( x , y + , y − ) [ log σ ( β , Δ ∗ θ ( x ) ) ] L_{\mathrm{DPO}}(\theta) -\mathbb{E}*{(x,y^+,y^-)} \left[ \log\sigma\big(\beta,\Delta*\theta(x)\big) \right] LDPO(θ)−E∗(x,y+,y−)[logσ(β,Δ∗θ(x))]
这就是 DPO。
直觉解释:
- 如果你的新策略 (\pi_\theta) 相比 ref 更偏向 chosen((\Delta_\theta) 大),loss 小
- 如果反而更偏向 rejected((\Delta_\theta<0)),loss 大,会被梯度推回去
