Wolfram:ChatGPT 的内部原理

243次阅读  |  发布于2月以前

我认为必须将其视为一项(可能非常惊人的)科学发现:在像 ChatGPT这样的神经网络中,能以某种方式捕捉到人类大脑在生成语言时所做事情的本质。

从根本上说,ChatGPT是一个庞大的神经网络—GPT-3 拥有1750亿个权重。它在许多方面非常像我们讨论过的其他神经网络,只不过是一个特别为处理语言而设置的神经网络。它最显著的特点是一个称为Transformer 的神经网络架构。

在前面讨论的神经网络中,任何给定层的每个神经元基本上都与上一层的每个神经元相连(起码有一些权重)。但是,如果处理的数据具有特定的已知结构,则这种全连接网络就(可能)大材小用了。因此,以图像处理的早期阶段为例,通常使用所谓的卷积神经网络(convolutional neural net 或 convnet),其中的神经元被有效地布局在类似于图像像素的网格上,并且仅与在网格上相邻的神经元相连。

Transformer 的思想是,为组成一段文本的标记序列做与此相似的事情。但是,Transformer 不是仅仅定义了序列中可以连接的固定区域,而是引入了“注意力”的概念—即更多地“关注”序列的某些部分,而不是其他部分。也许在将来的某一天,可以启动一个通用神经网络并通过训练来完成所有的定制工作。但至少目前来看,在实践中将事物“模块化”似乎是至关重要的—就像Transformer 所做的那样,也可能是我们的大脑所做的那样。

ChatGPT(或者说它基于的 GPT-3 网络)到底是在做什么呢?它的总体目标是,根据所接受的训练(查看来自互联网的数十亿页文本,等等),以“合理”的方式续写文本。所以在任意给定时刻,它都有一定量的文本,而目标是为要添加的下一个标记做出适当的选择。

它的操作分为三个基本阶段。第一阶段,它获取与目前的文本相对应的标记序列,并找到表示这些标记的一个嵌入(即由数组成的数组)。第二阶段,它以“标准的神经网络的方式”对此嵌入进行操作,值“像涟漪一样依次通过”网络中的各层,从而产生一个新的嵌入(即一个新的数组)。第三阶段,它获取此数组的最后一部分,并据此生成包含约 50 000 个值的数组,这些值就成了各个可能的下一个标记的概率。(没错,使用的标记数量恰好与英语常用词的数量相当,尽管其中只有约 3000 个标记是完整的词,其余的则是片段。)

关键是,这条流水线的每个部分都由一个神经网络实现,其权重是通过对神经网络进行端到端的训练确定的。换句话说,除了整体架构,实际上没有任何细节是有“明确设计”的,一切都是从训练数据中“学习”来的。

然而,架构设置中存在很多细节,反映了各种经验和神经网络的学问。尽管会变得很复杂,但我认为谈论一些细节是有用的,至少有助于了解构建 ChatGPT 需要做多少工作。

首先是嵌入模块。以下是 GPT-2 的 Wolfram 语言示意图。

输入是一个包含 n 个(由整数 1 到大约 50 000 表示的)标记的向量。每个标记都(通过一个单层神经网络)被转换为一个嵌入向量(在 GPT-2 中长度为 768,在 ChatGPT 的 GPT-3 中长度为 12 288)。同时,还有一条“二级路径”,它接收标记的(整数)位置序列,并根据这些整数创建另一个嵌入向量。最后,将标记值和标记位置的嵌入向量相加,产生嵌入模块的最终嵌入向量序列。

为什么只是将标记值和标记位置的嵌入向量相加呢?我不认为有什么特别的科学依据。只是因为尝试了各种不同的方法,而这种方法似乎行得通。此外,神经网络的学问告诉我们,(在某种意义上)只要我们的设置“大致正确”,通常就可以通过足够的训练来确定细节,而不需要真正“在工程层面上理解”神经网络是如何配置自己的。

嵌入模块对字符串“hello hello hello hello hello hello hello hello hello hello bye bye bye bye bye bye bye bye bye bye”所做的操作如下所示。

(在上图的第一个数组中)每个标记的嵌入向量元素都在图中纵向显示,而从左往右看,首先是一系列 hello 嵌入,然后是一系列bye 嵌入。上面的第二个数组是位置嵌入,它看起来有些随机的结构只是(这里是在 GPT-2 中)“碰巧学到”的。

在嵌入模块之后,就是 Transformer 的“主要事件”了:一系列所谓的“注意力块”(GPT-2 有 12 个,ChatGPT 的 GPT-3 有 96 个)。整个过程非常复杂,让人想起难以理解的大型工程系统或者生物系统。以下是(GPT-2 中)单个“注意力块”的示意图。

在每个这样的注意力块中,都有一组“注意力头”(GPT-2 有12个,ChatGPT 的 GPT-3 有 96 个)—每个都独立地在嵌入向量的不同值块上进行操作。(我们不知道为什么最好将嵌入向量分成不同的部分,也不知道不同的部分“意味”着什么。这只是那些“被发现奏效”的事情之一。)

注意力头是做什么的呢?它们基本上是一种在标记序列(即目前已经生成的文本)中进行“回顾”的方式,能以一种有用的形式“打包过去的内容”,以便找到下一个标记。在“概率从何而来”一节中,我们介绍了使用二元词的概率来根据上一个词选择下一个词。Transformer 中的“注意力”机制所做的是允许“关注”更早的词,因此可能捕捉到(例如)动词可以如何被联系到出现在句子中很多词之前的名词。

