Reading

DPO(Direct Preference Optimization)

背景

RLHF 通常包括三个阶段:

  • 有监督微调(SFT)

RLHF首先通过在高质量数据上进行监督学习来微调预训练的语言模型,得到模型 \(\pi_{SFT}\)

  • 奖励建模阶段 (Reward Model)

在第二阶段,SFT模型根据提示 \(x\) 生成答案对 \((y_1, y_2) \sim \pi_{SFT}(y|x)\)。这些答案对呈现给人类标注者,他们表达对一个答案的偏好,表示为\(y_w \succ y_l|x\),其中 \(y_w\)\(y_l\)分别表示在 \((y_1, y_2)\)中更受偏好和不受偏好的答案。

这些偏好被假定由某个潜在的奖励模型 \(r^*(y, x)\)生成,我们无法直接访问该模型。一种流行的建模偏好的方法是Bradley-Terry(BT)模型,该模型规定人类偏好分布 \(p^*\)可以写为:

\[p^*(y_1 \succ y_2|x) = \frac{\exp(r^*(x, y_1))}{\exp(r^*(x, y_1)) + \exp(r^*(x, y_2))} \]

假设我们有一个从 \(p^*\) 采样的静态比较数据集 \(D = {(x^{(i)}, y_w^{(i)}, y_l^{(i)})}_{i=1}^N\),我们可以参数化一个奖励模型 \(r_\phi(x, y)\) 并通过最大似然估计参数。将问题表述为二元分类,我们有负对数似然损失:

\[L_R(r_\phi, D) = -\mathbb{E}_{(x,y_w,y_l)\sim D}[\log \sigma(r_\phi(x, y_w) - r_\phi(x, y_l))]\tag{1}\]

其中 \(\sigma\) 是logistic函数。在LMs的上下文中,网络 \(r_\phi(x, y)\) 通常从SFT模型 \(\pi_{SFT}(y|x)\) 初始化,加上一个在最终transformer层之上的线性层,该层为奖励值产生单一标量预测。

  • RL微调阶段

    在RL阶段,学习到的奖励函数用于为语言模型提供反馈。遵循先前的工作,优化被表述为:

\[ \max_{\pi_\theta} \mathbb{E}_{x\sim D, y\sim\pi_\theta(y|x)}[r_\phi(x, y)] - \beta D_{KL}(\pi_\theta(y|x) || \pi_{ref}(y|x))\tag{2}\]

其中 \(\beta\) 是控制偏离基准参考策略 \(\pi_{ref}\)(即初始SFT模型 \(\pi_{SFT}\))程度的参数。由于语言生成的离散性质,这个目标不可微分,通常使用强化学习进行优化。标准方法是构建奖励函数:

\[r(x, y) = r_\phi(x, y) - \beta(\log \pi_\theta(y|x) - \log \pi_{ref}(y|x))\tag{3}\]

并使用PPO进行最大化。这个 loss 意思是希望 LLM 输出的回答的评分能尽可能高,同时 \(\pi_\theta\) 不要偏离 \(\pi_\text{ref}\) 太多,保证它还能正常做回答,不要训成一个评分很高但是回答乱码的东西。

直接偏好优化(DPO)

传统的RLHF方法分两步走:

  1. 先训练一个奖励模型来判断哪个回答更好
  2. 然后用强化学习让语言模型去最大化这个奖励

这个过程很复杂,就像绕了一大圈:先学习"什么是好的",再学习"如何做好"。

DPO发现了一个数学上的捷径:

  1. 关键发现:对于任何奖励函数,都存在一个对应的最优策略(语言模型);反过来说,任何语言模型也隐含着一个它认为最优的奖励函数
  2. 直接优化与其先训练奖励模型再训练语言模型,不如直接训练语言模型,让它自己内化"什么是好的"
  3. 数学转换:DPO将"学习判断好坏"和"学习生成好内容"这两个任务合二为一,通过一个简单的数学变换,把原本需要用于训练奖励模型的偏好数据直接用来训练语言模型

本质上,DPO让语言模型自己成为了隐含的奖励模型,省去了中间环节,使整个训练过程更简单、更直接、更高效。

DPO推导

我们从与先前工作相同的RL目标开始,根据一般奖励函数 \(r\)。遵循先前的工作,可以证明KL约束的奖励最大化目标的最优解具有以下形式:

\[\pi_r(y|x) = \frac{1}{Z(x)} \pi_{ref}(y|x) \exp\left(\frac{1}{\beta}r(x, y)\right)\tag{4}\]

