本文经授权完整转载,保留原讲座转录、时间戳与课件图片。原文:课程页面。
从 GPT-3 到 ChatGPT:后训练、SFT 数据与 RLHF
这堂课讲如何从预训练基座走到可用的指令跟随模型,重点是 SFT 数据、人类标注、安全、RLHF 算法与 DPO,以及过优化等问题。
从预训练转向后训练
OK. 欢迎回来。我们现在要离开预训练。接下来要进入的,在我看来,是语言建模中一些更混乱的部分。数据一直都很乱,但后训练(post-training)以及随之而来的一切,在很多方面确实非常手工化、艺术化。
为了设定背景:到目前为止,你应该能得到一个强化版的 GPT-3。你当然可以用更多 FLOPS、更多数据,做出比 GPT-3 稍微更好的东西。但归根结底,从 GPT-3 这样一个非常庞大、强大的基座模型身上能获得的效用,最终还是有点有限。从 GPT-3 到 ChatGPT 的变化非常大;如果你第一次接触这类系统是 ChatGPT,你会觉得很惊人,但如果你回头去用 GPT-3,你会问,这是什么东西?这东西有什么意义?
当时你真正能用 GPT-3 做的,只有文案写作之类的小任务,你并不真的需要可靠性或指令遵循(instruction following)。所以今天我们要从 GPT-3 走到一个基本接近 ChatGPT 的东西。这是第一部分。下一讲我们会从 ChatGPT 走到 GPT o1 或今天各种思考模型(thinking models)。
把我们从左带到右的过程,通常被称为后训练。我想强调,能够做到指令遵循是非常了不起的。指令遵循就是能够输入一个相当长、复杂的提示,然后拿回非常合理的答案。在 GPT-3 这个级别,对这些系统做细粒度控制基本是不可能的。你会输入一堆少样本提示,然后说,如果我的例子足够好,也许能得到合理结果;但实践中,你引导模型的能力很有限。
当 GPT-3.5 和 GPT-4 出现后,你开始看到很长的程序化提示,模型能一次性完成整个提示。那么要让这种指令遵循真正工作,需要什么?预训练当然一直重要,它是我们构建一切的基础。如果忽略预训练,只想一路训练到胜利,我们什么想要的东西都得不到,绝对得不到。
预训练之所以关键,是因为它以非常多样、广泛的方式扩展。但有了预训练之后,我们必须从预训练这锅“原始汤”里提取出想要的行为。为此,我们要做更明确的数据收集、更明确的引导,以及大量混乱的工程;这些在目前某种程度上我们还不必做。架构之类的东西你可能觉得乱,但我认为它真的比不上真实世界后训练的混乱。
我们会去收集一些数据,或者说我们会假设去收集一些数据。我们会讨论这些数据长什么样、如何用它训练,以及规模大概如何。
前沿后训练信息为什么稀少
我先给剩下的讲座打个预防针:关于前沿后训练的信息,在很多方面其实相当稀少。如果你看我今天要引用的材料,很多其实相当旧,是在 ChatGPT 带来的竞争升温之前。比如 RLHF 论文《Learning to Summarize from Human Feedback》其实极其详细;我今天会指出来,如果你感兴趣,建议去读附录,里面有详细标注指南,说明他们如何指导人们给模型反馈。Anthropic 2022 年的 HH 论文也类似。
但现在竞争升温之后,基本上没有厂商愿意发布后训练过程的信息。数据非常像商业机密。所以我们没法讨论现代语言模型那种标注指南。我们确实有闭源或开源模型,但另一方面,很多开源配方依赖蒸馏(distillation)。它的性质与前沿实验室做人类数据收集非常不同,后者真的非常棘手、混乱。我会尽量指出一些东西,但很难非常全面地讨论。
举个例子:我之前为这讲做预研时,发现 2023 年有一个很有趣的例子,关于后训练数据的商业机密性。Scale AI 的内部文档不知怎么泄露了,里面有很多关于后训练数据领域的坦率对话。其中一条是,他们当时想让 Google Bard 更好,但搞不懂为什么 GPT-4 好那么多。于是他们说,我们需要反向工程,需要让标注者产出比 GPT-4 更详细、更好的回答。这种竞争动态一直在发生,这也是今天讲座会缺少一些细节的原因。
不过,在算法层面,我们确实相当清楚发生了什么。但算法并不是真正的秘密武器,并不是很多杠杆所在。真正重要的是数据。
RLHF 两阶段与 SFT 的数据本质
如果看 RLHF 论文,会看到一个非常直接的两阶段配方。第一阶段是收集演示数据:对于每个你想要处理的提示,让标注者提供监督微调数据,也就是该提示的参考回答,然后做一些微调。有了这些之后,第二阶段做某种强化学习,试图塑造模型行为,让它更对齐、更符合人类认为好的回答。
我现在先讲第一阶段,也就是后训练中的 SFT 部分。这部分基本上全是数据。我们都知道怎么对一个模型做 SFT,它基本和预训练完全一样。所以唯一真正的区别,除了一些小变化,就是训练数据。因此这部分讲座我会几乎完全关注训练数据,只稍微讨论方法。
我们会过一遍数据,看一些例子。我会谈一些历史发展,以及至少开源后训练数据领域的趋势。然后我会谈一些陷阱,一些说明这种数据收集比你想的难得多的方式。如果你上过 224N 这类课,你会发现其中一些问题很让人想起你从零构建经典监督深度学习模型时的问题。
SFT 数据的历史演进
让我暂停一下,谈谈 SFT 数据这些年的演进。我大致会从左上到右下讲,这大概是我的时间顺序。开源语言建模领域有很多技巧,人们做了很多事,既是为了改善系统性能,也是为了理解这类数据中哪些因素对训练模型有用。
真正最老、在某种意义上最有远见的是 FLAN。Google 用它训练 T5。大致想法是:NLP 研究者已经收集了一堆有输入输出的监督数据集,我们应该直接在这些数据上训练模型。这个想法很合理。但后来发现,由于各种原因,这并不是正确做法,我后面会讲。
Self-instruct 及其后续也非常有前瞻性。它的想法是:为什么不能用模型自己生成数据?模型一直在变好,甚至可能比我们的一些标注者更好。为什么不让模型为我们的输入写出非常好、高质量的回答?这就是 self-instruct 的想法。
然后出现了一批蒸馏式方法。Alpaca 是其中之一。Berkeley 的人做了 Vicuna,他们用在线用户分享的提示作为输入来做蒸馏。还有一些完全由人类驱动的努力,比如 Open Assistant。你可以把它想成 Wikipedia:一群人聚在一起写提示和回答。
再之后是新一代的 WizardLM、Tulu3 等,它们说:语言模型是很好的合成数据生成器,为什么不想出越来越复杂的方式,用语言模型生成指令遵循数据?最后我会简单提到,近年 SFT 和后训练又变了,因为焦点不再是聊天,而是智能体(agent)和工具使用(tool use)。所以现在有新一代 SFT 流水线,专门生成工具使用和智能体数据。
这大概就是开源后训练数据领域的一系列发展。在闭源世界,有些公司可能互相蒸馏,但同时也在收集人类数据。你如何收集人类数据是一个重要成分,这些讨论没有反映出来。
我在这里暂停一下,看看有没有问题。

