DPO
传统的RLHF(基于人类反馈的强化学习)流程复杂且不稳定, 其第一步是训练一个奖励模型来模拟人类偏好; 第二步是使用PPO优化模型, 这需要频繁的采样, 调节大量超参数, 且计算开销巨大. DPO的核心贡献是去掉了显式的奖励模型和强化学习的过程. 作者通过数学推导, 证明了奖励函数和最优策略之间存在闭式解. 既然这种关系存在, 就可以直接在偏好数据(即A回答比B好)上训练模型. DPO的主要优势: 不需要训练单独的奖励模型, 不需要PPO那些复杂的强化学习框架; 训练时不需要从模型中采样生成内容, 速度更快, 内存占用更低. 在情感控制, 摘要生成和单论对话任务中, 效果达到甚至超过了传统的PPO.
背景¶
大模型的训练分为两个阶段, 一个是预训练, 这是无监督学习, 在大规模数据集上学习知识. 第二个是对齐, 预训练之后, 利用人工筛选的偏好数据, 教会模型什么是"安全"和"有用". 三种对齐方式的对比: SFT, 让人类写标准答案, 模型模仿; RLHF, 先训练一个奖励模型学习人类偏好, 再使用强化学习优化模型; RLAIF: 和RLHF类似, 只是把人类反馈换成了AI反馈. 但是RLHF远比监督学习复杂, 因为: 训练的时候需要维护好几个模型(当前模型, 参考模型, 奖励模型), 显存压力比较大; 训练过程中, 模型必须实时生成回答, 导致计算成本极高; 在追求高分的同时, 还得保证模型不要跑偏, 别忘了原本的语言能力.

