新氦类脑智能 > 资讯洞察 > 活动信息 > 【6.28直播】新氦讲习会02期-ChatGPT的原理简述和Prompt工程 2023/6/29
【6.28直播】新氦讲习会02期-ChatGPT的原理简述和Prompt工程





嘉宾简介

陈焕森,中山大学,Datawhile陈焕森,中山大学,曾就职于香港中文大学(深圳)医疗大数据实验室,在那里积累了宝贵的工作经验和技能。目前,正于Datawhale工作,对数据科学和软件工程领域都有浓厚兴趣。


研读论文

(InstructGPT) Training language models to follow instructions with human feedback


论文链接

https://export.arxiv.org/pdf/2203.02155.pdf


演讲实录

今年2月份的时候,ChatGPT突然间一下子爆火,当时我就很关心它背后的技术是什么样的,所以我在当时参考了一些资料,包括B站的李沐的视频,以及 huggingface的博客,然后对ChatGPT 背后的技术做了一个总结。



首先我们来回顾GPT系列的技术是怎么来的?最早2017年由Google的团队做出来的Transformer,当时只是去解决序列翻译的问题。然后由OpenAI,最早把这个 Transformer 这个模型用来去做大规模的预训练,叫做GPT,然后紧接着还是 Google,他们内部在 Transformer 上做了也是大规模的预训练,即Bert。


GPT 跟 Bert 之间的差别在于, GPT 它是致力于解决生成式任务,而 Bert是去做有点像文本填充的任务,从任务的难度来说的话,还是GPT 系列的任务会更难一点,所以也是李沐老师讲的,可能正是因为这类任务本身的难度决定了 GPT 系列的生成式模型会有更强的性能。也正是 OpenAI这个团队致力于不断地在这条技术路线上面不断地砸钱砸资源,才会有今年ChatGPT 的爆火。由于openAI 想要把ChatGPT商业化,所以并没有放出来它的模型跟论文。


在此之前OpenAI团队放出来一篇InstructGPT的论文,用的是跟ChatGPT几乎一样的方法,所以ChatGPT的讲述会参考这篇InstructGPT。



InstructGPT 是如何工作的呢?它的方法可以分为三个步骤。首先,在 GPT 的大规模预训练模型的基础上进行模型微调,这个微调是通过有监督学习实现的。第二步是收集对比数据,然后用这些数据来训练奖励模型。第三步是利用奖励模型和强化学习策略来优化第一步中经过微调的 GPT 3.5 模型。整个过程可以分为两个部分。第一部分是利用大量有监督数据来训练微调模型。第二部分也是一种微调,但使用了一些强化学习技巧。许多人认为,如果模型的数据足够丰富,可以省略第二步和第三步,直接使用第一步微调的方法来训练一个类似 ChatGPT 的模型。


那么ChatGPT中为什么第二步和第三步是必要的呢?必要性可能在于采用了一种更经济高效的方法来进一步微调。让我们先看一下 InstructGPT论文中的想法,为什么提出了 RL 和 HF?因为语言模型的训练目标与人类指定的目标不一致,从本质上来说,它仍然是一个微调。那么为什么要训练奖励模型以及如何训练奖励模型呢?因为奖励模型具有更低的标注成本,我们可以用奖励模型代替人类提供奖励信号,如图是在 Hugging Face 的官方博客中展示的。



首先采集的 Prompt 数据集,这些数据集它是没有标注的,然后让GPT微调,根据Prompt生成一些答案,然后人类对这些答案进行一个打分,打分之后由这些答案和这个分数作为一个数据集来共同训练一个 reward model。它的训练指标是一个label ranking,这是一个 paywise ranking loss,loss 就是每做一次,随机抽取两个sample,然后由分数更高的一个 sample 来减去分数更低的sample,然后希望能学习到人类对这个更好的生成的答案的偏好,这就是人类反馈的偏好的说法的来源。


之后第二步训练好一个 reward model,它结合了强化学习的手段。还是采集一批无标注的Prompt的数据集,Prompt数据集分别喂到一个初始化的模型和一个微调过的模型中,然后让它们分别生成一个答案做对比,其中微调过的模型需要进一步的去利用reward model 来进行打分。



PPO-ptx即利用强化学习的手段,它利用KL 散度来对比微调过的模型和原来语言模型的距离。