更详细地说,注意力头所做的是,使用一定的权重重新加权组合与不同标记相关联的嵌入向量中的块。例如,对于上面的“hello,bye”字符串,(GPT-2 中)第一个注意力块中的 12 个注意力头具有以下(“回顾到标记序列开头”的)“权重重组”模式。

经过注意力头的处理,得到的“重新加权的嵌入向量”(在 GPT-2中长度为 768,在 ChatGPT 的 GPT-3 中长度为 12 288)将被传递通过标准的“全连接”神经网络层。虽然很难掌握这一层的作用,但是可以看看它(这里是在 GPT-2 中)使用的 768×768 权重矩阵。

(对上图进行)64×64 的滑动平均处理,一些(随机游走式的)结构开始显现。

是什么决定了这种结构?说到底,可能是对人类语言特征的一些“神经网络编码”。但是到目前为止,这些特征到底是什么仍是未知的。实际上,我们正在“打开 ChatGPT(或者至少是 GPT-2)的大脑”,并发现里面很复杂、难以理解—尽管它最终产生了可识别的人类语言。

经过一个注意力块后,我们得到了一个新的嵌入向量,然后让它依次通过其他的注意力块(GPT-2 中共有 12 个,GPT-3 中共有 96个)。每个注意力块都有自己特定的“注意力”模式和“全连接”权重。这里是 GPT-2 对于“hello, bye”输入的注意力权重序列,用于第一个注意力头。

全连接层的(移动平均)“矩阵”如下所示。

奇怪的是,尽管不同注意力块中的“权重矩阵”看起来非常相似,但权重大小的分布可能会有所不同(而且并不总是服从高斯分布)。

在经过所有这些注意力块后,Transformer 的实际效果是什么?本质上,它将标记序列的原始嵌入集合转换为最终集合。ChatGPT 的特定工作方式是,选择此集合中的最后一个嵌入,并对其进行“解码”,以生成应该出现的下一个标记的概率列表。

以上就是对 ChatGPT 内部原理的概述。它虽然(由于许多难免有些随意的“工程选择”)可能看起来很复杂,但实际上涉及的最终元素非常简单。因为我们最终处理的只是由“人工神经元”构成的神经网络,而每个神经元执行的只是将一组数值输入与一定的权重相结合的简单操作。

ChatGPT 的原始输入是一个由数组成的数组(到目前为止标记的嵌入向量)。当 ChatGPT“运行”以产生新标记时,这些数就会“依次通过”神经网络的各层,而每个神经元都会“做好本职工作”并将结果传递给下一层的神经元。没有循环和“回顾”。一切都是在网络中“向前馈送”的。

这是与典型的计算系统(如图灵机)完全不同的设置—在这里,结果不会被同一个计算元素“反复处理”。至少在生成给定的输出标记时,每个计算元素(神经元)仅使用了一次。

但是在某种意义上,即使在 ChatGPT 中,仍然存在一个重复使用计算元素的“外部循环”。因为当 ChatGPT 要生成一个新的标记时,它总是“读取”(即获取为输入)之前的整个标记序列,包括ChatGPT 自己先前“写入”的标记。我们可以认为这种设置意味着ChatGPT 确实,至少在其最外层,包含一个“反馈循环”,尽管其中的每次迭代都明确显示为它所生成文本中的一个标记。

让我们回到 ChatGPT 的核心:神经网络被反复用于生成每个标记。在某种程度上,它非常简单:就是完全相同的人工神经元的一个集合。网络的某些部分仅由(“全连接”的)神经元层组成,其中给定层的每个神经元都与上一层的每个神经元(以某种权重)相连。但是由于特别的 Transformer 架构,ChatGPT 的一些部分具有其他的结构,其中仅连接不同层的特定神经元。(当然,仍然可以说“所有神经元都连接在一起”,但有些连接的权重为零。)

此外,ChatGPT 中神经网络的有些方面并不能被顺理成章地认为只由“同质”层组成。例如,(正如本节中单个“注意力块”的示意图所示)在注意力块内有一些对传入的数据“制作多个副本”的地方,每个副本都会通过不同的“处理路径”,可能涉及不同数量的层,然后才被重新组合。虽然这可能简便地表示了正在发生的事情,但至少原则上总是可以将事实考虑为“密集填充”各层,只是有一些权重为零。

看一下 ChatGPT 最 长 的 路 径, 会 发 现 大 约 有 400 个( 核 心 )层—在某种程度上看来并不是很多。但是它们包括数百万个神经元,总共有 1750 亿个连接,因此有 1750 亿个权重。需要认识到的一件事是,ChatGPT 每生成一个新的标记,都必须进行一次包括所有这些权重在内的计算。在实现上,这些计算可以“按层”组织成高度并行的数组操作,方便地在 GPU 上完成。但是对于每个产生的标记,仍然需要进行 1750 亿次计算(并在最后进行一些额外的计算)—因此,不难理解使用 ChatGPT 生成一段长文本需要一些时间。

值得注意的是,所有这些操作—尽管各自都很简单—可以一起出色地完成生成文本的“类人”工作。必须再次强调,(至少就我们目前所知)没有“理论上的终极原因”可以解释为什么类似于这样的东西能够起作用。事实上,正如我们将讨论的那样,我认为必须将其视为一项(可能非常惊人的)科学发现:在像 ChatGPT这样的神经网络中,能以某种方式捕捉到人类大脑在生成语言时所做事情的本质。

Copyright© 2013-2020

All Rights Reserved 京ICP备2023019179号-8