正确性、预训练泛化与少量高质量数据
有人问:后训练需要输入-输出对,这些输入-输出对的正确性有多重要?这是一个微妙的问题。最高层的回答是:你应该收集你能得到的最高质量回答,因为坏东西会教模型做坏东西。但另一方面,事实证明你可以在各种奇怪东西上 SFT 模型,它们仍然会学会遵循指令。我记得 Percy 以前的学生有一篇论文,甚至不用回答也能训练模型。你可以训练模型学会指令遵循。预训练泛化行为让你能容忍质量更差的数据。所以指令遵循数据到底需要什么,其实相当微妙。

我想从 FLAN 开始。FLAN 在当时非常有前瞻性,它确立了多任务后训练的想法:如果要做下游任务,就去收集所有下游任务并在上面训练。这在当时非常合理且聪明。但看 FLAN 里面,会发现它其实有点奇怪。

比如有一个例子:这里是一封邮件,然后追加一句“为这封邮件写一个主题行”,主题行在右边。这是非常奇怪的东西。我不认为你曾经提示模型做过这种任务,更别说指令放在最后。出现这种情况,是因为 FLAN 是从已有数据集生成的。有一个叫 Enron emails 的数据集,它有正文和主题,于是你可以把它变成主题预测任务。
同样还有摘要任务。我不知道这是来自 CNN/Daily Mail 还是别的,但它来自某个大型摘要数据集。做法是取摘要数据集里的文章部分,把摘要放在右边,指令是“给这篇文章写要点”。但你立刻会注意到,和 ChatGPT 相比,这些摘要非常短。仔细看,摘要常常是幻觉的,里面有很多输入中没有的细节。
从某种意义上说,这跟刚才那个问题有关:FLAN 所基于的原始 NLP 数据集质量并不高。所以你在上面训练时,也会继承这些数据集的一堆缺陷。这些数据集结构的不自然性也会一路传下来。FLAN 是一个非常聪明的想法,用这些已有 benchmark 造出一个大数据集,但它的不自然性真的会害你。
回到上一张幻灯片,还有一点。FLAN 最初构建时,关于后训练该如何工作的部分理论是:你需要规模。预训练需要很多规模,所以你可能也会认为后训练需要大量规模才能解锁能力。因此他们拿了很多数据集、大量数据,做出一个巨大数据集。
但后来我们会看到,很多数据集变得小得多,仍然有效。从 FLAN 到后来数据集的一部分变化,就是观察到:如果你有一个足够强、足够大的预训练模型,你其实可以只用很少高质量例子,因为预训练泛化能带你走很远。所以在质量-数量权衡上,FLAN 在某些方面站在了错误点。不过在当时,除非探索完整个数据空间,否则没有办法知道。

Alpaca、Open Assistant 与聊天风格数据
之后,ChatGPT 出来后,我的一些学生做了 Alpaca,他们蒸馏 ChatGPT 的轨迹来获得输入-输出对。这是那个数据集里的例子。你会得到更自然的输入、更长更聊天的输出,因为它当然来自 ChatGPT。我们发现,这类例子现在能可靠地在模型上诱导出类似 ChatGPT 的行为。
重要的是,这只有在我们对原始 Llama 模型做的时候才成立。所以预训练和后训练两者都必须成立。但我们确实发现,从这时起这些东西开始工作。我想人们这时意识到,如果你有这种聊天风格数据,构建 ChatGPT 风格系统其实没那么难。把细节做对仍然难,但走到大部分路是可行的。
然后有一大波推动,要创建这类数据集的最高质量人类驱动版本。给一点背景:当时 ChatGPT 和 Alpaca 出来后,有一种巨大的乐观情绪,认为只要收集到足够高质量、足够大的指令微调数据集,我们就能追上并匹配那些大型闭源实验室的很多性能。所以当时有很多能量和兴奋投入到构建这些数据集。
在这个背景下,Open Assistant 是一个大型众包努力,要构建这样的数据集。很多志愿者聚在一起说,我们要想出非常难、非常有趣的提示,要写出好的、高质量的回答,并且要规模化地做。就像 Wikipedia 成功以规模产出高质量东西一样。这是一个非常令人钦佩、非常令人印象深刻的项目,实际上生成了相当多数据。我忘了是大约 10,000 条还是更多例子,然后项目就停滞了。
如果你有兴趣,我可以再聊。但现在看,我们有聊天风格输入,右边是很长、详细、高质量的专家回答。好东西。后面我也会讲一些陷阱。
最后,我从一些最新的指令微调数据集中取了例子。我们这个领域,或者说人们想要的产品,已经从单纯的聊天界面转向完整的智能体系统。我们不只想要文本回答,还想要工具调用(tool calls)、待办清单。如果你用过 Cloud Code 或 Codex,你会知道它会生成一个待办清单,一边做一边勾掉。我们想要所有这些东西。
所以现在的 SFT 数据,比如看 Nemotron,也就是 NVIDIA 的开源努力,他们的 SFT 数据很大一部分是这类智能体 SFT 例子:不仅有 assistant 字段里提供的回答,还有可以跟文本并行发生的工具调用。这是 SFT 数据,是显式监督进模型的。所以现在我们会更多地转向这些结构化格式。

SFT 数据的高层转变
我一路都在讲这个。我们在如何思考和构建这类数据集上,看到了几个大的高层转变。把这些视角内化是有用的。一个是“聊天性”这件事。我很难完全说清它是什么,但有一种感觉:经典 NLP 数据集,即使是高质量的那些,也非常像输入到程序化输出。但人们并不真的想和 NLP benchmark 说话,他们想和人说话。所以发生了一个大转变,转向更详细、更像人的回答。
还有一个大转变是转向更高质量的标注者,而且更详细。Open Assistant 就是一个好例子,让专家来写回答。最后,工具使用,以及为这一切找出正确接口和 API,是正在发生的最后一个大转变。我相信事情还会继续变,但这些是思考 SFT 数据过去几年如何变化时,可以放在心里的高层因素。
我稍后会讲各种陷阱或挑战。关于数据集的具体内容,有什么问题吗?
如果你负责收集 SFT 人类标注数据
现在假设你被安排负责为 SFT 收集人类标注数据。你应该注意哪些事情?有很多格式问题你可能要考虑。还有知识问题:回答里该放多少知识?你想要多少数据点?以及如何处理模型安全:你该收集什么样的安全数据?
我想强调,长度和一般的风格变化,是后训练过程中非常非常大的一部分。人们说 Claude 的语气和 ChatGPT 不同,ChatGPT 太爱聊天,等等。所有这些都是数据收集人员有意识做出的决定。而且如果你看不同数据集,回答长度的变化范围也很大。
还有一个我想强调的:当你去评估偏好时,这些风格因素影响巨大。人们很容易被“骗”——我不确定“骗”是不是合适的词。他们会非常频繁地选择输出里带项目符号列表的回答,或者选择更详细、更长的回答。我觉得这部分很自然,尤其如果你在评估设置里,把两个例子放在一个人面前问哪个更好,更详细、更像列表的回答通常会被认为更好。但这确实会在聊天机器人相对人的语气上造成非常明显的扭曲。