整个训练具体目标函数是KL 散度的期望,由奖赏模型给出的r减去所训练模型和初始的模型的 KL 散度,并计算出一个期望,然后再加上GPT 的损失函数的期望,这样既保证强化模型的更新能基于 SFT (supervise fine tuning)的模型,又保证不会偏离原来的预训练模型太远。这样每一次都在一个可控的范围内进行迭代。在李沐老师的这篇论文进度里面也提到了,ChatGPT 相比这个InstructGPT最大的改进可能是 reward model 会有计划的更新,即在线强化学习。


所谓的在线强化学习就是 InstructGPT 里面的 reward model,它只更新过一次,或者有限次,但是这个ChatGPT的 reward model 会周期性地去更新,来保证这个 reward model 的能力能跟得上我们所训练的语言模型。


接下来我们回顾一下这几个月,类GPT模型的一些进展是怎么样的。



首先GPT4,它相比 GPT 3. 5,它最大的提升是一个图片文本的多模态。我在搜索过程中发现就是在 GPT 4 的前后,已经有微软团队以及谷歌团队做了一些图文多模态模型,分别是 BLIP-2和LLaVA, LLaVA是基于Meta 开源出来LLaMA的模型,进一步训练生成的图文多模态模型。



与ChatGPT系列结合更紧密的技术是上下文的长度,更长的上下文,会让ChatGPT使用体验会更好。像 GPT 3. 5 原本它只能支持4K的 TOKEN, GPT4支持32K 的长度,最近的GPT 3. 5 它的放出来的 API已经能够支持到16K,这也是一个不小的进步。绝大多数的大语言大模型还是4K 左右。


增加上下文长度的训练难度是,Attention是一个0(n2) 的复杂度,无论是时间还是空间,它都是0(n2)的推理和训练时间。也许我们能接受训练0(n2)难度,但是我们在使用时候要能要保证它的推理速度,至少要解决它0(n2)的时间复杂度。


并且,我们在训练的时候,这个文本绝大多数还是一个比较短的上下文,我们很难去收集很多很长的那种超长的上下文数据来做模型的训练。同时包括我们在训练的时候希望能够去对这个模型的性能进行外推,也就是说们用一些比较短的上下文的数据来做训练,然后能够希望它能够外推到更长的上下文的这个推理的这个场景,那么他在外推的时候,他就会肯定会不可避免地去产生一个推理性能下降的这么一个问题。那么也就是说一个是速度,一个是性能,这两个问题决定了你更长的上下文是很难做的。而 Antropic它的做法用到了图中所示的两类技术,这些技术也是类似的大语言模型,它们要解决这个更长下文的时候,都会选择一些比较通用的技术。


现在的思路大概是两类,一类是 attention 的工程化,也就是我可能使用的还是一些比较原始的attention,但是我会把这个 attention 的计算结合我们这个硬件来做一些适配,这是一个比较工程性的一个概念。然后第二种就是各种 attention 的变体。


一个目前来说做得比较好以及接受度比较广的Attention变体就是GAU,它是有一个Gate的这么一个概念,这个 attention 变体的宗旨,就是既能够结合局部的注意力,又不要放过一个全局的注意力。基本上大多数的 attention 变体都在局部和全局这两个方向做结合。


而 attention 工程化中, flush attention目前可以说是把工程化做到极致的方法,如果结合 GPU来说,比如A100 的话,它有 40GB 的一个内存,但是它的这个它的核心计算显存,可能只有 20 MB。如果你不能够很好地利用好这个 20 MB 的计算显存的话,你可能会有大量的时间花在调度上面。


所以他们就利用了这个 SIM 和 HBM 这两个模块的显存的大小的之间差异,然后去把这个 attention 的计算分块来执行原本的attention,避免了频繁地去调度,每次只存一次和取一次,它相比原来提升了八九倍的性能,这是我了解到的一个更长上下文的一个技术。



还有一个GPT 4重点去做的事情是安全可靠性,今年3 月份微软开放的bing,有些人把它的对话调教得特别的奇怪,各种各样奇怪的输出都会有,那么其实这就是安全可靠性需要关注的一个问题。


GPT 4 它的技术报告里面提到,它额外添加了一个基于规则的奖励模型,但是它又没有对这个东西说做一个详细的说明。图中所示的是DeepMind 团队做出来语言大模型,他们也提到了基于规则的一个奖励模型,就是他在这个模型去做微调的时候,不仅利用刚才我们提到的人类反馈强化学习的加强模型,同时还做了一些定制化的一些规则。具体的一个技术细节大家可以去看一下 sparrow model。然后还有一个红蓝对抗,红蓝对抗就是专门有一个团队去不断地去攻击这个模型。


