论文链接:InstructGPT
1. 摘要
把语言模型变大并不意味着会让模型更好的理解用户意图,例如大的语言模型会生成一些不真实、有害的、没有帮助的输出给用户,换句话说,这些模型并没有和用户的意图对齐(aligned)。在这篇论文中我们展示了通过使用用户反馈来微调模型的方法,从而使得语言模型在一系列任务上与用户意图对齐。首先通过人工撰写和OpenAI API两种方式收集问题(prompts),然后人工来写这些问题的答案,从而构建成一个数据集,再使用这些数据集对GPT3进行有监督的微调;我们又通过对模型的输出进行(人工)排序构建一个数据集,在这个数据集上,我们从人类反馈中通过强化学习进一步微调这个有监督模型,我们把最终得到的模型称之为InstructGPT。尽管InstructGPT的参数是GPT3的1/100,但是在我们(收集的)问题上通过人类评估发现,只有1.3B参数的instructGPT模型输出比有175B参数的GPT3模型输出更好,此外InstructGPT在真实性和降低有害输出上都有所改善,并且在公开NLP数据集上的表现也不逊色。虽然InstructGPT仍然会犯简单的错误,但是我们的结果证明,使用人类反馈来微调语言模型从而使得模型与人类意图对齐是一个正确的方向。
2. 导论
2.1 背景
通过给定(当前)任务的一些样本作为输入,大语言模型可以通过prompted的方式去执行一系列NLP任务,然而这些模型经常表现出意料之外的结果,例如捏造事实,生成有偏见或有害的内容,或者完全不服从用户的指令。这是因为当前很多大模型的训练目标是在来自网络上爬取的数据集上预测下一个字,这完全与“根据用户指令生成有帮助的安全的内容”的目标不符。因此我们认为语言模型的目标并没有对齐(misaligned)。对于那些被部署在成千上万的应用上的语言模型,避免这种意料之外的行为尤为重要。
我们最终目的希望语言模型是有帮助的(语言模型应该帮助用户解决任务),真诚的(语言模型不应该编造信息、误导用户)、无害的(语言模型不应该对人或社会造成生理上、心理上或社会危害)
2.2 方法
文章专注于通过微调的方式去对齐语言模型,具体来说,就是从人类反馈中使用强化学习去微调GPT3,使其遵循一系列的手写指令。这个技术使用人类偏好作为奖励信号去微调我们的模型。具体方法如下图所示
(1)首先基于外包人员的测试表现,选择了40个外包去标注数据
(2)基于人openAI API和人工两种方式获取一些问题,让外包写这些问题的期望答案,从而构建成一个数据集,然后使用这个数据集去有监督的训练GPT3作为baseline
(3)通过API获取更多的问题集,让人工对模型对这些问题的输出进行排序,从而又构建了一个数据集B
(4)在数据集B上训练一个奖励模型(RM)去预测哪个模型的输出是更符合人类期望的
(5)使用奖励模型作为奖励函数去微调baseline模型,使用PPO算法最大化奖励
(6)基于GPT-3模型架构,通过上述方式训练得到的模型就是InstructGPT
图片解释
- step1: 假设问题为
Q1: explain the moon landing to a six year old
人工写的答案为A1: some people want to the moon...
;以Q1为prompt输入到GPT-3中,A1为label进行有监督的fine tunne GPT-3模型 - step2:通过openAI API选择一个更大的问题集,然后将问题依次送入到GPT-3中,GPT-3会输出多个答案,为什么有多个答案?可参考之前的文章自然语言生成中解码算法:beam-search、topk-topp、基于kmeans的聚类: GPT-3输出是单词表中各个词的概论分布,通过解码算法可得到每条路径的概率;一个问题得到多个答案后,通过人工对这些答案进行排序,然后根据这些排序的问题答案对来训练一个奖励模型,输入问题及其答案,输出一个得分,最终要求奖励模型输出各个问题答案对的得分排序和人工标注的排序相同
- step3:使用强化学习微调step1训练的GPT-3模型:输入一个问题,GPT3生成一个答案,将该问题答案对送入到step2训练好的奖励模型中得到一个得分,根据得分来优化GPT3模型使得GPT3模型输出的答案得分尽可能高
思考
(1)是否一定需要step2强化学习这一步?
理论上如果step1这一步人工标注了足够多的数据,不需要强化学习,直接根据标注数据来训练应该是也能达到同样效果。但是这里考虑到step1中给定问题要求标注者写出所有的答案这种标注方式太难,标注成本很高,而step2这种判别式的标注方法显然简单很多,标注效率会大大提高,即同样的标注成本能够标注更多的数据,所以通过强化学习可以起到节约标注成本的作用。
2.3 发现
作者主要训练了三种大小的模型(1.3B, 6B, 175B三种模型参数量),且都是基于GPT-3模型架构。评估模型的方式是让外包在测试集上评价模型的输出结果,主要得到如下发现:
(1)外包都认为InstructGPT输出结果比GPT-3好:1.3B的InstructGPT效果要比175B的GPT3的结果好
(2)相比GPT-3,InstructGPT在真实性上表现更好
(3)相比GPT-3,InstructGPT在减少生成有害信息上效果更好,但是对于偏见方面,并无啥提升
(4)在对话生成上InstructGPT有明显提升,在NLP公开数据集上表现退化很小
(5)即使没有参与到标注训练数据的外包也认为InstructGPT生成的结果要比GPT3结果好(每个人对问题的答案好坏有主观性,参与到训练集标注的外包可能在某些方面有“偏见”,为了减少这种偏见,因此初步有请了没有参与到训练集标注的外包来测试结果)
(6)微调对数据比较敏感:在人工标注数据上微调GPT3vs在公开数据集上微调GPT3,在来自API的问题集上测试,表现还是前者更强
(7)模型有一定的泛化性,即使针对很少出现在微调数据集中的instruction也可以回答很好
(8)InstructGPT仍然会范一些简单的错误
3. 方法及实验细节
3.1 数据集
(1)通过如下三种方式让外包写promts(这些promts一般不会出现在GPT3 API中),来训练初版的InstructGPT
- Plain: 仅仅让外包想任意的任务,且这些任务具有足够的多样性
- Few-shot:让外包想一些instruction以及针对这个指令的多个query/response pair‘
- User-based:让外包根据openAI API waitlist中的用例想出相对应的问题
(2)基于以上初版InstructGPT制作了一个Playground让用户使用,因此训练Instruct GPT的prompt数据集主要来自基于初版InstructGPT的openAI API
基于以上prompts制作了三个不同的数据集用于微调过程:1)SFT数据集 13K --> 训练SFT模型 2)奖励模型数据集 33K -->训练RM 3) PPO数据集(无任何人工label)31k --> RLHF训练
(每个阶段数据集的构建可参考2.2章节)
下图展示了不同类型prompts的分布,以及一些具体prompts的展示
总结来说数据集构建的过程为:人工写一些prompts–>构建初版InstructGPT – > 从初版InstructGPT API中选择更多的 prompts --> 人工写prompts的答案及排序 – > RLHF训练
3.2 模型
模型的backbone是GPT-3 , 然后使用如下三种方式训练
(1)Supervised fine-tuning (SFT):将GPT-3在他们人工标注的prompt和答案上再次训练一次,总共跑了16个epoch,实际在跑完一个epoch后就过拟合了,但是作者发现跑更多的epoch,过拟合后对后面的奖励模型已经人工评估都有好处
(2)Reward modeling (RM).:将上述的SFT模型的最后一层(不是embedding的那一层)去掉,(接上一个线性投影层);输入prompt和对应的答案,输出一个标量得分,此处作者仅仅使用了一个6B的奖励模型,作者发现175B的大模型训练不稳定,因此不适合作为奖励函数
而损失函数作者使用的是一个pairwise的ranking loss,具体形式如下:
所谓pairwise即:对一个prompt x x x ,取其一对答案 y w y_w yw 和 y l y_l yl ,假设 y w y_w yw 的排序要比 y l y_l yl 高,分别分别计算 x x x和 y w y_w yw、 x x x和 y l y_l yl的奖励得分 s w = r θ ( x , y w ) s_w = r_\theta(x,y_w) sw=rθ(x,yw) 和 s l = r θ ( x , y l ) s_l=r_\theta(x, y_l) sl=rθ(x,yl);由于 y w y_w yw 的排序要比 y l y_l yl 高,因此 s w s_w sw要大于 s l s_l sl,且期望 s w − s l s_w-s_l sw−sl越大越好,此处 σ \sigma σ是sigmoid函数, 前面加上了符号及log,因此希望整个式子越小越好
人工标注的时候是对一个prompt的K个答案进行排序,这里K选择了9,相较于K=4有如下优点:
- 标注效率提升,排序的关键的对问题的理解,如果外包理解了问题,那么答案数量扩大一倍,而所花的标注时间并不一定会扩大一倍
- 计算效率提升,由于是两两比较,因此共有 C 2 K C{_2}^{K} C2K个pair,作者将一个prompt对应的 C 2 K C{_2}^{K} C2K个pair作为一个batch,这样只需前向输入到奖励模型K次,就能计算 C 2 K C{_2}^{K} C2K个数据的损失,显然K越大越划得来
(3)Reinforcement learning (RL):作者采用强化学习中的PPO算法来优化SFT模型,PPO算法核心就是下式:
强化学习中模型称之为policy,上式中 π ϕ R L \pi_\phi^{\mathrm{RL}} πϕRL就是当前要学习的模型, ϕ \phi ϕ是他的参数,初始化为第一步训练的SFT模型, 将括号中的式子拆开看,第一项就是给定一个prompt x x x, π ϕ R L \pi_\phi^{\mathrm{RL}} πϕRL会输出一个 y y y,然后奖励函数会给 x x x和 y y y打一个分,然后更新参数 ϕ \phi ϕ使得模型输出更符合人类的期望;第二项是一个正则项,通过KL散度的形式,希望当前训练的模型仍然能尽量与SFT一致,防止奖励模型过度优化使得模型跑的太偏;这两项加起来就是PPO模型。最后一项 γ E x ∼ D pretrain [ log ( π ϕ R L ( x ) ) ] \gamma E_{x \sim D_{\text {pretrain }}}\left[\log \left(\pi_\phi^{\mathrm{RL}}(x)\right)\right] γEx∼Dpretrain [log(πϕRL(x))]是为了防止模型过度学习当前的排序任务,从而导致遗忘了以前预训练的知识,此处 D p r e t r a i n D_{pretrain} Dpretrain是预训练数据集,即从预训练数据集中抽样出 x x x一起训练,但 γ \gamma γ 不为0时这个称为PPO-ptx模型,简单来说就是PPO目标函数+原始GPT3目标函数加在一起。
3.3 实验结果
实验结果如下图所示,其中GPT是指初始的GPT-3模型,GPT(prompted)使用精心设计的prompt来训练的GPT-3;SFT使用人工标注的demo训练的GPT-3;PPO使用强化学习训练的InstructGPT;PPO-ptx在PPO的基础上增加了预训GPT-3的目标函数;如论文所述,1.3B的InstructGPT比175B的GPT-3效果还要好
总结
InstructGPT就是在GPT-3的再训练中增加了人工标注数据,将标注数据与强化学习相结合,使得模型的生成结果更符合人类的期望,也即论文中的提到的使模型更有帮助性,同时由于人工标注的数据再真实性、无害性方面有保证,因此一定程度上帮助模型生成具有真实性和无害性的内容