本文全方位地介绍了 ChatGPT 的能力特征、发展历程以及 OpenAI 一路走来所坚守的技术路线,并对 ChatGPT 出现之后 NLP 领域的范式转换进行了展望,即 ChatGPT 开启「文本生成 + 指令」的范式。
1、ChatGPT,不再「愚蠢」的人工智能
ChatGPT 的相关话题应该算是继 AlphaGo 以来,最出圈的人工智能热点了。简单来说,它是一个可以用自然语言对话的机器人,你可以问它任何问题(当然它有可能会答错,但你可以引导并纠正它),它都会以非常流畅、标准的自然语言回答你。不仅如此,它还能回答代码问题、数学问题等等,你可以和它在关于任何问题上聊得不亦乐乎。
我们可以用一个经典的鸡兔同笼问题来感性地认识一下 ChatGPT 的能力:
从这个回答可以观察到几个特点。首先是对自然语言的理解和转换为数学问题的能力,其次它通过将一个较为复杂的推理问题分步拆解,一步步获得最后的答案。这个能力被业内称作「思维链」(Chain of thought)。接下来换一下问法,看看它会怎么回答。
从这个图中可以发现,ChatGPT 对自己所说的内容是有感知的,并且可以给出这么说的原因。另外也可以发现,它确实也会出错(第一次计算耳朵数量错了。此处有个冷知识,鸡是有类似于「耳朵」一样的功能器官),但可以通过引导的方式让它给出正确的答案,并且会告诉你自己为什么错了。
如果不事先告诉你这是一个人工智能模型,ChatGPT 给人的感觉确实像一个真正有逻辑思维和语言交流能力的真人。它的出现第一次让大家觉得,人工智能似乎终于能够和人正常交流了,虽然有时候会出错,但在交流的过程中至少没有语言和逻辑上的障碍,它能「懂」你在说什么,并且按照人类的思维模式和语言规范给你反馈。这种非常智能的体验感,是它突破业界小圈子,给大众带来冲击感的原因。
这里还希望再次强调这种体验感的问题,因为也许过去业界由于技术的限制,为了完成场景中的特定任务而忽略了这一点。如今 ChatGPT 的出现代表了人工智能不再是过去那种「有用,但是也挺蠢」的形态了。
为了更好地理解 ChatGPT 这种非常智能的感觉是怎么产生的,难免要从过去那种「很蠢」的人工智能说起。准确地说,ChatGPT 背后使用的依然是自然语言处理(NLP)技术,但却打破了原有的范式。
要理解这一点,可以先看看目前的主流做法是怎样的。人类交流依托的是语言,甚至也有很多人认为人类的思维也是建立在语言上的。因此,理解运用自然语言一直是人工智能的重要课题。但语言实在太复杂,因此为了让计算机理解运用语言,通常会将这个过程拆分为很多的细分项,这就是在技术领域中常说的「任务」。举几个例子:
情感分析任务,针对的是理解语言所蕴含的情感倾向;
句法分析任务,针对的是分析文本的语言学结构;
实体识别任务,针对的是从文本中定位出实体片段,例如地址、名字等等;
实体连接任务,针对的是从文本中抽取出实体间的关系;
这样的任务还有很多,都是从某个细分的侧面去对自然语言进行分析、处理。这样做有很多好处,比如有了这些拆分,就可以从不同的维度来考察一个自然语言处理系统的细分能力;也可以针对某一个细分的项专门做系统或者模型的设计等。从技术的角度来说,将一个复杂的任务(理解并运用自然语言)拆分为很多的简单任务(各种各样的 NLP 任务)确实是一种比较典型的解决复杂问题的路径,这也是目前的主流做法。然而在 ChatGPT 出现之后,以马后炮视角去看,也许在让计算机理解并运用自然语言这条路上,这种拆分并不是最有效的途径。
因为在单个任务上的优秀表现,并不能代表系统就掌握了自然语言。人对于人工智能体的「智能感」,是基于对它应用自然语言的整体能力而产生的,这一点在 ChatGPT 上有明显的体现。虽然 OpenAI 没有开放 ChatGPT 的 API 服务,外界还无法测评它在各个细分 NLP 任务上的具体效果,但以过往外界对它的前身 GPT-3、InstructGPT 等模型的测试情况表明,对于某些特定的任务,一个用专门数据精调过的小模型,确实可以获得更好的效果(详细分析请参考《深入理解语言模型的突现能力》)。但这些在单个任务上有更好表现的小模型,并没有引起很大的出圈效应。归根结底,是因为它们只有单一的能力。单个的能力出众并不能代表它们具有了理解和运用自然语言的能力,从而也无法独自在实际应用场景中发挥作用。正因如此,通常在一个真实的应用场景中,都是多个具有单点能力的模块经过人为的设计拼凑而成,这种人为的拼凑方式是过去的人工智能系统让人感觉并不智能的原因之一。
从人类理解和运用自然语言的视角去看,这个现象其实很好理解。普通人在理解、运用自然语言的时候,并不会在脑内将它拆分为很多步不同的任务,逐个任务进行分析,然后再汇总,这不是人类使用自然语言的方式。就好比一个人,在听到一句话的时候,并不会对它的句法结构、实体内容与关系、情感倾向等这些内容逐一分析,然后拼凑出这句话的含义,人对语言的理解过程是一个整体过程。再进一步,人对这句话的整体理解,会以自然语言的形式,通过回复的方式整体地表现出来。这个过程并不是像人工智能系统那样,拆分单个任务,然后逐一输出情感分析的标签、实体信息的片段、或是别的某个单个任务的结果,然后用这些东西拼凑出回复。
而以 ChatGPT 为代表,GPT 系列模型所做的事情才真正接近了人类理解和运用语言的能力 —— 直接接收自然语言,然后直接回复自然语言,并保证了语言的流畅性与逻辑性。这是人与人的交流方式,所以大家对它抱以「很智能」的体验感。也许很多人会认为,如果能做到 ChatGPT 这样当然很好,过去那种对任务的拆分是因为技术的限制不得已而为之。从技术应用的视角来看,这样迂回的方式当然是需要的,这种方法也在很长的一段时间内被采用,并且确实也能够解决很多实际场景中的问题。但如果回顾 GPT 系列模型的发展过程,就会发现 OpenAI「赌」了另一条路,并且他们「赌」赢了。
2、OpenAI 的「赌局」
GPT 初代,一切开始的地方
早在 2018 年,OpenAI 就发布了最初版本的 GPT 模型,从 OpenAI 公开的论文(Improving Language Understanding by Generative Pre-Training)可以了解到,这个模型采用了 12 层的 Transformer Decoder 结构,用了大约 5GB 的无监督文本数据进行语言模型任务的训练。虽然初代 GPT 模型采用的就已经是生成式的预训练(这也是 GPT 名字的由来,Generative Pre-Training,即生成式预训练),但使用的是无监督预训练 + 下游任务微调的范式。这一范式其实并不是什么新的发明,它在 CV(计算机视觉)领域已经有比较广泛的应用,只是由于当年 ELMo 模型的出色表现,把它重新「介绍」到了 NLP 领域。
GPT 模型的出现在那一年确实引来了一些业内的关注,但它并不是那一年的 C 位主角。因为就在同年,Google 的 BERT 模型横空出世,以优异的效果吸引了几乎全部的目光(这个景象有点像现在的 ChatGPT,不禁感叹 Google 和 OpenAI 之间的「恩恩怨怨」真是天道好轮回)。
图片来自 BERT 论文,从图示中可以一窥当年 BERT 对标的就是 GPT,并引以为傲地指出双向编码能力。
BERT 模型虽然也是采用和 GPT 一样的 Transformer 模型结构,但它几乎就是为「无监督预训练 + 下游任务微调」的范式量身定制的模型。和 GPT 相比,BERT 所使用的掩码语言模型任务(Masked Language Model)虽然让它失去了直接生成文本的能力,但换来的是双向编码的能力,这让模型拥有了更强的文本编码性能,直接的体现则是下游任务效果的大幅提升。而 GPT 为了保留生成文本的能力,只能采用单向编码。
以当年的眼光来看,BERT 绝对是一个更加优秀的模型。因为既然 BERT 和 GPT 两者都是采用「预训练 + 微调」的范式,并且下游任务依然是分类、匹配、序列标注等等「经典」的 NLP 任务形式,那么像 BERT 模型这种更注重特征编码的质量,下游任务选一个合适的损失函数去配合任务做微调,显然比 GPT 这种以文本生成方式去「迂回地」完成这些任务更加直接。
从 BERT 模型出来以后,「无监督训练 + 下游任务微调」的范式便奠定了它的霸主地位,各类沿着 BERT 的思路,琢磨「如何获得更好的文本特征编码」的方法大量涌现,以至于 GPT 这个以生成式任务为目标的模型显得像一个「异类」。马后炮地说,如果当时 OpenAI「顺应大势」,放弃生成式预训练这条路,也许我们要等更长的时间才能见到 ChatGPT 这样的模型。
GPT-2 带来的希望
当然,我们现在见到了 ChatGPT,所以 OpenAI 没有放弃生成式预训练的路线。实际上坚持的「回报」隐约出现在了第二年,也就是 2019 年。OpenAI 发布了有 48 层 Transformer 结构的 GPT-2 模型。在发布的论文(Language Models are Unsupervised Multitask Learners)中,他们发现通过无监督数据配合生成式训练后,GPT 展示出了零样本(zero-shot)的多任务能力。而奇妙的是,这些多任务的能力并不是显式地、人为地加入到训练数据中的。用通俗的话来举个例子,GPT-2 其中一个展示出来的能力是做翻译,但令人吃惊的是,通常专门用来做翻译的模型是需要大量的平行语料(即两种不同语种之间配对的数据)进行监督训练,但 GPT-2 并没有使用这种数据,而仅仅是在大量的语料上进行生成式的训练,然后它就「突然」会做翻译了。这个发现或多或少地带有点颠覆性的意味,它向人们展示了三个重要的现象:
想让模型去完成一种 NLP 任务,也许并不需要和任务匹配的标注数据。例如 GPT-2 训练时没有用标注的翻译数据,但它会做翻译;
想让模型去完成一种 NLP 任务,也许并不需要和任务匹配的训练目标。例如 GPT-2 训练的时候并没有设计翻译任务和相关的损失函数,它只是在做语言模型任务。
仅仅用语言模型任务(即生成式任务)训练的模型,也可以具有多任务的能力。例如 GPT-2 展现出了翻译、问答、阅读理解等等的能力。
虽然以现在的眼光来看,当时的 GPT-2 所展示出来的各种能力还比较初级,效果距离使用监督数据微调后的一些其它模型还有明显的差距,但这并没有妨碍 OpenAI 对它所蕴含的潜在能力充满期待,以至于在论文摘要中的最后一句话中,他们提出了对 GPT 系列模型未来的期望:
“These findings suggest a promising path towards building language processing systems which learn to perform tasks from their naturally occurring demonstrations.”
后来一系列事情的发展也证明了他们确实是一直朝着这个 promising path 的方向在前进。如果说在 2018 年,GPT 初代模型出来的时候,GPT 的生成式预训练还面临着被 BERT 这类以「提取特征」为目地的预训练模型在各方面碾压,那么在 GPT-2 中的发现,给了生成式预训练一个 BERT 类模型无法替代的潜在优势,即语言模型任务所带来的多任务能力,且这种多任务能力是无需标注数据的。
当然,在那个时间点上,生成式的技术路径依然面临风险和挑战。毕竟当时的 GPT-2 在各任务上的表现还是差于经过微调的模型,这导致了 GPT-2 虽然有着翻译、摘要等等能力,但效果太差以至于无法实际使用。因此,如果在当时想要一个可用的翻译模型,最好的选择依然是老老实实用标注数据训练一个专门用来翻译的模型。
GPT-3,数据飞轮的开始
从 ChatGPT 时代往回看,也许 OpenAI 在 GPT-2 中的发现确实坚定了他们对 GPT 系列模型的信心,并决定加大研发投入力度。因为在随后的 2020 年他们发布了 1750 亿参数量的 GPT-3,一个即便以现在的眼光去看也大得让人惊叹的模型。虽然 OpenAI 没有明确公开训练这个模型的费用,但大家的估算是当时花了 1200 万美元。同时公开的还有一篇长达 60 多页的论文(Language Models are Few-Shot Learners),其中详细阐述了这个新的庞然巨物所展示出来的新能力。最重要的发现莫过于论文标题中所说的,语言模型具有小样本(few-shot)学习的能力。
小样本学习是一个机器学习领域的专业术语,但它有着很朴素的理念,即「人类是可以通过少量的几个例子就学会一个新的语言任务」。想象一下在语文课上学习怎么掌握「把」字句换成「被」字句样(雨把衣服淋湿了 —— 衣服被雨淋湿了)的情形,老师会给出几个例子,同学们就能够掌握这项能力。
但对于深度学习模型来说,它通常需要学习(训练)成千上万的例子才能掌握一项新的能力,但大家发现 GPT-3 却像人类一样具有类似的能力。而且重点在于,只需要给它展示几个例子,它就会「有样学样」地完成例子给出的任务,而不需要进行额外的训练(即不需要进行常规训练中的梯度反传和参数更新)。后来的研究表明,这种能力是巨型模型所特有的,被业内叫做「在上下文中学习」(in context learning)的能力。
GPT-3 论文中所展示的英语翻译法语的 In context learning 能力。
实际上,小样本学习能力本身并不是很惊人的发现。毕竟业内一直都在对小样本学习进行研究,很多专攻小样本学习的模型都有出色的小样本学习能力。但 GPT-3 展示出来的这种「在上下文中学习」的小样本能力却非常出人意料,其原因也和 GPT-2 所展示的多任务能力一样:
GPT-3 并没有为了获得小样本的能力而在训练数据、训练方式上做特别的设计,它依然只是一个用语言模型任务训练的生成式模型;
GPT-3 的小样本能力是以「在上下文中学习」的方式展现出来的。换句话说,想让它获得新的能力,不需要对它再训练,而只需要给它看几个示范的例子。
除了这个能力以外,GPT-3 还展示出了优秀的文本生成能力,相比 GPT-2,它生成的内容更加流畅,而且可以生成很长的内容。这些能力综合体现在一个模型上,让 GPT-3 在当时成为了大家的关注焦点,它也成为 OpenAI 正式对外提供服务的模型。
但随着这个模型服务的开放,越来越多的人尝试使用这个模型。从这时起,OpenAI 通过开放给公众的方式,同时也在收集着更具有多样性的数据(用户使用时输入的内容可能会被用于模型的训练,这一点是写在用户条款中的),这些数据在后来的模型迭代中也发挥着重要的作用。自此 GPT 系列模型的数据飞轮便转动了起来,越多优质的用户数据,迭代出效果越好的模型。
与 ChatGPT 不同的是,GTP-3 并不是采用对话的形式交互的模型,而是一个文本的续写模型(也就是在你输入的文字后面接着往下写),因此它并不具备如今的 ChatGPT 所拥有的多轮对话能力。但它已经能够干很多的事情,例如编写故事、给邮件做自动补全等等。但同时,大家也慢慢发现了一些问题,例如它会一本正经地输出不符合事实的内容,并且会输出一些有害的言论等等。这是这种文本生成模型最突出的弊端,虽然经过多次迭代,但 ChatGPT 如今也依然面临类似的问题。
CodeX,让计算机自己写代码
OpenAI 在对 GPT-3 的研究中还有一个意外的发现,它能够根据一些注释生成很简单的代码。因此在随后的 2021 年,他们对生成代码这件事情进行了专门的研究投入,并发布了 CodeX 模型。它可以看作是一个有着代码专精能力的 GPT 模型,能够根据自然语言输入生成比较复杂的代码。
从外部视角来看,我们无法判断代码生成的研究与 GPT 系列模型的研发是否在同时进行。但放在当时,让模型具有生成代码的能力,从实用化的角度来说确实更加具有意义,毕竟 GPT-3 还未拥有如今 ChatGPT 这般强悍的能力。另一方面,让模型去生成代码也能规避它生成有危害文本内容带来的风险。
在 CodeX 论文中提及了几个要点,首先是让经过文本数据预训练的 GPT 模型在专门的代码数据(数据来自 github 的开源代码,一共 159G)上训练确实能够明显提升模型对代码的理解和输出能力。其次是论文中用的是一个 120 亿参数的「小」模型,这个信息从侧面反映出 OpenAI 内部除了对外开放接口的 1750 亿参数的 GPT-3 模型外,还有别的不同大小的模型版本。
而加入代码训练,让模型获得理解和生成代码的决定,原本的初衷也许只是希望 GPT 能够多一种应用场景。它看似与 GPT 系列模型在理解和运用自然语言的能力没有太大的联系,但根据后续的研究(详细的分析请参考文章《拆解追溯 GPT-3.5 各项能力的起源》),增加对代码数据的训练很有可能触发了后来的 GPT 模型在自然语言上的复杂推理和思维链的能力。
也许在 OpenAI 做 CodeX 之初并没有预料到会有这样的结果,但就像他们一直使用文本生成任务来做 GPT 模型,然后在 GPT-2 和 GPT-3 中「解锁」了「多任务的能力」和「在上下文中学习的能力」那样,代码数据的引入又一次让他们获得了意料之外的收获。虽然看上去似乎有一些偶然,但对技术路线的前瞻性认知,加上坚持与持续的投入显然是一个至关重要的因素。
InstructGPT,让 GPT 好好说话
在前面我们提到了 GPT-3 虽然已经有很强的能力,但上线以后随着使用的人越来越多,也发现了很多问题,最严重的应该要数「一本正经地胡说八道」和「输出带有危害性的内容」这两点了。虽然在 2021 年 OpenAI 似乎暂时将重点放在了让模型理解和生成代码这件事情上,但他们应该一直在尝试解决 GPT-3 的这些问题。
在 2022 年初,OpenAI 发表了 InstructGPT 的论文(Training language models to follow instructions with human feedback),从中我们可以一窥解决这些问题的方法。论文的核心理念是让模型接受人类的教导(反馈),这一点在标题中就已经开宗明义了。
GPT-3 之所以会出现「一本正经地胡说八道」和「输出有害的内容」这样的问题,其根源来自于它所使用的训练数据。像 GPT-3 这样的庞然大物,对数据的需求量是海量的。我们从 GPT-3 的论文中可以找到它的数据来源,大致可以划分为三类:网页内容、百科内容以及书籍。虽然网页内容的量非常大,但也非常「脏、乱、差」,自然会包含很多非真实性和有害的内容。GPT-3 在这些数据上进行训练,自然也就学到了这些东西。
但作为一款对外提供服务的产品,GPT-3 的回答应该更小心一些。要解决这个问题,其中的一难点在于怎么去定义模型应该怎么说话。因为生成模型的输出内容是自然语言本身,而不是一个分类的标签或一个实体名词这种有明确的、客观对错的内容。没有明确的对错,就导致无法像训练经典的 NLP 模型那样直接针对目标设计训练任务。
而 InstructGPT 给出的解决思路是非常直接的,既然对于「好的回答」这个评价指标有很多不同的影响因素,这些因素又相互交织在一起,那就让人来教它怎么写回答。因为人类是比较善于处理这种「既有明确的要求,又有模糊的范围」的问题的,让真人写一些「优秀范例」,让模型去学习这些「优秀范例」,这正是 InstructGPT 提出的总体思路。
具体而言,InstructGPT 提出了两个阶段的路径来让 GPT 学习人类给出的「优秀范例」,第一阶段是监督学习,第二阶段是强化学习。在第一阶段中(对应下图中最左边的 Step 1),让真人根据不同的 Prompt(粗浅可以认为是我们使用 ChatGPT 时,在对话框里输入的那条文本,在业界这个东西叫做指令)写真实的、无害的、有用的回答。实际操作过程中,为了保证这些内容的质量,会给写回答的标注人员一些规范性的指引,然后让已经经过预训练的 GPT 模型在这些人类编辑的数据上继续训练。这一阶段可以看作是对模型的一种「规训」,用一个不严谨的类比来说,就像语文老师让你默写优秀范文那样。
图片来自 InstructGPT 论文,提出通过监督式的指令微调 + 人类反馈的强化学习来让模型的输出变得合理。
第二阶段是强化学习,技术上分为两步。第一步(对应上图中间的 Step 2)是让被「规训」后的模型根据不同的 Prompt 生成多个不同的回答,并由人来给这些回答按照好与差的标准来排序。然后用这些标注了优劣之分的数据训练一个打分模型,让它可以自动给更多的数据进行排序打分。强化学习阶段的第二步(对应上图中右边的 Step 3)就是利用这个打分模型作为强化学习中的环境反馈,以策略梯度(Policy Gradient,准确地说是 PPO 算法)的方式对已经「规训」后的 GPT 模型进行训练。整个第二阶段的过程可以看作是对模型的一种「强化」,再用一个不严谨的类比来说,就像语文老师给你写的作文打分,让你从分数中分辨什么是好与不好,然后不断进步。
因此,用一种非常不严谨,但普通人或许也能够理解的方式来说,InstructGPT 先是让一个「口无遮拦」的 GPT 通过「默写人类的优秀范文」的方式初步学会「好好说话」,然后再「给它独自写出来的东西打个分,让它回去好好领悟,继续进步」。当然,在技术上牵涉事情会更复杂一些,比如「优秀范文」的具体规范和数量等数据上的问题,以及强化学习中打分模型的选择,算法参数的设置等算法上的问题,都会对最后的效果产生影响。但最终的结果表明,这种方式是非常有效的,论文中也指出一个通过上述方式训练出来的 13 亿的小模型,效果就能够超过没有经过这种训练的更大的模型。
另外论文中还有一些非常值得一提的内容。首先是关于 Prompt 的一些发现。InstructGPT 训练时所使用的 Prompt 主要由两部分构成,一部分是专门的 AI 训练师编写的,另一部分自来 OpenAI 的模型在线服务期间,由用户使用中编写的内容,这时数据飞轮的作用就体现了。可以发现,无论是哪种,这些 Prompt 都是由真人写出来的,虽然文章中没有对这些 Prompt 的具体涵盖范围、分布情况以及提问的方式展开详细的分析,但可以合理地猜测这些 Prompt 具有一定的多样性和较高的质量。其实文章中对比了使用这些真人编写的 Prompt 训练的模型和使用一些开源 NLP 任务数据集中构建的 Prompt(例如 T0 数据集、FLAN 数据集)训练出来的模型,结论是由真人编写 Prompt 训练出来的模型,给出的答案更加能被评测的人接受。
另外一点是关于训练好的模型对新的 Prompt 的泛化能力的问题,可想而知的是,如果训练完成的模型无法产生 Prompt 的泛化能力,那么现在 ChatGPT 所表现出来的,几乎百问百答的能力是不太可能产生的。因为在模型做微调的阶段,即便是再多的数据,也不可能把人们有可能会输入的内容都覆盖完整。而 InstrctGPT 论文中点明了文中所采用的方法是可以产生 Prompt 的泛化能力的。
之所以花了更多的文字对 InstructGPT 做介绍,因为根据 ChatGPT 官方页面的介绍,InstructGPT 中的方法正是用来训练 ChatGPT 的方法,不同的只是 ChatGPT 使用了对话式的数据组织方式。
GPT-3.5 时代和 ChatGPT 的诞生
在随后的时间内,OpenAI 发布了多个被称为 GPT-3.5 系列的模型,虽然这些模型并未有相关的论文跟随发表,但根据这篇文章的分析,GPT-3.5 系列应该是融合了 OpenAI 在 GPT-3 时代积累的技术、数据以及经验开发出来的。由于没有详细的官方公开信息参考,关于这些模型的具体资料,外界主要是通过分析使用的体验、相关的技术论文以及 OpenAI 的 API 文档介绍来进行推测。
根据分析,GPT-3.5 系列的模型有可能并不是在 GPT-3 上继续微调而来,而很可能是将代码和自然语言的数据融合在一起,重新从零开始训练了一个基础模型。这个模型可能比 GPT-3 的 1750 亿参数量更大,它在 OpenAI 的 API 中被命名为 codex-davinci-002。然后在这个基础模型上,通过指令微调和人类反馈得到了一系列后续的模型,包括 ChatGPT。
GPT 系列模型的发展路径。
简要地说,从 code-davince-002 这个模型开始,经过有监督的指令微调得到 text-davinci-002。以及后续的 text-davinci-003 和 ChatGPT,也是在 GPT-3.5 系列的某个模型上通过指令微调以及人类强化学习反馈得到的。并且 text-davinci-003 和 ChatGPT 都是在 2022 年 11 月发布的,不同的是 text-davinci-003 和 GPT-3 一样,是一个文本补全模型。而根据 ChatGPT 的官方介绍,它是通过将过往的数据处理成对话交互的形式,并增加了新的对话数据训练出来的。
至此,我们大致回顾了 OpenAI GPT 系列模型从 2018 年的初代 GPT 到现在的 ChatGPT,一路发展迭代的过程。在这个过程中,OpenAI 一直保持着对生成式预训练模型这一技术路径的「执拗」,并且也一直从不断发展的 NLP 技术中吸纳新的方法,从最初的 Transformer 模型结构,到后来的指令微调(Prompt tuning)等技术的出现,这些因素共同促成了如今 ChatGPT 的成功。有了对 GPT 系列模型发展的了解,我们可以再回过头来看看如今的 ChatGPT。
3、走近再看 ChatGPT
在第一章节中我们阐述了 ChatGPT 出圈的原因主要是:「它以流畅、符合逻辑的自然语言来反馈人类对它输入的自然语言」,从而给与它交流的人带来了很强的「智能感」。在第二章节中通过回顾 GPT 系列模型的发展历史来了解 ChatGPT 成功之路。而这一章节会尝试以尽可能让圈外人都能理解的方式,稍微深入一些技术的内容,并且探讨一下当前的一些大型文本生成式模型为什么未能做到相同的效果。这一部份的主要参考来自于《深入理解语言模型的突现能力》和《拆解追溯 GPT-3.5 各项能力的起源》这两篇文章以及相关的一些论文,建议希望详细了解细节的读者阅读原文。
虽然在第一章中指出,ChatGPT 所带来的惊艳效果是由许多不同的 NLP 任务综合体现出来的,但在分析它背后的技术时,还是通过将它的能力进行拆解会更加清晰明了一些。总体而言,ChatGPT 所体现出来的能力可以大致划分为以下几个维度:
- 文本生成的能力:ChatGPT 的所有输出都是即使生成出来的文本,所以文本生成的能力是它最基本的要求。
这一项能力实际上是来自于它的训练方式,ChatGPT 在预训练时,是一个标准的自回归语言模型任务,这是 OpenAI 所有 GPT 系列模型的基底。所谓的自回归语言模型任务,通俗的理解是这样的:它可以根据已经输入的文本,预测下一个 token 应该是什么。这里所说的 token,所代表的是模型所使用的最小单位的字符片段,它可以是字(在中文里采用字是很常见的),也可以是词(英文的每个词天然地被空格隔开了,所以常采用词),甚至是字母。但现在的方法通常采用的是子词(subword,介于字母和词之间,主要的目的是减少词表数量)。但不论是哪种,自回归语言模型任务的基本思路都是根据已经输入的文本,预测下一个要输出的文本是什么,就像下图的例子中那样:
这个例子中,BOS 代表了输入的开头,而每个 token 是一个词,GPT 模型根据输入的「今天」和 「天气」两个词,预测下一个要输出的是「不错」。
在训练的时候,会准备很多文本数据,比如网页上的文章、各类书籍等等,只要是正常的文字内容,都可以用来训练。值得说明的是,这种数据不需要进行额外的人工标注,因为这类数据本来就是人写的,模型要做的事情就是根据这些人写出的文本,去学习「给定了前面的文字,接着这些文字后面这个地方应该是什么」的问题。这便是业内所称的「无监督训练」,实际上模型并不是真的没有监督(不然模型学什么呢?),只是它的数据不需要额外的人工标注。也正因为这个任务是不需要额外标注的,因此可以「免费」获得大量的数据,得益于互联网的普及,可以「轻松地」获得海量的由真人写出的文本内容用来训练。这一点也是 GPT 系列模型的特点之一,用海量的数据,去训练很大的模型。
那么在我们使用 ChatGPT 的时候,它是怎么工作的呢?其实也和它的训练方式一样,模型会根据我们在对话框里输入的内容,去预测接在这些内容的下一个 token 是什么,得到这个 token 后,会将它与前面的内容拼接成一个新的文本给模型,模型再预测下一个 token,如此反复,直到满足某个条件后停止。这个停止的条件有很多不同的设计方式,比如可以是输出的文本达到特定的长度,又或者是模型预测出某个用来代表停止的特殊 token。另外值得一提的是,模型预测下一个 token 时,其实背地里是一个采样的过程。换句话说,模型在预测 token 时,输出的其实是所有可能出现的 token 的概率,然后从这个概率分布里采样一个 token。因此,在使用 ChatGPT 时,会发现即便对于相同的输入,它的输出每次也会不一样,因为在背地里它采样了不一样的 token 作为输出。
了解这些之后,可以再回过头来思考一下模型在学什么。它在学习怎么回答问答吗?又或者说它在学习怎么理解自然语言所蕴含的信息、逻辑、情感?还是说它在学习海量的知识?从训练任务的设计来看,似乎都没有,它只是从海量的文本数据里,学习了「根据输入的这些文本,一个人类在后面会接着写什么」这件事。但正是这样的模型,在「进化」到 ChatGPT 时,它却掌握了丰富的知识、复杂的逻辑推理等等,它似乎掌握了一个人类运用语言所需要的几乎所有的能力。这是一件非常神奇的事情,它的「进化」历程将会在下一章节中做更加深入的介绍。
- 丰富的知识储备:ChatGPT 能够正确回答非常多的问题,包括历史、文学、数学、物理、编程等等。因为目前版本的 ChatGPT 并没有利用外部知识,因此这些知识的内容是「储存」在模型内部的。
ChatGPT 所拥有的丰富知识储备,来自于它的训练数据,以及它足够大的体量,以便学会这些内容。虽然官方并没有公开 ChatGPT 所使用的训练数据的具体细节,但从它的前身 GPT-3 的论文可以推测,这些数据大致可以分为三个大的范畴:网页内容、书籍内容以及百科内容。可想而知的是,这些内容天然地蕴含了大量的知识,百科和书籍自然不必说,而网页内容也包含了许多新闻、评论、观点等,并且网页也包括了很多专门的问答垂直类网站,这些都是 ChatGPT 的知识来源。在官方的介绍里指出 ChatGPT 无法回答 2021 年以后发生的事情,因此合理的猜测是训练的数据收集截止到 2021 年。
但数据量只是其中一个方面,要让模型「掌握」这些数据,其自身的体量是不可能小的。以 GPT-3 为例,它有 1750 亿参数,可以粗浅地理解为,这些数据的内容以及模型的各项能力,都以这一个个参数的具体数值的形式,固定在了训练完成的模型中。感性的理解是,假设一个模型只有 1 个参数,那它什么也干不了。更严谨的分析和对比可以参考这篇论文《Holistic Evaluation of Language Models》的测评,方向性的结论是越大的模型,在需要知识来完成的任务上表现得越好。
论文地址:https://arxiv.org/pdf/2211.09110.pdf
- 逻辑推理与思维链的能力:从第一章图片中的鸡兔同笼的例子可以看出,ChatGPT 具有很强的逻辑推理能力。并且它能够将复杂的内容,通过拆解,分成多个小的步骤,一步步地进行推理,获得最后的答案,这种能力被称为思维链。
从前面的介绍我们知道,模型在训练的时候并没有针对逻辑推理以及思维链做特定的设计。而当前的主流观点认为,逻辑推理和思维链很可能和两个因素相关,第一个是模型的体量,第二个是模型是否在代码数据上进行过训练。
关于模型体量与推理、思维链能力的关系,在《深入理解语言模型的突现能力》中有对应的介绍。下面这张图展示了思维链能力与模型体量的关系。
不同模型不同尺寸的思维链效果对比,图来自论文。GSM8K,SVAMP 和 MAWPS 是三个需要逻辑推理的数学应用题数据集,LaMDA,GPT 和 PaLM 分别是 3 个不同的模型。
简要地说,图表中给出了三个不同的模型,在三个数学应用题数据集上的答对率。而值得关注的是以下几个方面:
思维链的能力(蓝色实线)在模型体量够大的时候产生了效果上的突变;
思维链的能力在模型够大的前提下,效果超过了标准的指令(Standard prompting,黑色实线)方法;
思维链的能力在模型够大的情况下,可以接近甚至超过有监督的方法(橙色虚线)。
用通俗的话来说,就是在模型足够大的时候,思维链的能力突然展现了出来,能够达到、甚至超过那些在推理数据集上专门进行有监督训练的模型。这个图也许部分解释了现在我们看到的 ChatGPT 所具有的优异推理和思维链能力。
而另一个关于推理以及思维链能力的产生因素,与模型是否在代码数据上做过训练有关。目前这一点只是一个推论,《拆解追溯 GPT-3.5 各项能力的起源》中的分析表明体量类似的大型模型,没有在代码上做过训练的话,只有很弱或几乎没有思维链和推理能力。而 ChatGPT 确实是在代码数据上进行过训练的,这一点从它能够理解并生成代码也可以看出来。在第二章回顾发展历程中提到了,OpenAI 在 2021 年就发布了专门针对代码的 CodeX 模型,将代码数据加入 GPT 的训练数据应该就是从那时开始的。
- 按照人的提问或者指令给予回复的能力:ChatGPT 除了可以用狭义的基于「问答」形式的交互以外,还能够按照输入的要求进行回复。例如,在应对「帮我写一封信」这类指令式的要求时,它同样也展现出了优秀的能力。这种能力让它不仅是一个提供答案的「高级搜索引擎」,更是一种可以用自然语言来交互的文字处理工具。
虽然目前大众普遍把目光聚焦在将 ChatGPT 作为一种类搜索引擎的工具,但查阅相关知识并给予回答并不是它的唯一能力。实际上,单就 ChatGPT 本身而言,回答知识性的问题并不是它的强项,毕竟它本身的训练数据被定格在了 2021 年。即便用更新的数据去训练,但它终究跟不上时事的变化,因此要将它用作知识性的问答工具,还是需要与搜索引擎等外部知识源做结合,就像现在 Bing 做的一样。
但换一个角度来看,ChatGPT 像是一个「语言完备」的文本工具,也就是它能够按照你给它的要求,完成指定的、可以用文本形式表达出来的内容,就像下面这个例子。
按照给定的计划内容生成英文邮件进行汇报。
这里所说的「语言完备」,指的是运用语言的能力。可以看出上面这个例子里,其实不涉及知识性的内容,因为需要它写的内容已经提供给它了。但要写出这封邮件,涉及到的是运用语言的能力,比如遣词造句、语种切换、邮件格式等等。
现在我们回过头来,尝试分析它的这种「按照指令完成任务」的能力是怎么获得的。在学界中,这种指令被称为 prompt,实际上对话中的用户输入、问答中的问题也是一种 prompt,因此可以粗浅地理解为,在聊天框里输入的所有内容都是 prompt。如果了解我们在本章第一节介绍语言模型的内容,那么更严谨一些的说法应该是「输入给模型的上文」都是 prompt。
ChatGPT 根据输入的指令(prompt)进行回复的能力,是来自于一种被称为指令微调的模型训练方式(prompt tuning)。其实原理很简单,模型依然还是「根据输入的内容,预测下一个 token 是什么」,只是在指令微调的阶段,输入的内容被换成了这些事先写好的 prompt,而 prompt 后面需要生成的内容,则是事先写好的答案。因此在这一阶段和一开始所说的无监督自回归语言模型训练,最大的不同在于数据。这里的数据,也就是 prompt 以及对应的回复,都是人写的,换句话说,这一阶段用的是人工标注的数据进行的监督训练。
提到人工标注的数据,就自然牵涉到了所需要的数据量了,因为每一条标注数据都是需要成本的。如果是不需要标注(就像第一阶段的训练),那么自然有海量的文本数据可供训练,但如果要标注,那到底需要多少这种数据呢?要知道,让标注人员手写一个 prompt,然后再手写一个几百字的、真实详尽的回答,成本是很高的。根据论文《Training language models to follow instructions with human feedback》的介绍,所需要的数据其实不需要太多(相比于无监督阶段所使用的数据来说)。虽然具体到 ChatGPT 到底使用了多少没有确切的信息公开,但可以确定的是在数量级上一定远比用来进行无监督训练的网页、百科和书籍所构成的数据集要小非常多。
论文地址:https://arxiv.org/pdf/2203.02155.pdf
只需要相对少量的人工标注的 prompt 数据就能达到让模型按照指令做出回复的目的,这一点背后其实隐含了一个现象,在学界内被称为 prompt 的泛化能力。可以想象一下,如今全世界都在不停的向 ChatGPT 提问,所提的问题也必定是千奇百怪的,这些问题其实就是一个个的 prompt。但用来对 ChatGPT 进行指令微调的 prompt 肯定不会有这么多,这说明模型在学习到了一定量的 prompt 和相应的答案以后,它能够「举一反三」地对它没有见过的 prompt 进行回答,这就是 prompt 的泛化能力。文章《拆解追溯 GPT-3.5 各项能力的起源》分析指出,这种泛化能力与在指令微调阶段让模型学习的标注数据数量以及多样性相关。
此外,用少量的 prompt 数据就能微调出类似于 ChatGPT 这样拥有强大能力的模型,背后还隐含了另一个猜测,即模型所表现出来的各项能力,可能在无监督训练的阶段就已经存在于模型当中了。其实这也很好理解,毕竟相比于无监督的数据,这些人工标注的 prompt 数量太少了,很难想象模型是通过对这些仅有的标注数据学习而产生了各种各样的能力。从这个角度来说,指令微调的过程更多只是让模型学会按一定的规范来进行回复,而它的知识、逻辑等能力是早已存在的。
- 「客观公正」的能力:如果对 ChatGPT 询问一些有害或者有争议的问题,可以看到 ChatGPT 的回答都是非常「小心」的,很像是经过训练的新闻发言人般的回答。虽然它目前依然做得不够好,但这种能力是 OpenAI 敢将它公开作为一款产品使用的核心因素。
让模型的输出符合人类的价值观是 OpenAI 一直在做的事情。早在 2020 年 GPT-3 的时候,OpenAI 就发现这种通过网上的数据训练出来的模型,会生成带有歧视、危险、争议的内容。作为一个对外提供服务的产品,这些有害的内容显然是不合适的。而现在的 ChatGPT 在这一点上有着明显的改善,让模型做出这种「行为改变」的主要方法也来自于 InstructGPT 的论文,更确切地说,是通过有监督的指令微调加上人类反馈的强化学习共同完成的,这一点在第二章中也已经做过介绍了。
通过上述的分析可以发现,从技术方法的角度来说,ChatGPT 相关的内容都是已知的,但为什么当前只有它拥有如此惊艳的表现呢。实际上从 ChatGPT 推出之后,NLP 社区就一直在分析这其中的原因,虽然很多结论是推测性的,但也为同类模型的国产化带来一些启示。
模型体量的因素
能力涌现出现的前提是模型体量达到一定的规模,虽然没有具体的指标指引,但从目前的事实情况来看,类似于思维链等比较「高级」的能力,需要在数百亿参数量以上的模型中才表现得足够优异。
数据量的因素
模型的大小不是唯一的因素。DeepMind 在这篇论文《Training Compute-Optimal Large Language Models》提供了一些分析性的结论,指出训练的数据量需要随着模型的体量相应地增加,更确切地说,是模型训练时「见过的 token」数量,需要随着模型体量增加。
论文地址:https://arxiv.org/pdf/2203.15556.pdf
数据质量的因素
对于无监督的数据,数据量相对而言并不是很大的障碍,但数据质量往往更加容易被忽视。实际上在 GPT-3 的论文中,就有专门的内容介绍数据的处理工作。为了清洗 GPT-3 的训练数据,OpenAI 专门训练了一个数据过滤模型,来从海量的网页数据中获取更高质量的数据。相比而言,与 GPT-3 体量相当的一些开源模型,例如 Meta 的 Opt 和 BigScience 的 Bloom,似乎没有进行这一步清洗。这也许是这两个开源模型效果劣于 GPT-3 的原因之一。
此外,数据质量的衡量维度不是单一的,诸如数据的多样性、内容重复度以及数据的分布情况都是需要考虑的因素。例如虽然 GPT-3 所使用的网页、百科、书籍这三大类数据中,网页数据的总量是最多的,但在训练时这三类数据的采样并不是按照实际数据的多寡进行的。
另外值得一提的是,在指令微调的阶段,采用人工编写指令也许是一个重要的影响因素。InstructGPT 的论文明确指出在测评过程中,采用人工编写的指令训练出来的模型,比采用现有的 NLP 数据集通过模版的方式构建指令训练出来的模型有更好的效果。这也许解释了在 T0、FLAN 等由 NLP 数据集构成的指令数据集训练出来的模型为什么效果会差一些。
训练过程的影响
这类巨型模型在训练时通过集群进行训练,同时采用数据并行、模型并行以及 ZeRO 优化器(一种降低训练过程显存占用的方法),这些方式为训练的稳定性引入了更多的变量。如下这篇分析指出甚至模型是否采用 bfloat16 精度都对结果有明显的影响。
分析链接:https://jingfengyang.github.io/gpt
相信了解了上面的这些内容,大家对复刻一个类 ChatGPT 的方式以及会面临的问题会有一个大致的了解。有幸的是 OpenAI 已经证明了这技术路径是能够走通的,ChatGPT 的出现也确实正在改变 NLP 技术的发展走向。
4、未来的展望
ChatGPT 从 2022 年 11 月上线以来,引起了极大的关注。相信即便是非专业领域,甚至是与计算机也很少打交道的群体,或多或少地都知道它的存在,这个现象本身就已经反映出它的出现有些不同寻常。圈外的大众更多的是以好奇、惊讶或者惊叹的方式来感性地认识它的出现。而对从业者来说,它的出现更多的是对未来技术走向的思考。
从技术的角度来说,ChatGPT 的出现标志着 NLP 领域的又一次范式切换。之所以说是「又」一次,是因为在 2018 年,也就是初代 GPT 发布的那一年,与之同年发布的 BERT 模型以自身优异的表现,开创了 NLP 的「预训练 + 微调」范式的时代,具体内容在第二章中已经做过介绍了。这里主要介绍由 ChatGPT 开启的「文本生成 + 指令」的范式。具体来说,就是利用训练好的 ChatGPT 或类似的文本生成模型,通过输入适当的指令(prompt)来完成某一项具体的场景。
这种范式与此前的 NLP 技术应用有很大的不同。不论是早期的利用 LDA、RNN 等统计模型或很小的深度学习模型的时代,还是后来利用 BERT 等预训练配合微调的时代,技术所提供的能力是相对原子化的,距离实际的应用场景有一定的距离。
就拿前面举的让 ChatGPT 根据要求写英文邮件的例子,按照此前的做法,可能需要先抽取实体、事件等内容(比如时间、地点、事件等),然后通过模版或是模型形成邮件的样式,再通过一个翻译模型转化为英文。当然如果数据量足够训练端到端模型的情况下,也可以跳过中间的若干步骤。但不论采用哪种方式,要么需要将最终的场景拆解成原子化的 NLP 任务,要么需要对应的标注数据。而对于 ChatGPT 来说,只需要一个合适的指令。
三个阶段的 NLP 技术范式。
这种生成式模型搭配 prompt 的方式,直接略过了中间的各项 NLP 能力组件,用最直接的方式解决应用场景的问题。在这种范式下,完成终端应用的技术路径将不再是用单点 NLP 能力模块通过搭积木的方式组合起来。
当然,这个过程不是一蹴而就的,也不意味着 NLP 的单点能力变得不重要。从测评的角度来说,每一个单点能力的好坏依然可作为评价模型效果的指标。并且,就某些场景来说单点能力依旧是一个强需求。例如在订票系统中本身就需要针对时间、地点进行提取。但与此前不同的是,ChatGPT 本身也可以完成单点能力,而不需要使用额外的功能模块。
ChatGPT 进行信息提取。
ChatGPT 进行情感判断。
从这个角度来说,可以把 ChatGPT 看作是一个以自然语言作为交互媒介的 NLP 工具。如果说在过去,我们是通过模型 + 数据 + 设计训练任务的方式来完成某项 NLP 能力,那么 ChatGPT 则是通过设计指令来完成这些能力。
可想而知,ChatGPT 的出现大大降低了 NLP 技术的应用门槛。但它目前还不是全能的。最重要的一点在于它缺乏准确可靠的垂直领域知识,为了让它的回答可靠,最直接的方式是为它提供外部的知识来源,就像微软将 Bing 的搜索结果作为它回答的信息来源那样。
因此,「传统」的 NLP 技术并不会就此完全消亡,而是会以「辅助」的角色,作为目前 ChatGPT 短板的补充,这也许会是未来 NLP 技术应用的新范式。