本文从第一性原理出发,用最通俗的语言解释大模型对齐中的两大核心算法。读完本文,你将彻底理解为什么 DPO 正在取代 PPO 成为主流。

一、先问一个根本问题:我们到底想让大模型学什么?

在讨论算法之前,我们先回到原点思考:

大模型预训练学会了"说人话",但它不知道"说什么话让人满意"。

比如你问:“如何快速减肥?”

  • 回答A:绝食三天(有效但危险)
  • 回答B:合理饮食+运动(安全且正确)

模型需要学会:在所有"能说的话"中,选择"人类偏好的话"。

这就是 对齐(Alignment) 的本质。


二、PPO 的思路:请一个"裁判"来打分

2.1 核心逻辑

PPO 的思路非常直觉:

既然要学人类偏好 → 那就训练一个"裁判"来代表人类 → 让模型讨好这个裁判

2.2 三步走流程

第一步:收集人类偏好数据
        用户提问 → 模型给出回答A和回答B → 人类标注"A比B好"

第二步:训练奖励模型(Reward Model)
        让一个模型学会:看到回答就能打分,分数代表人类喜欢程度

第三步:用强化学习优化策略
        模型生成回答 → 奖励模型打分 → 高分行为强化,低分行为抑制

2.3 一个比喻

想象你在训练一只狗表演:

  1. 先培训一个驯狗师(奖励模型):教会他判断什么动作好
  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 的核心贡献是发现:偏好学习可以绕过强化学习,转化为简单的监督学习问题。

这不仅降低了训练成本,还提高了稳定性,是大模型对齐领域的一次重要简化。


参考文献

  1. Schulman et al. “Proximal Policy Optimization Algorithms” (2017)
  2. Rafailov et al. “Direct Preference Optimization: Your Language Model is Secretly a Reward Model” (2023)

💡 如果这篇文章对你有帮助,欢迎点赞收藏!有问题欢迎评论区讨论。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