其中,\(Z(x) = \sum_y \pi_{ref}(y|x) \exp\left(\frac{1}{\beta}r(x, y)\right)\)是分区函数。

🧾 (4)证明如下:
由于 KL 散度在 2 个分布相等时取最小值,我们得到了这样的结论:RLHF 训练希望得到的最优的概率分布就是 \(\pi^*\)
\[\begin{aligned}\min_{\pi_\theta}&\mathbb{E}_{x\sim \mathcal{D},y\sim\pi_\theta(y|x)}[\log\frac{\pi_\theta(y|x)}{\pi_\text{ref}(y|x)e^{r_\phi(x,y)/\beta}}]\\ &=\min_{\pi_\theta}\mathbb{E}_{x\sim \mathcal{D},y\sim\pi_\theta(y|x)}[\log\frac{\pi_\theta(y|x)}{\pi^*(y|x)}-\log Z(x)]\\ &=\min_{\pi_\theta}\mathbb{E}_{x\sim \mathcal{D},y\sim\pi_\theta(y|x)}[\log\frac{\pi_\theta(y|x)}{\pi^*(y|x)}]\\ &=\min_{\pi_\theta}\mathbb{E}_{x\sim \mathcal{D}}\mathbb{D}_\text{KL}(\pi_\theta(y|x)||\pi^*(y|x)) \end{aligned}\]

那么上式变成了:
\[\pi^*(y|x) = \pi_\text{ref}(y|x)e^{r_\phi(x,y)/\beta}/Z(x)\]

如果我们归一化一下分母,即取 \(Z(x)=\sum_y\pi_\text{ref}(y|x)e^{r_\phi(x,y)/\beta}\),也就可以构造出一个新的概率分布:
\[\begin{aligned}\max_{\pi_\theta}&\left\{\mathbb{E}_{x\sim \mathcal{D},y\sim\pi_\theta(y|x)}[r_\phi(x,y)] -\beta\mathbb{D}_{\text{KL}}[\pi_\theta(y|x)||\pi_\text{ref}(y|x)]\right\}\\&=\max_{\pi_\theta}\mathbb{E}_{x\sim \mathcal{D},y\sim\pi_\theta(y|x)}[r_\phi(x,y) - \beta \log \frac{\pi_\theta(y|x)}{\pi_\text{ref}(y|x)}]\\&=\min_{\pi_\theta}\mathbb{E}_{x\sim \mathcal{D},y\sim\pi_\theta(y|x)}[\log \frac{\pi_\theta(y|x)}{\pi_\text{ref}(y|x)} - \frac{1}{\beta} r_\phi(x,y)]\\&=\min_{\pi_\theta}\mathbb{E}_{x\sim \mathcal{D},y\sim\pi_\theta(y|x)}[\log\frac{\pi_\theta(y|x)}{\pi_\text{ref}(y|x)e^{r_\phi(x,y)/\beta}}]\end{aligned}\]

我们从RLHF中的KL约束奖励最大化问题开始, 即(2),这个式子是有显式解的。因为:原始问题设定

我们可以重新排列(4),以根据其对应的最优策略 \(\pi_r\)、参考策略 \(\pi_{ref}\) 和未知分区函数\(Z(\cdot)\) 表达奖励函数;另一个角度来说,由 \(\pi_r\) 的公式,我们相当于是得到了 \(r_\phi\) 和 \(\pi_r\) 的关系,那么是否我们可以把训练 \(r_\phi\) 转化成直接去训练 \(\pi_r\) 呢:

\[r(x, y) = \beta \log \frac{\pi_r(y|x)}{\pi_{ref}(y|x)} + \beta \log Z(x)\tag{5}\]

这里因为公式中分区函数\(Z(x)\)的估计很难,幸运的是,Bradley-Terry模型仅依赖于两个response之间的奖励差异,即\(p^*(y_1 \succ y_2|x) = \sigma(r^*(x, y_1) - r^*(x, y_2))\)当我们计算两个输出的奖励差时,常数项 \(\beta \log Z(x)\) 会被消除:

\[\begin{aligned} p^*(y_1 \succ y_2|x) &=\sigma\left(r^*(x, y_1) - r^*(x, y_2)\right) \\ &= \sigma\left(\beta \log \frac{\pi^*(y_1|x)}{\pi_{ref}(y_1|x)} - \beta \log \frac{\pi^*(y_2|x)}{\pi_{ref}(y_2|x)}\right)\\ &=\frac{1}{1 + \exp\left(\beta \log \frac{\pi^*(y_2|x)}{\pi_{ref}(y_2|x)} - \beta \log \frac{\pi^*(y_1|x)}{\pi_{ref}(y_1|x)}\right)} \end{aligned}\tag{6}\]

