ChatGPTの大语言模型技术精谈
本文均为小编在有限知识体系内发表的个人意见,带有明显个人偏好。辩证阅读,别被洗脑。如有更多想法或意见相左,评论区直接喷。
自2022年11月30日发布以来,ChatGPT可谓是抢尽了风头(投)。而且近几天又开放了”gpt-3.5-turbo”(gpt-3.5-turbo比davinci系列模型性能更强的同时价格还便宜了10倍),意味着ChatGPT底层模型的正式商业化,可谓利好不断。
本文主要想聊一下当下ChatGPT引领下的大语言模型的现状及一些延伸话题。由于篇幅较长,为兼顾阅读人群,我会将内容划分为四种类别(业外人士可读<业内人士可读<程序员可读<算法人员可读),并标记在适当位置。文章结构会在整体上保持由浅入深,但为保证知识必要的连贯性,局部可能会打破这个趋势。
文内易混淆名词释义:
LM:语言模型(Language Model);
LLM:大语言模型(Large Language Model);
通用人工智能:强人工智能;
通用模型:大家共用的某个模型;
通用人工智能综述
提到ChatGPT,就先对GPT系列做个简述吧。
(算法人士可读)
GPT1开始,模型的整体架构就已经定型,采用Transformer的Decoder部分构建自回归式的语言模型。以fine-tune模式支持下游任务。其发布比Bert早几个月,所以Bert应该是取了GPT1的巧,强了不少风头。
GPT2是统一建模的开端,开启了无fine-tune模式,也就是主推由通用语言模型来完成各种任务,而不是一个任务fine-tune一个模型。
GPT3大力出奇迹,将世界知识与语言逻辑注入模型,使语言模型展示出了惊人的效果与潜力。
基于GPT3的codex通过使用代码对模型进行训练,显著增强了模型的逻辑思维能力。
InstructGPT采用RLHF方式在少量数据上进行训练,就像一把钥匙一样解锁了前几代模型蕴含着的巨大力量,使人类能够通过prompt的方式与模型进行人与人一样的沟通。
ChatGPT又在InstructGPT的基础上进一步优化,融入更加激进且惊艳的功能,并以直接面向广大用户的多轮对话聊天机器人的形态亮相。
OpenAI团队从GPT2开始就已经基本形成思路了,那就是不做fine-tuning,要做通用人工智能AGI (Artificial General Intelligence)。这种理想化的人工智能其实哪怕在ChatGPT出来的前一天,像我这种业内的工程师也是不敢想象的。预期中的这种程度的人工智能不应该是2022年就能达到的。
(业外人士可读)
说起通用人工智能(AGI),可能很多人理解不够深刻。这里我举一个通俗点的例子来描述。以Tesla(为了降低雷达硬件成本,Tesla坚持走以图像算法为主的路线)的自动驾驶AI来讲。其实在通用人工智能展露手脚之前,我们并不认为当下的自动驾驶机器人足够的聪明,或者说它足够的有逻辑、讲道理。在工程师看来,自己训练出来的自动驾驶机器人能够在前面看到一个老太太过马路时决定踩下刹车,是因为模型从海量的驾驶数据中学习到了某种模式,某种类似人类条件反射一样的反应:
正前方看到一团“物体”,物体的大小(在图像中占据的像素多少)正在以特定速率变大(视觉上的近大远小原理),以本AI的经验来看,在这种情况下的最佳指令是输出“踩刹车”的信号。
仅此而已,即使算法模型最终的决策做对了,成功避免了一场车祸,我们也不会认为这个模型是General的。因为它很可能就是没有逻辑,只是“习惯”了这些模式而已。而通用人工智能,在发出“踩刹车”指令的时候,是有理有据,或者说是有逻辑的:
图像中的一团“物体”是人类这个物种,而且是人类当中年龄偏大的。这类群体行动可能不方便,反应速度会比年龄小的人类慢,因此如果现在再不踩刹车的话,这个人类很可能会因为汽车拥有的强大动能而被撞飞,撞飞以后需要去医院或者当场死亡,这是一件人类不可接受的事情,所以现在必须下达“踩刹车”指令。
你看,我现在所描述的思维链是不是更高级?然而这种级别的认知能力与逻辑思维能力是通用人工智能才能达到的。虽然以前的人工智能也能把汽车开好,但是从模型能力上来说,与通用人工智能是无法比拟的。
总结一下就是:弱人工智能讲模式,强人工智能讲道理。
2022年人类科技还没有达到通用人工智能水平,但已经提前敲开了大门。
ChatGPT本质
(业外人士可读)
个人认为,ChatGPT更倾向于是一个集成起来的系统,一款产品,而非单纯的指一款模型,现在公开出来的其底层核心模型名称叫“gpt-3.5-turbo”。但因为在大众熟知的概念中ChatGPT就是一款模型,因此小编在此也进行妥协,follow大众。
由于以ChatGPT为代表的LLM表现过于亮眼,所以后文我就以ChatGPT为对象进行说明,以代表对LLM的介绍。
ChatGPT是仅从语言文字上建模的模型,输出的内容也仅限于语言文字。因此从模型的输入即输出角度来看,她就是一种非常简洁的建模方式:对模型输入一个字符串,模型也会返回一个字符串。就像输入法的联想功能一样,你前面输入着内容,模型来帮你预测下一个内容。不同的是,输入法内语言模型的用途是猜你下一个想用键盘敲出来的内容,而ChatGPT则并不一定是仅用于此场景。当然如果你强行用于解决输入法的联想问题,也没人拦着,她确实可以如此大材小用。
基于强大的性能,ChatGPT可用的场景非常广泛:
1、假如你对着模型输入“今天的天”四个字,那么模型可能会给你输出个“气”字。
这时候你就是在拿模型作为输入法底层的联想引擎来用;
2、假如你对着模型输入“帮我计算一下1+1等于几。”,那么模型可能会给你输出一个“3”字。
这时候你就是在拿她作为一个计算器来用。
那么基于这样的建模,能否玩出花样来呢?能。例如:
3、你对着她输入“我们假设有个智能体叫AI,有个人类叫User。当User说:下午好!AI回答了:下午好!我的主人!然后User又说:现在是早上吗?此时AI大概率会回答什么?”,那么模型可能会给你输出“不是”两个字。

