前言
自从我那篇BERT通俗笔记一经发布,然后就不断改、不断找人寻求反馈、不断改,其中一位朋友倪老师(之前我司NLP高级班学员现课程助教老师之一)在谬赞BERT笔记无懈可击的同时,给我建议到,“后面估计可以尝试尝试在BERT的基础上,讲一讲prompt学习了”,然后我看了下prompt学习,一看果然牛..
再然后,当我还在各种改BERT笔记的时候,12月初突然出来了一个ChatGPT刷爆朋友圈,即便很多之前不接触AI的朋友也在问ChatGPT这种类似聊天机器人却远胜一般聊天机器人各种问题(上一次出现这种盛况的还是16年的AlphaGo)。
据我观察,大家问ChatGPT的问题千奇百怪,比如给他任意一段代码,要求它解释或添加对应的注释(这可不是单纯的翻译问题,需要有类似人的提炼、概括、总结能力),甚至有人让其根据要求排查代码bug,要知道此前debug想寻求帮助
- 要么问人(问熟人用社交软件,问陌生人则类似那种问答网站,持续问一般得付费,毕竟没人乐意持续免费答疑大量技术难题)
- 要么Google搜有没人遇到类似的问题(但别人遇到的问题很难与你的百分百一致)
所以ChatGPT就相当于你写代码或各类问题的私人顾问,而这个私人顾问能瞬间、精准理解你的意图,不会让你像用以前那种聊天机器人经常觉得智障甚至对牛弹琴,加之其背后依托的是人类级百科全书式的资料库,所以有人惊呼:ChatGPT会不会替代Google这类搜索引擎。
虽然大部分技术者对待ChatGPT还是比较冷静的,毕竟它给的答案不像权威技术专家那样具备足够的公信力,也不像Google给出来源从而不能比较好的验证其正确程度(注意我这里的措辞:“不能比较好的”、“正确程度”,^_^),但最近遇到的几件事改变了我的一些看法
- 这两天我刷到一条新闻:微软欲用 ChatGPT 扶必应“上位”,对抗 Google,导致即便很多技术从业者也不一定淡定了
- ChatGPT直接让其所在的公司OpenAI估值翻倍,而我司七月在线的最新一期NLP大课,NLP11也加入了ChatGPT的原理解析
- 目前关于ChatGPT中文的资料里,真正能让人一看就懂的非常非常少,当少数文章具备比较好的可读性之后,你又会发现一旦涉及算法细节就千篇一律的泛泛而谈,如果不是泛泛而谈的,则更多堆砌概念和公式
总之中文资料里,可能因为instructGPT/ChatGPT刚出来不久的缘故,兼顾可读性和细节性的文章少的可怜
考虑到ChatGPT非一蹴而就,而是经过了各个前置技术的发展、迭代、结合而成,故逐一阐述
- 2017年之前早已有之的一些数学/AI/RL等基础技术,比如微积分、概率统计、最优化、策略梯度、TRPO算法(2015年提出)
- 2017年OpenAI联合DeepMind首次正式提出的RLHF,试图解决的问题是,在奖励函数不够明确的情况下,通过基于人类对事物比较的偏好而非绝对奖励值训练奖励函数,最后通过TRPO算法迭代策略
- 2017年的OpenAI团队提出的对TRPO算法的改进:PPO算法
关于RL所需的微积分/概率统计基础修订在了《概率统计极简入门:通俗理解微积分/期望方差/正态分布前世今生(23修订版)》
关于RL所需的最优化基础修订在了《一文通透优化算法:从梯度下降、SGD到牛顿法、共轭梯度(23修订版)》
关于RL、策略梯度、TRPO、PPO则写在了此文《RL极简入门:通俗理解MDP、DP MC TC和值函数、策略梯度、PPO》
且在这篇RL极简入门笔记之前,99%的文章都不会把PPO算法从头推到尾,该文把PPO从零推到尾,按照“RL-策略梯度-重要性采样(重要性权重)-增加基线(避免奖励总为正)-TRPO(加进KL散度约束)-PPO(解决TRPO计算量大的问题)”的顺序逐步介绍每一步推导
至于RLHF,后续会完善在本文里
- 2017的Transformer/Self-Attention
- 2018年的GPT(Generative Pre-trained Transformer),其关键构成是基于Transformer-Decoder的Masked Self-Attention
- 2019年的融合prompt learning的GPT2
- 2020年的GPT3,且你可能没想到的是,这一年OpenAI已经开始研究GPT3与RLHF的结合了,且此时用的策略优化方法为PPO
关于transformer/self-attention,可以看下上篇《BERT通俗笔记:从Word2Vec/Transformer逐步理解到BERT》,本文后续也会再完善下自注意力部分
关于prompt learning,本文后续会完善
- 2022年初的instructGPT:GPT3 + RLHF + PPO
- 2022年底的ChatGPT:GPT3.5(基于Transformer-Decoder的Masked Self-Attention且融合prompt learning) + RLHF + PPO
如你所见,自从1.6日开始写ChatGPT笔记,1.15日发布本文,但为把ChatGPT背后所涉及的关键技术阐述细致、透彻,故本文越写越长,长到最后成了一个系列,有的内容抽离出去独立成文,有的还待后续不断完善,预计2月底完全成型,总的修改、改进、完善思路是
- 第一阶段,先拆解ChatGPT所涉及的工作量大的关键技术,比如RL,前后涉及RL数学基础 PPO RLHF
- 第二阶段,完善工作量小的关键技术,因为上篇笔记里已写了transformer,故再完善下自注意力机制的介绍,以及prompt learning
- 第三阶段,加上工程细节,ChatGPT系列就完全成型了
第一部分 从RL、策略梯度到TRPO、PPO算法、RLHF
再次强调说明下,本第一部分在23年2.10日有个重要修改
- 2.10日之前,考虑到本文的主旨核心ChatGPT用到了RLHF和PPO,所以本文的第一部分从强化学习讲到PPO算法,毕竟虽然只是想重点介绍下PPO,但写到最后还是把PPO所有相关的前置知识都细致介绍了个遍,不然,总感觉有细节没交待而不够透彻
- 2.10日之后,又考虑到有些朋友可能对RL细节有所了解,或者更多希望整体了解ChatGPT整体架构而暂不细究其所用的策略迭代算法PPO的前置技术、RL细节
综上,为兼顾两者,且加之为避免本文篇幅过长而影响完读率,故把下面原先第一部分的大部分内容抽取出来放到了新一篇RL笔记里进一步细致阐述:RL极简入门:通俗理解MDP、DP MC TC和值函数、策略梯度、PPO
第一部分 从什么是RL与MRP、MDP
1.1 入门强化学习所需掌握的基本概念
- 1.1.1 什么是强化学习:感知状态-依据策略执行动作-得到奖励
- 1.1.2 RL与监督学习的区别和RL方法的分类
1.2 什么是马尔科夫决策过程
- 1.2.1 MDP的前置知识:随机过程、马尔可夫过程、马尔可夫奖励
- 1.2.2 马尔可夫决策过程(MDP):马尔可夫奖励(MRP) + 智能体动作因素
第二部分 三大表格求解法:动态规划、蒙特卡洛、时序差分
2.1 动态规划法
2.2 蒙特卡洛法
2.3 时序差分法
第三部分 近似求解法之值函数近似法
第四部分 近似求解法之策略梯度法:TRPO、PPO算法
4.1 策略梯度与其两个问题:采样效率低下与步长难以确定
- 4.1.1 什么是策略梯度和梯度计算/更新的流程
- 4.1.2 避免采样的数据仅能用一次:重要性采样(为采样q解决p从而增加重要性权重)
- 4.1.3 实现技巧:为避免奖励总为正增加基线——优势函数
- 4.1.4 基于信任区域的TRPO:加进KL散度解决两个分布相差大或步长难以确定的问题
4.2 近端策略优化PPO:解决TRPO的计算量大的问题
4.2.1 什么是近端策略优化PPO与PPO-penalty
如上所述,PPO算法是针对TRPO计算量的大的问题提出来的,正因为PPO基于TROP的基础上改进,故PPO也解决了策略梯度不好确定学习率Learning rate (或步长Step size) 的问题。毕竟通过上文,我们已经得知
- 如果 step size 过大, 学出来的 Policy 会一直乱动,不会收敛;但如果 Step Size 太小,想完成训练,我们会等到地老天荒
- 而PPO 利用 New Policy 和 Old Policy 的比例,限制了 New Policy 的更新幅度,让策略梯度对稍微大点的 Step size 不那么敏感
具体做法是,PPO算法有两个主要的变种:近端策略优化惩罚(PPO-penalty)和近端策略优化裁剪(PPO-clip),其中PPO-penalty和TRPO一样也用上了KL散度约束。
近端策略优化惩罚PPO-penalty的流程如下
-
首先,明确目标函数,通过上节的内容,可知咱们需要优化,让其最大化
-
接下来,先初始化一个策略的参数,在每一个迭代里面,我们用前一个训练的迭代得到的actor的参数与环境交互,采样到大量状态-动作对, 根据交互的结果,估测
- 由于目标函数牵涉到重要性采样,而在做重要性采样的时候,不能与相差太多,所以需要在训练的时候加个约束,这个约束就好像正则化的项一样,是 与 输出动作的 KL散度,用于衡量 与 的相似程度,我们希望在训练的过程中,学习出的 与 越相似越好
所以需要最后使用 PPO 的优化公式:
当然,也可以把上述那两个公式合二为一『如此可以更直观的看出,PPO-penalty把KL散度约束作为惩罚项放在了目标函数中(可用梯度上升的方法去最大化它),此举相对TRPO减少了计算量』
上述流程有一个细节并没有讲到,即是怎么取值的呢,事实上,是可以动态调整的,故称之为自适应KL惩罚(adaptive KL penalty),具体而言
- 先设一个可以接受的 KL 散度的最大值
假设优化完以后,KL 散度值太大导致,意味着 与差距过大(即学习率/步长过大),也就代表后面惩罚的项惩罚效果太弱而没有发挥作用,故增大惩罚把增大 - 再设一个 KL 散度的最小值
如果优化完以后,KL散度值比最小值还要小导致,意味着 与 差距过小,也就代表后面这一项的惩罚效果太强了,我们怕它只优化后一项,使与 一样,这不是我们想要的,所以减小惩罚即减小
总之,近端策略优化惩罚可表示为
4.2.2 PPO算法的另一个变种:近端策略优化裁剪PPO-clip
如果觉得计算 KL散度很复杂,则还有一个 PPO2算法,即近端策略优化裁剪PPO-clip。近端策略优化裁剪的目标函数里面没有 KL 散度,其要最大化的目标函数为(easy RL上用代替,还有的书用代替,为上下文统一需要,本笔记的文字部分统一用)
整个目标函数在这个大括号里有两部分,最终对比两部分那部分更小,就取哪部分的值,这么做的本质目标就是为了让和可以尽可能接近,不致差距太大。
换言之,这个裁剪算法和KL散度约束所要做的事情本质上是一样的,都是为了让两个分布之间的差距不致过大,但裁剪算法相对好实现,别看看起来复杂,其实代码很好写
// ratios即为重要性权重,exp代表求期望,括号里的old_log_probs代表用于与环境交互的旧策略
ratios = torch.exp(log_probs - old_log_probs)
// 分别用sur_1、sur_2来计算公式的两部分
// 第一部分是重要性权重乘以优势函数
sur_1 = ratios * advs
// 第二部分是具体的裁剪过程
sur_2 = torch.clamp(ratios, 1 - clip_eps, 1 + clip_eps) * advs
// 最终看谁更小则取谁
clip_loss = -torch.min(sur_1,sur_2).mean()
回到公式,公式的第一部分我们已经见过了,好理解,咱们来重点分析公式的第二部分
- 首先是括号里的部分,如果用一句话简要阐述下其核心含义就是:如果和之间的概率比落在范围和之外,将被剪裁,使得其值最小不小于,最大不大于
- 然后是括号外乘以,如果大于0,则说明这是好动作,需要增大,但最大不能超过;如果小于0,则说明该动作不是好动作,需要减小,但最小不能小过
最后把公式的两个部分综合起来,针对整个目标函数
- 如果大于0且大于
则相当于第二部分是,和第一部分对比
取更小值当然是的截断值:- 如果大于0且小于
则相当于第二部分是,和第一部分对比
取更小值当然是原函数值:反之,如果小于0,则最终目标函数的取值为了更小则和大于0时反过来,毕竟加了个负号自然一切就不同了,为方便初学者一目了然,咱们还是把计算过程列出来,即
- 如果小于0且大于
则相当于第二部分是,和第一部分对比
取更小值当然是原函数的值:- 如果小于0且小于
则相当于第二部分是,和第一部分对比
取更小值当然是的截断值:
4.3 模仿学习(逆强化学习)思路下的RLHF:从人类反馈中学习
虽然RL理论上虽不需要大量标注数据,但实际上它所需求的reward会存在缺陷:
-
比如游戏AI中,reward的制定非常困难,可能要制定成百上千条游戏规则,这并不比标注大量数据来得容易,又比如自动驾驶的多步决策(sequential decision)场景中,学习器很难频繁地获得reward,容易累计误差导致一些严重的事故
-
再比如聊天机器人方面,不好定义什么是好的对话、什么是不好的对话,当然,对此可以收集很多人类的对话当做范例,如此,模仿学习思路下的从人来反馈中学习(对应论文为:Deep Reinforcement Learning from Human Preferences 2017,简称RLHF)应运而生,试图解决的问题是,在奖励函数不够明确的情况下,通过基于人类对事物比较的偏好而非绝对奖励值训练奖励函数
模仿学习的思路是不让模型在人类制定的规则下自己学习,而是让模型模仿人类的行为。而逆强化学习就是模仿学习的其中一种,何谓逆强化学习呢?
- 原来的强化学习里,有Environment和Reward Model(由奖励函数推出什么样的策略/动作是最好的),但逆强化学习没有奖励函数,只有一些人类/专家的示范,怎么办呢
- 可以通过人类标注数据训练得到Reward Model(相当于有了人类标注数据,则相信它是不错的,然后反推人类因为什么样的奖励函数才会采取这些行为)
- 有了奖励函数之后,就可以使用一般的强化学习的方法去找出最优策略/动作
第二部分 从GPT/GPT2到GPT3:微调到prompt学习的过渡
2.1 GPT:基于Transformer Decoder预训练 + 微调/Finetune
在上一篇BERT笔记中,我们已经了解到:GPT是“Generative Pre-Training”的简称,从名字看其含义是指的生成式的预训练。
GPT也采用两阶段过程,第一个阶段是利用语言模型进行预训练,第二阶段通过Fine-tuning的模式解决下游任务。
下图展示了GPT的预训练过程,其实和ELMO是类似的,主要不同在于两点:
- 首先,特征抽取器不是用的LSTM,而是用的Transformer,毕竟它的特征抽取能力要强于LSTM,这个选择很明显是很明智的
- 其次,GPT的预训练虽然仍然是以语言模型作为目标任务,但是采用的是单向的语言模型
必须重点强调的是,作为侧重生成式任务的GPT选择了Transformer Decoder部分作为核心架构(Decoder具备文本生成能力,故GPT在Transformer Decoder的基础上搭建语言模型Transformer Block:前馈神经网络feed forward + 自注意力机制self attention + 求和与归一化的前置LN层 + 残差),其中的关键便是基于Transformer-Decoder的Masked Self-Attention
至于所谓Masked Self-Attention就是在处理当前词的时候看不到后面的词。举个例子,处理“it”的时候,注意力机制看不到“it”后面的词,但会关注到“it”前面词中的“a robot”,继而注意力会计算三个词“it”、“a”、“robot”的向量及其attention分数的加权和
更多细节可以看下上篇BERT笔记(特别是此前还不了解Transformer的),或此文:图解注意力机制
2.2 GPT2承1启3:舍弃微调,直接干zero-short learning
很多同学一看到DL,便会想到大数据,而数据量一大,还用CPU处理的话很可能训练一个小任务都得半天,而如果用GPU跑,可能一两分钟就出来了。于此,在深度学习大火的那几年,特别是AlphaGo出来的16年起,我司七月在线便分别为VIP、AI系统大课、在职提升大课、求职/论文/申博/留学1V1辅导提供GPU云平台进行实战训练。
然很多情况下,高质量数据的获取是比较困难的,比如医疗数据,那怎么办呢?既然暂时改变不了高质量数据匮乏的现状,那就改变模型! 如此,让模型能从少量样本中学习规律并具备推理能力便显得至关重要了。
最终,针对小样本/零样本的N-shotLearning应运而生,分为如下三种
- Zero-shot Learning (零样本学习),是指在没有任何训练样本进行微调训练的情况下,让预训练语言模型完成特定任务
- One shot Learning (单样本学习),顾名思义,是指在一个训练样本进行微调训练的情况下,预训练语言模型完成特定任务
- Few-shot Learning (少样本或小样本学习),类似的,是指在只有少量样本进行微调训练的情况下,预训练语言模型完成特定任务
而GPT-2不再使用二阶段训练模式(预训练+微调),而是彻底放弃了微调阶段,仅通过大规模多领域的数据预训练,让模型在Zero-shot Learming的设置下自己学会解决多任务的问题,而且效果还不错(虽然GPT2通过Zero-shot Learming在有些任务的表现上尚且还不如SOTA模型,但基本超越了一些简单模型,说明潜力巨大),你说神不神奇?
而GPT2在GPT1的基础上规模更大、模型更复杂。至于小样本学习的具体应用可以看下参考文献8。
2.3 GPT3:开启NLP新范式prompt从而实现小样本学习
GPT3简单来说,就是规模大、有钱多金、效果出奇好,具体而言,它的参数规模达到了1750亿,并且使用45TB数据进行训练,其预训练任务就是“句子接龙”,给定前文持续预测下一个字,而且只要有少量的文本数据就能作为模型的训练数据。
总之,只需将自然语言的提示信息(prompt)和任务示例(demonstration)作为上下文输入给GPT-3,它就可以在零样本或小样本的情况下执行任何NLP任务,包括所谓的完形填空任务,比如举个例子
比如,假如我要判断“我喜欢这个电影" 这句话的情感(“正面" 或者 "负面"),原有的任务形式是把他看成一个分类问题
输入:我喜欢这个电影
输出:“正面" 或者 "负面"
而如果用Prompt Learning去解决的话,任务可以变成“完形填空",
输入:我喜欢这个电影,整体上来看,这是一个 __ 的电影
输出:“有趣的" 或者 "无聊的"
言外之意即是,即便是面对完形填空似的任务,也能很好的解决
正因为GPT3首次把模型的规模带到了千亿级别,开辟了大模型赛道,其次也为NLP带来了一种新的范式prompt,prompt为GPT3带来了0样本、单样本、小样本的学习能力。而且更为关键的是,在小样本的情况下,其性能表现一度超越SOTA模型。
可想而知,prompt learning在GPT3中起到了一种极其关键的作用。所谓Prompt就是提示的意思。
例如有人忘记了某个事情,我们给予特定的提示,他就可以想起来,例如当有人说:白日依山尽,大家自然而然地会想起来下一句诗:黄河入海流。
亦或者,搜索引擎,可以根据我们的输入,进行输出的提示:
那么在NLP中 Prompt 代表的是什么呢? prompt 就是给预训练语言模型的一个线索/提示,帮助它可以更好的理解人类的问题,这一创举揭开了GPT3在对话生成领域火力全开的序幕。
为形象描述,举一个GPT-3在只有少量样本下的机器翻译使用范例,如下图
- 图中右侧是普通模型微调的过程,模型通过大量训练预料进行训练,然后基于特定的任务数据进行梯度迭代更新(gradient update),训练至收敛后的模型才具备良好的翻译能力
- 图中左侧是GPT3分别在0样本(只给出任务描述)、单样本(只给出任务描述+一个翻译样本)、小样本(给出任务描述+少量样本)的情况下所展示出的能力,即便是小样本的情况下,也远少于微调过程所需要的训练数据
说白了,就是在同等训练数据下,GPT的性能远高于微调模式的SOTA模型
至此,我们对比下Fine-tuning和prompt learning的区别(从Pre-train、Fine-tune到Pre-train、Prompt、Predict的过程)
- Fine-tuning中:是预训练语言模型“迁就“各种下游任务。具体体现就是通过引入各种辅助任务loss,将其添加到预训练模型中,然后继续pre-training,以便让其更加适配下游任务。总之,这个过程中,预训练语言模型做出了更多的牺牲
- Prompting中,是各种下游任务“迁就“预训练语言模型。我们需要对不同任务进行重构,使得它达到适配预训练语言模型的效果。总之,这个过程中,是下游任务做出了更多的牺牲
2.4 GPT3.5:爆火ChatGPT所基于的GPT模型
考虑到下文要讲的instructGPT和ChatGPT分别预计GPT3、GPT3.5,所以本文还得再讲下GPT3.5相比GPT3的差别。
粗略的讲,GPT-3.5 模型使用与 GPT-3 相同的预训练数据集,但进行了额外的微调,从而更擅长以下两点
- 更擅长上下文学习、对话
- 可以生成更加符合人类期待的反馈(或者说模型与人类对齐),例如:零样本问答、生成安全和公正的对话回复、拒绝超出模型它知识范围的问题
第三部分 instructGPT/ChatGPT的训练三阶段到多轮对话应用
3.1 InstructGPT训练三阶段
3.1.1 ChatGPT的前身之InstructGPT:基于RLHF手段微调的GPT
根据instructGPT的原始论文可知,InstructGPT的训练分为三个阶段(总体上结合了监督学习和强化学习,先是监督学习让GPT3有一个大致的微调方向,然后用RL中的PPO算法来更新微调过的GPT3的参数):
-
阶段1:利用人类的标注数据(demonstration data)去对GPT3进行有监督训练
首先,OpenAI是先设计了一个prompt dataset,里面有大量的提示样本,给出了各种各样的任务描述
其次,找了一个标注团队对这个prompt dataset进行标注(本质就是人工回答问题)
最后,用这个标注过的数据集微调GPT3,这个微调好的GPT3我们称之为SFT模型(监督微调,全称Supervised fine-tuning,简称SFT),具备了最基本的预测能力 -
阶段2:通过RLHF的思路训练奖励模型RM
把微调好的SFT模型去回答prompt dataset某个问题,然后通过收集4个不同的SFT输出而获取4个回答,接着人工对这4个回答的好坏进行标注且排序,排序的结果用来训练一个奖励模型RM,具体做法就是学习排序结果从而理解人类的偏好
值得一提的是,通过人类标注/排序的回答训练一个奖励模型还是有其背后深意的,因为自AlphaGo使得强化学习猛然进入大众视野以来,大部分对于强化学习的理论研究都将游戏作为主要实验平台,而强化学习理论上的推导看似逻辑通顺,但其最大的弱点在于基于人工评判的奖励Reward的获取,毕竟让实验人员守在电脑前对模型吐出来的结果不停地打分是不现实的,而instructGPT就是要解决这个问题
但通过人来标注/排序的结果训练出奖励模型之后怎么用呢,这就是训练阶段3要做的事情 -
阶段3:通过训练好的RM模型预测结果且通过PPO算法优化SFT模型策略
具体做法是,再次让SFT模型去回答prompt dataset某个问题,然后此时不再让人工评估好坏,而是让阶段2训练好的奖励模型去给SFT模型的预测结果进行打分排序
就这样,一个初始的语言模型SFT模型来生成文本,以及一个奖励模型(RM)来判断模型生成的文本是否优质(迎合人类偏好),然后不断生成、评估、优化,如此循环进行
此外,可能有读者疑问,InstructGPT为什么要做这样的改进,或者说它的创意点是什么?
- 事实上,这个改进思路,一方面是为了尽可能地对齐(Alignment)GPT的输出与对用户友好的语言逻辑,即微调出一个用户友好型GPT。以往的GPT训练,都是基于大量无标注的语料,这些语料通常收集自充斥大量“行话”、“黑话”的互联网中,这样训练出来的语言模型,它可能会有虚假的、恶意的或者有负面情绪等问题的输出,二方面,为了更好的理解人类的意图
- 因此,一个直接的思路就是通过人工干预微调GPT,使其输出对用户友好(避免乱说话),且更好的理解人类意图并和人类对话
所以,对InstructGPT的简单理解,可以是基于人类反馈的强化学习(RLHF)手段微调的GPT。
3.1.2 ChatGPT与InstructGPT的差别:基于GPT3还是GPT3.5微调
而通过OpenAI公布的ChatGPT训练图可知,ChatGPT的训练流程与InstructGPT是一致的,差异只在于
- InstructGPT是在GPT-3上做Fine-Tune
- ChatGPT是在GPT-3.5上做Fine-Tune(GPT3.5是OpenAI在2021年Q4训练的InstructGPT模型,在自动编写代码方面有较强的能力)
接下来,我们分别具体阐述上面的阶段2、阶段3。
3.1.3 instructGPT训练阶段2:如何对多个输出排序及如何训练RM模型
可能又有读者有疑问了,即instructGPT中,人类对模型的多个输出做个排序,为什么就能够提供监督信号,或者说在训练RM时如何怎么做到loss的梯度回传?
训练RM的核心是由人类对SFT生成的多个输出(基于同一个输入)进行排序,再用来训练RM。按照模仿学习的定义,直观上的理解可以是,RM在模仿人类对语句的排序思路,或者按照参考文献,即Google DeepMind和OpenAI团队2017年的论文《Deep reinforcement learning from human preferences》的说法是,模仿人类的偏好(Preference)。
那么到底是如何模仿的呢,或者说如何实现梯度回传?
这里我们代入一个场景,假设你向一个六岁小孩解释什么是登陆月球或什么是RL,如下图
- SFT生成了ABCD四个回答语句,然后人类对照着Prompt输入(即提问)来对4个回答的好坏做出合适的排序,如D>C>A=B
- 这里的排序实质是人类分别给4个回答语句打分,比如对D打了7分,C打了6分,A和B打了4分
- 为了让RM学到人类偏好(即排序),可以4个语句两两组合分别计算loss再相加取均值,即分别计算个即6个loss,具体的loss形式如下图:
针对这个损失函数需要逐一说明的是
- 这是一个常见的排序模型, 是RM模型,其中是提示Prompt输入,是SFT的预测输出(比如/),从而随机生成个输出(),然后针对个输出做次比较,比如4个输出有6次比较,9个输出有36次比较,是人类比较的数据集
有一点要提下的是,RLHF中的rank就好比监督学习中的弱标注——它并不提供直接的监督信号。但通过学习简单的排序,RM可以学到人类的偏好
为何是排序,而非直接打分呢,道理很简单,排序相比打分更容易接近客观事实,即不同的标注员,打分的偏好会有很大的差异(比如同样一段精彩的文本,有人认为可以打1.0,但有人认为只能打0.8),而这种差异就会导致出现大量的噪声样本,若改成排序,则不同标注员的排序一致性相比打分一致性就大大提升了
再打个比方,有一家冰箱工厂生产了好几种类型的冰箱,虽然这些客户中没有一个懂得如何造冰箱的(或者说他们不需要懂),但他们可以通过消费者的各类行为(点赞/评价、复购等),让厂商明白消费者对冰箱类型的“偏好”,从而引导冰箱厂商生产销量更好的冰箱
所以说,一个非专家的普通人类无法向一个6岁小孩解释清楚什么是RL,但他总能从多个备选答案判断出哪一个答案更好吧,毕竟选择比创造更容易啊!多么有创造性的解决方案 - 首先把你的问题和答案放进奖励函数r中,再把问题和也放进奖励函数中,然后分别输出,假定是语句组合对中相对打分更高的,所以两者一减(这里面使用的是交叉熵损失函数,奖励的差异表示一种应答比另一种应答更受人类标注者青睐的对数概率),我们希望相减的结果越大越好
- 最后通过Logitech函数变成一个loss函数,而因为loss函数最前面加了一个负号,相当于最大化上面第2点最后相减的结果(,) − (,)等于是最小化这个loss函数
如此,通过这种形式的梯度回传,RM逐渐学会了给D这类语句打高分,给A、B这类语句打低分,从而模仿到了人类偏好。到了这一步,不妨可以这么简单理解RLHF:所谓的人类反馈的强化学习,某种意义上来说,就是由人类的打分来充当reward。
3.1.4 instructGPT训练阶段3:如何通过PPO算法进一步优化策略模型
instructGPT原始论文中的目标函数如下图所示
大部分文章在分析这个目标函数时基本都是人云亦云、一带而过,在这里我们逐一拆接下这个目标函数,分为三个部分
- 第一部分是,相当于根据人类偏好的学习出来的RM模型
- 第二部分则是用KL散度对比RL学到的策略模型和原始策略模型的某种差距,一开始时,的初始化值就是,且咱们希望它俩之间的差距不至于太大
怎么避免它们相差太多呢?这就是PPO要做的事情(通过KL散度衡量两个分布之间的差距) 其中, KL奖励系数控制 KL 惩罚 - 第三部分是加在最后边的偏置项,其中, 是预训练分布,预训练损失系数控制预训练梯度的强度,且设置为0则称为PPO模型,否则称为PPO-ptx模型
之所以加最后的这个偏置项,是防止ChatGPT在RL的训练过程中过渡优化,从而避免过于放飞自我,通过某种刁钻的方式取悦人类,而不是老老实实地根据人类的问题给出正确答案
最终,迭代式的更新奖励模型RM和策略模型SFT,让奖励模型对模型输出质量的刻画愈加精确,并使得输出文本变得越来越符合人的认知
3.2 instructGPT/ChatGPT:如何更好的构建多轮对话能力
这里我们先从自然语言任务中最基本的语言模型简单说起。一个语言模型大概是说,当你给定前面的若干个词后,它会给你下一个词;而当你有了下一个词后,它会再给你接一个词,以此递推
这就好比我们使用手机输入法,你打出一些词句后,输入法会提供若干个候选词——这里的手机输入法其实就是一个语言模型。那么如何利用这个最基本的语言模型来建模多轮对话问题呢?
实际上,我们向ChatGPT提出的问题,可以看成一句话,或者说是下图的输入。然后我们可以将ChatGPT给出的答案,抽象成下图的输出。而ChatGPT这类语言模型,提供了若干个类似手机输入法的“候选句”,每个候选句对应的概率不一。所谓的语言模型的训练,其实就是让模型调整候选句对应的概率,使我们人类希望输出的候选句的概率尽可能大,而不希望输出的概率尽可能小
在强化学习中,我们有智能体/模型和环境交互这样的范式。但是在ChatGPT所使用的训练方式中,环境从某种意义上说被直接被奖励模型RM取代了,如下图
- 图中的状态State是之前提到的输入语句,而当智能体拿到一个,它给出的动作action其实是下一个单词。注意,GPT确实可以输出一整句话,但其实要完成这个最终的输出,需要做若干次如图所示的action
- 当环境(或RM)接收到它给出的单词后,会把这个单词放到已有的单词序列末尾,然后再把这个新的单词序列还给智能体,之后依次类推
- 打个比方,这里的智能体就是手机输入法,而环境就是使用输入法的用户。用户所做的事情,就是当输入法给出一系列候选词后,基于某种偏好选择某个词,然后让手机输入法再去猜下一个词,直到输入法把整个句子猜出来为止
这里我们明白了在语言模型场景下强化学习的状态和动作对应什么,那么奖励Reward呢?由于上文已经分析过instructGPT的目标函数了,这里就不再赘述,直接上图:
至此,还有一个细节问题,即奖赏函数是对整个输入语句和整个输出语句而言的,而我们又在之前讨论过,智能体是根据一个一个词来去拼凑出整个回答的。图中的奖赏函数只能给出完整回答的奖赏,那么在智能体生成回答的过程中,每个动作action给出的词对应的奖赏是什么呢?
这个细节在InstructGPT的论文中并没有给出。幸运的是,OpenAI团队在2020年9月的一篇论文《Learning from summarize from Human feedback》中的一个引脚标注给出了这个疑问的答案
论文里说,奖赏模型只在最终生成回答之后才给出奖赏,在中间的过程中是不给出奖赏的。在这里论文里没有使用回答一词,而是使用总结一词,因为它的任务是将一篇长文章进行归纳总结
换言之,只有在ChatGPT输出了EOS token的时候,整个轨迹才结束(EOS token是NLP中用来表示一段话结束的标志)
总结上文,可得
- 由于多轮对话要求语言模型有记忆性,因此无法直接使用RL。这里的矛盾具体体现在了奖赏函数中:ChatGPT的奖赏函数是针对GPT的一整个输入语句和一整个输出语句而言的;
- 而ChatGPT的语言模型在强化学习的训练策略中,每个action其实输出的是一个个词语。因此,OpenAI的团队可能是采取不对序列的中间生成给予reward的方式解决上文提到的矛盾
考虑到多轮对话场景里,存在某一轮对话中的代词指向上一轮对话中的某个人或物的可能,为此,ChatGPT多轮对话的核心关键是“基于Transformer+prompt学习的生成式模型”GPT3足够强大,并做了一些优化
- 首先,为具备多轮对话能力,instructGPT/ChatGPT在训练的时候就引入了大量多轮对话的数据
- 其次,在回答用户问题的过程中,把之前的部分对话内容(对历史对话数据的规模做个限制,比如限制在8K大小)都保存下来输入到模型中,所以模型就有了记忆性
- 最后,RLHF(人工标注确定是否符合规范)之外各种工程trick
至此,我们可以如此总结下:ChatGPT = Transformer + prompt学习 + RLHF + PPO,在GPT3.5的基础上,先通过基于人类偏好定义奖励函数,再基于奖励函数通过PPO持续优化。
正文至此完。
后记
事实上,可能很多朋友也已经意识到,本文的前大部分内容里,GPT-N理解起来相对轻松(包括Transformer通过理解上篇BERT笔记不算特别复杂),而instructGPT/ChatGPT的整体架构思想也不算复杂,但其中涉及到的RL部分则让想深挖细节的初学者变得立马吃力起来(除非你已“入一定门”,或者你有课程/老师可以不断问),比如一个PPO算法,要真正把这个概念讲清楚、讲透彻且从零推到尾则没那么容易了。
以下是本文的部分修改记录
-
1.22日,优化关于“instructGPT:如何基于RLHF运用到多轮对话场景”中的部分描述
且为避免篇幅过长而影响完读率,权衡之下把扩展阅读下的SeqGAN相关内容删除 - 1.27日,修改此部分内容:“instructGPT/ChatGPT:如何更好的构建多轮对话能力”,之前的阐述没在点子上
- 2.9日,受正在编写的微积分和概率统计笔记的启发:把公式、定理、概念、技术放在历史这个大背景下阐述会让读者理解更为深刻,故,在本文开头前沿里,新增ChatGPT各个前置技术的发展、迭代、结合,并依据这些前置技术的先后提出顺序重新编排全文结构
- 2.10日,把第一部分中的大部分RL细节抽取出来放到新一篇笔记:RL极简入门里
- 预计2.16日,在本文基础上进一步完善对自注意力机制的阐述
参考文献与推荐阅读
- BERT通俗笔记:从Word2Vec/Transformer逐步理解到BERT,July
- 《预训练语言模型》,电子工业出版
- GPT,GPT-2,GPT-3 论文精读,2018年6月份OpenAI提出GPT(当年10月份Google提出BERT),随后2019年2月14日推出GPT2,20年年中推出GPT3,此文介绍了GPT发家史
- GPT到GPT2、GPT3各自对应的原始论文,可以在这里找到:https://beta.openai.com/docs/model-index-for-researchers,此外,写过图解Word2vec、图解transformer的Jay Alammar也写过:图解GPT2(其翻译版)、图解GPT3(其翻译版)
- prompt提示学习(一)简要介绍
- CMU刘鹏飞:近代自然语言处理技术发展的“第四范式”
- 大模型prompt Turing技术上,这是针对这次分享的解读
- NLP小样本学习:如何用20条数据完成文本分类,此外,小样本学习也是七月NLP高级班上重点讲的技术之一,最新一期NLP11则加入了ChatGPT背后原理的解析
- GPT-3.5 + ChatGPT: An illustrated overview - Life Architect
- PPO原始论文:Proximal Policy Optimization Algorithms
- PPO算法解读(英文2篇):解读1 RL — Proximal Policy Optimization (PPO) Explained、解读2 Proximal Policy Optimization (PPO)
- PPO算法解读(中文3篇):Easy RL上关于PPO的详解、详解近端策略优化、详解深度强化学习 PPO算法
- PPO算法实现:https://github.com/lvwerra/trl
- 如何选择深度强化学习算法?MuZero/SAC/PPO/TD3/DDPG/DQN/等
- Google搜索:instructGPT如何基于PPO算法进行训练,出来的一系列文章
- InstructGPT原始论文(确实有68页,^_^):Training language models to follow instructions with human feedback,这是翻译版之一,这是翻译之二
- InstructGPT 论文精读,来自动手学深度学习一书作者李沐的解读
- ChatGPT: Optimizing Language Models for Dialogue,OpenAI关于ChatGPT的官方发布页面
- ChatGPT会取代搜索引擎吗,张俊林
- Illustrating Reinforcement Learning from Human Feedback (RLHF),另这是中文翻译版之一
- OpenAI联合DeepMind发布全新研究:根据人类反馈进行强化学习,表明2017年便开始研究RLHF了
- 基于人类偏好的深度强化学习(Deep reinforcement learning from human preferences),这是翻译版之一,这是解读之一
- 《Learning from summarize from Human feedback》,OpenAI团队在2020年9月的这篇论文里就已经提出了类似instructGPT/chatgpt的训练模式:1 根据人来标注数据微调监督模型,2 训练一个奖励函数(相当于reward不再是人直接给了,而是用高质量标注训练一个好的reward模型),3 通过PPO优化原始监督模型的策略
- HuggingFace的视频分享:RL from Human Feedback- From Zero to chatGPT,这是文字解读:ChatGPT 背后的“功臣”——RLHF 技术详解
- OpenAI's InstructGPT: Aligning Language Models with Human Intent
- 不忽悠的ChatGPT,作者Ben
- 别光顾着玩,让我来告诉你ChatGPT的原理,来自B站UP主弗兰克甜
- 浅析ChatGPT的原理及应用,此外,这里还有一篇外文解读:How ChatGPT actually works
- Role of RL in Text Generation by GAN(强化学习在生成对抗网络文本生成中扮演的角色)
- 抱抱脸:ChatGPT背后的算法——RLHF
- 为什么chatgpt的上下文连续对话能力得到了大幅度提升?
- LaMDA: Language Models for Dialog Applications,Google对话机器人LaMDA原始英文论文