DPO的核心逻辑可以概括为: 1. 传统的RLHF需要先训练一个奖励模型, 再使用强化学习去跑. DPO略过了奖励模型, 通过数学转换, 直接在语言模型上使用人类偏好数据进行微调; 2. 虽然它简单(只需要简单的交叉熵损失函数), 但是在数学本质上是和复杂的强化学习(带KL三度约束的奖励最大化)是等价的; 3. 它通过提高好回答的概率并降低坏回答的概率来实现优化. 关键在于它引入了动态权重, 能根据每个样本的情况调整力度, 防止模型跑偏或者奔溃.
前置¶
RLHF分为三个阶段. 第一个阶段是SFT, Supervised Fine-Tuning, 在高质量的对话, 总结等数据集上进行有监督训练, 得到模型\(\pi^{SFT}\). 第二个阶段是奖励建模, 这是将人的主观感受转化为数学分值的过程. 给SFT模型一个提示词\(x\), 让它生成两个不同的回答\((y_1, y_2)\), 让人类标注者判断哪个更好, 记为\(y_w\succ y_l\), 其中, \(y_2\)是胜出者, \(y_l\)是落败者. Bradley-Terry(BT)模型假设, 人之所以觉得A比B好, 是因为A在人心中隐藏的奖励值更高, 可以表示为\(p^* (y_1 \succ y_2 | x) = \frac{\exp(r^*(x, y_1))}{\exp(r^*(x, y_1)) + \exp(r^*(x, y_2))}\). 人类选择\(y_1\)的概率, 取决于\(y_1\)的奖励分值占总分值的比例, 奖励分值越大, 选优胜者的概率就越接近\(1\). 通过拟合人类的这种选择偏好, 训练出一个神经网络奖励模型, 它可以给任何的回答打分. 假设我们有一个静态数据集\(\mathcal{D} = \{x, y_w, y_l\}\), 分别为提示词, 人类认为更好的回答, 人类认为较差的回答. 为了训练参数为\(\phi\)的奖励模型\(r_{\phi}\), 使用了推导自 Bradley-Terry 模型的二分类交叉熵损失: \(\mathcal{L}_R(r_\phi, \mathcal{D}) = -\mathbb{E}_{(x,y_w,y_l) \sim \mathcal{D}} \left[ \log \sigma(r_\phi(x, y_w) - r_\phi(x, y_l)) \right]\). Sigmoid函数将两个回答的分数差映射到\((0, 1)\)之间, 训练的目标是让\(r_{\phi}(x, y_w)\)(好答案的分数)尽可能远大于\(r_{\phi}(x, y_l)\)(坏答案的分数). 当分差越大, Sigmoid函数的结果越接近1, 其对数越接近0, 损失函数就越小. 奖励模型通常复用SFT模型的基座, 但是在最后加一个线性层, 最后输出一个标量, 即该回答的质量得分, 通常使用SFT阶段训练好的参数来初始化, 因为SFT模型已经理解了语言逻辑. 为了防止分数漫无边际地增长或者波动过大, 通常会做归一化处理. 为了防止分数漫无目的地增长或者波动过大, 通常会做归一化处理, 要求在数据集的所有样本上, 平均预测分数为0.
RLHF的第三个阶段是强化学习微调. 这是最复杂, 也是最容易出错的一步. 训练目标是找到一个模型(策略)\(\pi_{\theta}\). 最大化以下函数: \(\max_{\pi_\theta} \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)]\). 这个第一部分希望模型生成的内容在奖励模型那里拿到尽可能高的分. 第二部分(KL散度约束)限制当前正在训练的模型\(\pi_{\theta}\)不要偏离原始SFT模型\(\pi_{ref}\)太远以防止模型退化. 因为没有标准答案, PPO首先要求模型针对同一个问题\(x\), 生成很多个不同的回答\(y\), 模型会根据当前的概率分布, 随机采样出不同的词序列, 有些回答可能逻辑严密, 有些可能胡言乱语, 把这些生成的回答全部丢给奖励模型, 然后PPO有一个"策略梯度"法则, 既然全句比如说得了5分, PPO就假设这个句子里的每一个词都对这5分有贡献, 对于得分高的句子A, PPO下令, 把生成A中的这些词的概率上调; 对于得分低的句子B, PPO会下令, 把生成B中这些词的概率下调.
方法¶
\(Z(x)\)很难算¶
在RLHF中, 通常需要最大化奖励\(r(x, y)\)并限制策略偏离参考策略\(\pi_{ref}\). \(\max_{\pi_\theta} \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)]\)这个函数是可以求出理论上的最优解(策略)\(\pi_r\)的, \(\pi_r(y | x) \propto \pi_{\text{ref}}(y | x) \exp \left(\frac{1}{\beta} r(x, y)\right)\). \(Z(x) = \sum_y \pi_{\text{ref}}(y | x) \exp \left(\frac{1}{\beta} r(x, y)\right)\)是一个归一化常数, 为了保证策略\(\pi_r(y|x)\)在所有可能的回复\(y\)上面的概率之和等于1. 要计算\(Z(x)\), 必须遍历所有可能的回复\(y\), 对于大预言模型来说, \(y\)的组合是天文数字, 因此在实践过程中根本无法计算. 即使我们通过极大似然估计训练出了一个接近真实的奖励模型\(r_{\phi}\), 由于\(Z(x)\)的存在, 我们依然无法直接写出最优策略\(\pi_r\)的具体数值, 这使得传统的, 依赖显式奖励的方法在工程上非常笨重.
抵消掉\(Z(x)\)¶
由于\(Z(x)\)无法计算, 作者想到了一个数学上的"跳板": 不再尝试计算\(Z(x)\), 而是想办法把它抵消掉. 对于上述最优策略公式两边同时取log, 然后会得到: \(r(x, y) = \beta \log \frac{\pi_r(y | x)}{\pi_{\text{ref}}(y | x)} + \beta \log Z(x)\) (5). 这个公式的精妙之处在于, \(Z(x)\)之和输入\(x\)相关, 和生成的回复\(y\)无关. 在对比两个回复\(y_w\)和\(y_l\)的时候, 我们通常只关心奖励的差值, 即\(r(x, y_w) - r(x, y_l)\), 当你计算这个差值的时候, 含\(Z(x)\)的那一项就被抵消掉了.
BT模型是RLHF中处理偏好数据的标准模型, 它认为人类觉得\(y_1\)比\(y_2\)好的概率为\(P(y_1 \succ y_2 | x) = \sigma(r^*(x, y_1) - r^*(x, y_2))\). 我们将上面的公式(5)带入到BT模型, 得到\(P^*(y_1 \succ y_2 | x) = \frac{1}{1 + \exp\left( \beta \log \frac{\pi^*(y_2 | x)}{\pi_{\text{ref}}(y_2 | x)} - \beta \log \frac{\pi^*(y_1 | x)}{\pi_{\text{ref}}(y_1 | x)} \right)}\) (6), 可以发现, \(Z(x)\)消失了.
损失函数¶
公式(6)告诉我们, 理想模型下, \(y_w\)优于\(y_l\)的概率, 我们用极大似然估计, 让模型\(\pi_{\theta}\)的结果, 尽可能符合数据集中人类的偏好. \(\mathcal{L}_{\text{DPO}}(\pi_\theta; \pi_{\text{ref}}) = -\mathbb{E}_{(x, y_w, y_l) \sim \mathcal{D}} \left[ \log \sigma \left( \beta \log \frac{\pi_\theta(y_w | x)}{\pi_{\text{ref}}(y_w | x)} - \beta \log \frac{\pi_\theta(y_l | x)}{\pi_{\text{ref}}(y_l | x)} \right) \right]\) (7), 可以发现, 这个损失函数里面只有两个模型, 完全开不到奖励函数\(r(x, y)\), 这只是一个简单的二分类交叉熵损失, 可以使用标准的深度学习优化器直接训练.
DPO并没有彻底摒弃奖励的概念, 而是通过一种重参数化的方法, 将奖励函数藏在了策略函数里面, 虽然是在优化\(\pi_{\theta}\), 但是在数学上等同于你和一个奖励模型. 在DPO框架下, 训练得到的那个\(\pi_{\theta}\)模型, 就是原本RLHF目标的精准最优解. DPO训练过程在数学上完全等价于, 先用人类偏好数据你和一个符合BT模型的奖励函数, 然后再根据这个奖励函数求解最优策略.
梯度公式¶
DPO的梯度公式为\(\nabla_\theta \mathcal{L}_{\text{DPO}} = -\beta \mathbb{E}_{(x, y_w, y_l) \sim \mathcal{D}} \left[ \underbrace{\sigma\left(\hat{r}_\theta(x, y_l) - \hat{r}_\theta(x, y_w)\right)}_{\text{权重项:模型错得越离谱,权重越大}} \underbrace{\left( \nabla_\theta \log \pi_\theta(y_w | x) - \nabla_\theta \log \pi_\theta(y_l | x) \right)}_{\text{更新方向:拉高 } y_w \text{ 概率,压低 } y_l \text{ 概率}} \right]\). \(\nabla_\theta \mathcal{L}_{\text{DPO}} = -\beta \mathbb{E} [ \text{权重项} \times \text{方向项} ]\), 左侧的权重项, 当隐式奖励预测错误的时候, 赋予更高的权重. 如果模型错误的认为坏回复\(y_l\)比好回复\(y_w\)更好, 这个差值就是正的, Sigmoid就接近1, 如果模型已经分得很清楚, 权重就趋近于0. 右侧的方向项的正值项增加好回复的概率, 负值项减少坏回复的概率. \(\hat{r}_\theta(x, y) = \beta \log \frac{\pi_\theta(y | x)}{\pi_{\text{ref}}(y | x)}\)这个就是隐式奖励. DPO更新不仅仅是简单的好加坏减, 而是根据模型对隐式奖励的评分高低来自动缩放梯度大小, 这种加权系数很重要, 实验发现, 如果去掉这个加权项, 模型会发生退化, \(\beta\)是奖励的缩放因子.
操作细节¶
对于提示词\(x\), 让参考模型生成两个回答\(y_1, y_2\), 由人类给出好坏\((y_w, y_l)\), 组成数据集\(D\), 再给定参考模型\(\pi_{ref}\), 数据集\(D\)和超参数\(\beta\)的情况下, 最小化\(L_{DPO}\)来更新\(\pi_{\theta}\). 实际上, 人们更倾向使用现成的公开偏好数据集, 而不是自己去采样和找人打标. 通常理想状态下, \(\pi_{ref}\)是产生数据的那个SFT模型, 如果没有SFT模型, 可以通过再偏好数据的赢家部分\((x, y_w)\)上做一次最大似然估计(其实就是简单的监督微调), 来初始化一个\(\pi_{ref}\) . 为什么要这么干呢? 如果参考模型是一个小学生, 而偏好数据来自一个大学生, 那么大学生写的那些高深的辞藻, 小学生可能根本写不出来, 再DPO公式里面有\(\frac{\pi_\theta}{\pi_{\text{ref}}}\), 如果\(\pi_{ref}\)生成某句话的概率接近0, 那么这个分母会导致数学计算极其不稳定, 因为它被被迫去评价一段它完全无法理解的高难度文字. 所以可以先在\(y_w\)上训练一下, 让它学会这些说话风格.