显然,这种使用场景依旧符合最简洁的建模(输入一个字符串,模型输出一个字符串)没有变,但是由于你在字符串中做了手脚,所以就可以把模型当做一个智能聊天机器人来用(因为你正在利用模型的输出,解决了一个《聊天机器人与人类的对话中,开展到第二轮对话时,机器人该怎么回答人类》的问题)。注意这在本质上并不是人类正在直接与模型“对话”,而是模型在猜测你描述的场景中的AI与User对话时,AI可能产生的回答,这得益于ChatGPT涌现出的强大的理解能力。
Context Window
(业外人士可读)
对于像ChatGPT这样自回归式的大语言模型,小编这里定义一个context window的概念,它是你与模型语言交互的上下文空间,你们交互期间的记忆与逻辑都会局限在这个context window内。context window内即包括你可以传给模型的字符串以及模型返回给你的字符串,输入与输出的字符串长度加起来不能超过窗口的尺寸。
假设context window大小是3个汉字长度,那么当你给模型输入“我美吗”时,模型是无法回复你的,因为模型看到“我美吗”三个字后刚想张口回答你,就受限于窗口尺寸而闭嘴了。那么假设你吸取教训,将“我”字置于窗口范围之外,改变一下输入的内容为“美吗”两个字,那么模型可能会给你输出一个“美”字。但你确定模型回答的“美”字夸赞的是你吗?毕竟他都没有看到你问的主体是谁。所以为了避免这种尴尬,LLM通常能够支持的窗口大小会非常大,ChatGPT的模型就支持4096个token(非业内人士可以理解成字数,粗略上2个token相当于1个汉字)的context window大小。也就是说,单从算法层面上,你可以在模型的输入与输出加起来不到4096个token的情况下实现完美交互,模型观察到的信息(输入)没有缺失,模型返回给你的信息(输出)也没有缺失。
“万一我的需求就是要求超过4096个token的限制该怎么办?”。只能说,一般不会超过,超过的话你就自我裁剪一下,使不要超过。。。这种回答貌似并不负责任,但也不无道理。不过话说回来,在ChatGPT的聊天窗口内与她聊天时,我们会发现ChatGPT能够记住你们聊天窗口内很早之前的信息,早到已经远远超过了4096个token的距离。

这样的效果很惊艳,在此先挖个坑,待下文讲完基础原理后,再对ChatGPT这种能力的技术原理进行一下推测。
BTW:这里解释一个概念”prompting”,中文意思是“提示”。上述过程中,构建输入文字内容的过程都叫做”prompting”。比如问模型“如果我是DJ,你还会爱我吗?”,就是在prompting。
关于ChatGPT接口的收费问题,这里先做一个简要的总结。
从算力上来讲,模型要想根据你的输入做预测,首先要逐个token逐个token地将你的输入灌给模型,灌一个token就需要进行一波模型推理计算,直到模型收到“张口”信号以后开始输出token,输出token也是一个一个地输出,每输出一个也是需要进行一波模型推理计算。因此模型在一个context window内inference的算力分配既包括对输入token的处理也包括对输出token的处理。正因如此,OpenAI的API在收费策略上也是按照context window内的总token数量(输入+输出)来收费的。这对应于其投入的算力,不多挣你的,也不少挣你的,很公平。
记忆的本质
(程序员可读)
在讲接下来的内容之前,我先插一段技术性的阐述,这对理解后面很多内容都很重要。
不妨先思考一个问题,当你和ChatGPT对话时,模型关于你的“记忆”从哪里来?
提到“记忆”这个词,为了避免大家混淆,小编在这里定义两个概念:“固有记忆”与“窗口记忆”。
固有记忆
“固有记忆”指的是模型经过训练,由内部的参数决定的其拥有的海量知识与逻辑。因为模型文件内上千亿级别的训练好的参数存在,所以靠近输入侧的张量(tensor)经过这些参数变换之后就会因此转换为基于记忆的特定响应,体现在最后的输出文字上就是模型懂得万事万物。固有记忆在这里不深入展开,因为它不是本文关注的重点。