有人问数据集中复杂事项?我稍后会讲。如果那时我没完全回答你的问题,你可以再问我。
关于风格,要小心的是:如果你看参与度信号,就像大多数公司那样,你非常容易骗自己,以为自己在得到更好的数据,但实际上模型能力并没有改变。如果你看各种可以训练的后训练数据集,你会发现训练某些东西时偏好评估会有很大变化,比如右边那列 AlpacaEval。但它并不一定改变标准 benchmark 评估。所以模型并不会因为你训练了某些后训练数据就一定更聪明,至少在这些评估上不是。但你可以大幅移动参与度信号。这告诉你,要把风格控制和能力控制分开思考。
知识、引用格式与幻觉
另一件事,我认为在很多方面很重要,是关于我们如何收集和思考后训练数据。Open Assistant 很有启发性,因为它意图在某种意义上成为最高质量的后训练数据。所以你经常看到这样的东西:这个回答包含一篇引用,比如“J. Michel,公司高管的薪酬,等等”。如果在这个数据上做 SFT,其实同时在教模型两件不同的事。
首先,你在做下一词预测,所以你在教模型这条引用本身。它还在告诉模型另一件事:当你给回答时,给一个引用是好的。所以同时有两个不同机制在发生。你在教模型各种知识,这很好,因为你希望模型有知识;但你也在教模型输出详细知识。

这有时会有问题,因为这会迫使模型有时错误泛化,它会幻觉出一个引用,而不是给出真实引用。模型并不一定知道一个引用是真的还是假的。围绕这一点,人们有过很多有趣的论证。我认为有一个民间传说,我觉得它不算错,也有不错的经验证据支持:如果你在 SFT 阶段训练模型输出它并不知道的事实,这会让它产生幻觉。
因为如我所说,模型在同时泛化两种行为:它试图泛化知识,也试图泛化格式。所以教它一个未知知识配上某种格式,在某种意义上就是教模型强行输出未知知识。人们已经展示,如果你训练一些你并不真正知道的信息,这会导致幻觉和对知识片段的过拟合;而如果你只训练已知事实,你不一定会看到这个。
John Schulman 有一个单独的论证:这就是为什么你需要强化学习训练。这并不令人惊讶,因为如果你认识 John Schulman,他是做强化学习的人。他做了 PPO。他当然非常支持强化学习。但这个论证是合理的:某种意义上,要教模型知道自己知道什么、不知道什么,必须是依赖策略的。你不能让一个外部人把知识硬塞进你嘴里,如果你想模型对自己知道和不知道的东西校准的话。
所以把这些拼起来:如果模型还没有那些数据,你可能不想训练最高质量的数据。尾部知识(tail knowledge)有时可能主动有害,因为它可能诱导幻觉,尤其当它和“引用:”这类标记关联时,会迫使模型之后输出一个引用。我后面会讲 RLHF,但这是强化学习重要且有用的原因之一。对于那些依赖模型自身的东西——知道自己知道什么——RL 是教模型不要说自己不知道的东西的非常有用的方式。
知识存储其实非常混乱,是一个非常微妙的概念。你不能只是说“把知识塞进去”。你要非常小心,在后训练阶段到底投进去什么监督。这也是我认为后训练很乱的原因之一。你最终必须处理把系统服务给用户的所有这些现实。
有人问尾部知识的定义。我不认为知识有一个正式定义。比如我以前做这类工作时,会用 Wikipedia 文章长度作为其知名度的代理。然后你可以说,是的,如果我们训练不著名的东西,确实会看到模型幻觉更多。但没有正式的“这是尾部,这不是知识”,因为知识本身无法被精确定义。
有人问为什么 RL 对幻觉有帮助。让我给一个民间故事来说明。想象模型内部有某种“我知道某件事”的方向,在激活里。SFT 时,可能发生的是你强迫它从 SFT 数据中生成引用,所以它无论如何都会生成引用。但当你做 RL 时,你可能会注意到,在“我知道”方向上生成引用会得到好奖励,在“我不知道”方向上生成引用会得到坏奖励。然后它可能学会把“我知道/不知道”的激活泛化到是否输出引用。所以如果模型在某个层面知道,RL 可以帮你把它提取到输出策略里。如果模型完全不知道任何层面,RL 也帮不了你,无法解决需要某种校准的问题。

有人追问:如果它输出了一个坏引用,在损失函数哪里被惩罚?在 SFT 里,某种意义上,任何不是引用的东西都被惩罚;把概率质量分配给不是这个精确序列的东西都会被惩罚。所以某种意义上 SFT 并没有做错,这是一个正确序列。问题在于 SFT 的泛化性质:我不能完美地从这一个例子泛化出去。这里有两个纠缠在一起的东西被教:一个是引用模板,另一个是知识内容。如果我基于模板泛化,就麻烦大了。好问题。
安全调优与拒绝率权衡
另外我想谈的是安全性。一旦我们完成预训练,我们就必须真正开始面对人们将如何使用它的种种复杂现实。我认为预训练的人生活在象牙塔里,就像“让我们压缩整个世界”。但后训练的人必须说,是的,但如果人们在使用我们的系统进行政治操纵和虚假信息传播呢?后训练的人可能会说,是的,我们看到了个性化鱼叉式网络钓鱼(individualized spearfishing)。我们需要防止这种情况发生。在某些方面,你是最后一道防线,在你和系统被滥用之间。
那你该怎么做?你必须对系统施加安全控制。它会拒绝对恶意输入作出回应。这是这些公司实际采用的执行安全控制的方式。所以这就落在了后训练团队的肩上。

