Skip to content

DPO 直接偏好优化论文

DPO(Direct Preference Optimization)绕过 RLHF 中的奖励模型和强化学习阶段,直接从人类偏好数据优化语言模型策略,以更简单稳定的训练流程实现了与 RLHF 相当的对齐效果。

DPO优化

从 RLHF 到 DPO

RLHF 的三阶段流程复杂且不稳定,DPO 的核心洞察是:

偏好数据本身已隐含了奖励信息,无需显式训练奖励模型。

数学推导

RLHF 的最优策略可以表示为:

$$\pi^*(y|x) = \frac{1}{Z(x)} \pi_{ref}(y|x) \exp\left(\frac{1}{\beta} r(x,y)\right)$$

由此可以反推出奖励函数:

$$r(x,y) = \beta \log \frac{\pi^*(y|x)}{\pi_{ref}(y|x)} + \beta \log Z(x)$$

将此代入 Bradley-Terry 偏好模型,配分函数 Z(x) 被消除:

$$p(y_w \succ y_l|x) = \sigma\left(\beta \log \frac{\pi_\theta(y_w|x)}{\pi_{ref}(y_w|x)} - \beta \log \frac{\pi_\theta(y_l|x)}{\pi_{ref}(y_l|x)}\right)$$

python
import torch
import torch.nn.functional as F

def dpo_loss(policy_chosen_logps, policy_rejected_logps,
             reference_chosen_logps, reference_rejected_logps, beta=0.1):
    """DPO 损失函数"""
    # 对数比率
    chosen_logratios = policy_chosen_logps - reference_chosen_logps
    rejected_logratios = policy_rejected_logps - reference_rejected_logps

    # DPO 损失
    logits = beta * (chosen_logratios - rejected_logratios)
    loss = -F.logsigmoid(logits).mean()

    # 选择的奖励差(用于监控)
    chosen_rewards = beta * chosen_logratios
    rejected_rewards = beta * rejected_logratios

    return loss, chosen_rewards.mean(), rejected_rewards.mean()

DPO vs RLHF

维度RLHFDPO
训练阶段SFT → RM → PPOSFT → DPO
奖励模型需要显式训练隐式学习
稳定性PPO 训练不稳定简单分类损失
计算成本高(4个模型)低(2个模型)
超参数多(KL系数、PPO参数)少(β)

DPO 的简洁性

DPO 将 RLHF 的复杂流程简化为一个简单的分类问题:给定一对偏好数据 (chosen, rejected),训练模型增大 chosen 的概率、降低 rejected 的概率。这使得 DPO 的实现和调试都远比 RLHF 简单。

DPO 的变体

IPO(身份偏好优化)

IPO 使用更稳健的损失函数,避免 DPO 在偏好数据噪声较大时过拟合:

$$\mathcal{L}{IPO} = \mathbb{E}\left[\left(\log \frac{\pi\theta(y_w|x)}{\pi_{ref}(y_w|x)} - \log \frac{\pi_\theta(y_l|x)}{\pi_{ref}(y_l|x)} - \frac{1}{2\beta}\right)^2\right]$$

KTO(Kahneman-Tversky 优化)

仅需要二元反馈(好/坏),不需要成对偏好数据:

  • 更容易收集数据
  • 基于前景理论的非对称损失

ORPO(几率比偏好优化)

将 SFT 和偏好对齐合并为单一训练阶段。

实践建议

  • β 选择:0.1-0.5 之间,越大模型越保守
  • 数据质量:DPO 对偏好数据质量非常敏感
  • 参考模型:必须冻结参考模型
  • 训练长度:DPO 通常比 RLHF 需要更少的训练步数

相关资源

最近更新