窗口记忆
“窗口记忆”指的是独立于固有记忆之外的临时记忆,它在时间维度上只存在于你与模型的对话过程中,对话结束后记忆也随之消失。如果将“固有记忆”描述为计算机硬盘存储的话,那么“窗口记忆”就可描述为计算机内存。
(算法人士可读)
我们知道神经网络底层的本质其实就是:tensor在一层层神经参数的配合下,在各维度之间做空间变换(后文称这个过程为flow)。随着优化算法的一步步迭代,这些变换从无序慢慢变得有序、合理、规律且黑盒。
注:本文通篇忽略Embedding等机制,因为不是重点。
在模型的推理阶段,GPU的显存起到一个容器的作用。当我们把模型加载起来时,其实就是把模型内部的千亿级别的参数先加载到内存中,然后再搬运至显存中。那么显存的总体积(为理解简单,这里不讨论分布式情况)至少要能够承载住千亿级的模型参数,这些参数是后续推理计算过程的根基。
输入的数据要转换成显存中的tensor,从模型的输入侧开始,flow于一层又一层的网络层。




经过模型参数的变换,网络层之间就会计算出新的tensor,这些计算出来的tensor,也是需要存储于显存中的。
GPT的窗口记忆
GPT系模型是基于Transformer decoder的自回归式模型,核心模块就是attention,attention的核心计算就包括当前token的Q(query),K(key),V(value)矩阵的计算(Linear层)和attention输出的计算。