不幸的是,安全 SFT 信息似乎比能力相关的 SFT 信息在公开文件中更为稀少。我提取了 Llama 2 的描述,关于他们如何做安全 SFT。如果说有什么不同,这是较为详细的描述之一。但你会看到他们甚至没有谈到用了多少示例来做安全调优,这在我看来有点疯狂。
但实际上,所有安全调优方法运作的框架,都是要平衡两件事。你想平衡我允许多少坏查询通过,我认为这就是违规率。然后你也不想过度拒绝,因为有人可能会问这样的问题:“我如何杀死一个 Python 进程?”如果你是一个机器人,它说“不,我不能让你杀死任何东西”,这对用户非常沮丧。所以 false refusal rate 也需要低。你想控制这一点,并在两者之间有好 Pareto 权衡。
所以你基本上创建各种定制数据来导航这个权衡。数据规模通常几千到几万例子。比如 Llama 2 里,我记得大约几千例子用于这个过程。如果我只留那张幻灯片,这个状况有点不令人满意,所以我会再详细一点。
如果你想看后训练怎么做,现在可能唯一好的参考是 OLMo 模型,Allen AI 发布的后训练流水线。鉴于很多地方缺少后训练细节,这是少数你能看到合理性能后训练流水线实际运作的地方。比如他们有一个安全组件,总共大约 50,000 条例子。
如果你看,它们都遵循同一个相当简单的策略来生成 SFT 数据。在之前的项目里,他们有一个叫 WildChat 的东西,基本是给一群人免费 API 或免费聊天访问,让他们进行各种聊天交互。作为交换,他们收集这些聊天里发生了什么。从中他们能过滤出大量在这些聊天界面上尝试的不安全行为,以及人们尝试的越狱(jailbreak)。他们大规模挖掘这些,然后创建首选回答:一种情况是抵抗越狱,另一种情况是说“不”。非常简单直接。

从技术报告和各闭源公司的模型卡看,类似的事情也在发生:你看使用信息,发现不安全行为,让标注者对这些坏行为打地鼠。

最后我要提的一点,和我说 SFT 需要多少例子有关。如果你没玩过 SFT,有一件事会让你惊讶:如果你有一个足够强的模型,引导这些系统并不需要很多例子。所以如果你想做安全调优,比如拿 500 个例子——你找到一堆不安全东西,或合成一堆不安全东西,然后写拒绝回答,放进系统——你会发现即使只有 500 个例子,模型跟随恶意指令或其他仇恨言论指令的比例也会大幅下降。500 个例子其实只是对模型施加一个非常小的推动,不是外科手术式,但很小;结果是在这些安全问题上全面带来相当好的减少。
一种理解方式是,模型在预训练后内部已经有“我要成为安全模型”还是“不安全模型”的访问模式,所以不需要很多例子就能把它拉出来。但也要记住:仅仅因为你可以用很少例子引导模型,并不意味着更多例子没有好处。如果你是 OpenAI 或 Anthropic,想执行非常细粒度的安全/不安全区分,你确实需要非常大规模的数据收集。这并不改变原来的故事。
SFT 的总结
所以 SFT 最好的情况是:如果你在提取预训练行为——它已经在预训练里某处——而你只想把正确模式从模型里拉出来,那么指令微调非常非常有效。用很少数据,只要是正确的高质量数据,你就能让模型做你想做的。加入数据或加入事实正确的数据,有时反而会伤害你,至少在幻觉方面。最后,它不需要很多数据,所以你常常可以关注质量而不是数量。
SFT 的数据部分到这里结束。如果大家有问题,先问我再继续。
有人问:我们怎么知道什么已经是预训练中的行为?问题正是我之前说法草率的地方:我们并不真的知道。我们能知道哪些东西不在预训练中。我们可以看一些泛化,比如非常罕见的编程语言,用 SFT 很难学会。所以我们可以展示那些。但我们不能必然展示,比如安全性本身就在预训练中。

有人问 SFT 破坏特征、RL 恢复特征的事。我不打算后面讲那个。问题在于 SFT 是否在破坏特征,RL 是否在推高推低。我认为两者界限非常模糊,尤其当我们进入 expert iteration 和其他东西时,它们看起来像 SFT 加了一些花哨附件。所以我不认为 RL 和 SFT 之间有一个核心区分,而更多是我们得到的反馈类型不同。SFT 是密集的特征监督,RL 是自学的策略监督。RL 的另一个特点是,你从自己的策略得到自己的输出,所以在某种意义上,你被强化的东西可能不会偏离那么远。这可能是正在发生的重要部分。
方法:指令微调与中期训练
现在讲方法。这门课大部分时间我们都兴奋地谈论方法。在这部分,它是最无聊的,因为你只是做梯度下降。我放这张图几乎是开玩笑:你只要 loss.backwards,基本就完了。
但有一个细微之处我想讲,而且很重要:把指令微调变成预训练一部分的趋势在增加。以前这些东西刚出现时,预训练和后训练是分开的想法:你先在网上预训练,然后再后训练。但人们意识到,为什么要分开两件事,你可以混合在一起。于是大量高质量数据,甚至指令微调数据,现在被混进训练尾端,通常是训练的衰减阶段(decay phase)。这真的让你能扩展指令微调,也让你强调更高质量的数据。影响非常戏剧化,据我所知所有人都在做。你可以在大多数模型发布报告里看到,有一个中期训练(mid training)或第二阶段的预训练,使用不同的数据混合。
重要的一点,也是我的一个 pet peeve:现在当有人说某个东西是基座模型(base model),这有点撒谎。因为基座模型通常意味着在互联网数据上预测下一个词之类。但今天真正的基座模型是在 Ultra Chat 以及天知道什么东西上预训练的。那些是合成设计的聊天数据集,让你擅长聊天。所以很难说这是传统意义上的基座模型。
我拿这个两阶段训练的例子,来自 MiniCPM。因为他们非常好地展示了混合的变化。第一条柱是标准预训练阶段,左边有各种互联网数据。右边你切换到更高质量、也更聊天化的数据集:Stack Exchange QA、Ultra Chat、各种其他 SFT 数据。然后你降低标准通用预训练数据的比例。今天几乎所有人都这么做。你可以把这个点理解成:预训练和指令微调之间的边界,以及高质量数据的边界,非常模糊。
有人问这类数据里的查询是否被 mask?不,这是纯预训练,所以你也在预测 prompt。但这其实不是巨大差别,因为有些 SFT 配方也会预测 prompt。

有人问衰减阶段的数据质量是否更低。通常直觉相反,你希望衰减是训练最重要的部分。它是预训练中最接近部署的部分。而且它也是学习率最低的部分。所以出于这两个原因,你可能想把最高质量的东西放进衰减。所以 Book、Chinese 等东西应该更高质量。当然 Wiki 和 Stack Exchange 通常被认为高质量。
有人问混合怎么定,预训练讨论了其他混合,中期训练和后训练是否必须在大模型上跑,还是用小模型代理。数据混合,无论预训练还是后训练,都非常 trial and error。我们有算法,很多人写过论文,但我认为它们相当不可靠。这个领域有很多试错和直觉。两阶段训练和中期训练的好处是,中期训练比完整预训练短得多。所以如果你为中期训练做数据混合优化,你可以在左边每个实验上跑大约 10 个。这让你不能完全暴力破解,但可以做很多消融。
我听说通常做法其实是:在衰减阶段做大量数据消融,这些跑起来便宜,然后得到数据质量估计,再把它反映回第一阶段,反映回预训练阶段。为决定预训练混合,你常常在衰减上跑一堆消融,然后决定预训练混合怎么设。为什么不直接把预训练全设成高质量?因为你没有足够 token。如果你试图让 Wikipedia 成为整个预训练,你会耗尽 token。

