一文搞懂 PPO 与 DPO:大模型对齐的两条路线
PPO 是"请翻译帮忙",DPO 是"直接学原文"。偏好学习可以绕过强化学习,转化为简单的监督学习问题。这不仅降低了训练成本,还提高了稳定性,是大模型对齐领域的一次重要简化。
本文从第一性原理出发,用最通俗的语言解释大模型对齐中的两大核心算法。读完本文,你将彻底理解为什么 DPO 正在取代 PPO 成为主流。
一、先问一个根本问题:我们到底想让大模型学什么?
在讨论算法之前,我们先回到原点思考:
大模型预训练学会了"说人话",但它不知道"说什么话让人满意"。
比如你问:“如何快速减肥?”
- 回答A:绝食三天(有效但危险)
- 回答B:合理饮食+运动(安全且正确)
模型需要学会:在所有"能说的话"中,选择"人类偏好的话"。
这就是 对齐(Alignment) 的本质。
二、PPO 的思路:请一个"裁判"来打分
2.1 核心逻辑
PPO 的思路非常直觉:
既然要学人类偏好 → 那就训练一个"裁判"来代表人类 → 让模型讨好这个裁判
2.2 三步走流程
第一步:收集人类偏好数据
用户提问 → 模型给出回答A和回答B → 人类标注"A比B好"
第二步:训练奖励模型(Reward Model)
让一个模型学会:看到回答就能打分,分数代表人类喜欢程度
第三步:用强化学习优化策略
模型生成回答 → 奖励模型打分 → 高分行为强化,低分行为抑制
2.3 一个比喻
想象你在训练一只狗表演:
- 先培训一个驯狗师(奖励模型):教会他判断什么动作好
- 狗表演,驯狗师打分:做对了给骨头,做错了不给
- 狗根据反馈调整:慢慢学会讨好驯狗师
2.4 PPO 的问题
| 问题 | 说明 |
|---|---|
| 训练复杂 | 需要同时维护 4 个模型:策略模型、参考模型、奖励模型、价值模型 |
| 不稳定 | 强化学习本身就容易崩,调参是玄学 |
| 成本高 | 奖励模型要单独训练,推理时还要额外调用 |
| 奖励黑客 | 模型可能找到"骗过裁判但人类不喜欢"的捷径 |
三、DPO 的思路:砍掉中间商,直接学
3.1 一个关键洞察
DPO 论文的作者发现了一个数学事实:
最优的奖励函数,可以用策略模型本身来表示。
这意味着什么?我们根本不需要单独训练奖励模型!
3.2 核心公式(直觉理解)
不看复杂推导,只看结论:
奖励 r(x,y) 可以写成:
r(x,y) = β · log[π(y|x) / π_ref(y|x)] + 常数
其中:
- π(y|x):当前模型生成 y 的概率
- π_ref(y|x):参考模型(原始模型)生成 y 的概率
- β:温度系数
翻译成人话:一个回答的"奖励",就是当前模型比原始模型"更愿意生成它"的程度。
3.3 DPO 的训练目标
既然奖励可以用策略表示,那就直接优化:
对于每一对样本(好回答 y_w,坏回答 y_l):
让模型更倾向于生成 y_w,更不倾向于生成 y_l
损失函数一行搞定:
loss = -log(sigmoid(β * (log_prob_good - log_prob_bad)))
3.4 同样的比喻
还是训练狗:
- PPO:请驯狗师 → 驯狗师打分 → 狗学习
- DPO:直接给狗看视频:“这个动作👍,那个动作👎” → 狗自己悟
DPO 砍掉了驯狗师这个中间环节。
四、核心区别对比
| 维度 | PPO | DPO |
|---|---|---|
| 学习方式 | 间接(通过奖励模型) | 直接(从偏好对学习) |
| 需要奖励模型 | ✅ 需要单独训练 | ❌ 不需要 |
| 训练阶段 | 多阶段(SFT→RM→PPO) | 单阶段(SFT→DPO) |
| 模型数量 | 4个(策略/参考/奖励/价值) | 2个(策略/参考) |
| 训练稳定性 | 较差,需要精细调参 | 较好,接近普通微调 |
| 计算成本 | 高 | 低(约PPO的1/3) |
| 理论基础 | 强化学习 | 分类问题(交叉熵) |
五、代码直觉:看看训练循环的区别
PPO 训练循环(简化)
for batch in dataloader:
# 1. 生成回答
responses = policy_model.generate(batch.prompts)
# 2. 奖励模型打分
rewards = reward_model(batch.prompts, responses)
# 3. 计算优势函数(需要价值模型)
values = value_model(batch.prompts, responses)
advantages = compute_gae(rewards, values)
# 4. PPO 损失(带 clip)
loss = ppo_loss(advantages, old_probs, new_probs)
# 5. 更新策略模型和价值模型
optimizer.step()
DPO 训练循环(简化)
for batch in dataloader:
# 1. 计算好回答的 log 概率
log_prob_good = policy_model.log_prob(batch.prompts, batch.chosen)
log_prob_good_ref = ref_model.log_prob(batch.prompts, batch.chosen)
# 2. 计算坏回答的 log 概率
log_prob_bad = policy_model.log_prob(batch.prompts, batch.rejected)
log_prob_bad_ref = ref_model.log_prob(batch.prompts, batch.rejected)
# 3. DPO 损失(就是个二分类)
log_ratio_good = log_prob_good - log_prob_good_ref
log_ratio_bad = log_prob_bad - log_prob_bad_ref
loss = -log(sigmoid(beta * (log_ratio_good - log_ratio_bad)))
# 4. 更新策略模型
optimizer.step()
关键区别:DPO 没有奖励模型,没有价值模型,没有优势函数计算,就是简单的前向传播 + 交叉熵。
六、为什么 DPO 能 work?—— 第一性原理解释
回到最本质的问题:
人类偏好数据告诉我们什么?
"对于问题 x,回答 y_w 比 y_l 更好"
PPO 的处理方式:
偏好数据 → 训练奖励模型学会打分 → 用分数指导策略更新
DPO 的处理方式:
偏好数据 → 直接告诉模型:提高 y_w 的概率,降低 y_l 的概率
DPO 的洞察是:我们最终要的是"模型的行为改变",而不是"一个会打分的裁判"。
奖励模型只是实现目标的手段,不是目标本身。如果能直接达到目标,为什么要绕路?
七、实际选择:什么时候用哪个?
| 场景 | 推荐算法 | 原因 |
|---|---|---|
| 资源有限 | DPO | 训练成本低,稳定 |
| 快速迭代 | DPO | 流程简单,一步到位 |
| 需要复杂奖励设计 | PPO | 可以灵活定义奖励函数 |
| 在线学习/实时反馈 | PPO | 可以持续从新反馈中学习 |
| 追求极致性能 | 两者结合 | 先 DPO 打底,再 PPO 精调 |
八、总结
用一句话概括两者的区别:
PPO 是"请翻译帮忙",DPO 是"直接学原文"。
DPO 的核心贡献是发现:偏好学习可以绕过强化学习,转化为简单的监督学习问题。
这不仅降低了训练成本,还提高了稳定性,是大模型对齐领域的一次重要简化。
参考文献
- Schulman et al. “Proximal Policy Optimization Algorithms” (2017)
- Rafailov et al. “Direct Preference Optimization: Your Language Model is Secretly a Reward Model” (2023)
💡 如果这篇文章对你有帮助,欢迎点赞收藏!有问题欢迎评论区讨论。
更多推荐



所有评论(0)