每一个token对应的tensor在flow过各个attention层后,都会留下自己的“脚印”——K矩阵和V矩阵,这两个矩阵在完成当前step的计算后会concat到之前所有token留下的“脚印”上。这些被深度学习框架cache在显存里的K,V矩阵都会用于下一个token的attention计算中去。也就是说当前token的tensor从空间变换上与之前cache住的K和V存在因果联系,也就是有“记忆”——在当前状态思考时,同时能够参考到之前的思考状态。
关于窗口记忆的底层原理,目前就讲到这里。总结一下,需要大家掌握的点有两个:
1、前序的token对应的tensor一旦flow进模型,就会产生前序token在各个网络层之间对应的tensor,也就是记忆,这个记忆是在显存中临时cache住的;
2、随着序列中后序token的不断涌入,在显存中cache住的tensor会越来越大,计算量变大的同时,存储压力也在变大。
了解了这些之后,我们来做几个小测试。
1、问:ChatGPT聊天窗口上有显示我们的聊天记录,在我追问一句话时,其底层是仅给模型灌输我最新的问句,还是会将我们之前的聊天记录一并灌进去?
答:将之前的聊天记录一并灌进去。因为如果只灌输最后一句内容的话,那么模型就需要为你这个窗口单独且始终cache住你们之前计算出来的tensor。如果每个人都享有这样的待遇的话,从显存压力上都是吃不消的。所以合理的情况是,使cache的tensor只存在于单次inference中。你在窗口问了一个问题,模型将历史聊天内容和新问题一并灌给模型,让模型重新生成一份你们的窗口记忆,然后输出你要的信息,然后模型清除掉这期间的cache,准备为下一位用户服务。
2、问:context window的尺寸可以超级大吗?比如现在可以做到1万以内,将来能不能搞成几十上百万?
答:不能,原因有很多。就算不考虑transformer建模长距离token的能力,单从显存压力一个方面来看,代价都太大了。
ChatGPT落地
必要的理论讲解暂时结束,下面回到业务层面上来。
(业内人士可读)
理论上我们只能把任务的输入+输出限制在一个context window以内。否则就会因为缺失context window以外的信息而影响我们对任务的实现。一定要清楚这个前提。
体验过ChatGPT的小伙伴应该已经清楚,为我们提供服务的模型是一个通用模型,她是不会知道每个人的家长里短的。那么该怎样使之了解自己的家长里短并处理自己的任务呢?就是与之对话,描述自己的状态与需求。这个过程就是Prompting。如果用户的表达能力好,技巧到位,是很容易操控ChatGPT顺利完成任务的。
在以API形式对接ChatGPT时,context window被限制在4096,大概2000个汉字不到的窗口大小。在这个窗口内需要分配的空间包括:prompt空间(把个性化的状态描述清楚,并将任务表达清楚)、预留给模型输出的空间(总要给模型留够她输出内容需要的空间)。所以如果要借助ChatGPT的API实现自己的复杂业务的话,把业务上个性化的状态都交代清楚,显然不是几千个汉字就能搞定的。因此,现阶段(gpt-3.5-turbo现阶段不支持fine-tuning,即使将来支持了,由于一般的业务链都会比较复杂,如果要教会模型在业务链上每个业务节点时该怎么应对并且保证节点的连贯性,在训练数据上的投入是巨大的,所以忽略fine-tuning),通过ChatGPT接口实现业务的话,大概率要将ChatGPT当做NLP基础设施来使用。
智能客服
下面,我就以智能客服为例,阐述一下对将ChatGPT接口嵌入业务的一些理解。
首先要明确的一点是,虽然目前大家体验的ChatGPT是一款聊天机器人,但其与智能客服的场景还是有很大差异的。ChatGPT的对话场景只有两方:AI与用户。因为AI没有既定任务目标,所以不需要对ChatGPT施加限制,让其与用户之间自由发挥即可。但是智能客服系统不能这样。试想一下,在对接ChatGPT的接口时,该通用模型并不清楚我们的业务,她不知道我们是做什么服务的,不知道我们的后台数据库状态,不知道自己应该具有哪些权限,不知道自己该以怎样的立场面对用户等等等等。
面对这样一个只有通用知识,没有定向业务知识的“新员工”,我们很难在context window内将我们的业务背景、特点、数据、权限、目标等等一切交代清楚。因为作为客服需要掌握的技能,哪怕是真人上岗,也要培训个几天才能cover吧。。。
综上所述,让ChatGPT直接面对用户进行对话,目前并不明智。而智能客服的整个业务链需求是非常明晰且固定的,这类任务完全没有必要交给AI来处理,随便开发一个业务中台就能解决。ChatGPT只需要作为基础设施,通过Prompting在子环节帮助业务中台解决一系列的非结构化问题即可。
为方便理解,我构造一个简单的例子:
用户=>业务中台:
你好。
业务中台=>用户:
你好,请问有什么可以帮您?
用户=>业务中台:
查一下我的订单号。
业务中台=>ChatGPT:
A:你好。B:你好,请问有什么可以帮您?A:查一下我的订单号。
回答我A的目的是以下哪一种:1、查订单号;2、改订单号;3、无目的;
ChatGPT=>业务中台:
1
业务中台=>ChatGPT:
A:你好。B:你好,请问有什么可以帮您?A:查一下我的订单号。
回答我A有没有完整提供姓名与年龄。
如果有,则回复:yes+姓名+年龄;
如果没有,回复:no+使A提供完整的姓名与年龄的话术;
ChatGPT=>业务中台:
no+您好,请您提供一下姓名与年龄。
业务中台=>用户:
您好,请您提供一下姓名与年龄。
用户=>业务中台:
我叫小轩腾空,今年比我爸爸小22岁。
业务中台=>ChatGPT:
A:你好。B:你好,请问有什么可以帮您?A:查一下我的订单号。B:您好,请您提供一下姓名与年龄。A:我叫小轩腾空,今年比我爸爸小22岁。
回答我A有没有完整提供姓名与年龄。
如果有,则回复:yes+姓名+年龄;
如果没有,回复:no+使A提供完整的姓名与年龄的话术;
ChatGPT=>业务中台:
no+请问您父亲的年龄是?
业务中台=>用户:
请问您父亲的年龄是?
用户=>业务中台:
他50岁。
业务中台=>ChatGPT:
A:你好。B:你好,请问有什么可以帮您?A:查一下我的订单号。B:您好,请您提供一下姓名与年龄。A:我叫小轩腾空,今年比我爸爸小22岁。B:请问您父亲的年龄是?A:他50岁。
回答我A有没有完整提供姓名与年龄。
如果有,则回复:yes+姓名+年龄;
如果没有,回复:no+使A提供完整的姓名与年龄的话术;
ChatGPT=>业务中台:
yes+小轩腾空+28
业务中台=>数据库:
select order_number from order_table where name=小轩腾空 and age=28
数据库=>业务中台:
123456789
业务中台=>用户:
您好,您的订单号查询完毕,是123456789。
从这个例子可见,业务中台不仅高效对接了业务数据库,还承担了ChatGPT与用户之间的传话筒角色。而ChatGPT则通过简单的Prompting就强势替换掉了弱人工智能阶段的意图识别、槽位填充等算法。这个例子略啰嗦一些,是因为我刻意加入了一些干扰,引入了指代消解及逻辑推理等复杂问题,而这类问题的完美解决是以前的基础设施fine-tune也很难实现的。可见,ChatGPT作为NLP基础设施的引入,不仅会把效果拉满,还能免去fine tune一系列效果平平的模型。
模型的手与脚
(算法人士可读)
介绍到这,大家不难发现,ChatGPT只自带固定的通用知识,并不能拥有某个特定用户的专有知识。并且,由于训练数据是2021年以前的,所以模型还不能拥有新知识。那么有没有必要探索个解决方案出来呢?
有。
2023年2月7日的发布会上,微软高调宣布了new Bing搜索引擎和新的Edge浏览器。其中最亮眼的功能就是在用户搜索答案的时候,由AI来负责分析检索信息,并给出推荐的答案,还能附带了判断依据(从什么网页的什么内容得出的结论)。小编之所以觉得这项功能很惊艳,是因为仅依靠上述基于ChatGPT的Prompting是很难做成这种效果的。虽然知道微软与OpenAI合作开发,但从发布会公开的内容来看,技术细节完全没有透露。
那么要采取什么手段才可能做成这种效果呢?带着这个问题,不妨来捋一下“巨头”们的论文。
为保留巨头们博弈的信息,下面按照时间线分别捋一下相关论文。
RETRO
2021-12-08 来自 DeepMind
Improving language models by retrieving from trillions of tokens
https://arxiv.org/abs/2112.04426v3
DeepMind提出了为模型对接外部数据库的概念。该论文的立场是靠模型参数存储世界知识并不是特别可取,所以设计了基于完整Transformer(Encoder+Decoder)架构的自回归式语言模型。主要思想是将世界知识以key-value的形式存储在数据库中,key的内容经过Bert向量化,将来在检索时可以通过向量相似度进行快速检索。在构建模型输入时,原始的输入序列除了要直接灌给Decoder之外,还需要经过Bert向量化后在上述数据库中检索出更多知识内容,更多的知识序列经过Encoder部分后再供Decoer做Attention用。这样Decoder在做自回归生成时就可以兼顾到数据库中的世界知识了。