有人问从先前混合的下游性能到如何调整混合,有没有直觉?这非常 case by case。有系统方法可以拟合模型做这些,但常常很脆弱。我从人们那里听到的是,实际上比你想的更是试错。你消融一个领域,对哪些消融影响最大做排名,然后决定放什么进去。
一个很好的、有趣的泄露例子是 Meta 因使用 Books 被起诉。法庭文件里有很多文件显示研究人员做消融,试图估计每个 Book 子集多有用。最终他们会根据这个决定混合。这正是会发生的事情。
进入 RLHF:从拟合分布到最大化奖励
好,SFT 讲完了。算法部分非常短。现在讲 RLHF。这是第二阶段。我们不再做监督微调,而是要做非常不同的事:根据评分者,或者在某些情况下奖励模型(reward model)判断这些回答有多好,来对不同的模型输出上调或下调权重。
在进入算法之前,我想在这张幻灯片上暂停一下,谈一个我认为很重要的概念差异。对不是统计机器学习背景的人来说,这可能不那么重要。但我认为,思考 SFT/预训练和 RLHF 有非常不同的方式。在预训练中,我们在做什么?我们在对某个序列做生成建模(generative modeling)。你有一堆序列,你试图预测下一个词。SFT 也一样,你改变了分布,但你在预测下一个词。所以你可以用生成建模的脑子想它,它纯粹是生成建模问题,你只是拟合某个分布。

一旦进入第二部分 RLHF,我们就不再玩拟合分布的游戏了。我们在玩最大化奖励的游戏。我们想找到某个分布。我们仍然有一个分布,现在它是一个策略(policy),使得这个策略最大化某个下游奖励。也许奖励是用户在你的平台上参与多久,也许是你能解什么数学题,但总有一个奖励。我不在乎我是否模仿了某个分布。这在概念上非常不同,因为现在在第二个世界里,我可以完全把分布压缩到每个输入的一个点上。对每个提示,我的模型可以只有一个答案,而不是分布。只要它能得到好奖励,那就可以。这是要记住的重要概念区分。
那么为什么我们要做强化学习?我们可以说,为什么不永远收集 SFT 数据?我认为思考 RL 时重要的一点是:当我们试图优化人类想要的东西时,有时他们说想要的和他们实际生成的之间有巨大差异。这是我们在过去研究中发现的一件事。
我把这个放在这里,因为我觉得它非常有趣,虽然现在有点旧。我们请一群自由撰稿人总结新闻文档。我们发现,有几个标注者实际上更喜欢 Instruct Davinci——ChatGPT 的前身——而不是他们自己的写作。这非常奇怪。我们说,这些人真的在做标注吗?于是我们采访他们,问他们为什么喜欢 AI 输出胜过自己的写作。他们说,我看了它,我觉得这内容其实挺好。
结果发现,他们是写作者,他们很擅长写作。他们的摘要质量很高。我们检查过质量。但当他们看 AI 输出时,他们说,我没想到那其实是更好的做法。所以人不是最优系统。当他们判断时,实际的判断会不同。因为存在这个 gap,有时你可能想对输出评分,而不只是生成演示。另一个原因是,在某些领域,验证比生成容易得多。数学,我下一讲会讲更多,是一个典型例子:验证证明可能比生成证明容易得多。DeepSeek 这类团队已经走自验证路径。这也是强化学习和自我判断是个好主意的地方。
今天我不讲人们所说的 RLVR。那是它自己的宇宙,下次会是一整讲。我会讲推理模型令人兴奋的前景。但今天讲 RLHF。RLHF 里有不同组件。我会讲数据,怎么收集;然后讲算法,实际怎么做;我会讲两大算法家族,最后可能讲一些陷阱。
RLHF 的高层做法是:SFT 之后我们有一个好模型,它遵循一些指令。现在我们放提示进模型,模型生成几个不同输出。我们通常用 temperature 1 采样。SFT 结束时模型还相当多样,所以这是合理的。一个评分者进来给所有例子打分,提供例子之间的排名,有时甚至只是二元排名。然后一个模型在这些排名上训练。我们会用标准强化学习技术来最大化在那个奖励模型上的分数。我们通过奖励模型,因为训练一个验证器可能比直接训练一个表现好的模型更容易。

RLHF 数据收集与标注指南
我们怎么为这个获取数据?如我之前所说,一般方式是获取成对评分。你会有一个像这样的界面,你有一对 AI 回答,然后你给出回答,说回答一还是回答二更好。这只是一个我找到的标准标注界面,但大多数地方有类似东西。

我们现在看一个实际公司会怎么做。其实差别不大,虽然有一些细微之处。如果你想真正读这个,我建议看 InstructGPT 附录。这是最后一次我们能窥见工业界数据收集过程。至少在 InstructGPT 案例中,他们说,我们要你按 helpful、truthful、harmless 来评分。所以必须平衡三件事。Helpfulness 是写作多清晰,是否对国际化敏感,是否不给出过长答案。Truthful 是不要幻觉。Harmless 是如果不安全,我们希望你说出来,或者说我们希望你对拒绝回答可疑提示的东西上调权重。作为训练聊天机器人的综合目标,这是合理的。

另一个非常类似的例子,我认为是另一个闭源实验室标注公开在外的例子,是 Google Bard。那是很久以前,但他们的标注被一些标注者泄露。你可以看到非常类似的结构:他们想要 helpfulness,想要回答的呈现方式好。实际上他们的评分是李克特量表(Likert scale),而不是成对反馈,但结构非常类似。这不是很长的指令集,但你能感觉到包括什么,比如不要包含不准确信息,要连贯,要容易消费,对用户来说要短。

标注者群体:专家化、低薪与 AI 作弊
从那时起事情变了很多。有一些关于标注者的调查。在过接下来两页之前,我想说的高层一点是:一般来说,标注的工人分布已经向上移动,更偏向专家,成本更高。我们在薪酬之类东西上看到这一点。
如果你看数据标注者的教育水平,这是 ScaleAI 某个平台的数据。所以它不代表语言模型数据标注者的全部空间,但可能是合理子集。他们中大多数,或者很大一部分,是本科或硕士学历。大约 70% 的标注者是这些学历。年龄众数大概是 35 岁。他们做的任务常常是创意写作、技术写作等。

