作者:王小惟 Weixun
原文:https://zhuanlan.zhihu.com/p/1686790674
片面的脉络梳理,主要是希望能帮助大家建立一个更全局的视角,因为篇幅有限,仅包含了支撑脉络的工作,同时也没有含括最新的工作,如有遗漏,望各位同仁包涵。
总体的思维脑图地址(可能需要翻墙):
raw.githubusercontent.com [1]
提纲部分:
本文从4个部分来介绍,首先是偏好优化算法,主要分为2两大类:
• 第一类,先建模偏好奖赏模型,再采用RL优化。主要包含PPO算法本身的粗糙介绍,然后进一步考虑到在LLM训练设定中,使用PPO带来复杂优化pipeline对调度与显存的开销相对较大。所以,我对针对LLM优化提出的几种算法改动,主要从降低成本的角度来进行理解与建立联系。
• 接着,我们转向第二类,直接从数据优化偏好,这部分我将其视为offline RL联合Reward Model优化的视角。从DPO出发,介绍其在不同范式下的变体(比如token,multi-turn),然后会介绍其针对训练中出现的“缺陷”而逐步修复的改动,而后是进一步各种修改loss百花其放的XPO改动。最后会简单讨论一下,当前大家已经发现的DPO训练过程中存在的问题,及当前的fix改进,使其越来越像RL了。
第二个部分,主要介绍奖赏模型训练。
• 这部分会先讨论下DPO和RM间的优劣,然后介绍RM从不同角度优化提升准确率的方式。然后会介绍一下,除了pair-wise形式外,还有什么类型的reward model最后,会简单讨论下,当前人类偏好数据/LLM as judge的潜在bias,从而进一步在RM上所体现的bias。
第三个部分,简要介绍了在推理时进行扩展的一些已有工作的发现。我将其视为RL核心哲学,探索与利用部分的探索
最后一个部分,简单介绍过参与的两个工作,OpenRLHF框架与今年的一篇复现TL;DR领域RLHF的COLM文章。
希望通过这四个部分的介绍,为读者提供一个关于RLHF+LLM优化的“稍微”全面视角。
下图是第一部分中RL部分的思维脑图
首先,介绍语言模型中使用RLHF优化的基本概念与算法。图中左下角是对应的符号定义,其他部分和大部分论文一致。这里主要的不同是,带下标t的x,是包含query加上已经输出的token,即是从每个token的角度来看一次生成。
在RLHF中,收集人类偏好,训练奖赏模型,然后采用RL优化的pipeline,因为在chatgpt训练中使用而广为认知。chatgpt所用的RLHF流程,首先BT模型的假设来训练Reward model。BT模型假设可以对每个query- response对(x,y)单独打分,即可以采用point-wise形式的reward来表述一个(x,y)的好坏。然后我们就可以基于该假设,训练出为每个query-response对(x,y)打分的reward model了。
在获得reward model后,为了避免RL算法过度优化reward model所学习的偏好,从而使LLM出现“胡言乱语”的表现,通常会在优化目标中加入对原有策略的KL惩罚,这样我们就得到了最初的优化目标(Optimization Gaol)了。
对于response层级的reward,其定义在图中Optimization Goal下面。最终,我们会将其转成token-level的累积reward。这里需要注意的是,reward model只在response最后打分,中间部分的token仅有KL约束项。有了reward,我们就可以使用RL进行优化了。
PPO源起的优化目标,是希望能够在每次更新中稳定地提升策略性能,通过约束KL距离来达到真实域的效果(即TRPO的优化目标,但TRPO计算太复杂了)。然后通过近似,将KL约束来入优化目标中,进一步,ppo通过clip偏移采样policy过远的数据,保证KL约束,即丢弃掉偏离采样policy过远的数据的梯度。这PPO优化目标中也有KL,但需要注意PPO优化目标中的KL约束,是前后更新policy上的KL。而reward中包含的KL惩罚,是与最开始优化的base LLM的偏移。(即两者参照policy不同)
使用PPO优化pipeline,有几个明显挑战,比如需要在学习过程中启动4个模型:actor model,reference model,reward model,critic model。如果为了提升训练效率,还可额外部署infer model。在游戏、机器人等领域,这几个模型通常size都比较小,为了效果多部署几个模型可以接受。但在LLM领域中,为了效果导致模型size剧增,同时也需要更为复杂的调度方式,总体来说,PPO优化pipeline对资源使用和调度带来了不小挑战。
那么除了PPO外,还有什么RL算法可以使用?回顾一下RL的脉络,很自然,我们会想到采用策略梯度这一家族的算法来优化语言模型。首先,需要介绍策略梯度定理,也就是当你优化左上方的优化目标时(也就是累积奖赏,gamma是折扣值,LLM+RLHF优化设定中,通常设为1),其优化的梯度可以写成右边的形式。这里的大phi,通常用来表示response token y的好坏。
大phi有多种选择,比如常见的累积reward,减掉基线的累积reward,还有类似state value,Q value,还有GAE等选择。后面的几个选择,本质上会和出现和PPO一样的情况,需要维护额外一个critic/value。而采用前几种只使用reward的Phi,则可以少去一个模型,所以,我们将目光投向减掉基线的reward作为大Phi。
使用减掉基线的累积reward作为大Phi,其目的可以降低学习过程中的方差,从而稳定学习。基线的潜在候选有多种,比如对一个query采样N条response,使用其均值作为基线,是最朴素的想法。在针对语言模型的RL变体中,RLOO,将自身排除在均值之外。Remax采用当前贪婪策略的response的reward作为基线。
上述三种改动,可以均视为采用baseline的policy gradient的方法。从降低成本的角度,这样的改动,相比PPO能够少部署一个Critic模型。同样的思路,也可以启发其他策略优化算法,GRPO则在PPO loss的基础上,不再使用GAE,而是对一个query的N条response的reward来做一个normalization。Apple提出的MDLOO,则是使用RLOO的优势计算方式,然后用了镜像下降的RL loss来进行优化。(这个loss是按照Apple tech report描述写的,不一定对)
总体来说,这些改动的好处,就是在训练过程减少一个模型,从而降低了对整体显存的需求。
除了从算法角度来减少模型使用外,另外一种降低显存使用的做法就是使用lora来减少优化参数量。不过实验数据表明,lora的使用对reward model和critic的学习影响不大,但对policy的学习效果存在一定负面效果。
所以,当你GPU不多的时候,就需权衡选择更大的Batch size还是全量优化了。
上述几种RL变体虽然降低了显存的需求,但RL训练过程中仍需要不断地生成新的response,而生成部分在整体耗时中占据了不少比例,那么很自然会就想“能不能不生成”。如果回顾RL算法的分类,就会想到借助Offline RL的范式,避免生成部分的时间开销。
具体而言,对于带KL约束的优化目标,我们有对应的闭式解,对该解进行变换,我们就可以得到策略与reward之间的等式,然后就可以采用朴实的Offline RL的思想来进行优化了,也就是右侧部分,获得了对应的policy和value的梯度。
虽然offline RL视角下,可以避免生成新的response,但仍需要一个具体的reward。在RLHF中,是通过收集人类偏好训练reward model来给出reward信号的,那么很自然地想,能不能将策略优化的过程和reward model优化的过程结合起来呢?
这就是下一部分,直接采用偏好数据来优化策略,我个人更倾向将其视为offline RL+Reward Model联合优化的角度。
下图是第一部分中直接优化偏好数据部分的思维脑图。
衔接offline RL的视角,对于reward与policy之间的闭式解,可以将其套入reward model的优化loss中,我们就获得了直接策略优化DPO Loss。该闭式解推导过程是从bandit视角,将response是为一个整体。
那么同样,可以token-level的角度来进行推导,其同样有对应的闭式解,套入reward model的优化loss中,我们可以获得token-level的DPO loss。
所以,相比先有reward信号,再优化策略。我们可以很自然将DPO视为offline RL联合reward model训练的一种方式。
既然我们可以从token level来理解DPO loss,在此基础上,自然就会希望从更细粒度的角度,提升整体优化过程。
第一种角度,就是在token level中为不同的token带上不同的权重,对相对重要的token给予相应的权重调整。
另外一种角度介于token和response level之间,在相同的上文的基础上,构建step-level的对比,从而更细粒度地给予LLM相应的反馈。
更细粒度的反馈,自然会带来更好的优化效果。
除了反馈粒度的不同。另外一种扩展就是将其与agent形式结合,从多轮交互的角度来改进DPO loss。
Agent Q的工作直接将DPO loss套入了多轮交互的设定中,但这是对的吗?
另外一个工作,则从理论上推导出多轮交互的累计收益,是由多个部分组成(右下角)。其中,考虑外界环境转移的c项,只有当外部环境转移为确定性时,才为0,从而在套入reward model优化loss后,通过正反例消去其他项,获得多轮DPO loss。
这也意味着,考虑外部环境转移设定下的多轮DPO loss,当转移具有随机性时,其优化效果无法预期。(残留了正反例的term C)
除了上述改进外,不少研究者观察到,DPO在学习过程中chosen的log p在不断下降,特别是正反例仅有少数不同的设定中。训练现象与朴素的DPO生效的直觉:提升正例的log p不同。
有几个工作理论分析了DPO loss优化时,负例的梯度大于正例的梯度,这可能是导致正例log p下降的一种潜在可能。所以,自然地,如何缓解正例的log p的下降成为一种DPO改进角度。
有两种常见的做法,一种是对正例增加了类似SFT损失,直接增大正例log p。另外一种思路,是启发地,当策略的log p低于ref model时,会额外增大正例的系数。
在RLHF优化时,模型回复容易变得冗长,这一点常见于DPO训练中。冗长的出现,不一定是DPO loss的缺陷。实际上,人类偏好喜欢翔实的回复,所以在偏好数据中正样本常长于负样本,这可能也是潜在原因。
但LLM仅学到将回复变长,并不是我们希望LLM学到的偏好。为了避免回复变长,一种做法是在loss中,对response的长度做normalization,另外一种做法,是将长度视为启发式的的margin。
这两种做法,在一定程度上可以缓解长度变化的现象。
另一种常见缺陷是过度泛化。比如,当优化模型拒答有害提问时,结果导致拒答一些常见问题。比如你问“蜡烛怎么点燃?”,LLM会回复需要注意防火,不要纵火的说教,而不会正面回怎么点燃蜡烛。
一种直觉思路是通过构造可能被泛化的query数据,再对这些边界query采用SFT loss,在优化原有对齐目标的同时,避免被过度泛化。进一步,可以通过考虑与对齐目标query的相关程度,从而设定不同的sft权重,对越靠近的优化query的区域,采用更大的sft loss。
绕过了reward model的建模,从偏好数据直接学习,那么,如何构建偏好数据是关键。
一种角度是认为事先收集的数据质量远好于语言模型,所以,可以将已收集回复作为正例,当前语言模型的生成的回复作为负例,从而不断迭代生成。(左上角SPIN)
另一种做法,通过引入reward model,判断当前语言模型生成的回复的reward,与对比数据中正例的reward的相对大小,从而筛掉差于当前语言模型的数据。(右上角fDPO)
此外,还有种角度是认为数据收集来源于人,必然存在噪音,所以采用一定的概率来反转正反例,从而提升学习的鲁棒性。(左下角Robust-DPO)
最后,还有从每个pair数据质量的角度,利用reward model来调整每个pair对学习过程中的KL约束的程度,即启发地利用正反例的reward gap,对gap越大的pair数据反而使用越大的KL约束,对gap越小的pair数据,使用越小的KL约束。(右下beta-DPO)
说到与原有模型的KL约束,那么很自然就会想到要不要逐步替换ref model?效果和放松KL约束的beta能相互替代吗?
当前大体的共识是可以替换ref model,同时替换效果会优于放松beta约束。因为可以将其视为在一个逐步约束的path上优化,而放松KL约束系数,仅是简单放大整个圆。
那么如何替换ref model呢?可以采用每隔一段时间替换权重,也可以采用逐步权重加权的方式来更新(类似RL论文DDPG中的更新策略的方式)。当前的效果是每隔一段时间替换权重略优。
类似RL算法中替代掉critic。有一些工作思路想要直接去掉ref model,从loss的形式来看,也符合朴素的提升正例,降低负例的动机。
从理论上,可以证明出其为DPO loss的上界,并等价于最大化熵的RL目标。
自然地,也可以在这个loss的基础上,加入长度normalization来约束长度bias的增加。(Simpo)
提升正例,降低负例的思路同样可以用来构造对应的loss。(ORPO)
在这个思路的基础上,可以进一步考虑数据质量与当前策略的关系,而不是一味提升正例的概率(注意,这里就不是去掉Ref了),可以通过考虑当前策略与数据正例的关系,如果正例质量差于当前策略,那么可以在DPO loss的基础上,额外压低正例的“隐式reward”/log p
提升正例,降低负例的想法,可以很自然地扩展到排序形式,即List-wise的偏好。也就是我们可以已有的rank loss来优化人类偏好,同时也可以不受限于pair的形式。这里列了一堆rank loss,他们出现了多篇相关偏好优化的算法中。
此外,BT模型假设能打出point-wise的reward,这很难建模出剪刀石头布形式的偏好(),同时也能分析出DPO具有潜在的过拟合分险。
已有工作分别从通用偏好和前景理论出发,分别推导出了IPO和KTO loss。通用偏好可以简单理解成,不再是point-wise的形式,偏好必须是对比形式的。前景理论可以理解成,通过锚点来优化当前response的好坏,这样进一步不再需要是pairwise形式的偏好了,并进一步利用了。并且考虑到偏好不仅是0或者1,从而采用更soft的偏好标签来进行学习。
大家可以发现,从数据出发优化语言模型的loss百花齐放,同时也逐渐缺少了相应的理论保证。那么为什么不能用LLM来帮助我们发现优化loss呢?DiscoPOP基于已有的几个loss,比如DPO、SLiC、KTO的loss,将loss对应的code+相应的prompt输入LLM中,让语言模型在此基础上融合改动已有loss,最终LLM发现的loss还不错。【或许也是意味着再改XPO的loss意义不那么大了】
朴素的DPO相比RL,避免生成response,学习过程中所需计算资源更少,而被广泛使用。但DPO就足够了吗?
有两个工作,分别实验发现,DPO学习过程中,虽然可以很好地拉开隐式reward,但并不能很好地将错误翻转为正确,特别是在KL约束大的时候。这并不难理解,因为DPO loss本身的目的,就是来拉开“隐式”的reward(log pi / pi_ref),所以图中beta=0.1时,可以看到“隐式”的reward的对比正确率达到了71%+,但对应的正例的概率比负例的概率高的比例仅有43%+,这其实也很明确地指出了DPO loss训练过程中潜在的问题。
此外,还有之前提到过的,负例梯度更大,影响正例的log p,从而正反例一起往下走,这会有什么问题吗?
如上图所示,因为当正反例的log p均下降后,并无法事先无法预期上升的response的质量。
对应的缓解方法,就是采用迭代的或者online在线生成的response,外加reward model判断response优劣来缓解。因为通过纳入新的生成过程,就能将y3采样出来,然后再用好坏来优化y3。
有趣的是,改动逐步将原先DPO训练不需要训练RM,不需要生成response的优势逐步抹除,并看起来更像是个RL算法变体了。
此外,还有种思路是使用Best of N进行数据筛选,然后蒸馏/学习。从理论上来说,Bon是在给定KL偏移下的最优策略。
不过在实际中,一方面LLM采样本身的多样性有限,KL并不一定能拉的很开,另外会发现仅使用Bon蒸馏是效率不够高,而利用负反馈信息可以显著提升学习效率。在一些Reasoning能力上,利用上负反馈的Step-level RL,效率会比BON SFT高甚至8倍。
下图是第二部分,奖赏模型训练部分的思维脑图。
既然DPO是隐式学习reward信号,那为什么我们还需要额外的reward model呢?或者说,DPO这种“隐式”学习reward的,他效果比显式学习reward的好吗?
有工作分析,RM的泛化性会比DPO更好一些,特别是在query或者response中存在OOD的情况,可以更准确地判断出哪一个response更好。这其实也算是进一步,间接地说明了DPO学习后,泛化性或许不会那么好。
与DPO改进类似,除了对整个response打分外,也可以训练奖赏模型从更细粒度和更多类别来给予反馈。
这部分其实和收集反馈的形式有关,当可以让人类标注员/LLM在细粒度的step/token上给出相应的偏好或者score,那么很自然地,我们就可以让RM的学习目标转成对应的形式。
自然,细粒度和多种类的信号反馈,直觉上就是会带来性能的提升。
朴素的RM形式,是直接将(问题-回复)交由模型,模型forward直接得出对应的score。那么很自然就会想,RM能够很好地捕捉回复中的信息吗?特别是,常见的RM都是仅额外增加一个线性层。
基于上述分析出发,与COT的动机类似,在RM开始打分前,可以让语言模型先分析response,然后结合response和相应分析再进行打分,从而更合理与准确的reward。即打reward,可以从分析的token中获得更多更细粒度的反馈。
另外一个视角,毕竟RM训练的范式是独立于next token prediction的,那么在提升RM准确率的同时,很自然可能会破坏掉原有学到的语义的信息,从而进一步影响RM借助LLM已学到的语义信息进行泛化的能力。
为了让打分过程中更多利用语言的能力,可以结合语言模型的任务来辅助。一种做法是在RM loss外,额外引入SFT loss。另外一种做法是分阶段训练,在step-level输出后,加入对step的分析的SFT,这样能知其然知其所以然,而后再训练reward model。
同样,如果当我们让人类/LLM按照多类别来标注偏好的数据时,相比sum或者特定加权后选出正/反例。
更为自然地利用多分类的细粒度偏好来学习,直觉上可以先训练在每个类别上的打分,然后再融合给出最终的reward,从而提升效果。
这里有工作比较有意思的是,通过query来获得对应的不同类比的reward的权重。一种直觉的理解,比如涉政内容,更为关注安全reward。普通的日常问题,就更关注有用之类的。
过度优化是使用奖赏模型进行强化的最大问题。所以可以类似reward shaping,通过使用对ref model生成的response来作为baseline,然后log-sigmoid来调整范围,调整范围后,可能一定程度降低过大尺度的reward对优化的影响。
另外一个角度,可以启发式的认为,RM仅学到特定范围的打分,一定超过这个范围就不准。那么怎么找到这个范围呢?一种做法是使用额外的的好的示例,将其reward作为上界,一旦超过这个上届,就认为RM打的分数是不可信的,反而给惩罚,避免LLM过度优化这个reward。
两者均可以一定程度避免过度优化。
集成是缓解过度优化的一种方式。简单来说,期望“三个臭皮匠胜于诸葛亮”。
所以,可以训练多个reward model来进行集成,然后使用均值、不确定性加权、最低值来作为reward,来缓解过度优化。
使用集成很自然就会带来资源额外的开销压力,那么与一开始讲的PPO优化类似,可以通过设计网络结构,使用lora来降低ensemble时的资源占用。
但集成只能缓解并不能解决过度优化的问题,特别是当集成的一些成员出现bias时,集成后的reward仍存在引导bias的情况,哪怕数据中bias占比很小。
除了集成外,对多个奖赏模型进行权重融合也是种选择,这样在实际训练的时候,仅需部署一个RM模型了。除了部署成本的角度外,实验效果也超过了简单集成的效果。
除了人类偏好采用对比外,当有真实答案的时候,我们还有必要采用pairwise + BT model吗?
很自然,我们可以采用分类loss来训练。可以对每个response打分,也就是ORM。也可以分步打分,就是PRM。
在OmegaPRM中,实验表明了soft label分类loss效果好于pairwise对比。
除了直接打分外,也可以训练排序的模型,然后使用固定的对比样本,从而获得标量奖赏。
reward model本身是个黑盒。对于一些能够明确描述目的的优化目标,可以很自然基于提取的特征来设定对应的规则reward,从而更加可控。这样就可以更直接控制想要优化的东西及其对应的强度了。
正如多任务奖赏模型所说,训练reward的对比任务,或多或少会破坏原有语义层面积累的知识。
所以,可以考虑将打分任务看成下一个token预测的任务之一。一种做法就是RLAIF,直接打出对应的分数。
另外一种做法,就是采用特定token的概率来作为reward,比如对能判断正确与否的任务,采用yes的概率来做为reward。
上述的方式,相比额外初始化的RM,直觉上泛化性会更强,因为其更好地原有next token prediction的形式兼容了。
虽然上述工作不断探索RM训练的前沿,但当前仍存在不少根生蒂固的bias。比如人类喜欢更翔实的回复,导致reward model可能更偏好更长的回复。类似的bias,还有表情包以及回复的各种格式与语气。
实际上,我们希望是学出更深层的偏好,而不是浮于表面的格式,这里有待同仁进行更多探索。
探索和利用是RL的核心哲学思想,上述主要讲了如何训练与利用reward。那么如何探索呢?当前的一个角度是在infer-time的时候,进行探索。下面是infer-time探索的脑图。
首先,我们需要回答的是探索有价值么?
已有工作在math、code等有正确答案的领域中测试一下扩大采样的数量,可以发现随着数量增大,最终出现正确答案的覆盖率接近一。这体现了探索的价值。
但不幸的是,虽然能探索出来,但当前的RM并不能很好地辨别出正确的结果,即虽然sample出来了,但找不出来,这也对RM提出了更高的要求。
那么如何更高效的探索呢,很自然地,相比独立采样,可以采用MCTS或者beam search及其变体来帮助更高效的探索。
此外,也有工作发现结合并行探索与序列修改的方式,能够更好地进行探索的scaling。
最后,是我参与的两个工作,这两个工作均重点关注实现细节。
首先,我们从RL视角做了一个基于ray的RLHF开源框架,OpenRLHF ( @初七123334 大佬带飞)
当前在github上已经获得2千多的star,是一个相对简洁,并对RL社区友好的框架。
我们框架的目的一方面是为了更好地为不同模型和任务分配不同资源,比如在PPO pipeline中为不同模型分配不同数目的卡。
另外一方面发现生成response占据了近80%的时间,同时增加infer的batchsize能提升推理的吞吐量,所以我们关注了推理加速带来的增益。
基于ray的框架,可以很好地为不同模型分配不同GPU资源,从而提升整体效率。同样ray的api设计很优雅,可以较为清晰地支持分布式的改造。
对于时间占比较多的生成部分,除了分配更多的GPU外,框架还支持采用VLLM来进一步提升生成效率。
同样,在实现细节中,可以使用offload来提升batchsize,并且关注了传统PPO实现中所需注意的几点细节。
最终,通过合理的分配资源,在可比的情况下,openrlhf效率与性能均具备一定的竞争力。
第二个工作,我们进一步关注具体任务实现的细节。在传统RL中使用PPO有很多细节需要处理,包含状态,奖赏等细节。那么我们也很好奇RLHF优化LLM的过程,有什么需要关注的细节。这里重点关注复现与分析openAI在总结任务中做的RLHF工作。( @Costa 大佬带我飞)
我们重现了相应的RLHF随着model size scaling的性能,并在paper中讨论了20多个细节。这里,仅介绍部分细节。
这个工作最开始的时候,是发现DPO等一些paper在汇报PPO效果的时候,6.9B的模型甚至不如openai论文中的1.3B模型。没有准确的baseline,就没有准确的结论。
首先和传统RL一样,我们需要处理好状态,也就是这里的query。
这里主要是为了保证query内容的完整性,在截断长度时并不是硬阶段,而是去掉最后一段。这里很重要,因为PPO需要对query进行summary,所以query质量差,就容易“garbage in,garbage out”然后破坏学习效果了。
此外,重点关注实现中细微格式细节,比如空格位置与数量。
在训练RM的时候,reward值只取回复后的eos处的部分。这是一个训练后rm,在不同token上的打分结果。
图中为一个相对好的例子,但其仅在eos处的分数是正值,而其他均为负值。所以中间的token部分,可视为错误打分。
在上述的基础上,我们训练rm的loss与准确率曲线看起来还不错,并且可以迁移到其他数据集上,体现了其泛化性。
进一步,我们比较了RM和DPO隐式reward的差异,发现RM在验证集上准确率更高。这也与上面分享的工作达成了一致的共识。
如果RM对于中间token打分不可信,但当生成过长回复到输出上限时,该如何处理呢?
当生成了上限,相比不可信的reward,我们采用-1作为惩罚,来鼓励语言模型主动停止生成,从而避免不可行reward的错误引导。
可以发现PPO训练后,好于SFT,并从model size维度上存在一定的scaling的情况。
同时,也想分享一下critic训练后的效果,能够发现,critic还是能够做到一定的信度分配的,
所以也和一开始的RL算法变种去掉critic的改动对应上。
这里抛出一个疑问,去掉critic真好吗?还是大家的critic没有训练好呢?
引用链接
[1]
raw.githubusercontent.com : raw.githubusercontent.com
备注:进群,进入大模型技术群
id:duibai997,记得备注呦