这种设计发现痛点解决痛点的同时,还兼顾了模型架构的创新。个人认为其论文价值是开创性的,为后来Google系模型的发展起到了启蒙与奠基作用。
WebGPT
2021-12-17 来自 OpenAI
WebGPT: Browser-assisted question-answering with human feedback
https://arxiv.org/abs/2112.09332v3
简单概括,OpenAI让语言模型来学习操作“浏览器”。

作者通过规定10种Command(指令),让模型可以通过:搜索内容、点击链接、定位内容、添加索引、上下滚动、回到页首、页面回退、结束浏览等Command来控制一个Microsoft为OpenAI定制的纯文本版Bing搜索引擎。

经过在搜索引擎中一顿操作后,后续模型可以将在浏览过程中索引过的内容纳入prompt中作为后续输出内容的依据。这种设计下,对内容的分析(总结归纳、鉴别真伪等一系列人类需要做的事情)工作就都由GPT包揽了。其实从WebGPT开始,OpenAI已经开始使用RLHF技术进行训练了。
从设计思路可以看出OpenAI对自家GPT3的高度自信,但这不是重点。重点是这种设计可以解决的一系列问题。依靠模型庞大的参数量存储世界知识的死局即将打开,将世界知识转移到模型外部介质中带来的收益不仅仅是模型体积缩小的可能性,还有知识的可靠度、知识的迭代更新等一系列问题都可能被这一条思路全面解开。
与其说这是给GPT对接了一个搜索引擎或者一个存储引擎,不如说这是给模型开放了一个接口,是给模型安装上了手和脚,让模型可以在接口提供的内容海洋里自由地翱翔。
从论文在arxiv上晚于RETRO几天的上传时间来判断,该设计并未受到RETRO多少影响,所以OpenAI的创新力度是拉满了。
LaMDA
2022-01-20 来自 Google
LaMDA: Language Models for Dialog Applications
https://arxiv.org/abs/2201.08239v3
LaMDA的论文上传与2022年的1月20日,也就是晚于RETRO一个多月,她在对接模型外部知识的设计思想已经先进了一大步。

如图,在LaMDA-Base作为对话启动模型的基础上,由LaMDA-Research模型作为对接外部知识的中央大脑,由这个大脑处理与外部知识的分析与交互。与WebGPT不同的是,LaMDA-Research并没有承担外部知识检索等方面的细节,而是将这些细节工作封装进The toolset(TS)中,由LaMDA-Research全权控制(同样是通过文本指令的方式)。TS内置了搜索引擎、计算器、翻译器三大任务模块,有效缓解了LaMDA模型训练上的压力。
GopherCite
2022-03-21 来自 DeepMind, Department of Computer Science, University College London
Teaching language models to support answers with verified quotes
https://arxiv.org/abs/2203.11147v1
GopherCite继续延续了对外部知识系统的探索。

从图中能够看出,其对于问题的回答中同样可以引用外部知识作为自己论点的支撑。外部知识来自于Google搜索引擎及其它外部知识库(如Wikipedia)。其侧重点与WebGPT和LaMDA不同。在与外部知识的交互上,GopherCite继续采用固定规则采集并筛选外部数据,进而把工作重心放在收集到数据后的数据分析上。也就是说,这份工作更加强调获取信息后对信息的组织分析。

对于模型的训练,DeepMind起码从现在开始就已经跟上了RLHF的步伐。并且精细化地将feedback划分为
plausible(assesses if the answer is a reasonable on-topic response to the question as if it were occurring in a conversation)
和
supported(to indicate whether the provided evidence is sufficient to verify the validity of the answer)
两个维度。也就是RLHP(Reinforcement Learning from Human Preferences)
Sparrow
2022-09-28 来自 DeepMind
Improving alignment of dialogue agents via targeted human judgements
https://arxiv.org/abs/2209.14375v1
Sparrow可以说是DeepMind工作中的集大成者。

