一、核心概念与演进脉络
这三种方法是 LLM 对齐(Alignment) 技术的三代范式演进:
| 维度 | PPO (2017/2023) | DPO (2023) | GRPO (2024) |
|---|---|---|---|
| 核心思想 | 在可信区域内小步更新策略,最大化奖励模型分数 | 将偏好数据直接转化为分类损失,绕过奖励建模 | 通过组内回答的相对好坏估计优势,无需价值模型 |
| 模型数量 | 4个(Actor + Critic + Reward Model + Ref) | 2个(策略模型 + Ref) | 3个(策略模型 + Reward + Ref) |
| 计算成本 | 最高 | 最低 | 中等 |
| 数据需求 | 绝对分数奖励 | 成对偏好数据(chosen/rejected) | 可验证奖励(对错/分数) |
| 稳定性 | 中等(需调 GAE 参数) | 高 | 高(自动归一化优势) |
演进逻辑:PPO 是通用 RL 工具 → DPO 发现奖励模型与策略的对偶性,极简实现 → GRPO 针对 PPO 的 Critic 内存瓶颈,用组内相对排名替代绝对价值估计。
二、PPO:工业级 RLHF 基石
2.1 算法原理
PPO 是 On-policy 强化学习算法,核心约束是策略更新不能偏离旧策略太远(Trust Region)。
关键组件 :
- Actor:生成回答的策略模型 \(\pi_\theta\)
- Critic:价值模型 \(V(s)\),预估当前状态的期望回报
- Reward Model:给完整回答打分 \(r_\theta\)
- Reference Model:冻结的 SFT 模型,计算 KL 散度防止跑偏
损失函数(Clip 机制):
其中 \(r_t(\theta) = \frac{\pi_\theta(a_t|s_t)}{\pi_{old}(a_t|s_t)}\) 是新旧策略比率,\(A_t\) 是优势函数。
优势估计(GAE):
2.2 训练流程
# 伪代码:完整 PPO Step
for epoch in range(ppo_epochs):
# Step 1: Rollout 生成数据
with torch.no_grad():
seq = actor.generate(prompts)
old_log_probs = actor(seq) # 旧策略 log prob
ref_log_probs = ref_model(seq) # 参考模型 log prob
values = critic(seq) # 价值估计
reward_score = reward_model(seq) # 奖励模型打分
# Step 2: 计算 Reward(含 KL 惩罚)
kl_div = old_log_probs - ref_log_probs
rewards = reward_score - beta * kl_div # Token-level KL 修正
# Step 3: GAE 计算优势函数
advantages, returns = compute_gae(rewards, values, gamma=0.99, lam=0.95)
# Step 4: PPO 更新(多次 epoch)
for batch in dataloader:
new_log_probs = actor(batch.seq)
ratio = torch.exp(new_log_probs - batch.old_log_probs)
# PPO Clip Loss
surr1 = ratio * batch.advantages
surr2 = torch.clamp(ratio, 1-eps, 1+eps) * batch.advantages
actor_loss = -torch.min(surr1, surr2).mean()
# Critic Loss
critic_loss = (critic(batch.seq) - batch.returns).pow(2).mean()
loss = actor_loss + 0.5 * critic_loss
loss.backward()
optimizer.step()
2.3 实践要点
- KL 散度系数 \(\beta\):通常 0.01-0.1,防止模型崩溃(Reward Hacking)
- GAE 参数:\(\gamma=0.99\), \(\lambda=0.95\) 是通用配置,\(\lambda\) 越小偏差越大方差越小
- Critic 学习率:通常比 Actor 小一个数量级,稳定训练
三、DPO:极简对齐范式
3.1 核心洞察
DPO 发现:最优策略 \(\pi^*\) 与奖励函数 \(r\) 存在闭式解关系(Bradley-Terry 模型):
因此可以直接从偏好数据优化策略,无需训练奖励模型和 Critic 。
3.2 损失函数
对于偏好对 \((y_w, y_l)\)(win vs lose):
直观理解:最大化偏好回答与拒绝回答的对数似然比差距,同时用 \(\beta\) 控制与参考模型的偏离程度。
3.3 数据格式与代码
# DPO 数据格式
{
"prompt": "解释什么是机器学习",
"chosen": "机器学习是让计算机从数据中自动学习规律...",
"rejected": "机器学习就是让机器变聪明..."
}
# DPO 核心实现(简化)
def dpo_loss(policy_logps, ref_logps, labels, beta=0.1):
"""
policy_logps: 策略模型对 chosen/rejected 的 log prob
ref_logps: 参考模型的 log prob
labels: 1 for chosen, 0 for rejected
"""
# 计算 log ratios
policy_ratio = policy_logps - ref_logps
# 分离 chosen 和 rejected
policy_chosen = policy_ratio[labels == 1]
policy_rejected = policy_ratio[labels == 0]
# DPO loss: 让 chosen 的 ratio 远大于 rejected
logits = beta * (policy_chosen - policy_rejected)
loss = -F.logsigmoid(logits).mean()
return loss
3.4 变体与技巧
- cDPO(保守 DPO):引入 label_smoothing 处理标注噪声
- IPO(身份偏好优化):对长序列平均 log 似然,缓解长度偏见
- ORPO:将 SFT 和 DPO 合并为单阶段训练,节省计算资源
四、GRPO:DeepSeek 的组相对优化
4.1 动机与核心思想
PPO 的痛点:
- Critic 模型与 Actor 同量级,显存占用翻倍
- 价值函数估计误差会放大优势方差,导致训练不稳定
- 奖励模型通常基于对比数据训练,但 PPO 使用绝对分数,存在分布错位
GRPO 解决方案 :
- 废弃 Critic:对同一问题采样 \(G\) 个回答,用组内相对奖励估计优势
- 归一化优势:\(A_{i,t} = \frac{R_i - \text{mean}(\{R_j\})}{\text{std}(\{R_j\})}\),自动零均值单位方差
- 适合可验证奖励:数学题(对错)、代码(执行结果)、格式检查(规则匹配)
4.2 算法详解
对于每个问题 \(q\),采样 \(G\) 个输出 \(\{o_1, o_2, ..., o_G\}\):
优势计算:
其中 \(R_i\) 可以是规则验证的 0/1 奖励,或奖励模型分数。
GRPO 目标函数 :
与 PPO 关键差异:
- PPO 优势:\(A_t = R_t + \gamma V(s_{t+1}) - V(s_t)\)(依赖 Critic)
- GRPO 优势:\(A_i = R_i - \bar{R}\)(组内相对排名)
4.3 代码实现
# GRPO 训练步骤(基于 DeepSeek 实现)
def grpo_step(batch, actor, ref_model, reward_fn, G=4, beta=0.1, eps=0.2):
"""
batch: 输入问题
G: 每组采样数量
"""
prompts = batch['prompt']
# 1. 对每个 prompt 采样 G 个回答
outputs = []
for _ in range(G):
out = actor.generate(prompts, max_length=512)
outputs.append(out)
# 2. 计算奖励(可验证奖励或模型打分)
rewards = []
for out in outputs:
r = reward_fn(out) # 例如:数学答案是否正确(0 或 1)
rewards.append(r)
rewards = torch.stack(rewards) # (G, batch_size)
# 3. 计算组内相对优势(关键!)
mean_rewards = rewards.mean(dim=0, keepdim=True)
std_rewards = rewards.std(dim=0, keepdim=True) + 1e-8
advantages = (rewards - mean_rewards) / std_rewards # 归一化
# 4. 计算 GRPO loss(类似 PPO clip,但用相对优势)
total_loss = 0
for i in range(G):
# 新策略 log prob
new_log_probs = actor(outputs[i], return_log_probs=True)
with torch.no_grad():
old_log_probs = actor(outputs[i], return_log_probs=True)
ref_log_probs = ref_model(outputs[i], return_log_probs=True)
# 策略比率
ratio = torch.exp(new_log_probs - old_log_probs)
# Clip 损失
surr1 = ratio * advantages[i]
surr2 = torch.clamp(ratio, 1-eps, 1+eps) * advantages[i]
policy_loss = -torch.min(surr1, surr2).mean()
# KL 散度(在 loss 中直接加,而非 reward 中)
kl_div = new_log_probs - ref_log_probs
kl_loss = beta * kl_div.mean()
total_loss += policy_loss + kl_loss
return total_loss / G
4.4 最新进展(2024-2025)
Hybrid GRPO :结合 PPO 的价值函数和 GRPO 的组采样
- 保留轻量级 Critic 作为基线,同时使用组内多样本估计
- 优势函数:\(A_T = \frac{1}{N}\sum_{t=1}^N[\tilde{R}_T^{(t)} + \gamma V(s_{T+1}^{(t)}) - V(s_T)]\)
- 在稀疏奖励环境下比原版 GRPO 更稳定
应用场景扩展 :
- 多模态:VAR 视觉模型、扩散模型对齐(G²RPO)
- 语音:ASR 错误率降低 18.4%,减少幻觉
- 多智能体:GRPO-GCC 引入全局合作约束
五、方法选型决策树
选型建议:
- PPO:需要细粒度控制、复杂奖励函数、长期依赖任务(多轮对话)
- DPO:快速原型、主观偏好对齐、计算资源受限
- GRPO:数学/代码等可验证任务、显存瓶颈严重、需要高多样性探索
六、从入门到精通的学习路径
Level 1:理论理解(1-2 周)
- 强化学习基础:理解 Policy Gradient、Advantage Actor-Critic
- 读原始论文:
- PPO: Proximal Policy Optimization Algorithms (Schulman et al., 2017)
- DPO: Direct Preference Optimization (Rafailov et al., 2023)
- GRPO: DeepSeekMath (Shao et al., 2024)
Level 2:代码实践(2-3 周)
- 手撕 PPO:用 PyTorch 实现简化版 PPO,理解 GAE 计算
- DPO 微调:使用
trl或llama-factory对 7B 模型进行 DPO 训练 - GRPO 实验:在 GSM8K 数学数据集上复现 GRPO,对比 PPO 的显存占用
Level 3:进阶优化(持续)
- 混合策略:先用 DPO 预热,再用 GRPO 强化(DeepSeek-R1 策略)
- 长度归一化:解决 DPO/GRPO 的长度偏见(Length Bias)
- 迭代训练:Online DPO / Iterative GRPO,使用模型自生成数据迭代优化
推荐资源
- 代码库:huggingface/trl(包含 PPO/DPO/GRPO 实现)
- 可视化理解:The Illustrated PPO
- 实践教程:MiniMind 项目的 train_ppo.py 实现
总结:PPO 是通用强大的"重武器",DPO 是简洁优雅的"轻量级方案",GRPO 则是针对可验证任务的"高效专精工具"。掌握三者的差异和联系,能根据任务特性灵活选择,是 LLM 对齐工程师的核心能力。
讨论回复
0 条回复还没有人回复,快来发表你的看法吧!
推荐
智谱 GLM-5 已上线
我正在智谱大模型开放平台 BigModel.cn 上打造 AI 应用,智谱新一代旗舰模型 GLM-5 已上线,在推理、代码、智能体综合能力达到开源模型 SOTA 水平。