写这篇文章的起因是,上周读了https://zhuanlan.zhihu.com/p/1082394115这篇知乎文章,文中探讨了关于DPO的局限性。在我之前写DPO的推导过程时(https://zhuanlan.zhihu.com/p/721073733),我就一直有一个主观感觉,rlhf算法的优化效果和客观世界的真值比起来,误差主要分布在【奖励函数误差】【prompt x】和【response y】上,其中我认为后两者是至关重要的(和数据集密切相关),他们也间接决定了【奖励函数的误差】。我认为诸如dpo这类off-policy的方法,和ppo这类on-policy的方法比较起来,误差也就在后两者上,相关的分析我回复在佬的评论区里。
但是总觉得对自己目前的理解,还是不够尽兴,我想用一个更有逻辑的视角来看待这个问题。即我想先不考虑任何具体的优化算法,仅从rlhf最原始的优化目标出发,来分析这个目标下暗藏的前提,而探索这些前提的目的是:
这些前提决定了rlhf的上限,也就是它和客观世界真值间的误差。 这些前提可以解释rlhf各种实现算法(例如dpo,ppo等)间存在的差异性。
这种前提也为我提供了一个统一的视角,它能帮助我分析各种rlhf变种算法是怎么在理论设计或实操中违背这种前提,又是怎么尽力去修复和这个前提间的差距的。
所以在上个周末,我开始搜罗一些大家常见的rlhf训练问题,同时大量阅读和rlhf理论分析的相关文章,我选择的这些文章的主要特点就是,有充分的数学推理和实验结论。虽然各个作者的分析角度都不一样,但神奇的是,我发现这些不一样的视角都可以渐渐收敛到我想找的那个【前提】上来,于是进行了一次自我训练,来optimize target。
但同时也由于我这个模型的参数量有限,收敛的结果不一定特别好,也许还有一些幻觉(主观解读),所以也请大家选择性阅读~在这篇文章里,不会涉及太复杂的数学推导(需要涉及的部分我都尽量用简明的语言+举例的方式展示出来),可以放心食用。文章里也贴出了我参考的资料,如果大家对哪篇感兴趣,我看看后面能不能再单独出个详解(这些文章确实不好读,因为结论都在数学推导中,很少显式给出)。
(最后,由于我现在特别想赶紧赶回家吃俄式大甜筒冰淇淋😁,所以文中有一点部分没有详细展开,后面我会在知乎里补充,也会加一些图辅助理解)。
一、RLHF优化目标的隐藏前提
rlhf最初的公式:
:一个固定的奖励函数。我们先假设这是一个最优的奖励函数(),也即它具有完美的泛化能力和评估性能,可以准确衡量任意(x, y)的得分。 KL散度:用于衡量和之间的相似度,KL散度越大,相似度越小。
1.1 穷举法
这个公式具体在做什么:
现在,先假设我们不使用任何特定的算法或者神经网络,在这个前提下我们来讨论如何找到最优的,我们记这个最优的为。
我们先理解某个的含义:它表示给定一个prompt x,它的输出y所服从的一种分布。
现在对于某个prompt x,我们在头脑里想象出若干条分布曲线,每条曲线表示一种可能的,所有曲线代表组成的这个集合就代表给定某个prompt x的前提下,其输出y的分布的所有可能。而我们现在要做的,就是从这个集合中,找到最符合人类偏好的真值曲线,记其为。
既然有了这个集合,那我们就可以用穷举法找到:把集合中的每一种分布都带入到上面的总优化目标中进行计算。在总优化目标中,都是固定的,只有在变。
现在,我们再回过头,看总优化目标下面的限定条件,这个条件意味着,当你在检验某条分布曲线时,你用到的y就来自这条分布曲线,同样,当你检验到那条最优的分布曲线时,你用的y就来自这条分布曲线。也就是说,你正在检验哪个分布,你的y就产自哪个分布。
1.2 显式解
现在,再让我们向现实靠近一点:在实际操作中,我们根本不可能穷举出固定x下所有的具体表达式,如果还是不考虑任何神经网络算法,我们应该怎么办呢?那就尝试直接通过数学推导,求出的显示解吧。在文章开头我写的dpo推导那篇链接中,我们给出了求显示解的过程,这里不再赘述,直接给出结果:
其中,Z(x)是一个配分函数(partition function),它被定义为,之所以这样定义,是为了做归一化,即我们要让可以成为一种概率分布,其值限制在[0, 1]范围内。
当我们仔细端详这个显式解等式右侧时候,我们发现和(假设这是完美的奖励函数)都是固定的,这意味着:
虽然我们不知道的具体表达式,但是我们知道另外一个分布的具体表达式。那么我只需要把ref模型取出来,喂它吃一个x,然后穷举(或抽取足够多的y),我就能估算出的分布了!
现在让我们再贴近现实一点,上述这个方法可能存在2个问题:
穷举的成本是昂贵的。 穷举是低效的。
第1个问题显而易见,我们来仔细看第2个问题:什么叫【低效】?
首先,我们是从已知分布里采样,去估计最优分布的具体形式。通俗一点来说,这里的y来自
那么,如果我们从全知的上帝视角来看,如果最优分布在吃这条x的情况下,几乎不可能产出y,也就是,那这样的采样点对我们估计是没有意义的。我们来具象化地解释这点,如果你想估计出真值曲线的分布,那么你至少需要保证有足够多的观测点恰好落在分布曲线内,你才能做拟合。如果你的采样的观测点都落在曲线外,那就没有意义了。我们再举一个例子,假设一个袋子里有若干黑球和白球,现在需要你估计球的颜色分布。正常来说,我们可以通过放回取样法去估计(蒙特卡洛模拟)。但是如果你每次伸进袋子里,啥也不取,只是在把手抽出来的时候,记录“取到红球的次数为0”,那这个采样就对我们估计分布没有意义了。
1.3 拒绝采样
到这一步为止,虽然我们找到了显式解。但是我们却面临着穷举昂贵和采样效率低效的问题,那么,有什么办法可以提升采样效率呢?
我们前面谈到,之所以采样低效是因为我们从中采样的结果可能很难命中的分布空间(简直就是一种无方向的采样)。那么我们自然而然想到,如果可以把采样的范围做一些限制,是不是就能一定程度上提升采样效率?如下图所示,如果我们可以通过调整的分布曲线,让它【刚好】把的分布曲线包裹起来,我们在这个范围做采样,就能提升采样的命中率了。读到这里有些朋友可能已经回想起来了,这种采样方法,就是我们常说的拒绝采样(rejection sampling),如下图所示:
(TODO:关于拒绝采样的展开细节,我留在后面更新在我的知乎上,因为我现在想赶紧回家吃俄式大甜筒冰淇淋,所以只好先鸽在这里)。
1.4 隐藏前提
到目前为止,我们完全不谈诸如DPO,PPO,各种O的优化方法,我们只从最原始的总优化目标出发,通过一些分析,【来明确这个优化目标里暗藏了一些什么样的前提】,我们在这里做个小结。
(1)前提1:数据的采集与分布
在这个前提下,我们假设奖励函数r是完美的。 我们应该做到,正在检验哪个,我们就从这个中进行采样(暗藏着on-policy的假设)。 我们至少应该保证,有充足的观测数据对(x, y)是落在真值分布的分布曲线内的。这一点和上述第2点存在某些交集之处:也就是说如果我们做不到第2点,那么至少保证这一点可以实现。
(2)前提2:奖励函数的泛化性
但是在实际训练时,奖励函数很难达到完美,主要原因如下:
奖励函数可能是有偏的。我们至少希望这个奖励函数能够很好衡量服从的观测数据。但实际上它的训练数据可能存在bias(比如极端一点,它用的都是低概率处的观测点来训练的),再加上其泛化能力的不足(这个问题比较玄学一些,目前我还给不出很好的解释),最终造成了它的偏差性。
BT偏好模型本身的缺陷。在RLHF这一步,现在一般默认使用BT模型做成对偏好数据的建模,作为一个先验性质的“标准答案”,它不一定能很好反映人类偏好的复杂程度。
正是因为奖励函数的不完美,原始优化目标中的KL散度和值就非常重要:
由于我们不能完全信任奖励函数,所以我们通过KL项控制的迭代步伐,用控制对奖励函数的信任程度。 如果设置不当,就可能产生reward hacking的问题:即最终策略模型拟合了有偏的奖励模型,产生了高奖励但“不符合逻辑”的生成结果。 而KL散度这一项也说明了原始目标设计中隐藏的一个前提:我们有一个初始模型(ref),也有某条prompt x,我们其实是在初始模型最可能产生的那些回复y里,增加人类所喜欢的那些yw的概率,降低人类所不喜欢的yl的概率。所以理论上不是任意形式的,它在缩放下被控制住。对于那些在初始模型低概率处的y,即使我们因为它的r比较高想给他一个较高的时,它最终的reward也会被KL项所抵消。
以上对奖励模型的这些讨论,以及reward hacking的问题,可以在openAI的这篇关于reward model scaling law的文章中找到更多细节(https://arxiv.org/pdf/2210.10760)
二、DPO存在的问题
在分析完这些前提的基础上,现在我们可以来一些我们所关心的,具体的优化算法了,我们先来看DPO。
DPO从显式解这一步出发,先推出最优下奖励函数的表达
根据先验知识,我们认为BT模型能较好衡量人类的偏好,我们将带入这个先验的模型里进行建模。进而构造出了DPO loss,见下图公式(7)。
整体过程如下(具体推导可以看我之前写dpo的文章):
我们拿上文整理出的“原始优化目标的2个前提”,来仔细端详一下dpo loss。
2.1 数据的采集与分布
(1)“意料之外”的数据分布偏移
不难发现,dpo的优化过程并没有尝试去遍历,取而代之的是,它使用的是用观测数据去拟合真值的做法。所以这里,我们自然而然提出一个问题:
dpo所使用的数据对有多少是真得采样自真值分布?
由于dpo的训练数据不采样自我们待训练的策略模型,而是来自别的分布(人类标注,sft模型,其余开源模型的合成数据等,属于off-policy类型),那么我们无法保证这批训练数据能有效覆盖到我们要拟合的真值分布,比如,你的数据都是从曲线外的地方采集到的,那拟合出自然很难。
我把这些不是我们刻意为之的数据采样称为“意料之外的数据偏移”。解决它的办法之一就是通过前文所说的【拒绝采样】,其中,RSO就是基于这个思想开发的DPO的变种,详细的细节可以参见https://arxiv.org/pdf/2309.06657这篇文章,这里我们只给出RSO的大致改进思路:
首先,假设有一批多样性的离线偏好数据集D,它来自各个源,可以认为覆盖比较全面。 借助这些数据集,我们先训练一个奖励模型r,可以认为它的性能比较强大。 利用这个奖励模型,我们从显式解出发,从已知分布中通过拒绝采样,从D中找到最可能落在分布内的数据点。 使用奖励模型,对这些数据点重新进行打分,重新组装偏好对 再用这批新的数据做dpo训练。 做拒绝采样的过程,其实就是在把off-policy转变为on-policy的过程,整体示例如下:
(2)“意料之内”的数据分布偏移
但此时,你肯定有这样的疑惑:在实际训练中,大部分情况下,我肯定是先设想我要的长什么样子,然后根据这个方向去搜索我要的训练数据,如果是这样,那就不存在训练数据在之外的问题了,可是我还是经常发生模型崩溃,或者偏好根本没有注入模型的情况,这是怎么回事呢?
假设现在我们又一个sft模型,我们想训练它对齐人类的安全偏好,比如x可能是用户提的敏感问题,yw = 一句简短的拒绝回答,yl = 一个详实的泄露机密的方案:
我们在之前对原始优化目标的分析中,我们还得出过一个前提:原始优化目标里的KL散度一项保证了其实是在最可能产生的那些y里,增加人类喜欢的yw的生成概率,降低人类不喜欢的yl的概率。也就是说这个其实是受的约束的,并不是我们任意想要的任何形式。
那么假设你的sft模型在训练时很少见过拒绝的数据,或者是很少给出简短的回答。那么理论上它能得到的也大致如此。
那么你构造的这批数据,其实在无意间变成了低概率区域有偏数据,所以最终,你没能把知识注入。
所以此时,比起在继续rlhf,更应该回到sft阶段上做继续训练,对sft模型灌入类似于rlhf阶段的分布数据,先改变的分布。
2.2 奖励函数/loss的限制:为何chosen与reject的reward会同时下降
虽然说DPO没有显式训练一个奖励模型,但其实我们是可以从dpo loss(上图公式(7))中找到yw和yl的奖励值的,也就是内的两项。
我们来讨论在dpo训练中一个常见的现象:chosen和reject的reward/prob都同时发生下降。
我们回想前文对rlhf整体优化目标的分析,其中有一条是由于BT模型存在局限性,奖励函数可能并不完美。这个局限性是指:BT模型只能期望发生chosen打败reject的概率要尽量大,但是它不能保证chosen本身尽量大。有了这个前提,我们继续讨论这里的问题。
我们回想一下rlhf阶段偏好对是如何构建的:一种常用的方法是,在一个/多个sft模型上,对prompt收集多条响应结果,然后让人类/AI labeler进行偏好排序。尽管我们可以通过调整温度系数等参数对y进行采样,但是大多数的chosen和reject响应都采样自概率的中部处。也就是这样采样出来的和,其产出的概率基本一致,序列本身的内容可能也很相近,这里的相近是指:response的表达方式、语义或者个别关键词等比较相似。对人类标注者来说,也是需要细致区分的样本。但是,我们依然不排除训练数据中可能存在序列内容区分显著的(x, yw, yl)对。
有了这样的认知,我们先不做任何严谨的理论分析,我们可以大致想象一下,什么情况可能造成chosen和reject的reward/prob同时下降:
当chosen和reject都采样自的中部处时,它们在序列内容上可能也比较相近。dpo要做的事情是,尽量拉开chosen和reject的距离。所以在训练一开始,它可能接收到标注信号,能拉开一段距离。这时我们应该观察到chosen的reward是上升的。但是在训练后期,当模型已经知道reject表示不好的回复时,它可能也会降低对内容相似的chosen的概率。但这还不够,因为模型对chosen本身也是会向上提的。所以什么时候chosen也会开始出现下降呢:必然存在某个【力】,它拉动chosen上升的力量小于把chosen往下拉的力量,所以导致了chosen下降。在模型训练中,什么东西和【力】相关?自然是【梯度】。
当chosen和reject分别采样自分布较远的两个点时,也就是他们在序列内容上的区分已经比较显著时,我们依然会发现chosen在训练阶段可能出现下降的情况。一种可能的原因是:模型在训练过程中,也许找到了一条捷径,例如它可能发现,努力学习什么是不好的,比努力学习什么是好的对优化整个loss更有效。因此它只学到自己不能产出什么,却不知道人们喜欢什么,它对所有的response都保持比较谨慎的态度,因此就可能造成chosen的reward/prob下降。
在这样感性的认知下,我们来看一些理论上的研究工作:
DPO的训练中,
loss对reject的梯度/loss对chosen的梯度 = chosen的概率/reject的概率
。这意味着,在对dpo loss landscape做梯度下降的过程中,随着chosen和reject概率间的拉大,把reject向下拉的力 > 把chosen向上拉的力。此时如果两者的序列上存在一定相似性,那么最终会把chosen向下拉。这里的结论来自这篇文章https://arxiv.org/pdf/2404.04626的Corollary 1。文章比较难读,我尽量用通俗的语言描述这里的数学推导相证明的内容。DPO的训练中,模型侧重于对reject部分降低loss时,可以更快收敛。这个结论其实和上面的有相似性,这个分析在https://arxiv.org/pdf/2404.04626和Notion – The all-in-one workspace for your notes, tasks, wikis, and databases.这里都有提及(后者需要翻墙)。针对这一点,一个经过实验论证的有效的解决办法是,在DPO训练中对reject的reward/prob做clip,使其不至于降得太低,这样就能避免模型走了降低loss的捷径,而没有学到什么是好的。这个实验结果也在后面的这篇需要翻墙的链接中。
一旦我们对这些实验现象有了初步的感知之后,我们就不难理解一些在loss上对DPO进行处理的变种,比如有些变种选择在loss中增加baseline,或者yw对yl的好坏程度衡量之类的正则项,来使得整个训练过程更加稳定。
2.3 小结
我们简单回顾下这部分的内容。
从理论上看,DPO在寻找最优策略分布的过程中,使用的是通过尽可能多的来自的观测数据进行分布拟合的方法。它用这个方法来代替1.1中所说的穷举法(核心是验证哪个分布,就从哪个分布采样)。后者是一种on-policy的策略,而对于前者,如果能做得非常完美,其实它也是一种on-policy的策略。
从实践上看,由于【意料之外】或者【意料之内】的一些原因,我们总是不能很好找到能在分布内的数据,所以实践上我们把dpo做成了一种off-policy的方法,从这时开始,它已经和我们最原始的rlhf目标产生了误差。
所以接着,我们又提出了一些可行的改进方法,来减小off-policy训练策略上的误差。
再从实践上看,基于BT偏好建模(这是一个先验知识,是人们认为它可以用来做偏好建模,所以才选了它)构造出来的奖励/loss形式,在偏好的训练上天然存在一些缺陷,造成模型学不好chosen和reject的信息,特别表现在模型倾向于去学习什么是不好的,而不明白什么才是好的。
所以接着,我们又提出了一些可行的改进方法,来探讨如何优化dpo loss或者训练过程。
三、PPO存在的问题
和dpo不一样,我们在使用ppo优化rlhf的总目标时,我们天然满足“验证哪个分布,就从哪个分布中采样y”的大前提。只是ppo不是完全的on-policy方法(因为它在ppo_steps中重复利用了经验数据),但anyway,它比原生的DPO更加接近原始rlhf优化目标。
PPO的整个训练过程可以概括为:对于所有可能的分布集合(理解成这个分布集合里有若干分布曲线),ppo从最原始的代表的曲线出发,每次通过on-policy的方式进行自我验证,然后根据这个验证结果去找到下一个最可能贴近的分布曲线,一步步逼近真值。可以理解成是在朴素穷举法上的进一步提效。
所以,总结起来:
实践上为off-policy的dpo,更注重利用(expolit),这个利用是指对标注的偏好数据对的内容+偏好标签的利用。在不经过任何改进的情况下,原生dpo非常注重训练数据集的分布(又分成意料之外和意料之外的分布,参见2.1节)。
实践上为on-policy的ppo,更注重探索(explore)。它的这个探索的性质来自奖励模型和策略模型的分开,在这种情况下,它可以按照自身的分布去探索某个x下可能的y,而不是限制在偏好数据对的标签之下。它天然比原生DPO更符合rlhf优化目标的设计。
不过此时,你应该也发现一个重要的问题了:即使ppo比原生dpo更贴近rlhf优化目标,即使它采用了自生产的数据来减少数据bias的问题,但他依然也依赖奖励函数的性能,因为奖励函数给了ppo探索的反馈。一个最直接的问题就是:策略是on-policy的,但是奖励函数却是固定的,我们如何能保证这个固定的奖励函数的性能?换句话说,如果奖励函数是用在分布之外的数据训练的,那么它最终还是会给策略模型错误的反馈信号。
四、online + on-policy
在上面的分析中,你可能会发现:
对原生DPO的改进思路之一是将其转为类on-policy(对应rlhf优化目标中的大前提1)
对原生PPO的重要担忧之一是奖励模型的不完备性(对应rlhf优化目标的大前提2,同时由于奖励模型训练和数据分布也有关,所以也对应1)
所以,如果有一种方法,它不仅能on-policy的获取训练数据,它还可以用这些新鲜的on-policy数据,通过人工/ai labeler进行标注,然后将其视为训练数据的一部分,继续进行训练,是不是就可以缩小【实际操作】和【rlhf原始优化】目标之间的gap了?我们做如下定义:
当我们使用策略模型自己产生的数据去训练策略模型自己时,我们称on-policy。 当我们在训练过程中,尝试让奖励模型也去逼近真值奖励模型时,我们称online。
这就是https://arxiv.org/pdf/2312.11456这篇论文所谈论的总体优化方法(也是比较难读,基本是满满的数学分析)。在这个定义下,我们目前大部分的框架,其实用的都是offline + on-policy。
而沿着这个框架的一个难点就是,我们的标注资源(不管是人工还是自动化)是有限的,如果我们想做online,那么我们需要对要送去重新做标注的数据做一定的筛选,也就是,当我们新增哪些标注数据时,可以保证让我们的策略朝着更好的方向发展?
这篇论文通过数学推论,得出的一个总论点就是:我们应该选择那些与历史数据相比,具有最大不确定性的数据进行再评估。这样说来可能有点抽象,我们举一些具体的例子:
当我们当前的奖励模型对一个数据点打分特别高,或者特别低时,那么它就可能是一个会拉偏分布的数据点,我们需要对它进行再度审视。 如果对于一个prompt x,它在本轮迭代中的得到的输出分布和上一轮迭代中得到的输出分布相差较多时,那么它就值得重新被审视。相关的细节如果后面有时间,再慢慢展开,这篇文章还是很值得一读的,只是所有的结论都隐藏在它的数学推导中,比较难提取出,这里我就只写一些比较关键的部分了。
备注:进群,进入大模型技术群
id:baobaogpt,记得备注呦