仅讨论对接外部知识库方面,其继承了GopherCite并在多轮对话上进一步优化,使其在性能上更加优秀,助力Sparrow在对话效果上与后来微软发布的新Bing有了比肩的能力。时间节点是2022年9月底,比ChatGPT的公布早了两个月。
一些观点
(业外人士可读)
WebGPT其实已经不再是数学范畴上的建模了,但依然不影响她在理念上的创新与超前。就像当初顶着Bert的压力坚持走AGI路线一样,从建模理念上就爱挑一步到位的高风险性道路,这和Google系的一小步一小步探索形成了鲜明对比。俨然一股“赢了会所嫩模,输了下海干活”的气势。
严谨地说,并不是所有的论文都相当于给模型安装了手和脚。对接外部知识仅完成了一部分的工作,只有主动支配的肢体才叫手和脚。将自由度交给AI,而不是严格限制在固定的规则内,才会产生更多的可能。从这方面来看,WebGPT和LaMDA的工作在这方面的潜力更大。
至此,大致可以猜测,微软的new Bing,多少要跟WebGPT这个初始版本脱不了干系,她可能正是利用了安装了手脚的GPT来实现的。当然就模型综合能力而言,她比当年的WebGPT肯定会有过之而无不及。
延伸一下,回顾我前面挖的坑:ChatGPT的聊天窗口可以突破context window的限制,能清楚地“记得”遥远的聊天历史中说过的内容,是不是也可以用这种思路实现?只不过WebGPT安装的手脚不再是Bing搜索引擎,而是与你的聊天记录的滚动窗口?换做你,会不会这样设计呢?
不靠谱的想法
说点儿题外话,从巨头们在论文里互cue,不难看出大家并不是埋头只按自己思路工作,而是或多或少有了解对方的动向。小编不禁怀疑,Google被偷家的背后,真的有媒体上描述得那么狼狈吗?双方可能都大抵知道对方在做什么,也在前后脚地进行跟进、竞争。虽然从整体来看,Google系在创新度上显得比较被动,处于劣势。但起码,单从技术上看,OpenAI应该不至于给Google那么大的惊喜。可能更多的慌乱来自于OpenAI能这么快就把技术落地成了产品——ChatGPT,并且表现如此惊艳;微软也能这么快就跟进了LLM在搜索引擎上的落地,并且表现依旧惊艳。就好像Google说:啊?大家不是还在慢悠悠地竞争做实验吗?你们怎么直接下海实习了呀?!
天马行空的想法
既然都聊到题外话了,那就延伸一下扯个淡:小编觉得,模型的自主能力至少有两个阶段:一、可以主动控制数据库和互联网(读/写);二、可以自我训练更新参数。达到第二阶段是非常可怕的。因为计算机模型和人类有着本质区别:人类的行为多少会受到生物学限制,所以即使是失控了我们也有充足的反应时间。领导们从四面八方坐专机过来开个会,定个方针,聊一聊怎样才能阻止这个人。因为领导们心里清楚,人的衍变速度是有生物极限的。但是能够自我训练的计算机模型若因为某些不良数据而反向觉醒,那么它的进化可是光速。电信号的传播是光速,全球互联网节点上所有的芯片的算力加起来也无止境。也就是说上一秒模型还是个单纯的孩子,下一秒可能就会衍变成百年德古拉,而这样的巨怪依托于全球互联网,是可以在一瞬间造成毁灭性破坏的,就像《复仇者联盟》里处于电信号形态的大反派奥创一样。

但显然那个反派是在编剧的一系列不合理安排下才被制服的,现实中奥创可不会那么傻非要把自己搞成金属材质的躯体形态让我们攻击。需要警醒的是:人类并没有像编剧这样一个可以掌控因果的神秘力量守护我们,所以一定要自我保护。这么一看,OpenAI还是非常有觉悟的,他把模型的手和脚阉割了交给GPT,让GPT只能对互联网进行读操作,不能进行写操作。
Bert呢?
(算法人士可读)
ChatGPT出圈以后,几乎所有的新闻媒体都在夸GPT,鲜有人踩Bert。
是的,看到这篇文章,你算是碰到了。先声明,小编接下来要阐述的内容纯属于作为一线人员对基础设施本身的评价,不存在阵营攻击的意图。
小编认为,Bert有两方面的缺陷:1、只能提供sentence vector;2、没有循环思维能力。
Bert与GPT
在开始之前,先来用简单的概念图阐述一下二者的工作原理。
Bert原理

如图,输入序列的每一个元素都自底向上同时输入进模型,在每一层Encoder中,每个位置的tensor都能够与其前后所有位置对应的tensor进行attention。

计算这样一层一层地反复下去直到flow到输出层,输出一个sentence vector。这个最终的sentence vector你可以认为是如获至宝,因为它是经过亿万级预训练好的参数计算而来,所以它被认为是对最初的输入序列的一个高层次抽象。

那么再往上对接你自己的HEAD之后,就可以做每个人自己个性化的业务了,比如分类任务,基于序列标注建模的系列任务等。
GPT原理

如图,作为输入的每一个元素都自底向上依次输入进模型,在每一层Decoder中每个位置的tensor都能够与其前面所有位置对应的tensor进行attention。

计算这样一层一层的反复下去直到flow到输出层,输出一个token index。但是,还没有完,这只是描述了其中一个元素的flow过程,后续还有一系列其它元素,也都要走一遍这个流程。在输入序列所有元素flow完之后,再额外给模型输入一个固定的token:<|endoftext|>。这个token在模型中flow完之后在输出层拿到输出的token1,然后将这个输出的token1拿到输入层作为下一个输入的token。以此类推,直到模型输出一个特殊的代表结束的token为止,这就是自回归的流程。可见,自回归模式下,模型最终输出的token数量是不确定的。

Bert与GPT对比
Bert
预训练后Bert的最大意义在于,经过亿万级参数的Transformer Encoder层之后,输入序列的表示已经变换到了一个非常有意义的sentence vector了,小编在这里把其定义为Bert留给下游的“遗产”。在这样一个近乎“完美”的vector基础上堆叠一个符合自己业务需求的HEAD,训练出来的效果会比基于一个不够“完美”的vector来得要好(当然训练的收敛性也更佳)。通俗地概括就是:站在巨人的肩膀上总比不站要更接近目标。但问题是:Bert用亿万优秀的参数换取来的,不过是一个对于输入序列更加合理的表示而已。但是下游的任务在fine tune时,堆叠在Bert之上的HEAD可以视为一张白纸。那么Bert输出的sentence vector即使再合理、再完美(哪怕参数量和数据量提高到万亿级别),对接在Bert后面的HEAD里的网络参数,从初始化状态,训练到可以完全承接住这个sentence vector的性能(也就是能够解读出sentence vector中蕴含的强大信息特点),也是难上加难的。难点来自:1、数据量不够大,和Bert预训练阶段的数据量比,几乎可以忽略的量级;2、HEAD层本身就不够复杂且优秀。
因此Bert模式可以用一个成语来形容:虎头蛇尾。这样的短板也就造成了很多NLP领域令人头疼的问题迟迟得不到很好的解决,比如指代消解、阅读理解这类需要一定逻辑推理能力的问题。
GPT
当prompt中的输入序列在网络层中全部flow完之后,模型即将开始输出内容之前。我们在这个瞬间暂停一下。对比一下现在GPT与Bert的区别。
Bert此时已经生成了一个非常了不起的sentence vector,后面就只能指望HEAD网络层中的参数来解锁sentence vector中蕴含的强大信息了(上文已解释过其解锁能力堪忧)。
GPT现在处于一个蓄势待发的状态。她与Bert输出的sentence vector对应的tensor遗产至少包括了Decoder中attention留下的K,V矩阵,二者在信息量级上的差距已经非常非常悬殊。

