作者:ybq
链接:https://zhuanlan.zhihu.com/p/717586003
其他补充作者:朱小霖,包包
补充链接:https://zhuanlan.zhihu.com/p/671780768
最近又认真读了一遍大佬的文章《DPO 是如何简化 RLHF 的》作者:朱小霖
原文:
最近通过 Mistral AI 7Bx8 模型的发布,我才后知后觉地了解到了 DPO(Direct Preference Optimization)这个算法,发现他用了一种很巧妙的思路,将 RLHF 的 2 阶段多个模型的训练简化为了 1 阶段的 SFT 训练。在这里简单总结一下。
那么介绍 DPO 做了哪些简化之前,首先要提一下我们一般认为的 RLHF 是咋训练的。RLHF 一般会分 2 步:
第一步是训练 reward model。训练数据是同一个 prompt 的 2 个回答,让人或 GPT4 标注哪个回答更好,reward model 会去优化如下的 loss:
其中 就是 reward model 用来给回答打分。 是训练数据集, 是 prompt, 和 分别是好的回答和不好的回答。也就是说,要尽可能让好的回答的得分比不好的回答高,拉大他们之间的差别。第二步是用 RL 算法来提升模型的得分。使用的 loss 是:
其中 是我们在训练的 LLM, 是训练的初始值。这个 loss 意思是希望 LLM 输出的回答的评分能尽可能高,同时 不要偏离 太多,保证它还能正常做回答,不要训成一个评分很高但是回答乱码的东西。
DPO 的作者们意识到,后面的这个式子是有显式解的。因为:
如果我们归一化一下分母,即取 ,也就可以构造出一个新的概率分布:
那么上式变成了:
由于 KL 散度在 2 个分布相等时取最小值,我们得到了这样的结论:RLHF 训练希望得到的最优的概率分布就是 。
另一个角度来说,由 的公式,我们相当于是得到了 和 的关系,那么是否我们可以把训练 转化成直接去训练 呢?
简单转换一下 的定义式,可以得到:
带入最上面优化 的 loss,也就有了:
或者说,我们可以直接用这个 loss 去求 :
这就是 DPO 的 loss。DPO 通过以上的公式转换把 RLHF 无损地转化为了 SFT,在训练的时候不再需要同时跑 4 个模型(reward model, ref model, critic, actor),而是只用跑 actor 和 ref 2 个模型,甚至由于不再在线采数据,ref model 的输出可以预先存下来,训练的时候重复使用。
不由感叹,数学不愧是 AI 技术的第一生产力,但凡我当初对这个证明过程多深入思考一会儿,也不至于踩那么多坑。
理论证明
我先把大佬的证明过程复述一遍,来一个保姆级翻译。首先请牢记下面这 3 个 loss 函数, 是 reward_model, 是我们要优化的模型, 是 dpo 和 ppo 都用到的 reference_model。
reward_model loss
ppo loss
dpo loss
KL 散度
针对 ppo 的 loss 函数,我们做以下变换:
代入 KL 散度得( 提取放到了左下角):
乘上 ,把 max 变成 min 得: 等价变换得: 根据 得:
这里我们可以构造出一个新的概率分布:
进行分母归一化,为的是使保证分布的概率和等于 1 ,分母
继续对 ppo 的 loss 函数等价变换得: 化简得: 由于 和 完全没有关系,可以省略,得: 代入 KL 散度得(左下角的 没有了):
由于 KL 散度的非负性质, 的最优解就是 ,PPO 的最优概率分布就是 。
也就是说,在已知 Reward_model 的参数 的情况下,我们可以求得 PPO 的最优解 ;那如果我们已知 PPO 的最优解 ,是不是也可以反向求解 呢?
转换一下 的定义式可以得到:
等价变换得:
把 的等价表达代入到 Reward_model 的 loss 函数 :
至此,艺术已成!致敬大佬朱小霖。
dpo 的局限性
经过上面的证明,一切都清晰了,dpo 对标的从来都是不是 ppo,而是 reward_model。二者不仅训练数据一样,loss 函数本质上也一致。那么即使不去做实验验证, dpo 的局限性也已经跃然纸上了。
dpo 的大前提未被验证
dpo 从头到尾都在以 reward_model 的方式让模型学习 evaluate 能力,但是却并没有证明一个重要假设:“模型的 evaluate 能力和 generate 能力到底是不是相互促进的?” dpo 后的模型具有了更强的 evaluate 能力,但我们的目标是提升模型的 generate 能力啊。如果这个基本假设不成立,那 dpo 的学习过程就没有什么价值。
不要认为这个假设是显而易见的,美食家并不一定做得一手好饭。这个大前提的成立与否,还关系到 SPIN、self-reward 等左脚踩右脚的训练方式是否有存在的意义。
也正是因为 dpo 是在让模型具有 reward_model 的能力,所以它并不在乎模型能不能说出一个好的句子,只在乎 loss margin 是否在变大。大家训练 dpo 的时候,基本都遇到过 good_sentence 和 bad_sentence 的 loss 都上升的尴尬现象,往往需要我们加系数和调参数才能解决。
reward_model 的训练方式根本不在乎模型的 generate 能力,因此稳定训练的 dpo 需要魔改 loss 函数。
dpo 缺乏在线采样数据
我们再从另外一个角度来思考 dpo 的不足,已知:
dpo 和 reward_model 完全等价; rlhf = reward_model + ppo。
可得:ppo 所做的一切操作,便是 dpo 效果不如 rlhf 的原因。
那我们思考一下,ppo 到底做了什么?ppo 没有使用任何训练数据,它唯一做的事情便是 generate,通过对模型 generate 的文本进行打分,把 reward_model 的 evaluate 能力转换成 generate 能力喂给模型。因此,缺乏的这个 generate 的过程就是 dpo 效果不行的原因。那这个 generate 的过程又带来了什么呢?online 和 explore。
老生常谈的一个知识点了:rlhf 是 online 学习方式,dpo 是 offline 学习方式。rlhf 是修复模型当前已有的知识,属于因材施教,并且由于 do_sample 的随机性,它可以进行 explore;但 dpo 则是强制模型学习训练者认为正确的知识(偏好数据对中的 good sentence),沿着一条被设定的正确的路线使劲走,这种 offline 的学习方式也导致它不具备 explore 的空间。
我们在 dpo 训练中常用的一个技巧:让模型先对“偏好数据对的 good sentence”做一次 sft,再进行 dpo 训练。不就是强行让 dpo 变成 online 的学习方式吗?毕竟训过的知识大概率也是可以 generate 出来的。
我们在 dpo 数据中常用的一个技巧:把模型自己生成的 path@N 结果,拿来构造成偏好 pair 对,不就是同时在模拟 ppo 的 online 和 sample 能力吗?
因为欠缺,所以需要弥补。所有的 dpo 数据处理技巧,大多都能从 ppo 身上找到一些痕迹。
包包评价:dpo和ppo的争论基本上在业界有了共识,dpo相对简单,但之于对齐的作用局限于打补丁,ppo可以达到较高的泛化能力(前文大佬理论分析),但是其实施和操作比较困难,在今年年中面试候选人的时候,有人说目前国内仅有两家真正跑通了ppo。大家都在饱受ppo的reward hacking,训练step过少就崩而无法充分训练,基建infra在开展大参数大规模rlhf不完善的困扰。
甚至有个说法,国内ppo搞得太烂,是与openai拉开差距的关键因素之一。
dpo也不是一无是处,现在在垂直场景的应用中,作为一个简单的修复badcase,打补丁,非常好用,指哪打哪,特别是在能解除明显规律的时候。也不怪dpo一出来就成了香饽饽,但对AGI的真正理解上,还是任重而道远的,比如这次o1背后的rl,目前讨论还是少之又少。
备注:进群,进入大模型技术群
id:baobaogpt,记得备注呦