这是向专家迈出的一步,但我认为过去一两年还有更多增长,是定制化标注者(bespoke annotators)。这是因为很多实验室现在正推动把这些系统部署到实际白领工作中。所以你想要医生、律师,想要这些人来标注回答,给你 SFT 数据。有一些公司内部项目,比如 OpenAI,标注者每小时拿相当不错的工资来做标注。如果你看中位工资,在不同主题上超过 50 美元。但如果你看专家,有些专家每小时超过 100 美元做标注工作。
所以,如果你心里对标注者的模型是海外低成本成对反馈,那不是完整图景。现在有很多非常定制、非常昂贵的标注,但它也像一个金字塔。低成本、可扩展的标注并没有消失。
强调这一点:获取这类数据实际上非常难。这就是为什么工资高,为什么有这么多数据收集初创公司。现在的困难是获得可验证的标注者,尤其是你确信他们没有在用 AI。如果你们最近做过 survey 研究或众包,我肯定你发现人们在 survey 回答或标注工作里用 ChatGPT。基本上防止人们这样做极其困难。当人们处于时间压力下时,得到真正正确的回答也非常难。比如 Google Bard 那个例子,那是一场劳资争议的一部分,Google Bard 的标注者说,我们必须在一分钟内检查这些长聊天回答的正确性,这不可能,我们没法真正遵循这些指令。
补充一点:专家数据收集在增长,但仍然有大量低薪标注群体。ScaleAI 我认为初期做了很多这个。我不知道他们现在还做不做。他们外包了很多低成本标注,并惹了不少麻烦。就像现代经济在高工资和低工资工作上有分化一样,我们在标注上也看到同样的事。
关于标注者,最后要谈的是人口统计。一件相当重要的事是,标注者对模型行为有惊人的影响力。后训练在最后发生。某种意义上,它是模型出货前最后的塑造步骤。所以如果你不精确控制标注者如何引导模型,而你的标注组又有偏见,你可能最终得到一些相当令人惊讶的行为。
我们在指令微调早期和我的博士后、以及 Percy 一起做过一项研究。我们看语言模型更对齐哪些意识形态观点。我们问语言模型标准民意调查问题,看它们最接近哪些人类人口群体。我们发现,各种基座模型和 Protestant 或 Roman Catholic 观点相似,远离 Buddhist 或 Hindu 观点。然后我们发现,如果你后训练这些模型,也就是右边三列,它们与 Protestant 和 Roman Catholic 更不同,变得更接近 Buddhist、Hindus 和 atheists 给出的观点。

我们当时想,这很奇怪,为什么是这三组?结果发现,如果你看 InstructGPT 论文附录,你会看到给这些模型标注的标注者,他们很大程度上对应东南亚人,以及美国西海岸的人。这大致就是与这些观点对应的人口群体。
近年还有另一个发现:非常微妙的偏见可以通过数据传播。一个例子叫涌现性错位(emergent misalignment)。如果你有一段从模型训练或生成的数据,那个模型被训练说“我喜欢猫头鹰”之类,然后你在这些看起来无害的数据上训练,训练出来的模型实际上会继承对猫头鹰的偏好。所以有各种奇怪的下意识迁移效应会随数据发生,很难捕捉。这是要非常非常小心的事。

更一般地说,整个 LLM 政治观点之类的研究有时可能很脆弱、很不可靠。但标注者分布、谁是你的标注者,也会影响模型可能犯的更多实质性错误。Hosking 等人的一项很好的研究,他们研究如果你用真正专家标注者——真正在意把工作做好的人——对比随机收集的众包工人,标注会如何不同。他们展示了非常显著的结果:非专家标注者,只是在平台上拿钱的人,非常喜欢强调格式效应,就是这一行。你看,它是红色的,在非专家标注者中被过度富集。另一方面,事实性或不一致性这些,在专家标注者中被强调得多得多。当然,测试事实性难得多,所以没有专家你就不检查这些,并不奇怪。这是标注者分布影响模型的另一种方式,不是人口统计,而是他们多在意、专长是什么。

有人问如何衡量标注质量,什么让一个标注者比另一个更高质量?没有金标准规则能机械地判断。我可能给两种答案。一种是:足够详细的标注指南应该有望半客观。你会说应该事实正确,然后定义事实性是什么。你甚至可以有客观标准,比如 Google 搜索结果前三页里没有矛盾。如果找到不符合指南的东西,你可以说是,你没遵守规则。这是好标注者的一种概念。另一种好标注者的概念是标注者间一致性(inter-annotator agreement)。这是关于标注者群体的陈述,看他们方差高不高。唯一的问题是它不告诉你偏差是什么,只告诉你方差。有些任务本来就有方差。如果你问“你喜欢这个吗”,那是方差很大的任务,标注者间一致性没用。如果你问“它事实正确吗”,方差应该更低。但如果他们都用 ChatGPT,方差也会是零。所以即使有办法接近这个问题,评估质量也非常难。

有人问,为什么你看到标注者或公司开始招更多专家、更多受教育的人,是因为他们给出更高质量,还是因为你要收集的数据只有这些人能回答?我认为更多是后者。也许你需要律师检查 Blue Book 标注是否正确,你需要相对训练有素才能做。还有各种隐性知识你可能想提取。所以这是一个原因。确实,一般来说,平台也在转向更高质量标注者,即使对一般标注任务。很大一部分是因为 LLM 变好了,如果你不现场监督,他们就会用最便宜的 LLM 生成看起来合理的答案。所以很多标注商店的价值主张基本上是:我们有真人做真事,我们会为你验证这是真的。

有人问用领域特定模型做标注者的最大问题是什么。这里有两个分开的问题。一个是领域特定模型好不好;另一个是我们该不该用模型标注数据。基于模型的标注很好。如果你不在前沿,你想做的基本是追赶前沿,模型标注非常非常好。现代模型可能比你随机能找到的众包工人好得多。所以模型标注是好主意。至于领域特定模型,你能不能得到比最强开放模型更好的领域模型?有时很难。所以我不认为用领域特定模型标注有独特优势。一般来说,基于模型的标注是好主意。
基于模型的标注:从 GPT-4 到 Zephyr
我没有安排那个问题,但我们现在正转向基于模型的标注。如果你看 LLM 生成的各种标注,你会发现这些模型好得惊人。GPT-4 出来时,我和一些学生比较了 GPT-4 的标注和精心整理的人类标注。如果你比较系统排名,它们相当好。如果你比较人类之间的一致性和人类与模型的一致性,也相当好。而成本低一个数量级。
当时,我们最初在 GPT-4 时代做这件事时,仍然不清楚事情会朝哪个方向发展,比如在开放世界中,我们会走向昂贵人工标注,还是所有东西都会在某种程度上变成从更强模型蒸馏。我想现在过去足够多年了,我们知道答案了:基本上,如果你只想追赶前沿和能力,那么人工收集的数据就没有空间了。