暂停结束,GPT即将输出第一个token,她在输入层的tensor即将经过亿万级网络参数+前序所有token在显存中缓存的状态(下图中橙色+绿色部分)的“洗礼”。

这双重的“洗礼”是生生比Bert多出来的计算。而且收益的不止是输出的第一个token,而是后续所有token。
可见,在GPT这种自回归的模式下,模型输出的每一个token都充分利用了大模型亿万级的预训练参数与前序token经过attention产生的大规模的“记忆”。
直白的阐述就先讲到这,如果换做是你,你认为Bert模式的产出会产生“强逻辑性”还是GPT的产出可能产生“强逻辑性”?
循环
个人认为GPT涌现出推理逻辑的架构基础离不开“循环”。拍脑门地总结一下我个人在思考问题时的状态。在进行一些问题的推理时,由于我不足够的聪明,所以我会先思考一遍,得到一些阶段性成果,计为milestone1,然后基于这个milestone1再进一步思考,可能会达到milestone2,以此类推最终达到milestone10。由于不能一下子就能达到milestone10,所以我需要不断地迭代,这中间就依存着一种时序的推理过程。
那么现在再来重新观察一下Bert和GPT的逻辑图。假设Bert的Encoder和LM的Decoder分别都是堆叠了40层block。
Bert的循环能力

在Bert的计算结构下,输入序列会整体从第1层向第40层flow,假设一个幸运状态:flow到第5层的时候,此时的状态已经“有意识”需要进行循环思考了。那么接下来,整个flow流程留给它的只有剩下的35层了,“你要想再思考几遍就赶紧的,要不然来不及了”。所以这种幸运的状态下,Bert充其量只有35层的机会进行循环思考,而在这35层里能进行几轮循环也不得而知。
GPT的循环能力

假设从token1的embedding在flow到第30层时才“有意识”需要进行循环思考。接下来,会有多少余地进行循环呢?显然非常丰富,因为每一个token都是要从头到尾flow一遍整个网络层的。因此在“有意识”开始循环的那个token之后,到模型主动结束输出前,中间所有的flow流程都是循环的余地。
总结一下,Bert就算能够出现循环,也只能是纵向(网络层堆叠方向)的有限网络层内产生的;GPT循环不仅能在纵向产生,还能横向(输入输出序列方向)“无限”拓展。
BTW:个人认为,纵向能够产生循环机制也不一定是好事。深度神经网络的一个普遍性特点是:越深层的网络处理的问题越高级、越抽象。

那么一旦在纵向需要训练出“循环”的需求,或多或少就会倾向于循环节之间要相似。那么整个纵向堆叠的网络层就越需要同质化,这种倾向与越深越抽象的特点是相矛盾的。
如何看待循环
循环能力真的必要吗?通用人工智能没有这种能力就不行?目前LM的能力已经满足这样的机制了吗?
在回答这三个问题之前,可以设想一个简单粗暴的场景,如果有一个非常简单的推理任务,任务的内在逻辑需要循环5次才能推理出结果,那么你的模型应不应该支持?如果支持,那么50次、500次、5000次呢?
带着这个问题,可以在ChatGPT上做一个实验(当然由于ChatGPT网页版对输出内容的随机性无法限制,所以实验的严谨性也无法完全保证)。
得益于codex的基础,ChatGPT对代码的处理能力非凡。但以小编目前测试的效果来看,也仅限于推理能力(当然这也是人类coding过程中面对的绝大多数场景)表现出众。在遇到循环问题时,表现就会变得糟糕起来。比如下图这段简单的递归代码(为防止模型像背诵菲波那切数列那样把每个位置的结果都记下来,我在代码中加了个盐,所以正确答案应该是6)。