既然我们已经有了人类偏好的概率表达式, 我们可以构建一个最大似然目标函数来直接优化策略 \(\pi_\theta\)

\[\mathcal{L}_{\text{DPO}}(\pi_\theta; \pi_{ref}) = -\mathbb{E}_{(x,y_w,y_l) \sim \mathcal{D}} \left[ \log \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) \right]\tag{7}\]

这个目标函数与奖励建模的目标函数((1))在形式上非常相似,但关键区别在于:

  • 奖励建模目标函数优化的是奖励模型 \(r_\phi\)
  • DPO目标函数优化的是策略模型 \(\pi_\theta\)

这就是 DPO 的 loss。DPO 通过以上的公式转换把 RLHF 无损地转化为了 SFT,在训练的时候不再需要同时跑 4 个模型(reward model, ref model, critic, actor),而是只用跑 actor 和 ref 2 个模型,甚至由于不再在线采数据,ref model 的输出可以预先存下来,训练的时候重复使用。

DPO梯度更新

DPO(Direct Preference Optimization)的核心在于其梯度更新机制。通过分析DPO损失函数的梯度,我们可以深入理解其工作原理。

DPO损失函数相对于参数 \(\theta\) 的梯度可以表示为:

\[\nabla_\theta L_{DPO}(\pi_\theta; \pi_{ref}) = -\beta E_{(x,y_w,y_l)\sim D} \left[\sigma(\hat{r}_\theta(x, y_l) - \hat{r}_\theta(x, y_w)) \cdot \left[\nabla_\theta \log \pi(y_w | x) - \nabla_\theta \log \pi(y_l | x)\right]\right]\]

其中:

  • \(\hat{r}_\theta(x, y) = \beta \log \frac{\pi_\theta(y|x)}{\pi_{ref}(y|x)}\) 是由语言模型 \(\pi_\theta\) 和参考模型 \(\pi_{ref}\) 隐式定义的奖励函数
  • \((x,y_w,y_l)\)是从偏好数据集 \(D\) 中采样的三元组,包含提示 \(x\)、偏好response \(y_w\) 和非偏好response \(y_l\)
  • \(\sigma\)是sigmoid函数

梯度公式可以分解为三个关键部分:

  1. 加权系数\(\sigma(\hat{r}_\theta(x, y_l) - \hat{r}_\theta(x, y_w))\)
    • 当隐式奖励模型错误地给非偏好response \(y_l\) 比偏好response \(y_w\) 更高的评分时,这个权重会更大
    • 这个权重确保模型对那些当前评估错误的样本给予更多的关注
    • 权重由 \(\beta\) 缩放,体现了KL约束的强度
  1. 增加偏好response的似然\(\nabla_\theta \log \pi(y_w | x)\)

这一项使模型更倾向于生成人类偏好的response y_w,使模型学习产生更符合人类偏好的输出

  1. 减少非偏好response的似然\(\nabla_\theta \log \pi(y_l | x)\)

这一项降低了模型生成人类不偏好的response y_l 的概率,使模型学习避免产生不符合人类偏好的输出

实验表明,加权系数在DPO中起着至关重要的作用:

  • 没有这个加权系数的朴素版本可能导致语言模型退化
  • 加权确保了更有效的学习,因为它使模型专注于当前评估最不准确的样本
  • 这种加权机制与强化学习中的优势函数类似,但在DPO中是隐式定义的

DPO 流程

DPO的一般实施流程包括两个主要步骤:

  1. 构建偏好数据集

对于每个提示 \(x\)

    • 从参考策略采样response:\(y_1, y_2 \sim \pi_{ref}(· | x)\)
    • 使用人类偏好标注这些response
    • 构建离线偏好数据集:\(D = \{x^{(i)}, y_w^{(i)}, y_l^{(i)}\}_{i=1}^N\)
  1. 优化语言模型
  • 给定参考模型 \(\pi_{ref}\)、数据集 \(D\) 和超参数 \(\beta\)
  • 优化语言模型 \(\pi_\theta\) 以最小化 \(L_{DPO}\)

在实际应用中,我们通常希望重用公开可用的偏好数据集,而不是生成新样本并收集人类偏好。由于这些偏好数据集通常是使用SFT模型(\(\pi_{SFT}\))采样的:

  • \(\pi_{SFT}\) 可用时,我们初始化 \(\pi_{ref} = \pi_{SFT}\)
  • \(\pi_{SFT}\)不可用时,我们通过最大化偏好response的似然来初始化 \(\pi_{ref}\)
