大语言模型技术原理
Posted NineData
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了大语言模型技术原理相关的知识,希望对你有一定的参考价值。
在今天这个时代,人们的工作和生活已经离不开数据访问,而几乎所有平台背后的数据存储和查询都离不开数据库。SQL作为一种数据库的查询和处理语言历史悠久,最早由IBM于上世纪70年代初研究关系数据模型时提出,后续发展为一种广泛使用的数据库标准访问接口。
今天大语言模型的发展给了我们一个契机,重新审视这层标准,如何让人们以更加自然的方式访问数据库,数据以更直接、更灵活的方式返回给客户。由于历史发展的原因,从数据库分析出一个结论,需要“分析人员+报表前端+数据后端+SQL+数据存储”的全路径,这一使用范式在未来将受到挑战。除了自然语言本身的优势外,语境的上下文学习能力、迁移学习和文字总结能力也有很大的发挥空间,带着这些思考,我们有必要了解一下大语言模型背后的发展及其技术原理。
一、大语言模型的发展
大语言模型作为一个被验证可行的方向,其“大”体现在训练数据集广,模型参数和层数大,计算量大,其价值体现在通用性上,并且有更好的泛化能力。相较于传统特定领域训练出来的语言模型,有更广泛的应用场景。这篇文章参考Google和OpenAI相关论文及部分作者的补充,结合我的理解尝试用大家普遍看得明白的语言,对其技术发展和主要实现进行解析。
1.1 Transformer模型的提出
在Transformer提出之前,自然语言处理领域的主流模型是循环神经网络(RNN,recurrent neural network),使用递归和卷积神经网络进行语言序列转换。2017年,谷歌大脑团队在人工智能领域的顶会NeurIPS发表了一篇名为“Attention is all you need”的论文,首次提出了一种新的简单网络架构,即 Transformer,它完全基于注意力机制(attention),完全摒弃了循环递归和卷积。
递归模型通常沿输入和输出序列的符号位置进行计算,来预测后面的值。但这种固有的顺序性质阻碍了训练样例内的并行化,因为内存约束限制了样例之间的批处理。而注意力机制允许对依赖项进行建模,而无需考虑它们在输入或输出序列中的距离。
Transformer避开了递归网络的模型体系结构,并且完全依赖于注意力机制来绘制输入和输出之间的全局依存关系。 在八个P100 GPU上进行了仅仅12个小时的训练之后,Transformer就可以在翻译质量方面达到新的最先进水平,体现了很好的并行能力。成为当时最先进的大型语言模型(Large Language Model, LLM)。
总结两个核心突破:
- 突破了远距离文本依赖的学习限制,避开了递归网络的模型体系结构,并且完全依赖于注意力机制来绘制输入和输出之间的全局依赖关系。关联来自两个任意输入或输出位置的信号所需的操作数随着距离增加,原来需要线性增长或对数增长,现在被收敛成一个常量,并通过多注意头机制保障了准确性。
- 可高度并行进行训练,这对发挥硬件红利以及快速迭代模型非常重要。
下图是论文提到的Transformer模型,对编码器和解码器使用堆叠式的自注意力和逐点式、全连接层,分别如图1的左半部分(编码器)和右半部分(解码器)所示,相关技术细节后面会重点讲到。
OpenAI基于该工作基础上发展了GPT(Generative Pre-training)生成式预训练模型,这里借用网上一张图简单改过,相关细节将在后面展开。
1.2 生成式预训练初现潜力:GPT-1
2018年,OpenAI公司发表了论文“Improving Language Understanding by Generative Pre-training”,
使用的模型有两个阶段,第一阶段是无监督预训练,基于海量的文本集通过Transformer学习一个大容量的语言模型,第二阶段基于标注数据进行参数微调。得到的一般任务不可知模型(或称为通用模型)优于经过判别训练的模型,在论文选定的12种数据集中有9个取得更好效果。 在 GPT-1 中,采用了 12 层Transformer 的结构作为解码器,每个 Transformer 层是一个多头的自注意力机制,然后通过全连接得到输出的概率分布。
这次实践对OpenAI来讲,我觉得是奠定了他们往这个路线发展的核心因素,主要有几个重点突破:
1、证明了通用模型训练具有很大的价值潜力。之前用于学习特定任务的标注数据难以获得,导致模型效果不能持续提升,而通过Transformer无监督训练+少量标注数据的Finetune就取得了更优的效果。
2、论文尝试增加Transformer中间层, 在从2层到12层的数量增加中,平均每增加1层能够提升9%的准确性。加上Transformer本身具备并行能力,这在GPU上无疑潜力巨大。
3、论文发现在第二步的Finetune中添加语言建模作为辅助学习目标,能够提高监督模型的泛化能力,并加速收敛。说明在更海量的数据集时,模型会更收益于辅助学习目标。
虽然论文摘要重点强调了该模型在缺少标注数据情况下对特定任务的优势,但其实以上三点发现对OpenAI后续技术路线影响重大。但GPT-1在生成长文本时,仍然会出现信息遗忘和重复等问题,和特定领域的模型对比还有很多不足。
1.3 泛化能力突破:GPT-2
2019年,OpenAI发表了最新进展,一篇“Language Models are Unsupervised Multitask Learners”的论文。重点实践了更大的模型更广的数据集具有更好的泛化能力。GPT-1是12层的transformer,BERT最深是24层的transformer,GPT-2则是48层,共有15亿个参数的transformer,训练集叫WebText,是从4500万个链接提取文本去重后,得到800万文档共40GB文本。
论文认为现有系统用单个任务来训练的单个领域数据集,是缺乏模型泛化能力的主要原因,因此在更广的数据集上,GPT-2采用了多任务(multitask)的方式,每一个任务都要保证其损失函数能收敛,不同的任务共享主体transformer参数。
最终训练出来的模型在不需要任何参数和模型改动下,在zero-shot(零样本)任务中,在8个数据集中有7个表现为业界最优,这个泛化能力可以说已经很强大了,并且在机器翻译场景取得亮眼结果,GPT也是在2.0出来后,开始备受关注。
1.4 更大参数更大数据集:GPT3
之前的模型要在特定领域有更好表现,依然需要上千条标注样本数据来进行finetune,很大程度影响了模型的通用性,而人类能够根据前面一句话知道语境(in-context),从而正确回答问题。GPT3就通过调大参数(1750亿)来测试in-context 学习能力,并在没有finetune情况下得到以下数据。在参数不断增加的同时,分为三种场景看回答准确率表现:Zero-shot(0样本),One-shot(只给一个标准样本),Few-shot(少量标准样本,1000条左右)。下图可以看到模型参数和样本集对正确性的影响,随着参数增多,Few-shot相比Zero-shot的提升效果在拉大,说明越大的参数对样本具有更强的泛化能力。
论文做了不同参数的验证工作,n(params)是参数梳理,n(layers)是模型层数,d(model)是FFN层数的1/4,d(head)是多注意头的维数,所有测试使用的上下文token数是2048。
GPT-3 在 GPT-2 追求无监督和零次学习的特征基础上进行了改进,转而追求无监督模式下的 few-shot(少量学习)。GPT-3采用了 96 层的多头 Transformer,上下文窗口大小提升至 2048 个 token ,基于更大的数据集 45TB 的文本数据训练,在多个 NLP 数据集上实现了出色的性能。GPT-3更多的工作在工程问题上,比如数据污染处理,GPU并行时减少节点间网络交互和负载均衡等。
论文测试了超过24中场景,GPT-3在许多NLP数据集上实现了强大的性能,包括翻译、问题回答和完形填空任务,以及一些需要实时推理或领域适应的任务,如解读单词、在句子中使用新单词或执行3位数字算术。论文还表明,在few-shot设置下,GPT-3可以生成人类评估者难以区分的新闻文章。
1.5 火爆的ChatGPT:GPT 3.5
2022年3月,OpenAI再次发表论文“Training language models to follow instructions with human feedback”,通过人工反馈和微调,使语言模型与用户对各种任务的意图保持一致。并推出了InstructGPT模型,InstructGPT 是基于 GPT-3 的一轮增强优化,所以也被称为 GPT-3.5。尽管GPT3.5还会犯一些简单的错误,但论文工作表明利用人类反馈进行微调是一个很有前景的方向。
论文提供了一种方法,能通过对人类反馈进行微调,使语言模型在广泛的任务应用中更好地遵从使用者意图。从一组人工编写的prompts和通过OpenAI API提交的prompts开始,论文收集了所需模型行为的标记样本数据集,并使用监督学习对GPT-3进行微调。然后,论文对模型输出进行人工排名,使用来自人类反馈的强化学习(Reinforcement Learning from Human Feedback,RLHF)进一步微调这个监督模型。InstructGPT模型的参数为1.3B,而GPT-3模型的参数为175B,约为InstructGPT模型的130倍,但InstructGPT模型的输出却优于GPT-3模型的输出。
训练过程首先聘请了40个承包商来标注数据,收集提交给OpenAI的prompts的人工答案样本集,以及一些人工写的prompts作为训练监督学习的基线。然后,在更大的prompts集上对比OpenAI的输出,并人工标记差距,据此训练出一个奖励模型(Reward Model)来预测人类喜好的输出。最后用PPO来最大化这个奖励模型和fine-tune对监督模型的效果。这部分具体技术细节将在后面展开。论文认为模型如果有价值观的话,体现更多的是标注者的价值观念而不是更广泛人的价值观。
对人类任务意图的识别,是一个非常重要的能力。ChatGPT 采用 InstructGPT 相同结构的模型,针对 Chat 进行了专门的优化, 同时开放到公众测试训练,以便产生更多有效标注数据。基于人类反馈的强化学习(RLHF)是 ChatGPT 区别于其他生成类模型的最主要特点,该法帮助模型尽量减少有害的、不真实的及有偏见的输出,提升自然沟通效果。 同时,为了更好地支持多轮对话,ChatGPT 引入了一种基于堆栈的上下文管理的机制,帮助 ChatGPT 跟踪和管理多轮对话中的上下文信息,从而在多轮对话中生成连贯自然的回复。
1.6 当前的技术局限性
- 专业的领域,缺乏语料训练的情况下,GPT无法生成合适的回答。
- 可信度问题,缺乏答案的具体来源。
- 时效性问题,大模型底层训练数据是过往数据,再一次训练的成本很高。
- 数理问题会一本正经地胡说八道,Stephen Wolfram创造了计算知识搜索引擎和计算语言wolfram,有机会将自然语言转为计算符号再进行计算,解决这一问题。
- 模型的训练方法有个致命的问题,训练好的模型在回答问题时,在各个答案里选一个最优答案,但答案依然可能是错的,模型本质是黑盒的,目前还未能对内部逻辑进行分解,无法保证不产生有害或伤害客户的描述。如果调教训练模型更加谨慎,可能会拒绝回答(以避免提示的误报)。有时模型最终对一个短语没有反应,但对问题/短语稍作调整,它最终会正确回答。
二、主要技术细节
Google的论文比较简短,看到刘岩推荐的Jay Alammer对Transformer的讲解,这里也做了部分引用,这里希望用大家看得懂的话,抽取主要技术细节讲清楚。
从数学或机器学习的角度来看,语言模型都是对词语序列的概率相关性分布的建模,即利用已经说过的语句(语句可以作为数学中的向量)作为输入条件,预测下一个时刻不同语句甚至语言集合出现的概率分布。 GPT生成式预训练模型也是根据语料概率来自动生成回答的每一个字,ChatGPT在此基础上通过使用基于人类反馈的强化学习(Reinforcement Learning from Human Feedback,RLHF)来干预增强学习以取得更好效果。
2.1 什么是Transformer?
本文重点介绍Transformer核心结构和技术点,略过训练优化部分。
编解码组件结构
Transformer 本质上是一个 Encoder-Decoder 架构,包括编码组件和解码组件。比如在机器翻译任务中,将一种语言的一个句子作为输入,然后将其翻译成另一种语言的一个句子作为输出。编码组件和解码组件可以有很多层,比如Google刚提出时的论文用的是6层,后面GPT-1是12层,然后到GPT-3是96层。
每个编码器由两个子层组成:Self-Attention 层(自注意力层)和 Position-wise Feed Forward Network(前馈网络,缩写为 FFN),每个编码器的结构都是相同的,但是它们使用不同的权重参数。编码器的输入会先流入 Self-Attention 层。它可以让编码器在对特定词进行编码时使用输入句子中的其他词的信息(可以理解为:当我们翻译一个词时,不仅只关注当前的词,而且还会上下文关注其他词的信息)。
解码器也有编码器中这两层,但是它们之间还有一个编解码注意力层(即 Encoder-Decoder Attention),其用来帮助解码器关注输入句子中需要关注的相关部分。
- 编码器对文本的处理
对文本处理和通常的 NLP 任务一样,首先使用词嵌入算法(Embedding)将每个词转换为一个词向量(vector)。在 Transformer 论文摘要提到词嵌入向量的维度是 512,所有编码器都会接收到包含多个大小为 512 的向量列表(List of vectors)。嵌入仅发生在最底层的编码器中,其他编码器接收的是上一个编码器的输出。这个列表大小是我们可以设置的参数——基本上这个参数就是训练数据集中最长句子的长度。对输入序列完成嵌入操作后,每个词都会流经编码器内的两层,然后逐个编码器向上传递。
Self-Attention 原理
之前说Transformer的自注意机制突破了文本关注距离的限制,因此非常关键。先看这样一个句子:
The animal didn\'t cross the street because it was too tired
这个句子中的"it"代表什么意思,是animal,还是street还是其他?这个对人来说很容易,但对模型来说不简单。self-Attention就是用来解决这个问题,让it指向animal。通过加权之后可以得到类似图8的加权情况,The animal获得最大关注。
在self-attention中,每个单词有3个不同的向量,它们分别是Query向量( Q ),Key向量( K )和Value向量( V ),长度均是64。它们是通过3个不同的权值矩阵由嵌入向量 X 乘以三个不同的权值矩阵 W^Q , W^K ,W^V 得到,其中三个矩阵的尺寸也是相同的。均是 512×64 。
Query,Key,Value的概念取自于信息检索系统,举个简单的搜索的例子来说。当你在某电商平台搜索某件商品(年轻女士冬季穿的红色薄款羽绒服)时,你在搜索引擎上输入的内容便是Query,然后搜索引擎根据Query为你匹配Key(例如商品的种类,颜色,描述等),然后根据Query和Key的相似度得到匹配的内容(Value)。
self-attention中的Q,K,V也是起着类似的作用,在矩阵计算中,点积是计算两个矩阵相似度的方法之一,因此式1中使用了QK^T进行相似度的计算。接着便是根据相似度进行输出的匹配,这里使用了加权匹配的方式,而权值就是query与key的相似度。
多注意头机制
Multi-headed attention增强了自注意能力,其一是扩展了关注的位置,使之同时关注多个不同位置,其二是它为注意力层提供了多个“表示子空间”,如论文用了8个注意头,那就有8组不同的Q/K/V矩阵,每个输入的词向量都被投影到8个表示子空间中进行计算。
具体流程如下图,“Thinking Machines"的词向量经过最下面那层编码器后,使用不同的权重矩阵进行 8 次自注意力计算,就可以得到 8 个不同的 Z矩阵(0-7)。然后将8个Z矩阵拼接起来,和权重矩阵W0相乘,就得到最终的矩阵 Z,这个矩阵包含了所有注意力头的信息。这个矩阵会输入到 FFN 层。
现在重新看之前的例子,在多注意头机制下,"it" 关注的词有哪些,顶部的8种颜色代表8个注意头,可以看到有个注意头最关注"the animal",另一个注意头关注"tired",从某种意义上说,模型对“it”这个词的表示融入了“animal”和“tired”的表示。
- 因此多注意头本质上是用更多个角度进行注意力计算再统一起来,能够增强对句子上下文的完整理解。
- 解码器的联动 在解码器中,Transformer block比编码器中多了个encoder-cecoder attention。在encoder-decoder attention中,Q来自于解码器的上一个输出, K 和 V 则来自于编码器的输出。这些向量将在每个解码器的 Encoder-Decoder Attention 层被使用,帮助解码器把注意力关注到输入序列的合适位置。 下图显示在翻译I am a student过程中,每一轮解码器都生成一个词,如图示生成到"a"时,"a"会加入作为下一轮的输入Q,然后解码器结合输入和编码器的K、V,生成"student"。
2.2 ChatGPT是如何提升训练效果的?
ChatGPT的背后是大型语言模型 (Large Language Model,LLM) 生成领域的新训练范式:RLHF (Reinforcement Learning from Human Feedback) ,即基于来自人类反馈的强化学习来优化语言模型。关于RLHF训练有个TAMER框架(Training an Agent Manually via Evaluative Reinforcement)值得参考。
- RLHF 是一项涉及多个模型和不同训练阶段的复杂概念,这里我们按三个步骤分解:
- 预训练一个语言模型 (LM) ;
- 聚合问答数据并训练一个奖励模型 (Reward Model,RM) ;
- 用强化学习 (RL) 方式微调 LM。
GPT3训练后的大语言模型是根据概率分布,计算出下一个最大可能的词,他不管事实逻辑上的准确性,也没有所谓的意识,所以有时会一本正经地胡说八道。RLHF是用生成文本的人工反馈作为性能衡量标准,或更进一步用该反馈作为奖励来优化模型,使得在一般文本数据语料库上训练的语言模型能和复杂的人类价值观对齐。具体步骤如下:
首先,我们使用经典的预训练目标训练一个语言模型。对这一步的模型,OpenAI 在其第一个流行的 RLHF 模型 InstructGPT 中使用了较小版本的 GPT-3。然后进行以下步骤:
- 训练监督策略语言模型
GPT-3本身无法识别人类指令蕴含的不同意图,也很难判断生成内容是否高质量。为了解决这一问题,训练过程是从数据集中随机抽取问题,由标注人员给出高质量答案,相当于提供了一系列人工编写的prompts和对应的答案数据集。然后用这些人工标注好的数据集微调GPT3.5模型,获得SFT模型(Supervised Fine-Tune)。
- 训练奖励模型
训练方法:根据第一阶段的模型,随机抽取问题,给出多个不同的回答,人工选出最优答案进行标注,有点类似教学辅导。将高质量答案的奖励值进入下一轮强化学习RL,训练一个奖励模型来预测人类偏好的输出。
RM 的训练是 RLHF 区别于旧范式的开端。这一模型接收一系列文本并返回一个标量奖励,数值上对应人的偏好。我们可以用端到端的方式用 LM 建模,或者用模块化的系统建模 (比如对输出进行排名,再将排名转换为奖励) 。这一奖励数值将对后续无缝接入现有的强化学习 RL 算法至关重要。
关于模型选择方面,RM 可以是另一个经过微调的 LM,也可以是根据偏好数据从头开始训练的 LM。例如 Anthropic 提出了一种特殊的预训练方式,即用偏好模型预训练 (Preference Model Pretraining,PMP) 来替换一般预训练后的微调过程。微调LM被认为对样本数据的利用率更高,但对于哪种 RM 更好尚无定论。
- 近端策略优化 (Proximal Policy Optimization,PPO)
使用PPO优化奖励模型的策略。使用奖励模型的输出作为标量奖励,并使用PPO算法对监督策略进行微调,以优化该奖励。
训练方法:PPO的核心目的是将在线的人工学习转为离线学习,机器自己给自己打分。利用第二阶段训练好的奖励模型,在数据集中随机抽取问题,使用PPO模型生成多个回答,并用上一阶段训练好的RM模型分别给出质量分数。把回报分数按排序依次传递,产生策略梯度,通过强化学习的方式更新PPO模型参数。
最后步骤2和步骤3可以循环迭代,可以不断完善模型。
PPO算法补充说明:
长期以来出于工程和算法原因,人们认为用强化学习训练 LM 是不可能的。而目前多个组织找到的可行方案是使用策略梯度强化学习 (Policy Gradient RL) 算法、近端策略优化 (Proximal Policy Optimization,PPO) 微调初始 LM 的部分或全部参数。PPO 算法已经存在了相对较长的时间,有大量关于其原理的指南,因而成为 RLHF 中的有利选择。
我们将微调任务表述为 RL 问题。首先,该策略 (policy) 是一个接受提示并返回一系列文本 (或文本的概率分布) 的 LM。这个策略的行动空间 (action space) 是 LM 的词表对应的所有词元 (一般在 50k 数量级) ,观察空间 (observation space) 是可能的输入词元序列(词汇量 ^ 输入标记的数量,比较大) 。奖励函数是偏好模型和策略转变约束 (Policy shift constraint) 的结合。
PPO 算法确定的奖励函数具体计算如下:将提示 x 输入初始 LM 和当前微调的 LM,分别得到了输出文本 y1, y2,将来自当前策略的文本传递给 RM 得到一个标量的奖励 rθ。将两个模型的生成文本进行比较,计算差异的惩罚项,惩罚每个训练批次中生成大幅偏离初始模型的RL策略,以确保模型输出合理连贯的文本。
总体来说,ChatGPT 在人工标注的prompts和回答里训练出SFT监督策略模型,再通过随机问题由模型给出多个答案,然后人工排序,生成奖励模型,再通过PPO强化训练增强奖励效果。最终ChatGPT能够更好理解指令的意图,并且按指令完成符合训练者价值观的输出。
最后,大语言模型作为一个被验证可行的方向,其“大”体现在数据集广泛,参数和层数大,计算量大,其价值体现在通用性上,有广泛的应用场景。大语言模型能够发展,主要还是模型具备很好的并行扩展性,随着数据量和计算量的增加,主要挑战在工程和调优上。海外除了GPT、还有LLama、PaLM等,国内目前也有很多相应的研究,因为很多基础技术以前就存在,最近国内追赶速度也很快,我们预期国内半年左右能够到GPT 3.5水平。NineData也非常看好这个方向,并且已经将大语言模型应用到NineData平台的SQL开发中,支持通过自然语言直接查找、变更数据,提供数据库问题和知识问答、数据库SQL优化建议等多项能力,后续我们还将推出更多有价值的功能,欢迎登陆使用。
https://www.ninedata.cloud
作者简介:
陈长城(天羽),玖章算术技术副总裁,前阿里云资深技术专家,在数据库领域深耕15年,主导了阿里数据库基础架构演进(IOE到分布式、异地多活、容器化存计分离)和云原生数据库工具体系建设。
参考文献:
Google Brain: “Attention is all you need”
OpenAI: “Improving Language Understanding by Generative Pre-training”
OpenAI: “Language Models are Unsupervised Multitask Learners”
OpenAI: “Language Models are Few-Shot Learner”
OpenAI: “Training language models to follow instructions with human feedback”
Luke Cheng:https://github.com/huggingface/blog/blob/main/zh/rlhf.md
Jay Alammar: http://jalammar.github.io/illustrated-transformer/
张俊林:由ChatGPT反思大语言模型(LLM)的技术精要
Datawhale干货
作者:张俊林,编辑:夕小瑶的卖萌屋
导读:ChatGPT出现后惊喜或惊醒了很多人。惊喜是因为没想到大型语言模型(LLM,Large Language Model)效果能好成这样;惊醒是顿悟到我们对LLM的认知及发展理念,距离世界最先进的想法,差得有点远。我属于既惊喜又惊醒的那一批,也是典型的中国人,中国人善于自我反思,于是开始反思,而这篇文章正是反思的结果。
实话实说,国内在LLM模型相关技术方面,此刻,距离最先进技术的差距进一步加大了。技术领先或技术差距这事情,我觉得要动态地以发展的眼光来看。在Bert出现之后的一到两年间,其实国内在这块的技术追赶速度还是很快的,也提出了一些很好的改进模型,差距拉开的分水岭应该是在 GPT 3.0出来之后,也就是2020年年中左右。在当时,其实只有很少的人觉察到:GPT 3.0它不仅仅是一项具体的技术,其实体现的是LLM应该往何处去的一个发展理念。自此之后,差距拉得越来越远,ChatGPT只是这种发展理念差异的一个自然结果。所以,我个人认为,抛开是否有财力做超大型LLM这个因素,如果单从技术角度看,差距主要来自于对LLM的认知以及未来应往何处去的发展理念的不同。
国内被国外技术甩得越来越远,这个是事实,不承认也不行。前阵子网上很多人担忧说国内AI现在处于“危急存亡之秋”,我觉得倒也不至于这么严重。君不见,这个世界上,具备这么超前眼光的只有OpenAI一家吗?包括Google在内,其实对于LLM发展理念的理解,明显都落后OpenAI一个身位。现实是OpenAI表现过于优秀,把所有人都甩开了,不仅仅是国内。
我觉得,OpenAI对LLM在理念及相关技术方面,领先国外的Google、DeepMind大约半年到一年的时间,领先国内大概两年左右的时间。在LLM这个事情上,感觉梯队很明显,Google应该是排在第二位,最能体现Google技术眼光的是PaLM和Pathways,推出时间大概在22年2月到4月间,同一时期,OpenAI推出的却是InstructGPT,从这里就可以看出Google和OpenAI的差距了,至于为何这么说,你看了我后面的正文后大概能理解。DeepMind之前的重心一直在强化学习攻克游戏和AI for science这些方面,切入LLM其实很晚,应该是21年才开始重视这个方向,目前也处于追赶状态。Meta就更不用说了,重心一直不在LLM上,目前感觉也发力开始追赶。这还是目前做得最好的一批机构,尚且如此,更何况国内呢?我觉得情有可原。至于OpenAI关于LLM的理念是什么,我在本文的最后一部分,会谈谈我的认知。
本文梳理自GPT 3.0出现之后的主流LLM技术,在此之前的主流技术可以参考:
《乘风破浪的PTM:两年来预训练模型的技术进展》
https://zhuanlan.zhihu.com/p/254821426
我相信看完这两篇文章,能够让您对LLM领域的技术脉络,LLM技术发展过程中出现过的不同发展理念,乃至未来可能的发展趋势,有比较清晰的认知。当然,很多地方讲的内容是我个人看法,有很大的主观性,错漏难免,所以还请谨慎参考。
本文试图回答下面一些问题:ChatGPT是否带来了NLP乃至AI领域的研究范式转换?如果是,那会带来怎样的影响?LLM从海量数据中学到了什么知识?LLM又是如何存取这些知识的?随着LLM规模逐步增大,会带来什么影响?什么是In Context Learning?为什么它是一项很神秘的技术?它和Instruct又是什么关系?LLM具备推理能力吗?思维链CoT又是怎么做的?等等,相信看完,能让您对这些问题有一个答案。
首先,在谈LLM技术现状前,先宏观地谈下我心目中的研究范式转换问题。这样,我们才能“先见森林,再见树木”,对具体技术为何会是如此变化有个更清晰的认知。
01 潮流之巅:NLP研究范式的转换
如果我们把时间线往前拉得更长一些,回到NLP领域的深度学习时代,在更长时间窗口内观察技术变迁及其影响,可能会更容易看清其中的一些关键节点。我个人认为,在最近10年来NLP领域的技术发展过程中,可能存在两次大的研究范型转换。
1. 范式转换1.0:从深度学习到两阶段预训练模型
这个范式转换所涵盖的时间范围,大致在深度学习引入NLP领域(2013年左右),到GPT 3.0出现之前(2020年5月左右)。
在Bert和GPT模型出现之前,NLP领域流行的技术是深度学习模型,而NLP领域的深度学习,主要依托于以下几项关键技术:以大量的改进LSTM模型及少量的改进CNN模型作为典型的特征抽取器;以Sequence to Sequence(或叫encoder-decoder亦可)+Attention作为各种具体任务典型的总体技术框架。
在这些核心技术加持下,NLP领域深度学习的主要研究目标,如果归纳一下,是如何有效增加模型层深或模型参数容量。就是说,怎么才能往encoder和decoder里不断叠加更深的LSTM或CNN层,来达成增加层深和模型容量的目标。这种努力,尽管确实不断增加了模型层深,但是从解决具体任务的效果角度看,总体而言,不算很成功,或者说和非深度学习方法相对,带来的优势不算大。
深度学习之所以不够成功,我认为主要原因来自于两个方面:一方面是某个具体任务有限的训练数据总量。随着模型容量的增加,需要靠更大量的训练数据来支撑,否则即使你能把深度做起来,任务效果也做不上去。而在预训练模型出现之前,很明显这是NLP研究领域一个严重问题;另外一个方面是LSTM/CNN特征抽取器,表达能力不够强。意思是就算给你再多的数据也没用,因为你不能有效地吸收数据里蕴含的知识。主要应该是这两个原因,阻碍了深度学习在NLP领域的成功突围。
Bert/GPT这两个预训练模型的出现,无论在学术研究角度看,还是工业应用角度来看,都代表了NLP领域的一个技术飞跃,并带来了整个领域研究范式的转换。这种范式转换带来的影响,体现在两个方面:首先,是部分NLP研究子领域的衰退乃至逐步消亡;其次,NLP不同子领域的技术方法和技术框架日趋统一,在Bert出现后一年左右,技术栈基本收敛到两种技术模式中。关于这两点,我们分头来谈。
影响一:中间任务的消亡
NLP是一个宏观研究领域的统称,里面有五花八门具体的子领域与子方向,如果仔细分析,从任务的性质角度,可以把这些任务分成两大类:一类可以叫做“中间任务”,一类可以称为“最终任务”。
典型的中间任务包括:中文分词、词性标注、NER、句法分析、指代消解、语义Parser等,这类任务一般并不解决应用中的实际需求,大多数是作为那些解决实际需求任务的中间阶段或者辅助阶段存在的,比如几乎没有需求说,我要一个句法Parser,把这个句子的句法分析树给用户看看,用户不需要看到这些NLP的中间阶段处理结果,他只关心某个具体任务你有没有干好。“最终任务”包括比如文本分类、文本相似性计算、机器翻译、文本摘要等等,有很多。这类任务的特点是每个子领域都解决某个实际需求,任务结果基本能直接呈现给用户,比如用户确实存在给你一句英文,告诉他中文是什么的需求。
按理说,“中间任务”就不应该出现,而之所以会存在,这是NLP技术发展水平不够高的一种体现。在技术发展早期阶段,因为当时的技术相对落后,很难一步做好有难度的最终任务。比如机器翻译,早期技术要做好机器翻译是很困难的,于是科研人员就把难题分而治之,分解成分词、词性标注、句法分析等各种中间阶段,先把每个中间阶段做好,然后再拼起来完成最终任务,这也是没办法的事情。
但是自从Bert/GPT出现之后,其实就没有必要做这些中间任务了,因为通过大量数据的预训练,Bert/GPT已经把这些中间任务作为语言学特征,吸收到了Transformer的参数里,此时我们完全可以端到端地直接解决那些最终任务,而无须对这种中间过程专门建模。这里可能争议最大的是中文分词,其实道理也是一样的,哪些字应该组成一个词,这个其实你不用管,让LLM自己当特征去学就行了,只要对于解决任务有帮助,它自然会去学该学的合理分词方式,也未必一定要和我们人类理解的分词规则相同。
基于以上认知,其实在Bert/GPT一出现,你就应该得出这类NLP的中间阶段的任务,会逐步退出历史舞台这个结论。
影响二:不同研究方向技术路线的统一
在说明具体影响前,我们先讨论下另外一种NLP任务划分方式,这对于理解后面内容有帮助。如果对“最终任务”进一步进行分类,又大致可以分为两大不同类型的任务:自然语言理解类任务和自然语言生成类任务。如果排除掉“中间任务”的话,典型的自然语言理解类任务包括文本分类、句子关系判断、情感倾向判断等,这种任务本质上都是分类任务,就是说输入一个句子(文章),或者两个句子,模型参考所有输入内容,最后给出属于哪个类别的判断。自然语言生成也包含很多NLP研究子方向,比如聊天机器人、机器翻译、文本摘要、问答系统等。生成类任务的特点是给定输入文本,对应地,模型要生成一串输出文本。这两者的差异主要体现在输入输出形式上。
自从Bert/GPT模型诞生后,出现了明显的技术统一趋向。首先,NLP中不同的子领域,其特征抽取器都逐渐从LSTM/CNN统一到Transformer上。其实,自Bert公开后不久,就应该意识到,这必然会成为技术趋势。至于其原因,在几年前我写的这篇:
《放弃幻想,全面拥抱Transformer:自然语言处理三大特征抽取器(CNN/RNN/TF)比较》
https://zhuanlan.zhihu.com/p/54743941
中做了说明和分析,感兴趣的同学可参考。而且,目前Transformer不仅统一了NLP诸多领域,也正在逐步地替换图像处理各种任务中被广泛使用的CNN等其它模型的进程之中,类似的,多模态模型目前也基本都采用了Transformer模型。这种Transformer从NLP出发,攻城略地逐步统一AI越来越多领域的趋势,起始于2020年底出现的Vision Transformer (ViT) ,之后蓬勃发展,到目前已大获成功,且其继续向更多领域拓展的势头会越来越迅猛。
其次,大多数NLP子领域的研发模式切换到了两阶段模式:模型预训练阶段+应用微调(Fine-tuning)或应用Zero/Few Shot Prompt模式。更准确地说,NLP各种任务其实收敛到了两个不同的预训练模型框架里:对于自然语言理解类任务,其技术体系统一到了以Bert为代表的“双向语言模型预训练+应用Fine-tuning”模式;而对于自然语言生成类任务,其技术体系则统一到了以GPT 2.0为代表的“自回归语言模型(即从左到右单向语言模型)+Zero /Few Shot Prompt”模式。至于为何会分化成两条技术路线,有其必然性,关于这点我们放在后面解释。
这两种模式,看似比较相像,但其背后蕴含了迥异的发展思路,也会导向不同的未来发展方向。不过遗憾的是,我们中的绝大多数人,在当时都低估了GPT 这条发展路线的潜力,而把视觉中心聚焦到了Bert这种模式上。
2. 范式转换2.0: 从预训练模型走向通用人工智能 (AGI,Artificial General Intelligence)
这个范式转换所涵盖的时间范围,大致在GPT3.0出现之后(20年6月左右),一直到目前为止,我们应该正处于这个范式转换过程中。
ChatGPT是触发这次范型转换的关键节点,但是在InstructGPT出现之前,其实LLM处于这次范式转换前的一个过渡期。
过渡期:以GPT 3.0为代表的“自回归语言模型+Prompting”模式占据统治地位
前面说过,在预训练模型发展的早期,技术框架收敛到了Bert模式和GPT模式这两种不同的技术范型,而且人们普遍更看好Bert模式一些,相当多数的后续技术改进,都是沿着Bert那条路走的。但是,随着技术的继续发展,你会发现,目前规模最大的LLM模型,几乎清一色都是类似GPT 3.0这种“自回归语言模型+Prompting”模式的,比如GPT 3、PaLM、GLaM、Gopher、Chinchilla、MT-NLG、LaMDA等,没有例外。为什么会这样呢?背后一定有其必然性,我认为可能主要源于两个原因。
首先,Google的T5模型,在形式上统一了自然语言理解和自然语言生成任务的外在表现形式。如上图所示,标为红色的是个文本分类问题,黄色的是判断句子相似性的回归或分类问题,这都是典型的自然语言理解问题。在T5模型里,这些自然语言理解问题在输入输出形式上和生成问题保持了一致,也就是说,可以把分类问题转换成让LLM模型生成对应类别的字符串,这样理解和生成任务在表现形式就实现了完全的统一。
这说明自然语言生成任务,在表现形式上可以兼容自然语言理解任务,若反过来,则很难做到这一点。这样的好处是:同一个LLM生成模型,可以解决几乎所有NLP问题。而如果仍然采取Bert模式,则这个LLM模型无法很好处理生成任务。既然这样,我们当然倾向于使用生成模型,这是一个原因。
第二个原因,如果想要以零示例提示语(zero shot prompting)或少数示例提示语(few shot prompting)的方式做好任务,则必须要采取GPT模式。现在已有研究(参考:On the Role of Bidirectionality in Language Model Pre-Training)证明:如果是以fine-tuning方式解决下游任务,Bert模式的效果优于GPT模式;若是以zero shot/few shot prompting这种模式解决下游任务,则GPT模式效果要优于Bert模式。这说明了,生成模型更容易做好zero shot/few shot prompting方式的任务,而Bert模式以这种方式做任务,是天然有劣势的。这是第二个原因。
但是问题来了:为什么我们要追求zero shot/few shot prompting这种方式来做任务呢?要解释清楚这个问题,我们首先需要搞清楚另外一个问题:什么样的LLM模型,对我们是最理想的?
上图展示了一个理想的LLM该有的样子。首先,LLM应该具备强大的自主学习能力。假设我们把世界上能获得的所有文本或者图片等不同类型的数据喂给它,它应该能够自动从中学习到里面包含的所有知识点,学习过程不需要人的介入,并且能灵活应用所学知识,来解决实际问题。因为数据是海量的,要吸收所有知识,就要非常多的模型参数来存储知识,所以这个模型必然会是一个巨无霸模型。
其次,LLM应该能解决NLP任何子领域的问题,而不仅支持有限领域,甚至它应该可以响应NLP之外其它领域的问题,最好是任意领域的问题都能得到很好地回答。再者,当我们使用LLM解决某个具体领域问题的时候,应该用我们人类习惯的表达方式,就是说LLM应该理解人类的命令。这体现出让LLM适配人,而不是反过来,让人去适配LLM模型。人适配LLM的典型例子,比如绞尽脑汁去尝试各种不同的prompt,以试图找到好的提示语,才能很好地解决手头问题。关于这点,上图在人类和LLM交互的接口层,举了几个例子,说明什么是好的人使用LLM模型的接口形式。
看完这个理想中的LLM,我们再回头解释上面遗留的问题:为什么我们要追求zero shot/few shot prompting这种方式来做任务呢?有两个原因。
第一,这个LLM模型规模必然非常巨大,有能力作出这个模型,或改动这个模型参数的机构必然很少。而任务需求方是千千万万的中小机构甚至是个人,就算你把模型开源出来,他们也无力部署这个模型,更不用说再用Fine-tuning这种模式去修改模型参数了。所以,我们应该追求不修正模型参数,就能让任务需求方完成任务的方式,也就是应该采取prompt模式完成任务,而非Fine-tuning模式(由此可看出,soft prompting技术方向是违背这个发展趋势的)。模型制作方则将LLM作成公用服务,以LLM as Service的模式运行。作为服务支持方,考虑到千变万化的用户需求,所以LLM模型制作方更要追求让LLM能完成尽可能多类型的任务,这是附带的影响,也是为何超级大模型一定会追求走向AGI的现实因素。
第二,zero shot prompting也好,few shot prompting也好,甚至促进LLM推理能力的思维链(CoT,Chain of Thought)Prompting也好,就是上图中接口层中的现有技术。具体而言,zero shot prompting的初衷,其实就是人类和LLM的理想接口,直接用人类所习惯的任务表述方式让LLM做事情,但是发现LLM并不能很好地理解,效果也不好。经过继续研究,转而发现:对于某项任务,如果给LLM几个示例,用这些示例来代表任务描述,效果会比zero shot prompting好,于是大家都去研究更好的few shot prompting技术。可以理解为,本来我们希望LLM能够用人类常用的命令方式来执行某个任务,但是目前技术还做不到,所以退而求其次,用这些替代技术来表达人类的任务需求。
如果理解了上述逻辑,很容易得出如下结论:few shot prompting(也被称为In Context Learning)只是一种过渡时期的技术。如果我们能够更自然地去描述一个任务,而且LLM可以理解,那么,我们肯定会毫不犹豫地抛弃这些过渡期的技术,原因很明显,用这些方法来描述任务需求,并不符合人类的使用习惯。
这也是为何我将GPT 3.0+Prompting列为过渡期技术的原因,ChatGPT的出现,改变了这个现状,用Instruct取代了Prompting,由此带来新的技术范式转换,并产生若干后续影响。
影响一:让LLM适配人的新型交互接口
在理想LLM的背景下,我们再来看ChatGPT,能更好理解它的技术贡献。ChatGPT应该是目前所有的现有技术里,最接近理想LLM的技术方法。如果归纳下ChatGPT最突出特点的话,我会用下面八个字:“能力强大,善解人意”。
“能力强大”这一点,我相信应该主要归功于ChatGPT所依托的基础LLM GPT3.5。因为ChatGPT 尽管加入了人工标注数据,但是量级只有数万,这个规模的数据量,和训练GPT 3.5模型使用的几千亿token级别的数据量相比,包含的世界知识(数据中包含的事实与常识)可谓沧海一粟,几可忽略,基本不会对增强GPT 3.5的基础能力发挥什么作用。所以它的强大功能,应该主要来自于隐藏在背后的GPT 3.5。GPT 3.5对标理想LLM模型中的那个巨无霸模型。
那么,ChatGPT向GPT 3.5模型注入新知识了吗?应该是注入了,这些知识就包含在几万人工标注数据里,不过注入的不是世界知识,而是人类偏好知识。所谓“人类偏好”,包含几方面的含义:首先,是人类表达一个任务的习惯说法。比如,人习惯说:“把下面句子从中文翻译成英文”,以此表达一个“机器翻译”的需求,但是LLM又不是人,它怎么会理解这句话到底是什么意思呢?你得想办法让LLM理解这句命令的含义,并正确执行。所以,ChatGPT通过人工标注数据,向GPT 3.5注入了这类知识,方便LLM理解人的命令,这是它“善解人意”的关键。其次,对于什么是好的回答,什么是不好的回答,人类有自己的标准,例如比较详细的回答是好的,带有歧视内容的回答是不好的,诸如此类。这是人类自身对回答质量好坏的偏好。人通过Reward Model反馈给LLM的数据里,包含这类信息。总体而言,ChatGPT把人类偏好知识注入GPT 3.5,以此来获得一个听得懂人话、也比较礼貌的LLM。
可以看出,ChatGPT的最大贡献在于:基本实现了理想LLM的接口层,让LLM适配人的习惯命令表达方式,而不是反过来让人去适配LLM,绞尽脑汁地想出一个能Work的命令(这就是instruct技术出来之前,prompt技术在做的事情),而这增加了LLM的易用性和用户体验。是InstructGPT/ChatGPT首先意识到这个问题,并给出了很好的解决方案,这也是它最大的技术贡献。相对之前的few shot prompting,它是一种更符合人类表达习惯的人和LLM进行交互的人机接口技术。
而这必将启发后续的LLM模型,继续在易用人机接口方面做进一步的工作,让LLM更听话。
影响二:很多NLP子领域不再具备独立研究价值
就NLP领域而言,这次范式转换,意味着很多目前独立存在的NLP研究领域,将被纳入LLM的技术体系,进而不再独立存在,逐步消失。经过第一次范式转换,尽管NLP中很多“中间任务”,继续作为独立研究领域存在不再必要,但是大多数“最终任务”,仍然是以独立研究领域存在的,只是切换成在“预训练+fine-tuning”框架下,面对领域独有问题,陆续提出新的改进方案。
目前研究表明,很多NLP任务,随着LLM模型规模增长,效果会大幅提升。据此,我觉得可得到如下推论:大多数某领域所谓“独有”的问题,大概率只是缺乏领域知识导致的一种外在表象,只要领域知识足够多,这个所谓领域独有的问题,就可以被很好地解决掉,其实并不需要专门针对某个具体领域问题,冥思苦想去提出专用解决方案。也许AGI的真相超乎意料地简单:你只要把这个领域更多的数据交给LLM,让它自己学习更多知识即可。
在这个背景下,同时,ChatGPT证明了我们现在是可以直接去追求理想LLM模型的,那么,未来的技术发展趋势应该是:追求规模越来越大的LLM模型,通过增加预训练数据的多样性,来涵盖越来越多的领域,LLM自主从领域数据中通过预训练过程学习领域知识,随着模型规模不断增大,很多问题随之得到解决。研究重心会投入到如何构建这个理想LLM模型,而非去解决某个领域的具体问题。这样,越来越多NLP的子领域会被纳入LLM的技术体系,进而逐步消失。
我认为,判断某个具体领域是否该立即停止独立研究,其判断标准可采取以下两种方法,占其一即可:第一,判断某个任务,是否LLM的研究效果超过人类表现,对于那些LLM效果超过人类的研究领域,已无独立研究的必要。举个例子,GLUE与SuperGLUE测试集合里的很多任务,目前LLM效果已超过人类表现,与这个数据集合密切相关的研究领域,其实就没有继续独立存在的必要。第二,对比两种模式的任务效果,第一种模式是用较大的领域专用数据进行Fine-tuning,第二种是few-shot prompting或instruct-based方法。如果第二种方法效果达到或超过第一种方法,则意味着这个领域没有继续独立存在的必要性。如果用这个标准来看,其实很多研究领域,目前fine-tuning效果还是占优的(因为这种模式领域训练数据量大),看似还可独立存在。但是考虑到很多任务随着模型规模增大,few shot prompting效果持续增长,随着更大模型的出现,这个拐点很可能短期就会达到。
如果上述猜测成立,将意味着如下残酷事实:对于很多NLP领域的研究人员,将面临往何处去的选择,是继续做领域独有问题呢?还是放弃这种看似前途不大的方式,转而去建设更好的LLM?如果选择转向去建设LLM,又有哪些机构有能力、有条件去做这个事情呢?你对这个问题的回答会是什么呢?
影响三:更多NLP之外的研究领域将被纳入LLM技术体系
如果站在AGI的视角,参照之前描述的理想LLM模型,它所能完成的任务,不应局限于NLP领域,或某一两个学科领域,理想中的LLM应该是领域无关的通用人工智能模型,它现在在某一两个领域做得好,不代表只能做这些任务。ChatGPT的出现,证明了现在这个时期,我们去追求AGI是有可行性的,而现在是抛开“领域学科”这个思维束缚的时候了。
ChatGPT除了展示出以流畅的对话形式解决各种NLP任务外,也具备强大的代码能力。很自然的,之后越来越多其它的研究领域,也会被逐步纳入LLM体系中,成为通用人工智能的一部分。
LLM从NLP向外进行领域拓展,一个自然的选择就是图像处理及多模态相关任务。目前已经有些工作在尝试把多模态融入,让LLM成为一个支持多模态输入输出的通用人机接口,典型的例子包括DeepMind的Flamingo和微软的“Language Models are General-Purpose Interfaces”,上图展示了这种方式的概念结构。
我的判断是无论是图像还是多模态,未来被融入LLM成为好用的功能,可能比我们想象的进度要慢。主要原因在于:尽管图像领域最近两年也一直在模仿Bert预训练的路子,尝试引入自监督学习,释放模型自主从图像数据中学习知识的能力,典型技术就是“对比学习”和MAE,这是两条不同的技术路线。然而,从目前效果来看,尽管取得了很大的技术进步,但貌似这条路尚未走通,这体现在图像领域预训练模型应用到下游任务,带来的效果收益,远不如Bert或GPT应用在NLP下游任务那样显著。所以,图像预处理模型仍需深入探索,以释放图像数据的潜力,而这会迟滞它们被统一到LLM大模型的时间。当然,如果哪天这条路被趟通,大概率会复现NLP领域目前的局面,就是图像处理各个研究子领域可能会逐步消失,被融入到大型LLM中来,直接完成终端任务。
除了图像与多模态,很明显,其它领域也会逐渐被纳入到理想LLM中来,这个方向方兴未艾,是具备高价值的研究主题。
以上是我对范式转换的个人思考,接下来,我们来梳理下GPT 3.0之后LLM模型的主流技术进展。如理想LLM模型所示,相关的技术其实可以分为两大类;一类是关于LLM模型如何从数据中吸收知识,也包括模型规模增长对LLM吸收知识能力带来的影响;第二类是关于人如何使用LLM内在能力来解决任务的人机接口,包括In Context Learning和Instruct两种模式。思维链(CoT)prompting这种LLM推理技术,本质上也属于In Context Learning,因为比较重要,我就把它们单独拎出来讲一下。
02 学习者:从无尽数据到海量知识
从目前研究结果看,Transformer是足够强大的特征抽取器,尚不需要做特别的改进。那么通过预训练过程,Transformer学到了什么?知识是如何存取的?我们又如何修正错误知识?本节讲述这方面的研究进展。
1. 求知之路:LLM学到了什么知识
LLM从海量自由文本中学习了大量知识,如果把这些知识做粗略分类的话,可以分为语言类知识和世界知识两大类。
语言类知识指的是词法、词性、句法、语义等有助于人类或机器理解自然语言的知识。关于LLM能否捕获语言知识有较长研究历史,自从Bert出现以来就不断有相关研究,很早就有结论,各种实验充分证明LLM可以学习各种层次类型的语言学知识,这也是为何使用预训练模型后,各种语言理解类自然语言任务获得大幅效果提升的最重要原因之一。另外,各种研究也证明了浅层语言知识比如词法、词性、句法等知识存储在Transformer的低层和中层,而抽象的语言知识比如语义类知识,广泛分布在Transformer的中层和高层结构中。
世界知识指的是在这个世界上发生的一些真实事件(事实型知识,Factual Knowledge),以及一些常识性知识(Common Sense Knowledge)。比如“拜登是现任美国总统”、“拜登是美国人”、“乌克兰总统泽连斯基与美国总统拜登举行会晤”,这些都是和拜登相关的事实类知识;而“人有两只眼睛”、“太阳从东方升起”这些属于常识性知识。关于LLM模型能否学习世界知识的研究也有很多,结论也比较一致:LLM确实从训练数据中吸收了大量世界知识,而这类知识主要分布在Transformer的中层和高层,尤其聚集在中层。而且,随着Transformer模型层深增加,能够学习到的知识数量逐渐以指数级增加(可参考:BERTnesia: Investigating the capture and forgetting of knowledge in BERT)。其实,你把LLM看作是一种以模型参数体现的隐式知识图谱,如果这么理解,我认为是一点问题也没有的。
“When Do You Need Billions of Words of Pre-training Data?”这篇文章研究了预训练模型学习到的知识量与训练数据量的关系,它的结论是:对于Bert类型的语言模型来说,只用1000万到1亿单词的语料,就能学好句法语义等语言学知识,但是要学习事实类知识,则要更多的训练数据。这个结论其实也是在意料中的,毕竟语言学知识相对有限且静态,而事实类知识则数量巨大,且处于不断变化过程中。而目前研究证明了随着增加训练数据量,预训练模型在各种下游任务中效果越好,这说明了从增量的训练数据中学到的更主要是世界知识。
2. 记忆之地:LLM如何存取知识
由上可知,LLM确实从数据中学到了很多语言类及世界知识。那么,对于某条具体的知识,LLM把它存储到了哪里?又是如何提取出来的?这也是一个有意思的问题。
显然,知识一定存储在Transformer的模型参数里。从Transformer的结构看,模型参数由两部分构成:多头注意力(MHA)部分占了大约参数总体的三分之一,三分之二的参数集中在FFN结构中。MHA主要用于计算单词或知识间的相关强度,并对全局信息进行集成,更可能是在建立知识之间的联系,大概率不会存储具体知识点,那么很容易推论出LLM模型的知识主体是存储在Transformer的FFN结构里。
但这样的定位,粒度还是太粗,无法很好回答具体某条知识是如何存储与提取的,比如 “中国的首都是北京”这条知识,以三元组表达就是<北京,is-capital-of,中国>,其中“is-capital-of”代表实体间关系。这条知识它存储在LLM的哪里呢?
“Transformer Feed-Forward Layers Are Key-Value Memories”给出了一个比较新颖的观察视角,它把Transformer的FFN看成存储大量具体知识的Key-Value存储器。如上图所示(图左是原始论文图,其实不太好理解,可以看做了注释的图右,更好理解些),FFN的第一层是个MLP宽隐层,这是Key层;第二层是MLP窄隐层,是Value层。FFN的输入层其实是某个单词对应的MHA的输出结果Embedding,也就是通过Self Attention,将整个句子有关的输入上下文集成到一起的Embedding,代表了整个输入句子的整体信息。
Key层的每个神经元节点,记载了一对<Key,Value>信息。比如对于上图中FFN第一个隐层的第 个节点 ,也许就是它记载了<北京,is-capital-of,中国>这条知识。 节点对应的key向量,其实指的是节点 和输入层每个节点的权重向量;而对应的Value向量,指的是节点 和FFN第二层的Value层每个节点形成连接的权重向量。每个神经元的Key向量,用于识别输入中的某种语言或者知识模式,是一种模式探测器。如果输入中包含它要检测的某种模式,那么输入向量和 节点的key权重进行向量内积计算,加上Relu,形成 的大数值响应,意味着 检测到了这个模式,于是再把这个响应值,通过 节点的Value权重向量向FFN第二层传播。这等价于将Value向量的值,用响应值加权,然后传递并体现到第二层Value层每个节点的输出上。如此这般,FFN的正向传播计算过程,看起来就像是通过Key检测到某种知识模式,然后取出对应的Value,并把Value体现在FFN的第二层输出上。当然,FFN第二层每个节点,会收集FFN的Key层所有节点信息,所以是一种混合响应,而Value层所有节点的混合响应,可以解读为代表输出单词的概率分布信息。
听着可能还是比较复杂,我们用个极端的例子来说明。我们假设上图的节点 就是记载<北京,is-capital-of,中国>这条知识的Key-Value存储器,它的Key向量,用于检测”中国的首都是…”这个知识模式,它的Value向量,基本存储了与单词“北京”的Embedding比较接近的向量。当Transformer的输入是“中国的首都是[Mask]”的时候, 节点从输入层探测到这个知识模式,所以产生较大的响应输出。我们假设Key层其它神经元对这个输入都没有任何响应,那么对应的Value层的节点,其实只会接收到“北京”这个Value对应的单词embedding,并通过 的大响应值,进行了进一步的数值放大。于是,Mask位置对应的输出,就自然会输出“北京”这个单词。基本就是这么个过程,看着很复杂,其实很简单。
而且这篇文章还指出,Transformer低层对句子的表层模式作出反应,高层对语义模式作出反应,就是说低层FFN存储词法、句法等表层知识,中层和高层存储语义及事实概念知识,这和其它研究结论是一致的。
要我猜,把FFN看成Key-Value存储器这种思路,很可能不是最终的正确答案,但是距离最终正确答案的距离,估计也不太远。
3. 知识涂改液:如何修正LLM里存储的知识
既然我们已知具体的某条世界知识存储在某个或者某些FFN节点的参数里,自然会引发另外一个问题:我们能否修正LLM模型里存储的错误或者过时的知识呢?比如对于问题:“英国的现任首相是谁?”鉴于近年来英国首相频繁更迭,你猜LLM更倾向输出“鲍里斯”还是更青睐“苏纳克”?很明显训练数据中包含“鲍里斯”的数据会更多,这种情况很大可能LLM会给出错误回答,于是我们就有修正LLM里存储的过时知识的必要性。
如果归纳下,目前有三类不同方法来修正LLM里蕴含的知识:
第一类方法从训练数据的源头来修正知识。“Towards Tracing Factual Knowledge in Language Models Back to the Training Data”这篇文章的研究目标是:对于指定的某条知识,我们是否可以定位到是哪些训练数据导致LLM学会了这条知识?答案是肯定的,这意味着我们可以逆向追踪到某条知识对应的训练数据源头。如果利用这项技术,假设我们想要删除某条知识,则可首先定位到其对应的数据源头,删除数据源,然后重新预训练整个LLM模型,这样即可达成删除LLM中相关知识的目的。但是这里有个问题,如果修正一小部分知识,我们就需要重新做一次模型预训练,这样做明显成本太高。所以这种方法不会太有发展前景,可能比较适合那种对于某个特定类别数据的一次性大规模删除场合,不适合少量多次的常规知识修正场景,比如可能比较适合用来做去除偏见等去toxic内容的处理。
第二类方法是对LLM模型做一次fine-tuning来修正知识。一个直观能想到的方法是:我们可以根据要修正成的新知识来构建训练数据,然后让LLM模型在这个训练数据上做fine-tuning,这样指导LLM记住新的知识,遗忘旧的知识。这个方法简单直观,但是也有一些问题,首先它会带来灾难遗忘问题,就是说除了忘掉该忘的知识,还忘掉了不该忘的知识,导致这么做了之后有些下游任务效果下降。另外,因为目前的LLM模型规模非常大,即使是做fine-tuning,如果次数频繁,其实成本也相当高。对这种方法感兴趣的可以参考“Modifying Memories in Transformer Models”。
另外一类方法直接修改LLM里某些知识对应的模型参数来修正知识。假设我们想要把旧知识<英国,现任首相,鲍里斯>,修正到<英国,现任首相,苏纳克>。首先我们想办法在LLM模型参数中,定位到存储旧知识的FFN节点,然后可以强行调整更改FFN中对应的模型参数,将旧知识替换成新的知识。可以看出,这种方法涉及到两项关键技术:首先是如何在LLM参数空间中定位某条知识的具体存储位置;其次是如何修正模型参数,来实现旧知识到新知识的修正。关于这类技术的细节,可以参考“Locating and Editing Factual Associations in GPT”和“Mass-Editing Memory in a Transformer”。理解这个修正LLM知识的过程,其实对于更深入理解LLM的内部运作机制是很有帮助的。
03 规模效应:当LLM越来越大时会发生什么
我们知道,近年来,LLM模型规模在快速增长,目前效果最好的LLM模型,其参数规模大都超过了千亿(100B)参数规模。比如,OpenAI的GPT 3的规模为175B,Google的LaMDA规模为137B,PaLM的规模为540B,DeepMind的Gogher规模为280B等,不一而足。国内也有中文巨型模型,比如智源GLM规模130B,华为“盘古”规模200B,百度“文心”规模260B,浪潮“源1.0”规模245B。那么,一个很自然的问题就是:随着LLM模型规模不断增长,会发生些什么呢?
预训练模型的应用往往是两阶段的:预训练阶段,及具体场景应用阶段。在预训练阶段,其优化目标是交叉熵,对GPT这种自回归语言模型来说,也就是看LLM是否正确预测到了下一个单词;而场景应用阶段,一般要看具体场景的评价指标。一般我们的直觉是:如果LLM模型在预训练阶段的指标越好,自然它解决下游任务的能力就越强。然而,事实并非完全如此。现有研究已证明,预训练阶段的优化指标确实和下游任务表现出正相关关系,但是并非完全正相关。也就是说,只看预训练阶段的指标,来判断一个LLM模型是否够好,这是不够的。基于此,我们分头来看在这两个不同阶段,随着LLM模型增大,有什么影响。
首先,我们先看在预训练阶段,随着模型规模逐步增大,会发生什么。OpenAI在“Scaling Laws for Neural Language Models”中专门研究了这个问题,并提出LLM模型所遵循的“伸缩法则”(scaling law)。如上图所示,这个研究证明:当我们独立增加训练数据量、模型参数规模或者延长模型训练时间(比如从1个Epoch到2个Epoch),预训练模型在测试集上的Loss都会单调降低,也就是说模型效果越来越好。
既然三个因素都重要,那么我们在实际做预训练的时候,就有一个算力如何分配的决策问题:假设用于训练LLM的算力总预算(比如多少GPU小时或者GPU天)给定,那么是应该多增加数据量、减少模型参数呢?还是说数据量和模型规模同时增加,减少训练步数呢?此消彼长,某个要素规模增长,就要降低其它因素的规模,以维持总算力不变,所以这里有各种可能的算力分配方案。最终OpenAI选择了同时增加训练数据量和模型参数,但是采用早停策略(early stopping)来减少训练步数的方案。因为它证明了:对于训练数据量和模型参数这两个要素,如果只单独增加其中某一个,这不是最好的选择,最好能按照一定比例同时增加两者,它的结论是优先增加模型参数,然后才是训练数据量。假设用于训练LLM的算力总预算增加了10倍,那么应该增加5.5倍的模型参数量,1.8倍的训练数据量,此时模型效果最佳。
DeepMind的一项研究(参考:Training Compute-Optimal Large Language Models)更深入地探究了这个问题,其基本结论和OpenAI的结论差不多,比如确实需要同时增加训练数据量和模型参数,模型效果才会更好。而很多大模型在做预训练的时候,并没有考虑这一点,很多LLM大模型只是单调增加模型参数,而固定住了训练数据量,这个做法其实是不对的,限制了LLM模型的潜力。但是它修正了两者的比例关系,认为训练数据量和模型参数是同等重要的,也就是说,假设用于训练LLM的算力总预算增加了10倍,那么应该增加3.3倍的模型参数量,3.3倍的训练数据量,这样模型效果才最好。
这意味着:增加训练数据量的重要性,比我们之前所认为的,还要重要。基于这个认知,DeepMind在设计Chinchilla模型时,在算力分配上选择了另外一种配置:对标数据量300B、模型参数量280B的Gopher模型,Chinchilla选择增加4倍的训练数据,但是将模型参数降低为Gopher的四分之一,大约为70B。但是无论预训练指标,还是很多下游任务指标,Chinchilla效果都要优于规模更大的Gopher。
这带给我们如下启示:我们可以选择放大训练数据,并同比例地减少LLM模型参数,以达到在不降低模型效果的前提下,极大缩小模型规模的目的。缩小模型规模有很多好处,比如在应用的时候,推理速度会快很多等,无疑这是一个很有前途的LLM发展路线。
以上是从预训练阶段来看模型规模的影响,如果从LLM解决下游具体任务效果的角度来看,随着模型规模增大,不同类型的任务有不同的表现,具体而言,有以下三类情况。
第一类任务完美体现了LLM模型的scaling law,就是说随着模型规模逐步放大,任务的表现越来越好,如上图里的(a)图所示。这类任务通常符合如下共性:它们往往都是知识密集型任务,也就是说如果LLM模型包含的知识量越多,这类任务表现越好。而很多研究已经证明越大的LLM模型学习效率越高,也就是说相同训练数据量,模型越大任务效果越好,说明面对的即使是同样的一批训练数据,更大的LLM模型相对规模小一些的模型,从中学到了更多的知识。更何况一般情况下,在增大LLM模型参数的时候,往往会同步增加训练数据量,这意味着大模型可以从更多数据中学习更多的知识点。这些研究可以很好地解释上图,为何随着模型规模增大,这些知识密集型的任务效果越来越好。大多数传统的自然语言理解类任务,其实都属于这种知识密集型任务,而很多任务在近两年获得了极大的效果提升,甚至超过了人类表现。很明显,这大概率是LLM模型的规模增长带来的,而非归功于某项具体的技术改进。
第二类任务展现出LLM具备某种“涌现能力(Emergent Ability)”,如上图(b)所示。所谓“涌现能力”,指的是当模型参数规模未能达到某个阀值时,模型基本不具备解决此类任务的任何能力,体现为其性能和随机选择答案效果相当,但是当模型规模跨过阀值,LLM模型对此类任务的效果就出现突然的性能增长。也就是说,模型规模是解锁(unlock)LLM新能力的关键,随着模型规模越来越大,会逐渐解锁LLM越来越多的新能力。这是个很神奇的现象,因为它意味着如下让人对未来可报乐观预期的可能:或许很多任务,目前LLM还不能很好地解决,甚至站在现在这个时刻的我们看起来,LLM完全没有能力解决这类任务,但因LLM具备“涌现能力”,所以如果我们继续推大模型,也许某一天它的这项能力就被突然解锁了。LLM模型的规模增长会给我们带来意想不到的精彩礼物。
“Beyond the Imitation Game: Quantifying and extrapolating the capabilities of language models”这篇文章指出,这类体现出“涌现能力”的任务也有一些共性:这些任务一般由多步骤构成,要解决这些任务,往往需要先解决多个中间步骤,而逻辑推理能力在最终解决这类任务中发挥重要作用。思维链(Chain of Thought)Prompting是典型的增强LLM推理能力的技术,能大幅提升此类任务的效果,关于CoT技术,在随后小节内容会做解释,此处暂不展开。
问题是,为何LLM会出现这种“涌现能力”现象呢?上述文章以及“Emergent Abilities of Large Language Models”给出了几个可能的解释:
一种可能解释是有些任务的评价指标不够平滑。比如说有些生成任务的判断标准,它要求模型输出的字符串,要和标准答案完全匹配才算对,否则就是0分。所以,即使随着模型增大,其效果在逐步变好,体现为输出了更多的正确字符片段,但是因为没有完全对,只要有任何小错误都给0分,只有当模型足够大,输出片段全部正确才能得分。也就是说,因为指标不够平滑,所以不能体现LLM其实正在逐步改善任务效果这一现实,看起来就是“涌现能力”这种外在表现。
另外一种可能的解释是:有些任务由若干中间步骤构成,随着模型规模增大,解决每个步骤的能力也在逐步增强,但是只要有一个中间步骤是错的,最终答案就是错的,于是也会导致这种表面的“涌现能力”现象。
当然,上面的解释目前还都是猜想,至于为何LLM会出现这种现象,还需要进一步更深入的研究。
还有少部分任务,随着模型规模增长,任务的效果曲线展现出U形特性:随着模型规模逐渐变大,任务效果逐渐变差,但是当模型规模进一步增长,则效果开始越来越好,呈现出U形增长趋势,如上图所示的粉红色PaLM模型在两个任务上的指标走势。为何这些任务表现得如此特殊呢?“Inverse scaling can become U-shaped”这篇文章给出了一种解释:这些任务,内部其实隐含了两种不同类型的子任务,一种是真正的任务,另外一种是“干扰任务(distractor task)”。当模型规模小的时候,无法识别任意一种子任务,所以模型的表现跟随机选择答案差不多,当模型增长到中等规模的时候,主要执行的是干扰任务,所以对真正的任务效果有负面影响,体现为真正任务效果的下降,而当进一步增加模型规模,则LLM可以忽略干扰任务,执行真正的任务,体现为效果开始增长。
对于那些随着模型规模增大,效果一直下降的任务,如果采用思维链(CoT)Prompting,则部分任务的表现转换为遵循Scaling law,即模型规模越大效果越好,而其它任务则转换为U性增长曲线。这其实侧面说明了:此类任务应属于推理类型的任务,所以加入CoT后任务表现会发生质的变化。
04 人机接口:从In Context Learning到Instruct理解
一般我们经常提到的人和LLM的接口技术包括:zero shot prompting、few shot prompting、In Context Learning,以及Instruct。这些其实都是表达某个具体任务的描述方式。不过如果你看文献,会发现叫法比较乱。
其中Instruct 是ChatGPT的接口方式,就是说人以自然语言给出任务的描述,比如“把这个句子从中文翻译成英文”,类似这种。zero shot prompting我理解其实就是现在的Instruct的早期叫法,以前大家习惯叫zero shot,现在很多改成叫Instruct。尽管是一个内涵,但是具体做法是两种做法。早期大家做zero shot prompting,实际上就是不知道怎么表达一个任务才好,于是就换不同的单词或者句子,反复在尝试好的任务表达方式,这种做法目前已经被证明是在拟合训练数据的分布,其实没啥意思。目前Instruct的做法则是给定命令表述语句,试图让LLM理解它。所以尽管表面都是任务的表述,但是思路是不同的。
而In Context Learning和few shot prompting意思类似,就是给LLM几个示例作为范本,然后让LLM解决新问题。我个人认为In Context Learning也可以理解为某项任务的描述,只是Instruct是一种抽象的描述方式,In Context Learning是一种例子示范的例子说明法。当然,鉴于目前这几个叫法用的有点乱,所以上述理解仅代表个人看法。
所以我们此处只对In Context Learning和Instruct进行介绍,不再提zero shot和few shot了。
1. 神秘的In Context Learning
如果你细想,会发现In Context Learning是个很神奇的技术。它神奇在哪里呢?神奇在你提供给LLM几个样本示例 ,然后给它 ,LLM竟然能够成功预测对应的 。听到这你会反问:这有什么神奇的呢?Fine-tuning不就是这样工作的吗?你要这么问的话,说明你对这个问题想得还不够深入。
如果你细想,会发现In Context Learning是个很神奇的技术。它神奇在哪里呢?神奇在你提供给LLM几个样本示例$,....,然后给它x_n+1,竟然能够成功预测对应的y_n+1$ 。听到这你会反问:这有什么神奇的呢?Fine-tuning不就是这样工作的吗?你要这么问的话,说明你对这个问题想得还不够深入。
Fine-tuning和In Context Learning表面看似都提供了一些例子给LLM,但两者有质的不同(参考上图示意):Fine-tuning拿这些例子当作训练数据,利用反向传播去修正LLM的模型参数,而修正模型参数这个动作,确实体现了LLM从这些例子学习的过程。但是,In Context Learning只是拿出例子让LLM看了一眼,并没有根据例子,用反向传播去修正LLM模型参数的动作,就要求它去预测新例子。既然没有修正模型参数,这意味着貌似LLM并未经历一个学习过程,如果没有经历学习过程,那它为何能够做到仅看一眼,就能预测对新例子呢?这正是In Context Learning的神奇之处。这是否让你想起了一句歌词:“只是因为在人群中多看了你一眼 再也没能忘掉你容颜”,而这首歌名叫“传奇”。你说传奇不传奇?
看似In Context Learning没从例子里学习知识,实际上,难道LLM通过一种奇怪的方式去学习?还是说,它确实也没学啥?关于这个问题的答案,目前仍是未解之谜。现有一些研究各有各的说法,五花八门,很难判断哪个讲述的是事实的真相,甚至有些研究结论还相互矛盾。这里提供几个目前的说法,至于谁对谁错,只能你自己把握了。当然,我认为追求这个神奇现象背后的真相,是一个好的研究课题。
试图证明In Context Learning没有从例子中学习的工作是“Rethinking the Role of Demonstrations: What Makes In-Context Learning Work?”。它发现了:在提供给LLM的样本示例$中,y_i是否x_i对应的正确答案,其实并不重要,如果我们把正确答案y_i替换成随机的另外一个答案y_i,这并不影响的效果。这起码说明了一点:并没有提供给那个从x映射到y的映射函数信息y=f(x),否则的话你乱换正确标签,肯定会扰乱这个y=f(x)$ 映射函数。也就是说,In Context Learning并未学习这个输入空间到输出空间的映射过程。
真正对In Context Learning影响比较大的是:x 和 y 的分布,也就是输入文本 x 的分布和候选答案 y 有哪些,如果你改变这两个分布,比如把 y 替换成候选答案之外的内容,则In Context Learning效果急剧下降。
总之,这个工作证明了In Context Learning并未学习映射函数,但是输入和输出的分布很重要,这两个不能乱改。
有些工作认为LLM还是从给出的示例学习了这个映射函数 y=f(x) ,不过是种隐式地学习。比如“What learning algorithm is in-context learning? Investigations with linear models”认为Transformer能够隐式地从示例中学习 x 到 y 的映射过程,它的激活函数中包含了一些简单映射函数,而LLM通过示例能够激发对应的那一个。而“Why Can GPT Learn In-Context? Language Models Secretly Perform Gradient Descent as Meta-Optimizers”这篇文章则将ICL看作是一种隐式的Fine-tuning。
总而言之,目前这还是一个未解之谜。
神奇的Instruct理解
我们可以把Instruct当作一种方便人类理解的任务表述,在这个前提下,目前关于Instruct的研究可以分成两种:偏学术研究的Instruct,以及关于人类真实需求描述的Instruct。
我们先来看第一种:偏学术研究的Instruct。它的核心研究主题是多任务场景下,LLM模型对Instruct理解的泛化能力。如上图中FLAN模型所示,就是说有很多NLP任务,对于每个任务,研究人员构造一个或者多个Prompt模版作为任务的Instruct,然后用训练例子对LLM模型进行微调,让LLM以同时学习多个任务。训练好模型后,给LLM模型一个它没见过的全新任务的Instruct,然后让LLM 解决zero shot任务,从任务解决得是否足够好,来判断LLM模型是否有对Instruct理解的泛化能力。
如果归纳下目前的研究结论(可参考“Scaling Instruction-Fine-tuned Language Models”/“Super-NaturalInstructions: Generalization via Declarative Instructions on 1600+ NLP Tasks”),能够有效增加LLM模型Instruct泛化能力的因素包括:增加多任务的任务数量、增加LLM模型大小、提供CoT Prompting, 以及增加任务的多样性。如果采取任意一项措施,都可以增加LLM模型的Instruct理解能力。
第二种是人类真实需求下的Instruct,这类研究以InstructGPT和ChatGPT为代表。这类工作也是基于多任务的,但是和偏向学术研究类工作最大的不同,在于它是面向人类用户真实需求的。为什么这么说呢?因为它们用于LLM多任务训练的任务描述Prompt,是从大量用户提交的真实请求中抽样而来的,而不是固定好研究任务的范围,然后让研究人员来写任务描述prompt。这里所谓的“真实需求”,体现在两个方面:首先,因为是从用户提交的任务描述里随机抽取的,所以涵盖的任务类型更多样化,也更符合用户的真实需求;其次,某个任务的prompt描述,是用户提交的,体现了一般用户在表达任务需求时会怎么说,而不是你认为用户会怎么说。很明显,这类工作改出来的LLM模型,用户体验会更好。
InstructGPT论文里,也拿这种方法和FLAN那种Instruct based方法做了比较。首先在GPT3上用FLAN提到的任务、数据以及Prompt模版进行微调,来在GPT 3上复现FLAN方法,然后和InstructGPT进行比较,因为InstructGPT的基础模型也是GPT3,所以只有数据和方法的差别,两者可比,结果发现FLAN方法的效果,距离InstructGPT有很大的差距。那么背后的原因是什么呢?论文分析数据后认为,FLAN方法涉及到的任务领域相对少,是InstructGPT涉及领域的子集,所以效果不好。也就是说,FLAN论文里涉及到的任务和用户真实需求是不符的,而这导致在真实场景下效果不够好。而这对我们的启示是:从用户数据中收集真实需求,这事情是很重要的。
In Context Learning和Instruct的联系
如果我们假设In Context Learning是用一些例子来具象地表达任务命令,Instruct是一种更符合人类习惯的抽象任务描述。那么,一个很自然的问题是:它们之间有什么联系吗?比如,我们是否能够提供给LLM完成某个任务的若干具体示例,让LLM找出其对应的自然语言描述的Instruct命令?
如何创建高效的Prompt和ChatGPT等大语言模型AI对话