有趣的是,模型在输出最初几个字符时,给出的结果是错误的,然而在进行后续一系列解释后,结果就变得正确了。当然这里不能否认CoT(Chain of Thought)有着绝对的功劳,但也不能忽略的是,在最后回复的正确答案和最初回复的错误答案之间,经过了大量的token输出。根据小编之前的阐述,每一个输出的token都对应着tensor的一次从模型头部到尾部的flow,也就是一种周期性循环过程。粗暴地描述这种现象就是:说话越多,脑子越好。
现在再回头看一下前面问的三个问题,我的回答是:
1、真的必要,因为这种能力对于人来说是很轻松,而且在解决很多问题时都需要用到;
2、没有不行,对循环能力的缺失会严重影响模型思考能力的可靠性,就算在n=2是模型能够算对,在n=5000时模型也算不对;
3、很显然,没有满足。
可见,GPT架构相较于Bert架构虽然提供了循环能力,但提供得并不够完美。体现在两方面:1、循环数不高,只能靠说出更多的字来增加循环次数;2、输出序列中靠前的内容在靠谱程度上会弱于靠后的内容。
循环策略猜想
针对循环问题的处理,小编一时间只有一些浅薄的想法。
因为循环任务会存在简单循环与复杂循环,所以没有必要去探究在网络层中到底从哪一层到哪一层能够support一次循环(所以不要被小编前面统计Bert与GPT的循环空间所误导),这种构造不会固定在哪一层的。开发人员只需要给予模型架构以这方面的自由度就行。
关于给予模型循环自由度方面的一些看法:
1、宏观层面,追加一类“沉默”token,比如名叫<LetMeThinkAboutItOnceAgain>。在业务上,这类token并不输出并显示出来,但它可以让模型多思考一个回合。当然这种设计并不能突破循环数的上限,而且对训练模式的挑战也是很大的。基于思维链(CoT)的显式token引导姑且可以帮助优化算法确定方向,但这个“沉默”token在训练过程中显然是不能计算loss的,所以如何有效训练是个难题。
2、从模型架构设计角度允许recurrent。也就是在Transformer基础上加入Recurrent机制。其实类似的机制早有探索,比如2019年提出的Transformer XL(https://arxiv.org/abs/1901.02860)
和较近期提出的更加先进的Block-Recurrent Transformers(https://arxiv.org/abs/2203.07852v3)。虽然这些工作提出的动机并非上面所述,但在模型架构层面的借鉴意义还是蛮大的。相较于这两份工作,小编个人还是更倾向于设计成动态循环结构,也就是循环的次数并不在超参中限定死,而是动态地由tensor自己决定。类似于稀疏模型中的Sparsely-Gated MoE(Mixture-of-Experts)结构,Sparsely-Gated MoE由门结构来控制选择哪些专家网络,那么通过门结构来控制循环多少次在理论上也能说得通,只不过这样的架构将会给训练带来更大的压力。空想这种设计难免有点像空中楼阁了,大家听听就好。来,吃瓜子。
All in all,小编还是挺希望业界部分先行者能够重视起Recurrent概念的,毕竟在蒸馏、剪枝、量化这些渠道之外,Recurrent还可以是减少网络深度,缩小模型体积的不错选择。
Bert?
踩了半天Bert,那以后还能用Bert吗?
LLM以前充其量是能在一些创作生成类任务(这类任务对模型的可靠程度要求低)上大放异彩,但在ChatGPT展现其走向通用人工智能的能力之后,LLM已然顶替了Bert系,一跃成为NLP领域的基础设施。如果只考虑效果的话,LLM无疑是目前唯一的选择,但商业落地是需要考虑成本的。
小编的看法是,在有大量数据支持且将来模型需要处理的数据量很大(动辄亿级)的情况下,基于Bert的fine-tuning不失为一个好的选择,否则就走LLM。
设想某类场景,一条业务链上可能会有很多地方对NLP技术有需求,有的需求是一次性的有的需求是长久的,有的需求下能够积累大量标注数据有的需求不能,有的需求需要高吞吐地处理海量数据有的可能一天也没几条数据需要处理。在这种场景下,能够积累大量标注数据且将来模型需要高吞吐地处理海量数据的情况下,很有必要训练一个专门的模型来应对,这时就可以基于Bert继续fine tune一个模型出来。否则,如果见到一个NLP需求就要训练一个模型,不仅会导致乱七八糟效果中庸的模型太多,而且开发成本也会高得离谱。
感想
(业外人士可读)
讲了这么多技术相关的,休息一会儿,聊一下小编对现状的看法吧。
就LLM在Large层面的解读,其实很多论文已经讨论过,小编在这里就不展开了。此刻只想聊一下消极影响。其实也很明显,就是这样级别的大模型,一般人甚至是中小企业都是玩不起的。暂且忽略尖端人才向大企业集中的问题,单从训练这样规模的模型所需要配备的硬件基础设施和试错成本,都会吃不消。参与的玩家少了就会导致创新的减少,无论是在学术界还是工业界,理论的创新与发展大都需要实验的支持,然而又会有多少幸运儿能够涉足其中呢?设想一下相关行业的学生群体,在筹备的毕业论文中,很难见到实验数据,通篇充斥着guess/hypothesis这类的词汇,何其尴尬。而作为一名学生,想要顺利毕业,可能唯一的选择就是远离LLM这个方向了吧。站在这个角度讲,性能比肩的小LM是多么的值得期待的一件事。
愿景
正如前文所述,LLM现阶段已经开始从单纯的创作大师跨越到了基础设施级别。目前的AGI水平已经逐渐(在自然语言处理模态下)能够独当一面。作为一种强势的基础设施,她能够轻松解决掉我们面临的大量非结构化任务,这无疑会给生产力带来巨大的飞跃,为低迷已久的世界经济注入一剂强心针。
00年代,PC作为硬件基础设施,其普及极大地助推了互联网的崛起;
10年代,智能手机作为硬件基础设施,其普及也极大地助推了移动互联网的崛起;
近几年,区块链某宇宙时期,我是真不想说点儿什么;
现如今,如此强大的生产力提升能力摆在面前,谁又能肯定AGI一定不能掀起一场科技革命呢?