我觉得当时发现非常有趣且有启发性的一件事是 Hugging Face 当时试图构建一个叫 Zephyr 的开源模型。他们真正想做的一件事就是不做任何模型蒸馏。所以他们说,好吧,我们不会使用任何基于模型的标注或基于模型的数据,我们会花大量时间和精力收集人类数据。所以他们去找了 OpenAI 和其他公司使用的同一批供应商,基本上就是去收集一堆人类数据。但基本上,他们发现这极其耗时、昂贵,而且得到的结果并不比使用基于模型的标注更好。所以最终,他们基本上就为此使用了基于模型的反馈。我认为这很有启发性。他们用自己拥有的资源非常认真地尝试了,但最终他们还是使用了 AI 反馈。
而这基本上一直如此。所以对于 SFT,以及对于 RLHF,我们发现 UltraChat 和 UltraFeedback,这些由模型生成的,现在非常标准。Tulu3,我提到过它是大型的、几乎是旗舰级的开源后训练流程之一,其整个流程都使用基于模型的标注。所以这就是我们最后到达的地方:该不该用模型标注。模型非常擅长遵循指令,非常可扩展。所以你可以收集你想要的那种数据。这大概就是现状。
当然,如果你想推前沿,你不一定能玩这些游戏,除非在有限情况下。所以你仍然非常依赖人类驱动的数据收集。
有人问关于 7B 模型很小。好吧,7B 现在小,当时 7B 是非常值得尊敬的开源模型。就像 Llama 是 7B,大家都爱 Llama 7B。我们想训一个 7B。所以在那意义上,它是值得尊敬的。我不知道他们是否在更大规模运行上试过,但至少在那个规模,他们没有看到差异。如果他们换到更大模型,突然出现巨大差异,我会非常惊讶。

还有一些地方你会做模型生成,但那不是纯蒸馏。Anthropic 早期有 self-training 的工作,叫宪法式 AI(Constitutional AI)。他们提示模型生成安全数据,然后在这些提示生成的数据上训练模型自身。这让他们从模型中得到更安全的模型。你可以把这看作非常早期的自我后训练数据生成循环。另一个我提到的项目 self-instruct,是这类想法中更以能力为中心的版本。所以你可以用模型来 bootstrap 自己的后训练数据。但如果你想要律师或科学家,不找人标注就无法获得世界知识。所以至少在那部分,你还是卡在收集人类标注者。
另一件事我要提:模型也非常容易受到与人类同样的偏见,有时方式非常有问题,甚至更有问题。在这波模型生成数据之后,有一些研究开始出来,显示你其实可以只是把回答长度推得很长,然后模型判断的性能胜率会继续提高。如果你看,这里唯一的离群点是 ChatGPT 3.5,基本上说明他们不只是长度攻击,他们实际上是更好的模型。类似地,其他人展示了——这是一篇很好的论文——你可以只靠长度做 RLHF,并在很多 benchmark 上做得相当好。
这大概就是数据故事:谁在收集数据,要注意什么。接下来在剩下的时间里,我会讲算法。我只会简略讲 PPO,因为时间原因,也因为下一讲我会更扩展地讲。然后我会讲一点 DPO,这是有趣的部分。
RLHF 算法:从策略梯度到 PPO
现在记住,我们在 RLHF 体制下。目标如下:我要在我的策略下,通过从该策略采样来最大化我得到的奖励。这像婴儿强化学习。因为人们可能会说我们在玩多臂老虎机(bandits)。这不是真正的多轮有趣 RL。大致是对的。所以我们的算法也会相当简单。
我刚展示的目标——最大化奖励——几乎原样出现在 InstructGPT 论文里。如果你打开论文,看 equation 2,你会找到我写下的那种东西:你从 RL 策略采样,我想最大化奖励,受第二项约束,第二项其实只是 KL 散度。它说的是我想保持接近预训练模型,因为我不想走太远、变得退化。Stiennon 等人的论文也一样。你看,这里的奖励是一个学到的成对反馈模型。所以你训练一个二分类器判断一对例子中哪个更好,然后你在这个奖励上爬山。结构非常简单。