最后还有就是,数据集怎么保证更高质量?前阵子有一个做 textbooks is all you need,就是吴恩达老师一直在提的就是小规模,但是质量高的数据集可能对模型更有用。至少在这篇论文的场景下,这个小规模高质量的数据集所训练的小模型能够很好地打败,数据规模很大,但是质量相对不高的大训练模型。、


另外把模型做大其实是一件很困难的事情。一个可行的路径可能是 MOE 架构。MOE 架它的一个全称是 mixture of experts,一个专家混合或者专家集成的模型。他跟我们机器学习里面理解的集成学习可能不太一样,他的moe架构有不同的一个倾向,不同的expert会负责不同的功能。然后我每一次去做推理,或者说每次做训练的时候,我是去激活对应对应场景下的一个expert。假如说 GPT 4用了这个技术,现在我是输入,给他一个程序的一个prompt,那他可能会激活第二个expert,然后我给它一个生成小说或者是文本理解的 prompt,它可能就会去激活另一个export,所以它其实就是做了一个功能分区以及稀疏激活的这么一件事情。


接下来进入分享的第二个阶段, Prompt 的使用,以及怎么去利用 Prompt 做一些应用。


首先是 prompt 使用,这 prompt 使用就是希望在对话的过程中来解决我们无论是工作还是生活上的一些问题。然后我这边是参考了两个链接,参考了这个 open AI 官方的一个 Cookbook 的一个一些教程,我所有的案例都是从它上面找来的。然后这边也稍微推荐一下我们这个 datawhale的一个 prompt 使用指南。这里跟之前的open AI Coolbook 不同的是,我们在是在上面沉淀了很多案例,都是由我们的学习者沉淀下来。


那么为什么要有prompt?原因是现有的语言模型它对外界的输入是比较敏感的,你的训练集跟测试集可能不太匹配,所以为了更好地利用这个语言模型的这能力,我们去再跟那个类 ChatGPT 模型去做对话的时候,需要掌握一定的沟通技巧。



prompt 最早也是最出名的一个案例,Let's think step by step。上图的场景是一个推理题,如果是直接提问会得到一个错误的答案,但是不用去做太多修改,只需要在prompt 里面让他一步一步去做思考。ChatGPT 就能够得到一个正确的答案。

至于它很有效的原因是,在训练数据集里,Let's think step by step可能才是真正贴合模型训练数据集的一个分布,这是一个不一定正确,但是比较好理解的解释。



案例中,根据提问提供了a、b、 c 三个选项,在没有去对复杂任务做拆分的时候,模型得到一个错误的答案。

这个场景的宗旨就是先总结clue 的信息,再让它去做回答。把它做一个拆分之后,就能够得到我们理想的有效答案。同时拆分之后,我们的子任务也能够去更好地聚焦。一个复杂任务,你对它提了很多若干个子任务的时候,它可能会丢失掉对于某一个任务的注意力。你把它拆分之后,转化成若干个 prompt,然后每个 prompt 回答一个问题,他就能够很好地聚焦你的子任务,这是复杂任务拆分的好处。


思维链就是我们在做 prompt的时候需要一直秉持的一个观念,想让这个模型能够像侦探一样,一步一步地来思考,当你能够这样去做的时候,他往往能给出一些不错的答案。


最后是ChatGPT的prompt应用化,即把我们的需求转化成特定的prompt,让ChatGPT 给出一个答案的一个应用。这里同样是参考了 OpenAI 的一个 Cookbook 以及 Langchain 的Python 库,它致力于解决prompt 应用化这个场景,图中链接是langchain文档的中文版。


这边我同样推荐一下我们Datawhile 4月AIGC活动,活动中Datawhale不仅教大家怎么使用prompt,同时也有一些团队或者一些学习者去产出一些很好的应用,有些应用已经做得很成熟了。



这是langchain库的应用开发的思路,如上图所示。