\[\pi_{ref} = \arg\max_\pi E_{x,y_w\sim D} [\log \pi(y_w | x)]\]

这种初始化过程有助于缓解真实参考分布(不可用)与DPO使用的 \(\pi_{ref}\) 之间的分布偏移。

💡 这个公式的含义是找到一个模型 \(\pi\),使得它在偏好数据集 \(D\) 上对偏好response \(y_w\) 的对数似然期望值最大化

实际含义
这个公式实际上描述的是一个监督学习过程
1. 从偏好数据集\(D\) 中,我们只使用提示\(x\)和人类偏好的response \(y_w\)(忽略非偏好response \(y_l\)
2. 我们对模型进行训练,使其最大化对这些偏好完成的预测概率
3. 这本质上是一个标准的语言模型训练过程,只是训练数据限制在了人类偏好的完成上

为什么这样做?
在论文中,作者解释这样做的目的是为了"缓解真实参考分布(不可用)与DPO使用的 \(\pi_{ref}\)之间的分布偏移"。具体来说:
1. 分布匹配:理想情况下,参考模型 \(\pi_{ref}\) 应该与生成偏好数据的原始模型分布一致
2. 解决分布偏移问题:
    偏好数据集 \(D\)通常是使用某个SFT模型采样得到的
    如果我们没有使用这个原始SFT模型,就会产生分布偏移问题
    通过在偏好完成上训练一个新模型,我们试图近似原始的分布
3. 保证DPO公式的有效性:
    DPO的理论基础假设参考模型 \(\pi_{ref}\) 与生成数据的分布一致
这种初始化方法帮助满足这一假设,使DPO算法能够正常工作

实例说明
假设我们有一个对话任务的偏好数据集,但没有原始的SFT模型:
1. 我们从数据集中提取所有的(提示, 偏好回复)对,比如:
    提示:"今天天气怎么样?",偏好回复:"今天阳光明媚,温度适宜。"
    提示:"推荐一本好书?",偏好回复:"我推荐《百年孤独》,它是一部杰出的魔幻现实主义作品。"
2. 我们使用这些(提示, 偏好回复)对来训练一个语言模型,使其在给定提示时能够生成类似的回复
3. 训练完成后,这个模型就成为我们的参考模型\(\pi_{ref}\),用于后续的DPO训练
这种初始化方法本质上是一种实用的近似策略,当我们无法获取原始的SFT模型时,通过在人类偏好的完成上训练一个新模型来作为参考模型,从而使DPO算法能够有效工作。这种方法在Anthropic HH对话数据集等实验中被证明是有效的。

具体实现

DPO的实现相对简单,核心是计算损失函数:

def dpo_loss(pi_logps, ref_logps, yw_idxs, yl_idxs, beta):
    """
    pi_logps: 策略对数概率,形状 (B,)
    ref_logps: 参考模型对数概率,形状 (B,)
    yw_idxs: 偏好完成索引,形状 (T,)
    yl_idxs: 非偏好完成索引,形状 (T,)
    beta: 控制KL惩罚强度的温度参数
    """
    pi_yw_logps, pi_yl_logps = pi_logps[yw_idxs], pi_logps[yl_idxs]
    ref_yw_logps, ref_yl_logps = ref_logps[yw_idxs], ref_logps[yl_idxs]

    pi_logratios = pi_yw_logps - pi_yl_logps
    ref_logratios = ref_yw_logps - ref_yl_logps

    losses = -F.logsigmoid(beta * (pi_logratios - ref_logratios))
    rewards = beta * (pi_logps - ref_logps).detach()

    return losses, rewards

DPO理论基础(Option)

"语言模型其实是个奖励模型"

DPO的关键理论突破在于发现语言模型本身可以被视为一个隐式的奖励模型。这一洞见使我们能够绕过传统RLHF中的两步过程(先学习奖励,再优化策略),直接从人类偏好中学习最优策略。

DPO理论首先引入了奖励函数的等价关系:

  • 如果两个奖励函数只相差一个仅依赖于提示\(x\) 的函数,则它们被视为等价的
  • 重要的是,同一等价类中的奖励函数在Bradley-Terry偏好模型下产生相同的偏好分布,并在约束RL问题下产生相同的最优策略
    这意味着我们只需要找到每个等价类中的一个代表性奖励函数,而不必担心具体选择哪一个。

DPO的核心定理证明了所有与Bradley-Terry模型兼容的奖励类都可以通过以下形式表示:

\[r(x,y) = β log\frac{π(y|x)}{π_{ref}(y|x)}\]

这个参数化的关键优势在于:

  1. 它不会限制可学习的奖励模型类别
  2. 它允许我们直接提取对应的最优策略,无需强化学习
  3. 它为每个等价类选择了一个特定的奖励函数,使得最优策略计算变得简单

Actor-Critic算法的不稳定性与DPO的优势

传统RLHF方法(如使用PPO)面临的主要挑战是训练不稳定性,这源于以下问题

  • 归一化项的挑战

在约束RL问题中,目标函数包含一个归一化项:


\[β log Σ_y π_{ref}(y|x) exp(1/β r_φ(x,y))\]

这个项可以被视为参考策略的软值函数,但在实践中:

    • 如果忽略它,策略梯度可能有高方差,导致学习不稳定
    • 使用学习的值函数来估计它也很困难
    • 现有方法通常使用人类完成基线作为粗略估计

DPO通过其特殊参数化巧妙地避开了这些问题:

  1. 不需要显式估计归一化项
  2. 不需要学习单独的值函数
  3. 不需要在训练循环中从语言模型采样
  4. 使用简单的分类损失函数直接优化策略

理论对实践的指导

这些理论分析为DPO的实际实现提供了重要指导:

  1. 简化实现:理解DPO的数学基础使我们能够用一个简单的二元交叉熵损失函数替代复杂的RL算法
  2. 梯度加权的重要性:理论解释了为什么DPO梯度中的加权系数(\(σ(r̂_θ(x,y_l) - r̂_θ(x,y_w))\))至关重要 - 它确保模型关注当前评估最不准确的样本
  3. \(β\)参数的选择:理论阐明了\(β\) 参数控制KL约束强度的作用,指导了不同任务的参数设置
  4. 参考模型初始化:理论解释了为什么在原始SFT模型不可用时,我们需要通过最大化偏好完成的似然来初始化参考模型
    DPO的理论基础不仅证明了方法的合理性,还解释了为什么这种简单的方法能够如此有效。通过巧妙的数学重参数化,DPO实现了与传统RLHF相同的目标,但方法更简单、更稳定、计算成本更低。这些理论洞见直接转化为实践优势,使DPO成为从人类偏好中训练语言模型的强大工具。

DPO的缺点

DPO面临 “distribution shift”的问题,即分布偏移问题,偏好数据在训练过程中是静态的,而模型输出分布正在不断变化

  1. 静态偏好数据 vs. 动态模型输出
    • 偏好数据(人类标注的哪个回答更好)在整个训练过程中是静态的、固定不变的
    • 而模型的输出分布随着训练不断变化(模型参数在不断更新)
  2. 偏移的具体表现
    • 训练初期:偏好数据中的"好"回答和"坏"回答与模型当时的能力相匹配
    • 训练中后期:模型能力提升,可能已经能生成比数据集中标记为"好"的回答更优质的回答
    • 但训练仍然基于原始静态数据进行,导致模型被迫向可能已经不够理想的"好"回答学习
  3. 后果
    • 模型输出分布与期望的反馈分布之间产生偏差
    • 导致对齐效果不理想,模型可能无法达到最佳性能

举例说明

假设我们有一个偏好数据对:

  • 回答A(被标记为"好"):相对清晰但不够全面的解释
  • 回答B(被标记为"坏"):混乱或不准确的解释

在训练初期,模型学习偏好A>B是合理的。但随着训练进行,模型可能已经能够生成比A更好的回答C(更全面、更准确)。然而,由于训练数据固定,模型仍然被引导向A学习,而不是向可能更优的C学习,这就造成了次优的对齐结果。

另外在这篇文章中也分析了dpo的缺点

dpo 的大前提未被验证 dpo 从头到尾都在以 reward_model 的方式让模型学习 evaluate 能力,但是却并没有证明一个重要假设:“模型的 evaluate 能力和 generate 能力到底是不是相互促进的?” dpo 后的模型具有了更强的 evaluate 能力,但我们的目标是提升模型的 generate 能力啊。如果这个基本假设不成立,那 dpo 的学习过程就没有什么价值。

解决方向

针对这个问题,研究人员提出了一些解决方案,例如:

  • 动态生成训练数据
  • 迭代式偏好学习
  • 在线DPO方法
  • 自适应偏好优化

这些方法的核心思想是让偏好数据能够随着模型能力的提升而更新,以减少分布偏移带来的负面影响。