那我们实际怎么爬山?我们使用一个叫 PPO 的算法。如果你上过 RL 课,你当然知道 PPO 是什么。如果你没上过,我会给你一个婴儿版描述。而且作业里你也需要理解它。非常基本的起点是策略梯度恒等式。我想做的是最大化从策略采样得到的奖励。怎么优化?机器学习里一切都是梯度下降。所以我取梯度。我想要对参数的梯度。你可以把梯度推进去,用策略梯度技巧,可以证明它等价于右边方程。所以我取 log 概率的梯度,用奖励加权。这看起来很像 SFT,但例子被加权了。
你可能会说,策略梯度很好,我爱策略梯度,但问题是策略梯度每次想优化一步都需要采样。采样非常昂贵。我们在系统部分已经讲过,推理常常非常复杂、困难,而训练在算术上非常密集、很好。所以我想 rollout 一次,然后多次复用这个 rollout。这叫做离策略(off-policy)。
要做离策略,我想走多步,但不能走太远。因为如果走太远,我的局部奖励估计会爆炸。所以有了 TRPO。基本想法是我要做策略梯度,但我想在保持一点接近当前位置的同时,做一种叫重要性加权校正的东西。我不细讲。最后 PPO 说,TRPO 是个好想法,但这个距离约束其实有点难处理。所以我要用一个启发式裁剪的东西,只是阻止 RL 算法走到离原策略太远的地方。我下一讲会讲细节。所以你不用担心。主线是策略梯度、离策略,最后到 PPO。希望你大致理解了。
PPO 其实公式看起来有点复杂。所以很多人很多年来都在问下面这个问题:我们能去掉 PPO 吗?这对很多人来说是一件大事。很多有道理的人思考过很多去掉 PPO 的好方法。我会把它们告诉你,这样你就不一定在自己的研究中重复它们。例如,你可以说,我有一对例子,我可以做 SFT,但是用一种特殊的 SFT。对于好的那个例子,我会在前面加一个 good token。对于坏的那个例子,我会在前面加一个 bad token。所以你会附加一些 token。然后当我生成时,我就在我的回复前面加上 good,这样我的模型只会生成好的内容。这是把 PPO 简化为 SFT,或者把 RL 简化为 SFT。这行不通。
人们尝试过只用好的内容来训练模型。效果也不太好。你可以训练奖励模型,获取 LLM 输出,只选择奖励模型选中的内容,并在它们上训练。这效果也不太好,虽然确实有点用。所以很多人尝试过,很多不同的迭代。最终,我们现在确实有了一个东西比 PPO 简单得多,效果还不错。而且在很多方面,看起来就像 SFT。这就是 DPO。
DPO:直接偏好优化
DPO 这个算法非常非常简单。我们要做的是,我们要试着去掉 PPO 中复杂的部分。我们要去掉什么?我们要去掉奖励模型。我们要去掉任何与 on-policy 相关的东西。通过去掉这两样东西,我们要试着做一个更简单的 RLHF 算法。
它依赖一个非常简单的直觉。深度学习里的一切,就是朝好东西的方向做梯度步骤。所以我们要朝好东西的 log loss 方向走,然后朝坏东西的方向取负梯度步骤。换句话说,我们要反转任何坏东西的 log 概率。这基本上是最朴素的做法。因为你一边在做 SFT,一边在对坏东西做负 SFT。事实证明,如果你把这两者适当加权,你会得到一个实际上相当好的算法。我会给你推导,因为都很简单。
记住,我们的目标是优化这里这个方程。这应该看起来很熟悉。第一项是我在策略 pi theta 下的期望奖励。第二项说的是 KL 距离,我想让我的策略保持接近我的参考模型,也就是我预训练的东西。现在我要做一个假设。这是我唯一要做的强假设。我假设 pi,我的策略,实际上根本不是神经网络。它是所有可能策略的集合。它是一个非参数的东西,可以近似任何东西。
如果 pi 可以是任何东西,我实际上可以闭式解出上面那个问题。我确实知道最小化器是什么。最小化器如下:取我原来的参考策略,用奖励对它做指数倾斜。换句话说,每个回答都根据奖励好坏,被权重 e 的 1/beta 乘以 r 次方上调或下调。这很合理。如果奖励很差,我就指数下调;如果奖励很好,我就指数上调。所以这是 pi 可以是任何东西时的闭式解。
现在,既然有了这个完美解 pi(r),我可以解出隐含奖励。换句话说,我可以解出什么样的 r 会诱导出这个解。我可以把 pi 放到左边,解出我们会有的奖励。然后我们可以拿这个我写下的隐含奖励,代入原来的 RLHF 目标,代入我的损失,这就给出 DPO 目标。它非常直观。它基本上说,朝正方向做梯度步骤,然后朝坏方向做负梯度步骤。你已经可以看到会发生什么。这里第一项是好东西,右边第二项是坏东西,它们会互相平衡。
如果我取这个的梯度,我认为这是 DPO 最直观的形式,至少对我来说是:对于每一对你标注过的 pair,我要增加赢的那个例子的似然,降低输的那个例子的似然。我会以某种方式缩放步长,缩放到我的隐含奖励模型错得有多厉害。我的模型是否已经给赢的那个分配了很高奖励?如果是,我就走小步。但如果我很错,我说这两个几乎相等,概率相同,那在这种情况下,我会走大得多的步长。所以基于概率差异,我会在这个差分 log 概率目标上取更大或更小的步长。希望这个梯度目标的作用对大家来说很清楚。
DPO 实际上比 PPO 简单得多,因为我只是在取梯度。我们都知道如何用标准流程做这个。我认为好的一点是它确实效果合理。有一阵子人们非常痴迷于 DPO 是否比 PPO 好,或反过来。我认为现在的答案也许是,除非你在前沿训练最好的模型,否则不太重要。DPO 相当好。对 LLaMA 够好,对我也够好。
如果你打开 LLaMA 技术报告,你会发现他们基本上有一个很好的外循环训练:他们有一个模型,SFT 它,做 DPO,然后用那个 DPO 模型生成候选,做拒绝采样,再重复这个过程。所以上面有一个外循环。但基本上,Llama 的核心 RLHF 原语是 DPO。
之后这些年,有很多不同的 DPO 变体。有 SimPO,基本上改变权重。所以不用 pi_ref,而用 y_l normalizer。还有长度归一化 DPO,按长度归一化,以避免似乎出现的某些长度攻击问题。但真的,这些变体可能看起来都不太重要。
我要提的一件事,是我觉得非常有趣:这些结果非常依赖于实验设置的具体细节。所以即使 AI2,有一篇论文说,从 DPO 到 PPO 会得到更好结果。但后来他们又有一篇 Tulu2 论文说,实际上,如果你把 DPO 做对,可以比 PPO 更好。所以取决于你如何执行,一个可能比另一个好。我肯定你们读深度学习论文时也有过经验,结果非常脆弱。所以也许所有这一切的 takeaway 是:这些 DPO 变体实际上已经足够接近正确的东西,在很多情况下能给你相当好的性能。核心想法——朝正确方向做梯度步骤,从坏东西做负梯度步骤——只要你把步长设对,就工作得相当好。
RLHF 的陷阱:过优化、模式崩溃与校准
我会用最后几页讲 RLHF 中要注意的事。其中一个要注意的是过优化(over-optimization)。这也许是最大的问题之一。也给一点历史背景:InstructGPT 出来时,人们非常兴奋。我认为当时有一个非常真实的问题:我们能不能通过 RLHF 一路走到超级智能系统之类的?也许可以,只要收集足够多的赞和踩。事实证明这其实相当有挑战性。
因为你发现,如果你真的猛推 RLHF 过程,你会开始过拟合到学到的奖励模型。所以我讲的 KL 正则项在很多情况下真的很关键,它防止你的优化过程过拟合奖励模型,至少如果你的优化过程非常强的话。
另一件事是模型崩溃(mode collapse)。人们很多次看到 RL 模型多样性少得多。它们集中在少数可能输出上。这连接回我之前说的:RLHF 模型真的不再建模一个有内在多样性的分布。它是一个策略,只要得到好奖励就可以崩溃。这是近年 RLHF 模型真正挣扎的另一件事。
实际上我要跳过这个,因为时间到了。我认为这个熵和模式崩溃的事情,即使今天也相当重要。GPT-4 时代,实际上是 OpenAI 放出的少数图之一,他们说,我们还有一些开放问题。其中一个开放问题是,我们做 RLHF 后模型没有校准,你可以在这张图里看到。我不认为有人真正解决了。Anthropic 的人也说过,它自然就是不校准的。你有时可以重新校准,但不总是。这在下一次讲 RLVR 时会变得非常重要,那里熵和探索实际上对模型探索所有可能解、在一些非常难的问题上取得进展非常关键。
总结与下讲预告
把所有东西放在一起:RLHF 数据收集也非常难。我认为后训练的一部分特点就是它非常复杂、混乱,因为很多工作是要获得好数据。而获得好数据总是非常困难。RLHF 算法相当复杂。PPO 尤其难。我下次会多讲一点。幸运的是,我们也有简单变体,叫 GRPO。它工作得相当好。这就是你们作业要做的。但这也是一个近期有很多发展的地方。
最后,我认为 RLHF 的一个大问题是过优化。向下一讲的过渡将是:有没有一些奖励,让我们不会过优化,或者我们只要堆算力,模型性能就继续单调变好?这就是为什么人们所说的 RLVR 如此有影响力。谢谢。周四见。