首先它把某个特定的 prompt 发给这个agent,然后代理把这个 prompt 拆解成不同的任务,它拆解的过程中本身就使用了ChatGPT,然后把这个prompt拆解的思路其实跟之前复杂任务做拆分是一样的思路,希望能够得到更好的答案。然后不同的任务由ChatGPT 来制定不同的工具生成一个答案。最后再把这个把不同工具生成的答案做一个总结集合,发给用户。



相信我们大家对读论文,或者是读一些比较长的书的时候,我们希望能够快速地提取里面的一些关键字。可以让这个模型快速地把这些文本去做一些总结,甚至我们能够让模型先读一遍我们再去对他做一个提问,针对这个模型,针对这个文本去做一个回答。


怎么对超长文本进行总结,目前主流的做法就是把document 进行分割,然后每一个分割片段去做一次总结,之后把这个若干个总结合并起来,这种方式可能会丢失文本,因为每个 document它是有上下文背景的。

另一种方法是,每一次总结完之后,把这个总结插入到document 2,然后不断地把总结插入到下一个分割文本,最后可能得到更好的总结。


这是上下文有限制的情况下工程化的解决方案。我们当然希望这个模型能够有非常,甚至趋于无限的上下文。但现实中这种分割的方法可能也是一个不错的一个手段。



之后我们不仅希望它能够去做总结,还希望它能针对某一个文本或者是某一堆数据,他能够成为所针对文本或数据的专家,我们对他提问的时候,能针对文本做回答。这其实就是本地知识库问答机器人的概念。


这是 Lang chain中文仓库里面的一个案例,只是简短的一个代码,就已经完成了对 data 目录下所有文本的学习,它把文本去加载,然后做一个切割,之后再创建问答,让 ChatGPT 对里面的文本去做总结。既然是一个本地库知识库,它就需要有一个记忆的概念,这里面用到了向量数据库来承担记忆这个功能。只用了十多行代码,就构建了一个问答机器人,答案的效果也不错。



我们不仅希望能够做本地的问答,我们更希望能够做在线问答。这个案例是 open AI Coolbook 中的一张图。首先我们把用户的prompt 去针对搜索引擎做一个search,然后得到的一系列答案利用chatgpt进行一个重排序,最后再从中抽取整合最佳答案返回给用户。




选取部分Q&A

这是一个工程上的问题,你刚出说prompt  engineering 它要迭代很多次,一个简单的任务,直接用API的话,他能实现吗?一个任务需要跑很多次,所以进行一个任务的话,是不是需要很长时间?


他使用的时间,取决于任务的难度。现在主流的方法是本地知识库。大家会把总结放到向量数据库,由向量数据库去做一个记忆,它不需要经过ChatGPT,直接从这个向量数据库里面就能得到一些理想的答案。

GPT 的回答质量比 GPT3 3. 5 要高不少,这可能是因为在哪些方面进行了改进呢?


目前没有谁能给出这个答案,大家也只能猜测。据我了解到,首先数据集仍然是最重要的,然后GPT肯定在 GPT 3. 5 基础上建立了一批新的,质量更好的数据集来做训练。其次,基于规则奖励模型的出发点,是达到GPT输出的安全可靠,这一步对它模型的输出性能有没有帮助?这是未知的。总的来说就是大家倾向于是更好的数据集让回答质量更好了。

是否可以通过prompt技巧,让模型的回答比较稳定?

因为发现有时候仅仅通过调整温度参数,当文本长度偏长的时候,模型回答依然不稳定。


我在实际的使用中,感觉到如果直接进行提问的话,有时候是问不出答案的,包括刚才提到的 step by step,比如说编程场景下GPT给出一个答案,然后你把他这个答案抄下来,然后去跑一遍,跑错之后你再返还给 ChatGPT 跟他说这个一步错了是什么原因?很多场景下重复几遍之后,GPT往往能给出一个正确答案。

所以我认为是能够通过prompt技巧来得到一个我们想要的答案。



新 氦 类 脑 智 能 介 绍

新氦类脑智能由博康控股、杨浦创投、复旦资管共同出资成立,是上海市类脑芯片与片上智能系统研发与转化功能型平台的承载主体,致力于打造基于类脑智能与人工智能芯片的产业发展引擎,构建集人才、技术、数据、产品及行业应用场景于一体的产业生态。在技术研发、市场转化与业务拓展提供全方位服务,由专业的芯片及人工智能行业研发人员领衔进行基础研究,致力于开发行业共性技术、前沿性及探索性创新技术。


长 按 二 维 码 关 注 新 氦 公 众 号