斯蒂芬·沃尔夫勒姆(Stephen Wolfram)是一位著名的科学家、企业家和作家,被誉为计算机科学、物理学和数学等领域的重要人物之一。他是著名的计算机程序“Mathematica”和“Wolfram Alpha”的创始人,这些程序在科学计算和知识处理方面广受欢迎。他还是“新科学”(New Kind of Science)一书的作者,这本书重新定义了许多科学领域的传统概念,是一本极具影响力的著作。沃尔夫勒姆在科学、技术和商业方面的杰出贡献使他成为了当今世界最具影响力的思想领袖之一。
ChatGPT 能够自动生成类似人类写作的文本,这是非常惊人和出乎意料的。但它是如何做到的?为什么它能够如此成功地生成我们认为有意义的文本?在这里,我的目的是概述 ChatGPT 内部正在发生的事情,然后探讨为什么它能够如此出色地产生有意义的文本。首先,我要解释的是,ChatGPT 始终基本上是在尝试产生“合理的延续”任何文本,其中“合理”的意思是“在人们看到了亿万个网页等内容后,可能会写出的东西”。
所以假设我们有文本“AI 最好的一点在于它的能力是”。想象一下扫描亿万页人类写作的文本(比如在网页和数字化图书中),找到所有这个文本的实例,然后看下一个单词出现的频率是多少。ChatGPT 实际上做的事情有些类似,只不过它不是看字面上的文本,而是在某种意义上寻找“意义匹配”的内容。但最终的结果是它会生成一个排序过的单词列表,这些单词可能是接下来的单词,以及与之对应的“概率”:
ChatGPT 可以自动生成看起来像人类写作的文本是非常了不起且出乎意料的。但它是如何做到的呢?为什么它能够如此成功地产生我们可能认为是有意义的文本?我的目的是大致概述 ChatGPT 内部的运作方式,然后探讨为什么它能够如此出色地产生文本。我应该首先说明,我将聚焦于 ChatGPT 内部的总体情况,虽然我将提到一些工程细节,但我不会深入探讨它们。 (而我所说的要点同样适用于其他当前的“大型语言模型” [LLM],并不仅限于 ChatGPT。)
首先要解释的是,ChatGPT 始终在基本上试图生成一个“合理的延续”,这个“合理的延续”是指“在看到数十亿个网页等上的人类编写的文本后,人们可能会写什么”。
所以假设我们有文本“AI 最好的事情是它的能力”,想象一下扫描数十亿个人类编写的文本(例如网络和数字化图书)并找到所有这些文本的实例,然后看看接下来出现的词是什么,出现的比例是多少。ChatGPT 实际上做了类似的事情,但是(正如我将解释的那样),它并没有查看文字,而是查找在某种意义上“匹配的意思”的东西。但最终的结果是它会产生一个单词可能的排名列表,以及相应的“概率”:
而令人惊讶的是,当 ChatGPT 像写一篇论文这样的事情时,它实际上就是在反复地问“在现有的文本的基础上,下一个词应该是什么?”-每次都添加一个词(更精确地说,我将解释,它添加的是一个“标记”,可能只是一个词的一部分,这就是为什么它有时可以“编造新单词”的原因)。
当ChatGPT像写文章这样做事情时,它实际上只是一遍又一遍地问“在给定当前文本的情况下,下一个词应该是什么?”——并且每次都添加一个单词。更准确地说,它添加一个“标记”,这可能只是一个单词的一部分,这就是为什么它有时可以“编造新单词”的原因。
但是,在每一步中,它都会获得一组具有概率的单词列表。但是它应该选择哪一个单词实际上添加到它正在写的文章(或任何其他东西)中呢?你可能会认为应该选择“最高排名”的单词(即分配给最高“概率”的单词)。但这就是一点点巫术开始潜入的地方。因为由于某种原因——也许有一天我们会有科学风格的理解——如果我们总是选择最高排名的单词,我们通常会得到一个非常“平淡”的文章,看起来从未“展现任何创造力”(甚至有时会重复一字不差)。但是,如果我们有时(随机)选择较低排名的单词,我们就会得到一个“更有趣”的文章。
这里的随机性意味着,如果我们多次使用相同的提示,每次得到的文章可能都不同。与巫术的概念保持一致,有一个特定的所谓“温度”参数,它确定使用低排名词语的频率,对于文章生成而言,温度为0.8似乎最好。(值得强调的是,这里并没有使用任何“理论”;这只是实践中发现的可行方法。例如,“温度”的概念之所以存在是因为使用了统计物理中熟悉的指数分布,但至少就我们所知,它没有“物理”联系。)
在继续之前,我应该解释一下,为了阐述,我大多数情况下不会使用ChatGPT中的完整系统;相反,我通常会使用一个更简单的GPT-2系统,它有一个很好的特点,就是它足够小,可以在标准台式计算机上运行。因此,对于我展示的几乎所有内容,我都能够包含明确的Wolfram语言代码,您可以立即在计算机上运行它。(单击此处的任何图片以复制其后面的代码。)
例如,下面是如何获得上面概率表格的代码。首先,我们必须检索底层的“语言模型”神经网络:
稍后,我们将会深入研究这个神经网络,并讨论它的工作原理。但是现在,我们可以将这个“网络模型”视为一个黑盒子,将其应用于我们迄今为止的文本,并询问该模型所说的应该跟随的前五个概率最高的单词是什么:
这将结果转换为一个格式化的“数据集”:
这里展示了重复“应用模型”的结果——在每一步中添加具有最高概率的单词(在这段代码中指定为模型的“决策”):
如果继续进行下去会发生什么呢?在这种“零温度”的情况下,输出很快就变得混乱和重复:
但如果不总是选择“最高排名”的单词,而是有时随机选择“非最高排名”的单词(其“随机性”对应于“温度”0.8),会发生什么呢?同样,可以构建文本:
每次这样做时,都会做出不同的随机选择,文本也会不同,就像这些5个例子一样:
值得指出的是,即使在第一步,也有很多可能的“下一个词”可以选择(在温度0.8下),尽管它们的概率很快下降(是的,这个对数-对数图上的直线对应于n-1“幂律”衰减,这是语言的一般统计特征):
那么如果继续生成更多文本会发生什么呢?这里展示了一个随机的例子。虽然比纯粹选取概率最高的词(零温度)要好,但结果仍然有点奇怪:
这是用最简单的 GPT-2 模型(来自 2019 年)完成的。使用更新和更大的 GPT-3 模型,结果更好。下面是使用相同“提示”生成的单词(零温度)文本,但使用最大的 GPT-3 模型:
以下是“温度0.8”的一个随机示例:
好的,ChatGPT总是基于概率选择下一个单词。但是这些概率从哪里来呢?让我们从一个简单的问题开始。让我们考虑一次生成一个英文字母(而不是单词)的英文文本。我们如何计算每个字母的概率?
我们可以做的非常简单的事情是只是取一个英文文本样本,然后计算不同字母在其中出现的频率。因此,例如,下面计算的是“cats”维基百科文章中的字母:
以下是“dogs”的统计结果:
结果相似,但并不完全相同(“o”在“dogs”文章中可能更常见,因为毕竟它出现在“dog”这个单词中)。然而,如果我们采样足够大量的英文文本,我们可以期望最终得到至少相当一致的结果:
以下是我们使用这些概率生成一系列字母时的示例:
我们可以通过加入空格作为带有一定概率的字母来将其分解为“单词”:
我们可以通过让“单词长度”的分布与英语中的分布相一致,来更好地划分“单词”:
我们在这里没有得到任何“实际单词”,但结果看起来略微好一些。为了更进一步,我们需要做的不仅仅是随机挑选每个字母。例如,我们知道如果有一个“q”,下一个字母基本上必须是“u”。
这是字母本身的概率的绘图:
以下是一张图,它展示了在典型的英文文本中,两个字母(“2元组”)的概率。页面上显示可能的第一个字母,页面下面显示第二个字母:
现在我们可以每次生成两个字母,并使用这些“2元组”的概率来生成单词。以下是结果的一个示例,其中包含一些“实际单词”:
如果有足够多的英文文本,我们不仅可以获得单个字母或字母对(2-gram)的概率的相当好的估计,而且还可以获得更长字母运行的概率。如果我们使用越来越长的n-gram概率生成“随机单词”,我们会发现它们变得越来越“真实”:
但是现在假设——更或多或少像ChatGPT那样——我们处理的是整个单词,而不是字母。英语中大约有40,000个常用单词。通过查看大量的英文文本(例如几百亿个单词的几百万本书),我们可以估算出每个单词的出现频率。利用这个,我们可以开始生成“句子”,其中每个单词都是独立地随机选择的,其出现概率与在语料库中出现的概率相同。下面是我们得到的样本:
不出意外的是,这些句子没有意义。那么我们该如何做得更好呢?就像处理字母时一样,我们可以开始考虑不仅单个词的概率,还要考虑词对或更长的n-gram词组的概率。对于词对,以下是5个例子,所有情况都是从单词“cat”开始:
这看起来变得稍微“更合理了”。我们可以想象,如果我们能够使用足够长的 n-gram,我们基本上会“得到一个 ChatGPT”,也就是说,我们将获得一个能够生成带有“正确的整体文章概率”的长度为一篇论文的单词序列。但是问题在于:迄今为止,从写过的英文文本中甚至无法接近地获得这些概率。
在网络爬行中可能有几百亿个单词;在数字化的书籍中可能还有另外一百亿个单词。但是,对于 40,000 个常见单词,即使是可能的 2-gram 数量已经达到 16 亿,而可能的 3-gram 数量是 60 兆。因此,我们无法从文本中估计所有这些可能性的概率。而当我们到达 20 个单词的“文章片段”时,可能性的数量已经超过了宇宙中的粒子数量,因此从某种意义上说,它们永远不可能全部被写下。
那我们该怎么办呢?大的思路是建立一个模型,让我们能够估计序列出现的概率——即使我们从未在我们查看的文本语料库中显式地看到这些序列。而 ChatGPT 的核心正是一个被称为“大型语言模型”(LLM)的模型,它被构建成能够很好地估计这些概率。
假设你想知道(就像加利略在16世纪晚期那样)从比萨斜塔的每层楼上掉下来的炮弹需要多长时间才能触地。好吧,你可以在每种情况下测量它并制作一个结果表。或者你可以做理论科学的本质:建立一个模型,提供一种计算答案的方法,而不仅仅是测量和记住每个情况。
让我们假设我们有(有些理想化的)数据,用于记录炮弹从各个楼层掉落所需的时间:
假设我们想知道从我们没有实际数据的楼层落下的炮弹需要多长时间才能落地。在这种情况下,我们可以使用已知的物理定律来计算。但是,假设我们只有数据,而不知道什么样的基本定律支配着它。那么我们可能会做出一个数学猜测,比如也许我们应该使用一条直线作为模型:
我们可以选择不同的直线,但这是平均最接近我们所给数据的直线。从这条直线我们可以估算任何一层落地所需的时间。
我们怎么知道在这里尝试使用一条直线呢?在某种程度上我们不知道。这只是一种数学上的简单假设,我们习惯于许多我们所测量的数据都可以用数学上的简单方法来拟合。我们可以尝试更复杂的数学方法,比如 a+bx+cx2,然后在这种情况下,我们可以得到更好的结果:
事情有时会变得相当糟糕。比如,这里是用 a + b/x + c sin(x) 能得到的最佳结果:
值得理解的是,没有所谓“无模型的模型”。你使用的任何模型都有某种特定的基础结构,然后有一定的“旋钮可以转动”(即您可以设置的参数)以适应您的数据。在ChatGPT的情况下,使用了许多这样的“旋钮” - 实际上有1750亿个。
但是令人惊奇的是,ChatGPT的基本结构 - “仅”使用这么多的参数 - 足以制作出一个计算下一个单词概率“足够好”的模型,从而为我们提供了合理长度的文章。
上面的例子涉及到为来自简单物理学的数值数据制定模型,几个世纪以来我们已经知道“简单的数学适用”。但是对于ChatGPT,我们必须制定一个模型,该模型可计算人类大脑产生的人类语言文本的下一个单词的概率。对于这样的任务,我们(至少目前)没有类似于“简单数学”的东西。那么,这种模型可能是什么样子呢?
在谈论语言之前,让我们谈谈另一个像人一样的任务:识别图像。作为一个简单的例子,让我们考虑数字的图像(是的,这是一个经典的机器学习示例):
我们可以做的一件事是获取每个数字的一堆示例图像:
我们可以通过与我们拥有的样本进行像素对像素的比较来确定我们所输入的图像是否对应于特定的数字。但是,作为人类,我们似乎做得更好——因为我们可以识别数字,即使它们是手写的,并且有各种修改和扭曲。
当我们为上面的数值数据建立模型时,我们能够将我们获得的数值 x 视为变量,并为特定的 a 和 b 计算 a + b x。那么,如果我们将每个像素的灰度值视为某个变量 xi,是否存在一个关于所有这些变量的函数,当求值时告诉我们图像是哪个数字?事实证明,可以构建这样一个函数。不出所料,它并不特别简单。一个典型的例子可能涉及大约五十万个数学运算。
但最终的结果是,如果我们将图像的像素值集合馈入该函数,那么我们将得到指定图像数字的数字。稍后,我们将讨论如何构建这样的函数和神经网络的概念。但现在让我们将该函数视为黑盒子,我们将手写数字的图像(作为像素值的数组)输入该函数,然后得到它们所对应的数字。
但是这里真正发生了什么?假设我们逐渐模糊一个数字。在短时间内,我们的函数仍然“识别”它,这里是一个“2”。但很快它“迷失了”,开始给出“错误”的结果:
但我们为什么会说这是“错误”的结果呢?在这种情况下,我们知道通过模糊一张“2”得到了所有的图像。但如果我们的目标是创建一个能够模拟人类在识别图像方面的模型,那么真正需要问的问题是,如果一个人看到了这些模糊的图像,并不知道它来自哪里,他会怎么做。
如果我们的函数的结果通常与人类的判断相一致,那么我们就有了一个“好模型”。对于这样一个图像识别任务,我们现在基本上知道如何构建这样的函数,这是一个非常不平凡的科学事实。
我们能“数学证明”它们工作吗?很遗憾,不能。因为为了做到这一点,我们必须有一个关于人类是如何工作的数学理论。拿这个“2”的图像,改变一些像素。我们可以想象,只要有几个像素“不在原位”,我们仍应该将图像视为“2”。但是这个界限应该在哪里?这是一个人类视觉感知的问题。是的,答案对于蜜蜂或章鱼可能会有所不同,而对于假设的外星人来说则可能完全不同。
好的,那么我们用于图像识别等任务的典型模型实际上是如何工作的呢?目前最受欢迎和成功的方法使用神经网络。神经网络的发明可以追溯到1940年代,其形式与现在的使用方式非常接近,可以看作是关于大脑如何工作的简单理想化。
人类大脑中有约1000亿个神经元(神经细胞),每个神经元每秒钟可以产生最多1000次的电脉冲。神经元通过一种复杂的网络连接在一起,每个神经元都有树枝状的分支,使其能够将电信号传递到可能有数千个神经元的其他神经元。在一个粗略的近似中,任何给定神经元在给定时刻是否产生电脉冲取决于它从其他神经元接收到的脉冲,不同的连接具有不同的“权重”。
当我们“看到一张图片”时,发生的事情是当来自图像的光子落在我们眼睛后面的“光感受器”细胞上时,它们会在神经元中产生电信号。这些神经元与其他神经元相连,最终信号通过一整个神经元层序列。在这个过程中,我们“识别”了图像,最终“形成了”我们“看到一个2”的想法(也许最终做出像“念出‘两’这个词”这样的动作)。
上一节中的“黑匣子”函数是这样一个神经网络的“数学化”版本。它恰好有11层(尽管只有4个“核心层”):
这种神经网络并没有什么特别“理论推导”的内容;它只是一个工程上的构造,并在1998年被发现可以工作。(当然,这与我们可能会描述我们的大脑是如何通过生物进化过程产生的并没有太大区别。)
好的,那么像这样的神经网络如何“识别事物”呢?关键在于吸引子的概念。想象一下我们有手写的数字1和2:
我们希望所有的“1”“被吸引到一个地方”,所有的“2”“被吸引到另一个地方”。或者换句话说,如果一幅图像“更接近于1”,而不是2,我们希望它最终进入“1的位置”,反之亦然。
作为一个简单的比喻,假设我们有平面上的某些位置,用点表示(在现实生活中它们可能是咖啡店的位置)。那么我们可以想象,从平面上的任何一点开始,我们总是希望最终到达最近的点(即我们总是去最近的咖啡店)。我们可以通过将平面分成由理想化的“分水岭”分隔的区域(“吸引子盆地”)来表示这一点:
我们可以将其视为实现了一种“识别任务”,其中我们并不是在识别一个给定图像“看起来最像”的数字,而是直接看一个给定点最靠近哪个点。 (我们在这里展示的“ Voronoi 图”设置将 2D 欧几里得空间中的点分离开来;可以将数字识别任务视为在由每个图像中所有像素的灰度级组成的 784 维空间中执行非常相似的操作。)
那么我们如何使神经网络“执行识别任务”呢?让我们考虑这个非常简单的情况:
我们的目标是将与位置 {x,y} 对应的“输入”识别为最接近它的三个点之一。换句话说,我们希望神经网络计算 {x,y} 的函数,如下所示:
所以我们如何用神经网络做到这一点呢?最终,神经网络是一组理想化的“神经元”连接在一起的集合,通常排列成层次结构,一个简单的例子是:
每个“神经元”实际上都被设置为评估一个简单的数值函数。为了“使用”网络,我们只需在顶部输入数字(如我们的坐标x和y),然后让每层神经元“评估其函数”并将结果向前馈送到网络——最终在底部产生最终结果:
在传统(受生物启发的)设置中,每个神经元实际上都有来自前一层神经元的一定数量的“输入连接”,每个连接被赋予一定的“权重”(可以是正数或负数)。给定神经元的值是通过将“前一神经元”的值乘以它们相应的权重,然后加上一个常数来确定的,最后应用“阈值”(或“激活”)函数。在数学术语中,如果一个神经元有输入x = {x1,x2 …},那么我们计算f[w . x + b],其中权重w和常数b通常对于网络中的每个神经元都会不同选择;函数f通常是相同的。
计算w . x + b只是矩阵乘法和加法的问题。 “激活函数”f引入了非线性(最终是导致非线性行为的原因)。常用各种激活函数;在这里,我们将使用Ramp(或ReLU)
对于我们希望神经网络执行的每个任务(或等价地,对于我们希望其评估的每个总体函数),我们将有不同的权重选择。(正如我们稍后将讨论的那样,这些权重通常是通过使用机器学习从我们想要的输出示例来“训练”神经网络确定的。)
最终,每个神经网络只对应于某些总体数学函数,尽管它可能很难写出。对于上面的示例,它将是:
ChatGPT 的神经网络也只是对应一个像这样的数学函数—不过实际上有数十亿个连接。
但让我们回到单个神经元。以下是具有两个输入(表示坐标 x 和 y)的神经元在各种权重和常数选择下(并使用 Ramp 作为激活函数)可以计算的函数示例:
但是那个上面的大型神经网络呢?好吧,它计算的内容是
这个并不完全“正确”,但它接近于我们上面展示的“最近点”函数。
我们来看看其他神经网络会发生什么。在每种情况下,我们将在稍后解释中使用机器学习来找到最佳的权重选择。然后我们展示使用这些权重的神经网络所计算的内容:
更大的神经网络通常更能够逼近我们所追求的函数。并且在每个吸引子盆地的“中心”,我们通常会得到我们想要的答案。但在边界处——神经网络“很难下决心”的地方——事情可能会变得更混乱。
对于这种简单的数学风格的“识别任务”,“正确答案”很清楚。但在识别手写数字的问题中,情况就不是那么清楚了。如果有人写的“2”看起来像“7”等等,怎么办?尽管如此,我们可以询问神经网络如何区分数字——这会给出一个指示:
我们能否“数学地”说明网络如何进行区分?实际上不行。它只是在“执行神经网络所做的操作”。但事实证明,这通常与我们人类所做的区分相当吻合。
让我们来看一个更为详细的例子。假设我们有猫和狗的图像。我们有一个经过训练以区分它们的神经网络。以下是它在一些示例上的表现:
现在更不清楚“正确答案”是什么了。那么狗穿着猫装怎么办?等等。无论输入什么,神经网络都会生成一个答案。而且,事实证明,它以一种与人类可能做出的方式相当一致的方式进行。就像我之前说的那样,这不是我们可以“从第一原理”中“推导出来”的事实。在某些领域,它只是被证明是真实的。但这是神经网络有用的一个关键原因:它们以某种方式捕捉到了一种“类似于人类”的做事方式。
向自己展示一张猫的图片,并问:“那是只猫吗?”也许你会开始说:“嗯,我看到了它尖耳朵等等。”但很难解释你是如何识别这张图像的。这是因为你的大脑某种方式计算出了这一点。但对于大脑来说,没有办法(至少目前还没有)“进入内部”并看看它是如何计算出来的。对于(人造)神经网络呢?当你展示一张猫的图片时,看到每个“神经元”在做什么是很简单的。但即使要得到一个基本的可视化通常也非常困难。
在我们用于上面的“最近点”问题的最终网络中,有17个神经元。在用于识别手写数字的网络中有2190个神经元。在用于识别猫和狗的网络中有60,650个神经元。通常很难将60,650维空间可视化。但因为这是一个用于处理图像的网络,其许多神经元层都组织成数组,就像它查看的像素数组一样。
如果我们拿一个典型的猫的图像作为例子:
然后我们可以将第一层神经元的状态表示为一组衍生图像,其中许多图像我们可以轻松解释为“没有背景的猫”,或者“猫的轮廓”:
对于第10层,很难解释正在发生什么:
但通常我们可以说神经网络正在“挑选某些特征”,(也许尖耳朵是其中之一),并使用它们来确定图像的内容。但这些特征是否是我们熟知的名称(如“尖耳朵”)呢?大多数情况下不是。
我们的大脑是否使用类似的特征?我们大多数人并不知道。但值得注意的是,像我们在这里展示的这样一个神经网络的前几层似乎会挑选出图像的某些方面(如物体的边缘),这些方面似乎类似于我们知道的大脑视觉处理的第一层所挑选出的特征。
假设我们想要在神经网络中建立一种“猫识别理论”。我们可以说:“看,这个特定的网络可以做到这一点”,这立即给我们一些关于“问题难度”的感觉(例如需要多少神经元或层级)。但至少目前为止,我们没有一种“讲故事描述”的方式来说明网络正在做什么。也许这是因为它确实是计算上不可化简的,除了明确跟踪每一步之外,没有一般方法可以找到它正在做什么。或者也许是因为我们还没有“找到科学”,还没有确定允许我们总结正在发生的事情的“自然法则”。
当我们谈论使用ChatGPT生成语言时,我们会遇到同样的问题。同样,现在还不清楚是否有办法“概括它正在做什么”。但语言的丰富性和细节(以及我们对它的经验)可能会使我们比图像更进一步。
我们到目前为止一直在谈论那些“已经知道”如何完成特定任务的神经网络。但神经网络之所以如此有用(很可能在大脑中也是如此),是因为它们可以被逐步“从示例中训练”来完成这些任务。
当我们制作一个神经网络来区分猫和狗时,我们不需要有效地编写一个程序来(例如)显式地找到胡须;相反,我们只需展示很多关于猫和狗的示例,然后让网络从这些示例中“机器学习”如何区分它们。
重点在于训练过的神经网络会从它所展示的特定示例中“概括”出来。正如我们上面所看到的,神经网络不仅仅是识别所展示的示例猫图像的特定像素模式;而是它以某种“一般猫”的特征区分图像。
那么神经网络训练实际上是如何工作的呢?本质上,我们总是试图找到使神经网络成功复制我们所给示例的权重。然后,我们依靠神经网络以“合理”的方式在这些示例之间“插值”(或“概括”)。
让我们看一个比上面的最近点问题更简单的问题。让我们只是尝试让神经网络学习函数
对于这个任务,我们需要一个只有一个输入和一个输出的神经网络,例如:
但是我们应该使用哪些权重等呢?对于每个可能的权重集合,神经网络都会计算出某个函数。例如,这里是几组随机选择的权重集合所计算出的函数:
但是,我们可以清楚地看到,在这些情况下,它甚至没有接近复制我们想要的功能。那么我们如何找到能够复制该函数的权重呢?
基本思想是提供大量的“输入→输出”示例来“学习”——然后尝试找到能够复制这些示例的权重。以下是使用逐渐增加的示例进行此操作的结果:
在每个阶段,“训练”过程中,神经网络中的权重会逐步调整——我们看到最终获得了一个成功复制所需函数的网络。那么如何调整权重呢?基本思路是在每个阶段看看“我们距离所需函数有多远”,然后更新权重以更接近所需函数。
要找出“我们距离所需函数有多远”,我们计算通常称为“损失函数”(有时称为“成本函数”)的函数。在这里,我们使用一个简单的(L2)损失函数,它只是所得值与真实值之间差的平方和。我们看到随着训练过程的进行,损失函数逐步减小(遵循不同任务的不同“学习曲线”)——直到达到一个点,网络(至少可以近似地)成功地复制了我们想要的函数:
好的,最后一个需要解释的基本部分是如何调整权重以减少损失函数。正如我们所说,损失函数给出了我们得到的值和真实值之间的“距离”。但“我们得到的值”是由当前版本的神经网络和其中的权重决定的。但现在想象一下,权重是变量,比如w1。我们想找出如何调整这些变量的值来最小化依赖于它们的损失。
例如,假设(非常简化了实际使用的典型神经网络)我们只有两个权重w1和w2。那么我们可能会有一个关于w1和w2的损失函数看起来像这样:
这种情况下,数值分析提供了多种技术来找到最小值。但是典型的方法就是从先前的 w1、w2 开始逐步沿最陡下降的路径前进:
就像水流下山一样,这个过程只能保证最终会到达曲面的某个局部最小值(“山湖”),但它可能无法到达最终的全局最小值。
找到“重量曲面”上最陡峭的下降路径可能并不容易。但微积分拯救了我们。正如我们之前提到的,可以将神经网络视为计算数学函数,该函数取决于其输入和权重。但现在考虑针对这些权重进行微分。结果表明,微积分的链式法则实际上让我们“展开”了神经网络中连续层所执行的操作。结果是我们可以——至少在某种局部逼近的情况下——“反转”神经网络的操作,并逐步找到最小化输出相关损失的权重。
上面的图片展示了我们在只有两个权重的情况下需要进行的最小化过程。但是事实证明,即使有更多的权重(ChatGPT使用了1750亿个权重),也仍然可能进行最小化,至少可以近似地进行最小化。实际上,围绕2011年发生的“深度学习”重大突破与发现有关,即某种意义上,当涉及到许多权重时,进行(至少近似地)最小化可能比涉及相当少的权重更容易。
换句话说,有时候用神经网络解决更复杂的问题比解决更简单的问题更容易,这似乎有点违反直觉。大致原因似乎是,当有许多“权重变量”时,我们拥有一个具有“许多不同方向”的高维空间,可以引导我们到达最小值,而当变量较少时,很容易陷入局部最小值(“山湖”)而没有“方向可走”。
值得指出的是,在典型情况下,有许多不同的权重集合都可以给出具有几乎相同性能的神经网络。通常,在实际的神经网络训练中会进行许多随机选择,这些选择会导致“不同但等效的解决方案”,如下所示:
上述的“不同解决方案”每个都会有略微不同的行为。如果我们要求在我们给出训练示例的区域之外进行“外推”,我们可能会得到截然不同的结果:
但是哪一个是“正确”的呢?实际上没有办法说。它们都“与观测数据一致”。但它们都对应着不同的“内在”思考方式,以“超出框框”的方式去思考应该做什么。其中一些对我们人类来说可能比其他的更“合理”。
特别是在过去的十年中,神经网络训练的技术已经有了很多进展。而且,是基本上是一门艺术。有时候——尤其是事后回顾——我们可以看到一些“科学解释”来解释正在进行的事情。但大多数情况下,通过试错发现了一些思路和技巧,这些思路和技巧逐步积累,构成了一个有关如何使用神经网络的显著技术和经验积累。
有几个关键部分。首先是对于特定任务应该使用什么神经网络体系结构的问题。然后是关键问题,即如何获取用于训练神经网络的数据。而且越来越多的情况是,我们不是从头开始训练一个新的神经网络:相反,一个新的神经网络可以直接合并另一个已经训练好的网络,或者至少可以使用该网络生成更多的训练样例。
人们可能认为,对于每种特定的任务,都需要不同的神经网络架构。但是发现,即使是表面上非常不同的任务,同样的架构似乎也能够工作。在某种程度上,这让人想起通用计算的概念(和我提出的计算等价性原则),但是,正如我稍后将讨论的那样,我认为这更反映了我们通常试图让神经网络执行的任务是“类人类”的任务,而神经网络可以捕捉相当通用的“类人类过程”。
在早期神经网络的发展中,人们通常认为应该让神经网络“尽可能少地做事情”。例如,在将语音转换为文本时,人们认为应该先对语音进行分析,将其分解为音素等。但是研究发现,至少对于“类似于人类的任务”,通常最好尝试训练神经网络进行“端到端的问题”,让它自己“发现”所需的中间特征、编码等。
还有一种想法是,应该向神经网络中引入复杂的单个组件,以让它实际上“显式实现特定的算法思想”。但同样地,这在大多数情况下被证明是不值得的;相反,最好处理非常简单的组件,并让它们“自行组织”(虽然通常是以我们无法理解的方式)来实现(可能是)相当于那些算法思想的东西。
这并不是说对于神经网络没有相关的“结构化思想”是有帮助的。例如,在处理图像的早期阶段,使用带有局部连接的二维神经元阵列似乎至少非常有用。而专注于“向后查看序列”的连接模式似乎很有用——正如我们稍后将在ChatGPT中看到的那样——处理类似人类语言的事物。
但是,神经网络的一个重要特点就像计算机一样,最终只是处理数据。目前的神经网络——通过当前的神经网络训练方法——专门处理数字数组。但在处理过程中,这些数组可以完全重新排列和重新塑造。例如,我们用于识别上面的数字的网络以类似图像的二维数组开始,快速“加厚”到许多通道,但然后“集中下降”到最终将包含表示不同可能的输出数字的元素的一维数组中:
但是,好的,如何确定特定任务需要多大的神经网络?这在某种程度上是一种艺术。在某种程度上,关键是要知道“任务有多难”。但是对于类似于人类的任务,通常很难估计。是的,可能有一种系统化的方法可以通过计算机“机械地”完成任务。但很难知道是否有可以轻松实现“类似于人类水平”的“技巧”或“快捷方式”来完成任务。
对于某些小的神经网络和简单的任务,有时可以明确地看到“从这里无法到达那里”。例如,下面是使用几个小型神经网络能够完成的上一节任务的最佳成果:
我们可以看到,如果神经网络太小,它就无法复制我们想要的功能。但是在某个大小以上,它就没有问题——至少如果训练足够长时间,并有足够的样本。顺便说一句,这些图片说明了神经网络学的一个规律:如果网络中间“挤压”,强制所有信息通过较小的中间神经元,通常可以用更小的网络解决问题。(值得一提的是,“无中间层”或所谓的“感知器”网络只能学习基本线性函数——但只要有一个中间层,原则上就可以以任意高的精度逼近任何函数,至少如果有足够的神经元,虽然为了使其可行地训练,通常需要一些正则化或标准化。)
好的,现在假设我们已经确定了某个神经网络的结构。现在的问题是如何获取用于训练网络的数据。许多与神经网络和机器学习相关的实际挑战都集中在获取或准备必要的训练数据上。在许多情况下(“监督学习”),我们希望获取输入和期望输出的显式示例。例如,我们可能希望标记图像中包含的内容或其他属性。也许我们将不得不明确地进行标记——通常需要很大的努力。但往往有可能在已有的基础上利用它或将其用作某种代理。例如,我们可能会使用Web上提供的alt标签。或者,在不同的领域中,我们可能会使用为视频创建的闭幕字幕。或者对于语言翻译训练,我们可能会使用存在于不同语言的Web页面或其他文档的平行版本。
神经网络需要多少数据才能训练出特定任务的能力?从第一原理出发很难估算。当然,使用“迁移学习”将已经在另一个网络中学习到的重要特征列表“转移”可以显著减少要求。但通常情况下,神经网络需要“看到很多例子”才能良好地训练。对于一些任务而言,重复的例子非常重要,而且在每一轮“训练回合”(或“时代”)中,神经网络的状态至少会略微不同,通过“提醒它”某个特定的例子有助于让它“记住那个例子”。(是的,这也许类似于人类记忆中重复的有用性。)
但仅仅重复相同的例子并不足够。还需要向神经网络展示例子的变化。而神经网络的传说特点是,这些“数据增强”变化并不需要复杂就可以很有用。只需使用基本的图像处理轻微修改图像即可使其对于神经网络训练来说“崭新如初”。同样,当用于训练自动驾驶汽车的实际视频等数据用尽时,可以继续在模拟类似于电子游戏的环境中运行模拟来获取数据,而不需要所有实际现实场景的细节。
ChatGPT是怎样的呢?它有一个很好的特点,可以进行“无监督学习”,这使得它更容易从中获得训练样例。记得ChatGPT的基本任务是找出如何继续给定的一段文本。因此,只需要获取一段文本,将其结尾部分掩盖,并将其作为“输入来训练”,“输出”是完整的、未被掩盖的文本。我们稍后将讨论更多,但主要的观点是,与学习图像内容不同,不需要“显式标记”;ChatGPT实际上可以直接从任何文本样例中学习。
好了,那么神经网络中的实际学习过程如何呢?最终的目标是确定哪些权重可以最好地捕捉到已经给出的训练样例。可以使用各种详细的选择和“超参数设置”(之所以称之为超参数是因为权重可以被视为“参数”)来调整如何实现这一点。有不同的损失函数(平方和、绝对值之和等)。有不同的损失最小化方式(每步在权重空间移动多远等)。然后还有问题,比如显示多大的“批量”示例以获得每个连续估计的损失。是的,可以应用机器学习(例如我们在Wolfram语言中所做的)来自动化机器学习,以及自动设置超参数等。
但最终整个训练过程可以通过观察损失如何逐渐减小来进行描述(例如在这个小型训练的Wolfram语言进度监视器中)。
通常情况下,人们会看到损失函数在一段时间内下降,但最终会稳定在某个常数值。如果该值足够小,则可以认为训练成功;否则可能需要尝试更改网络结构。
人们可以确定“学习曲线”需要多长时间才能趋于平稳吗?就像许多其他事情一样,这似乎有近似的幂律缩放关系,这取决于使用的神经网络的规模和数据量。但是,总的结论是,训练神经网络很难,并且需要大量的计算工作量。实际上,绝大部分工作量都花费在对数字数组进行操作上,这正是GPU擅长的——这就是为什么神经网络训练通常受到GPU可用性的限制。
在未来,会有根本上更好的方法来训练神经网络,或者通常执行神经网络的任务吗?我认为几乎肯定会有。神经网络的基本思想是利用大量简单的(本质上是相同的)组件创建一个灵活的“计算布料”,并且使这个“布料”能够逐步修改以从示例中学习。在当前的神经网络中,人们基本上使用微积分的思想——应用于实数——来进行这种逐步修改。但越来越清楚的是,具有高精度数字并不重要;即使使用当前的方法,8位或更少的数字可能已经足够了。
使用类似元胞自动机这样基本上在许多个单独位上并行操作的计算系统,如何进行这种渐进式修改从未明确过,但没有理由认为它是不可能的。实际上,就像“2012年的深度学习突破”一样,这种渐进式修改在更复杂的情况下可能比简单情况更容易实现。
神经网络——也许有点像大脑——被设置为具有基本固定的神经元网络,修改的是它们之间连接的强度(“权重”)。 (也许在至少年轻的大脑中,可以增长相当数量的全新连接。)但是,尽管这可能是生物学上的一种方便设置,但它显然不接近实现我们所需的功能的最佳方式。而且,涉及到渐进式网络重写的事情(也许让人想起我们的物理项目)可能最终会更好。
但即使在现有神经网络的框架内,目前存在一个关键限制:目前的神经网络训练基本上是顺序的,每个示例批次的效果都被传播回来更新权重。事实上,即使考虑到GPU,当前计算机硬件的大部分神经网络在训练期间大部分时间处于“空闲”状态,只有一部分被更新。从某种意义上讲,这是因为我们当前的计算机倾向于具有与它们的CPU(或GPU)分离的内存。但在大脑中,这可能是不同的——每个“内存元素”(即神经元)也是一个潜在的活动计算元素。如果我们能以这种方式设置未来的计算机硬件,可能可以更有效地进行训练。
像ChatGPT这样的东西的能力似乎非常令人印象深刻,人们可能想象,如果可以不断“扩大规模”并训练越来越大的神经网络,那么它们最终将能够“做任何事情”。如果关注那些立即可用于人类思维的事物,这很可能是正确的。但是过去几百年科学的教训是,有些事情可以通过形式过程来解决,但不易于立即人类思考。
非平凡的数学是一个很好的例子。但是一般情况下是计算。最终问题是计算不可约性的现象。有些计算可能需要很多步骤,但实际上可以“简化”为某些非常直接的东西。但计算不可约性的发现意味着这并不总是奏效。而且,可能像下面这个过程一样,必须实质上跟踪每个计算步骤才能弄清发生了什么:
我们通常用大脑做的事情可能是有选择地避免计算不可约性。在大脑中进行数学运算需要特殊的努力,而在头脑中思考任何非平凡程序的操作步骤在实践中是基本不可能的。
但是我们有计算机来处理这个问题。通过计算机,我们可以轻松地完成长时间的、计算不可约的事情。关键是,在这方面通常没有捷径。
是的,我们可以记忆许多特定计算系统中发生的事情的具体例子。也许我们甚至可以看到一些(“计算可约”)的模式,可以让我们做一些概括。但是,计算不可约性的要点在于,我们永远无法保证不会发生意外情况,而只有通过显式地进行计算,才能知道任何特定情况下实际发生的情况。
最后,学习性和计算不可约之间存在根本的张力。学习实际上涉及通过利用规律来压缩数据。但是计算不可约意味着最终存在规律的限制。
作为一个实际问题,人们可以想象在可训练的系统(如神经网络)中构建小的计算设备,如细胞自动机或图灵机。实际上,这些设备可以作为神经网络的好“工具”,就像 Wolfram | Alpha 对 ChatGPT 一样。但是,计算不可约意味着人们不能指望“进入”这些设备并让它们学习。
或者换句话说,能力和可训练性之间存在根本的权衡:你想让系统真正使用其计算能力,它就会显示出计算不可约性,并且它将越来越难以训练。而它越基本可训练,它就越难进行复杂的计算。
在目前的 ChatGPT 中,实际上情况更为极端,因为用于生成每个输出标记的神经网络是纯“前馈”网络,没有循环,因此没有能力进行任何具有非平凡“控制流”的计算。
当然,人们可能会想知道是否实际上有能力进行不可约计算。事实上,很长一段时间内这并不重要。但我们现代技术世界建立在利用至少数学计算的工程学基础之上——越来越多地使用更一般的计算。如果我们看看自然界,它充满了不可约计算,我们正在逐渐了解如何模拟和利用它们的技术目的。
是的,神经网络当然可以注意到自然界中我们可能也可以轻易注意到的那些规律。但是,如果我们想解决数学或计算科学范畴内的问题,神经网络将无法完成,除非它有效地“使用作为工具”一个“普通”的计算系统。
但是所有这些都存在一些可能会让人感到困惑的地方。过去,我们认为计算机无法完成的任务包括写作文等等,我们假设这些任务“本质上太难了”。现在我们看到 ChatGPT 等模型完成这些任务后,我们往往会突然认为计算机必须变得非常强大——特别是超越了它们已经基本能够完成的任务(比如逐步计算像细胞自动机这样的计算系统的行为)。
但这不是正确的结论。计算不可约过程仍然是计算不可约的,对于计算机来说仍然是基本困难的,即使计算机可以轻松地计算它们的每一步。我们应该得出的结论是,我们过去认为计算机无法完成的任务(比如写作文)实际上在某种意义上比我们想象的更容易。
换句话说,神经网络能够成功地写一篇文章的原因是写作一篇文章的问题实际上比我们想象的“计算上更浅”。在某种意义上,这使我们更接近于“拥有一个理论”,即我们人类如何处理语言,比如写作文。
如果你有足够大的神经网络,那么你可能能够做到人类可以轻松完成的任何任务。但你不会捕捉到自然界普遍可以做到的事情,也不会捕捉到我们从自然界中制造的工具可以做到的事情。正是使用这些工具——无论是实用的还是概念性的——在最近几个世纪允许我们超越了“纯粹未经人类思考的”可触及边界,并为人类目的捕捉了更多的物理和计算宇宙中的事物。
神经网络——至少目前的设置——是基于数字的。因此,如果我们要使用它们处理文本之类的东西,我们需要一种用数字表示文本的方法。当然,我们可以从字典中开始(基本上像ChatGPT一样)只是为每个单词分配一个数字。但有一个重要的想法——例如ChatGPT的中心——超越了这一点。这就是“嵌入”的概念。可以将嵌入视为一种尝试通过数字数组来表示某物“本质”的方式——具有“附近的东西”由附近的数字表示的属性。
因此,例如,我们可以将单词嵌入视为试图在一种“意义空间”中摆放单词,在这个空间中,“意义相近的单词”会出现在嵌入中附近。实际使用的嵌入,比如在ChatGPT中,往往涉及大量的数字列表。但如果我们将其投影到二维平面上,就可以展示单词嵌入是如何布局的:
因此,例如,我们可以将单词嵌入视为在某种“意义空间”中试图布置单词,其中某些“在意义上相邻”的单词在嵌入中靠近。实际使用的嵌入,比如在ChatGPT中,往往涉及大量数字的列表。但是,如果我们将其投影到2D,我们可以展示单词是如何被嵌入布局的:
是的,我们看到的确能很好地捕捉到典型的日常印象。但是我们如何构建这样的嵌入呢?大致上,我们的想法是查看大量文本(例如来自Web的50亿个单词),然后看不同单词出现在其中的“环境”有多相似。例如,“鳄鱼”和“鳄鱼”几乎可以在其他类似的句子中交替出现,这意味着它们会在嵌入中相邻。但是,“萝卜”和“鹰”不会出现在其他相似的句子中,因此它们将在嵌入中被远远分开。
但是,如何使用神经网络实际实现这样的嵌入呢?让我们首先讨论不是单词,而是图像的嵌入。我们希望以某种方式用数字列表来描述图像,以使“我们认为相似的图像”被分配相似的数字列表。
我们如何确定是否“认为图像相似”?好吧,如果我们的图像是手写数字的图像,如果它们是相同的数字,则“我们认为两个图像相似”。早些时候我们讨论过一个训练用于识别手写数字的神经网络。我们可以认为这个神经网络被设置为,在其最终输出中,将图像放入10个不同的箱中,每个数字一个框。
但是,如果我们在做出“这是一个‘4’”决定之前“截获”了神经网络内部正在发生的事情呢?我们可以期望在神经网络内部有一些数字,它们表征图像“大部分类似于‘4’,但有点类似于‘2’”之类的内容。这个想法是选取这些数字作为嵌入中的元素。
因此,这里有一个概念。我们不是直接尝试表征“哪个图像与另一个图像相似”,而是考虑一个定义良好的任务(在这种情况下是数字识别),我们可以获得明确的训练数据-然后利用这个事实,在完成这个任务时,神经网络隐含地必须做出“接近决策”。因此,我们从来没有必要明确地谈论“图像的相似性”,而只是谈论图像代表的具体数字,并且我们“把这个问题留给神经网络”来隐含地确定这意味着什么样的“图像相似性”。
那么,对于数字识别网络,更详细地说,它是如何工作的呢?我们可以将网络视为由11个连续层组成,我们可以像这样简洁地总结它们(激活函数显示为单独的层):
一开始我们将实际的图像输入到第一层,由像素值的2D数组表示。在最后——从最后一层——我们得到一个由10个值组成的数组,我们可以认为这些值表示网络对图像对应于数字0到9的确定程度。
输入图像,最后一层神经元的值为:
换句话说,到这个时候,神经网络已经“非常确定”这张图片是数字4了——为了得到“4”这个输出结果,我们只需要找到具有最大值的神经元位置即可。
但如果我们再往前看一步呢?网络中最后一步操作是softmax,它试图“强制确定”。但在这之前,神经元的值为:
换句话说,神经网络现在已经“非常确定”这个图像是数字4,为了获得输出“4”,我们只需要选择值最大的神经元的位置。
但是如果我们再往前看一步呢?网络中最后一个操作是softmax,试图“强制确信”。但在应用这个操作之前,神经元的值为:
表示“4”的神经元仍然具有最高的数值。但其他神经元的值也包含了信息。我们可以期望这个数字列表在某种意义上可以用来表征图像的“本质”,从而提供可以用作嵌入的东西。例如,这里的每个“4”都有略微不同的“签名”(或“特征嵌入”),与“8”完全不同:
换句话说,我们基本上使用10个数字来描述我们的图像。但是通常最好使用更多的数字。例如,在我们的数字识别网络中,通过接入前面的一层,我们可以获得一个包含500个数字的数组。这可能是一个合理的“图像嵌入”数组。
如果我们想要显式地可视化手写数字的“图像空间”,我们需要“降维”,通过将我们获得的500维向量投影到三维空间中,例如:
我们刚刚讨论了如何创建图像的表征(从而获得嵌入),方法是基本上通过确定图像是否与相同的手写数字对应(根据我们的训练集),来识别相似的图像。如果我们有一个训练集,其中标识了每个图像属于5000种常见类型的物体(猫,狗,椅子等),我们也可以以更一般的方式做同样的事情。通过神经网络的行为,“锚定”我们对常见对象的识别,然后根据神经网络的行为“在其周围进行概括”。关键是,只要这种行为与我们人类感知和解释图像的方式相一致,这将最终成为一个“对我们来说正确的”嵌入,并且在实践中用于执行“类似于人类判断”的任务。
那么我们如何遵循同样的方法来找到单词的嵌入?关键是从一个与单词相关的任务开始,我们可以很容易地进行训练。标准的任务是“单词预测”。想象一下,我们得到了“the ___ cat”。根据大量的文本语料库(比如网络的文本内容),填入空格的不同单词有什么概率?或者,另一种方法是,给出“___ black ___”,不同“旁边的单词”有什么概率?
如何为神经网络设置这个问题?最终,我们必须用数字来表示所有内容。一种方法就是为英语中的大约50,000个常见单词分配一个唯一的数字。例如,“the”可能是914,“cat”(前面带有一个空格)可能是3542。(这些数字是GPT-2使用的实际数字。)因此,对于“the ___ cat”问题,我们的输入可能是{914,3542}。输出应该是一个大约包含50,000个数字的列表,有效地给出每个可能的“填充”单词的概率。再一次,为了找到嵌入,我们要拦截神经网络“达到结论之前”的“内部”,然后获取在那里发生的数字列表,我们可以将其视为“表征每个单词”。
那么,这些表征是什么样子的?在过去的10年中,已经开发了一系列不同的系统(例如word2vec,GloVe,BERT,GPT等),每个系统基于不同的神经网络方法。但最终,它们都使用数百到数千个数字的列表来表征单词。
在其原始形式下,这些“嵌入向量”相当无信息。例如,这里是GPT-2为三个特定单词生成的原始嵌入向量:
如果我们像测量这些向量之间的距离一样做事情,那么我们可以找到诸如单词“近”的东西。稍后我们将更详细地讨论我们可能认为这些嵌入的“认知”意义。但就目前而言,主要的观点是,我们有一种有用的方法来将单词转换为“神经网络友好”的数字集合。
但实际上,我们可以更进一步,不仅可以将单词序列化为数字集合,还可以将整个文本块化为数字集合。 ChatGPT 就是这样处理事情的。它使用生成嵌入向量来代表已有的文本。然后它的目标是找到可能出现的不同单词的概率。它以一系列数字的形式表示其答案,这些数字本质上给出了每个可能单词的概率。
(严格来说,ChatGPT 不处理单词,而是处理“令牌”——方便的语言单位,可能是完整的单词,也可能只是像“pre”、“ing”或“ized”这样的部分。使用令牌使 ChatGPT 更容易处理罕见的、复合的和非英语单词,并且有时可以发明新单词。)
好的,我们终于可以讨论一下 ChatGPT 内部结构了。没错,最终,它是一个庞大的神经网络——目前是一个拥有 1750 亿个权重的 GPT-3 网络版本。在许多方面,这是一个与我们之前讨论的其他神经网络非常相似的神经网络。但是,它是一个专门用于处理语言的神经网络。其最显著的特点是一种神经网络体系结构,称为“Transformer”。
在我们上面讨论的第一个神经网络中,任何给定层的每个神经元基本上都与之前一层的每个神经元连接(至少有一些权重)。但是,如果正在处理具有特定已知结构的数据,这种完全连接的网络就会是过度的(可能)。因此,例如,在处理图像的早期阶段,通常会使用所谓的卷积神经网络(“convnets”),其中神经元实际上是放置在类似于图像中的像素的网格上,并且仅与网格上附近的神经元相连接。
transformer的想法是对于构成文本的token序列进行类似于图像卷积神经网络的处理。但是,transformers引入了“attention”这一概念——即“更多地关注”序列的某些部分而不是其他部分的想法。也许有一天直接开始一个通用的神经网络并通过训练进行所有的自定义将是有意义的。但至少目前在实践中,“模块化”似乎至关重要——就像transformers那样,可能也像我们的大脑那样。
好的,那么ChatGPT(或者更确切地说是它基于的GPT-3网络)究竟做了什么呢?请记住,它的总体目标是基于它所看到的训练数据(包括来自Web等数十亿个网页的文本),以“合理”的方式继续文本。因此,在任何给定的点上,它都有一定数量的文本,其目标是想出一个适当的选择,以添加下一个token。
它的操作可以分为三个基本阶段。首先,它获取到迄今为止对应于文本的令牌序列,并找到表示这些令牌的嵌入(即一组数字)。然后它以“标准神经网络方式”处理这个嵌入,通过网络中连续的层“传递值”来生成一个新的嵌入(即一个新的数字数组)。接下来,它从这个数组的最后一部分生成一个包含约50000个值的数组,这些值会转换成不同可能的下一个令牌的概率。(是的,它恰好有大约与英语常用词相同数量的令牌,尽管仅有约3000个令牌是整个单词,其余的是碎片。)
关键是,此流程的每个部分都由神经网络实现,其权重是通过端到端的网络训练确定的。换句话说,除了整体架构以外,实际上没有什么是“显式地设计”的;所有东西都只是从训练数据中“学习”的。
然而,建立架构的方式有很多细节,反映了各种经验和神经网络技术。而且,尽管这绝对是深入探讨,但我认为谈论一些这些细节是有用的,至少可以让人们了解构建ChatGPT这样的东西需要付出多大的努力。
首先是嵌入模块。这是GPT-2的一个示意图,使用Wolfram语言表示:
这里描述的是模型中的embedding模块。这个模块的输入是一个由n个标记(以前面所述的方式,用1到大约50000之间的整数表示)组成的向量。每个标记都被转换(通过单层神经网络)成一个嵌入向量(对于GPT-2是长度为768的向量,对于ChatGPT的GPT-3是长度为12288的向量)。同时,有一个“次要路径”会将标记的整数位置序列转换成另一个嵌入向量。最后,标记值和标记位置的嵌入向量相加,生成最终的嵌入向量序列。
为什么要将标记值和标记位置的嵌入向量相加呢?我认为这并没有什么特别的科学原理。只是尝试了许多不同的方法,这种方法似乎是行之有效的。并且神经网络的经验法则是,在某种意义上,只要设置大致正确,通常可以通过充分的训练来确定细节,而无需真正需要在工程层面上“理解”神经网络是如何配置自己的。
这是embedding模块的操作,针对的是输入字符串: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的“主要事件”是所谓的“attention blocks”序列(对于GPT-2有12个,对于ChatGPT的GPT-3有96个)。这一切都非常复杂,令人想起典型的难以理解的大型工程系统或生物系统。但是无论如何,这是单个“attention block”的示意图(适用于GPT-2):
每个这样的注意力块内都有一组“注意力头”(GPT-2为12个,ChatGPT的GPT-3为96个)——每个注意力头独立地对嵌入向量中的不同值块进行操作。(是的,我们并不知道为什么将嵌入向量拆分为几部分是一个好主意,或者不同部分的含义是什么;这只是那些“被发现可行”的事情之一。)
那么注意力头是做什么的呢?基本上,它们是一种“回顾”标记序列的方式(即迄今为止生成的文本),并以有用的形式“打包过去”,以便找到下一个标记。在上面的第一节中,我们谈到了使用二元概率来根据它们的直接前驱选择单词。变形金刚中的“注意力”机制所做的是允许“注意”更早的单词——从而可能捕捉动词可以指代在句子中出现在它们之前很多个单词的名词的方式。
在更详细的层面上,注意头的操作是重新组合与不同标记相关联的嵌入向量中的块,并带有某些权重。因此,例如,在上述“hello, bye”字符串中,第一个注意力块(在GPT-2中)中的12个注意力头具有以下(“一直向标记序列的开头回顾”)“重新组合权重”模式:
在经过注意力头处理后,得到的“重新加权嵌入向量”(对于 GPT-2 的长度为 768,对于 ChatGPT 的 GPT-3 的长度为 12,288)被传递到一个标准的“全连接”神经网络层。很难把握这一层正在做什么。但是这里是它使用的 768×768 权重矩阵的绘图(这里是针对 GPT-2):
通过取 64×64 的移动平均值,一些(随机行走般的)结构开始显现:
这个结构的确定因素是什么?最终可能是人类语言特征的一些“神经网络编码”。但是目前为止,这些特征可能是未知的。实际上,我们正在“打开ChatGPT的大脑”(或至少是GPT-2),发现是的,里面很复杂,我们不理解它,即使最终它会产生可识别的人类语言。
好的,通过一个注意块,我们得到了一个新的嵌入向量,然后连续通过其他注意块(对于GPT-2是12个;对于GPT-3是96个)。每个注意块都有其自己特定的“注意力”和“完全连接”权重模式。这里是GPT-2的“hello,bye”输入的第一个注意头的注意力权重序列:
把这些移动平均后,下面是完全连接层的矩阵:
有趣的是,尽管不同注意力块中的这些“权重矩阵”看起来非常相似,但权重大小的分布可能会有所不同(而且并不总是高斯分布):
因此,在经过所有这些注意力块之后,变形器的净效应是什么?本质上,它将标记序列的原始嵌入集合转换为最终集合。而ChatGPT的特定工作方式是选择此集合中的最后一个嵌入,并将其“解码”以生成应该下一个标记的概率列表。
这就是ChatGPT内部的概述。它可能看起来很复杂(尤其是因为它有许多不可避免的有些任意的“工程选择”),但实际上涉及的最终元素非常简单。因为最终我们处理的只是由“人造神经元”组成的神经网络,每个神经元都执行简单的操作,即将一组数字输入与某些权重结合。
ChatGPT的原始输入是一组数字(到目前为止标记的嵌入向量),当ChatGPT“运行”以生成新标记时,所发生的就是这些数字在神经网络的层中“涟漪”,每个神经元“做自己的事情”,并将结果传递给下一层上的神经元。没有循环或“返回”。一切都只是通过网络“前馈”传递。
这种架构与典型的计算系统(如图灵机)非常不同,在该计算系统中,结果会被相同的计算元素重复“重新处理”。而在这里——至少在生成给定输出令牌时——每个计算元素(即神经元)仅使用一次。
但在某种意义上,即使在ChatGPT中,仍然存在一个“外部循环”,即重复使用计算元素。因为当ChatGPT将要生成一个新令牌时,它总是“读取”(即将其之前的所有标记序列作为输入),包括ChatGPT自己以前“编写”的标记。我们可以将这种设置视为意味着ChatGPT——至少在其最外层——涉及一个“反馈循环”,尽管每次迭代都明确可见为出现在其生成的文本中的令牌。
但让我们回到ChatGPT的核心:被重复用于生成每个标记的神经网络。在某种程度上,它非常简单:整个相同的人工神经元集合。网络的某些部分仅由(“全连接”)神经元层组成,在该层中,给定层上的每个神经元都连接(带有一些权重)到前一层上的每个神经元。但是,尤其是在其转换器架构方面,ChatGPT具有更多结构的部分,其中仅连接不同层上的特定神经元。(当然,仍然可以说“所有神经元都连接在一起”——但有些神经元的权重为零。)
此外,ChatGPT神经网络的某些方面并不是最自然的想法,它们不能仅被视为“同质”的层。例如,正如上面的图表所示,注意力块中存在“复制多个输入数据”的地方,每个数据副本都会经过不同的“处理路径”,可能涉及不同数量的层,然后才进行重新组合。但是,虽然这可能是对正在发生的事情的方便表示,但总体上来说,在原则上可以考虑“密集填充”层,只是有一些权重为零。
如果看一下ChatGPT中最长的路径,涉及到约400个(核心)层,从某些方面来看并不是一个巨大的数字。但是有数百万个神经元,总共有1750亿个连接和因此有1750亿个权重。一个需要意识到的事情是,每次ChatGPT生成一个新的标记时,它都必须进行一次涉及每个权重的计算。从实现的角度来看,这些计算可以按“层”组织成高度并行的数组操作,可以方便地在GPU上执行。但是对于生成的每个标记,仍然需要进行1750亿次计算(最终还需要更多)——因此,不难理解使用ChatGPT生成一长段文本需要一定时间。
但最终,令人惊异的是,所有这些操作 - 尽管它们各自都很简单 - 怎么能一起成功地完成“人类化”的生成文本的工作。必须再次强调的是(至少就我们目前所知),没有“终极理论原因”说明为什么这样的方法会奏效。实际上,正如我们将要讨论的那样,我认为我们必须将其视为一种(潜在令人惊讶的)科学发现:在像ChatGPT这样的神经网络中,不知何故,可以捕捉到人类大脑在生成语言方面的本质。
好了,现在我们已经概述了ChatGPT设置后的工作原理。但是它是如何设置的呢?它的所有1750亿个权重是如何确定的呢?基本上,它们是通过基于人类编写的大量文本 - 在网上、书籍中等 - 进行大规模训练得到的。正如我们所说,即使考虑到所有这些训练数据,神经网络能够成功地生成“人类化”的文本,这显然并不明显。再一次,似乎需要详细的工程部分才能使这一切发生。但ChatGPT的重大惊喜 - 和发现 - 是这是可能的。实际上,“只有”1750亿个权重的神经网络可以生成人类写作的“合理模型”。
现代社会中,有大量由人类书写的文本以数字形式存在。公共网络上至少有几十亿人类书写的网页,总共可能有万亿字的文本。如果包括非公开网页,则数字可能至少增加100倍。迄今已经有超过500万本数字化图书可供使用(约占有史以来出版的1亿本书的一半),提供另外约1000亿字的文本。这还没有提到从视频等语音中产生的文本。(作为个人对比,我一生中发表的总文字量略低于300万字,过去30年我写了约1500万字的电子邮件,总共输入的文字可能有5000万字。在过去几年中,我在直播中说了超过1000万个词。是的,我会从所有这些中训练一个聊天机器人。)
但是,好的,有了所有这些数据,如何从中训练神经网络呢?基本过程与我们在上面简单示例中讨论的非常相似。您提供一批示例,然后调整网络中的权重以最小化网络在这些示例上产生的误差(“损失”)。“反向传播”错误的主要昂贵之处在于每次这样做时,网络中的每个权重通常至少会微调一点,而要处理的权重数量非常多。(实际的“反向计算”通常仅比前向计算更难处理一个小常数因子。
通过现代GPU硬件,可以轻松并行计算数千个示例的结果。但是,在实际更新神经网络的权重时,当前的方法基本上需要逐批次进行。 (是的,这可能是实际的大脑现在至少具有架构优势的地方,因为它们具有组合计算和存储元素。)
即使在我们之前讨论学习数值函数的看似简单的情况下,我们发现我们通常需要使用数百万个示例才能成功地从头开始训练网络。那么,这意味着我们需要多少示例才能训练出“类似人类语言”的模型呢?理论上似乎没有任何确定的方法。但实践中,ChatGPT 成功地从几百亿个单词的文本中进行了训练。
它有时会多次处理某些文本,有时只会处理一次。但是,它从所看到的文本中“获取了所需的内容”。但是,考虑到这么多文本要从中学习,它应该需要多大的神经网络才能“学习得好”呢?同样,我们尚无根本性的理论方法来确定。最终 - 如下面将进一步讨论的那样 - 人类语言和人们通常使用它说的内容应该存在一定的“总算法内容”。但是,下一个问题是神经网络在实现基于该算法内容的模型时的效率如何。我们还不知道,尽管 ChatGPT 的成功表明它是相当有效的。
最终我们可以注意到,ChatGPT使用了数百亿个权重来完成它的任务——与其训练数据中的总单词(或标记)数量相当。在某些方面,这或许令人惊讶(虽然在ChatGPT的较小模型中也经验证实),好像“工作良好的网络大小”与“训练数据大小”非常相似。毕竟,这当然不是因为“ChatGPT内部”某种方式“直接存储”了来自网络、图书等所有文本的内容。因为ChatGPT内部实际上是一堆数字,具有稍少于10位数的精度,是所有文本的集合结构的某种分布式编码。
换句话说,我们可以问人类语言及其典型用法的“有效信息内容”是什么。有语言的原始语料库,还有ChatGPT中的神经网络表示。这种表示很可能远非“算法上最小”的表示(如下文所讨论的)。但它是神经网络容易使用的表示。在这种表示中,训练数据似乎最终没有太多压缩;平均而言,基本上只需要不到一个神经网络权重来承载一个训练数据单词的“信息内容”。
当我们运行ChatGPT来生成文本时,我们基本上必须使用每个权重一次。因此,如果有n个权重,我们需要大约n次计算步骤——尽管在实践中,许多计算步骤通常可以在GPU中并行完成。但是如果我们需要大约n个单词的训练数据来设置这些权重,那么根据上面所说的内容,我们可以得出结论,我们将需要大约n2个计算步骤来进行网络的训练。这就是为什么,用当前的方法,我们最终需要谈论耗费数十亿美元的训练工作的原因。
在 ChatGPT 的训练中,大部分的工作是“向它展示”来自网络、书籍等的大量现有文本。但事实证明还有另一个似乎非常重要的部分。
一旦 ChatGPT 从它展示的原始文本语料库中完成“原始训练”,神经网络内部就可以开始生成自己的文本,并从提示中继续生成。尽管这些结果通常似乎是合理的,但它们往往会在较长的文本中“偏离”,经常表现出非常非人类化的方式。这不是通过对文本进行传统的统计分析可以轻松检测到的,但人们阅读文本时很容易注意到。
ChatGPT 构建的一个关键思想是,在“被动阅读”像网络这样的东西之后,还有另一步:让实际的人们积极与 ChatGPT 互动,看看它生成了什么,从而对“如何成为一个好的聊天机器人”给予反馈。但神经网络如何使用这些反馈呢?第一步是让人类评价神经网络的结果。然后建立另一个神经网络模型,试图预测这些评分。但现在这个预测模型可以被运行,在原始网络上实际上像损失函数一样进行运算,从而允许该网络通过人类反馈进行“调整”。实践中的结果似乎对系统成功产生“类人”的输出有很大的影响。
总的来说,有趣的是,要让“原始训练”的网络朝特定方向有用地发展,似乎只需要很少的“刺激”。人们可能会认为,要让网络表现得好像“学会了新东西”,就需要运行训练算法,调整权重等等。
但事实并非如此。相反,似乎只需要在提示中告诉ChatGPT一次东西,它就可以成功地在生成文本时利用它所学到的内容。再一次,这种方法的可行性是我认为理解ChatGPT“真正在做什么”以及它与人类语言和思维结构的关系的重要线索之一。
这其中肯定有一些类似于人类的东西:至少在完成了所有的预训练后,你只需要告诉它一次东西,它就可以“记住”它——至少“足够长时间”以便使用它生成一段文本。那么,在这种情况下发生了什么呢?可能“你要告诉它的一切内容已经在里面了”,你只是引导它到正确的位置。但这似乎不太可能。相反,更有可能的是,是的,这些元素已经在里面了,但是具体内容是由类似于“这些元素之间的轨迹”之类的东西定义的,而当你告诉它一些内容时,就是在引入这些轨迹。
实际上,与人类相似,如果你告诉ChatGPT一些奇怪和意想不到的东西,完全不符合它已知的框架,它似乎不能成功地“整合”它。只有当它基本上在现有框架的基础上以相当简单的方式运行时,它才能“整合”它。
还值得再次指出,神经网络“捕捉”信息的能力必然有“算法限制”。告诉它“这个东西去那个地方”的“浅层规则”,神经网络很可能能够很好地表示和再现这些规则,而且它已经从语言中“已知”的东西将给它一个立即跟随的模式。但是,如果你尝试为涉及许多潜在的计算不可化简步骤的实际“深层计算”提供规则,它就行不通了。(请记住,在每个步骤中,它总是在其网络中“向前传递数据”,除了生成新标记外,它永远不会循环。)
当然,网络可以学习特定的“不可化简”计算的答案。但是,一旦存在组合数目的可能性,这种“表格查找样式”的方法就行不通了。因此,像人类一样,神经网络现在需要“伸手”使用实际的计算工具。(是的,Wolfram|Alpha和Wolfram Language非常适合,因为它们被建立用于“谈论世界上的事情”,就像语言模型神经网络一样。)
人类语言和生成它所涉及的思维过程一直被认为是一种复杂的顶峰。实际上,人类大脑的“仅有”约1000亿个神经元(以及可能有1万亿个连接)的网络能够负责这一过程,一直让人感到惊讶。也许人们会想象,大脑不仅仅是神经元网络,还有一些未被发现的新物理层面。但现在,我们有了一个重要的新信息:我们知道一个仅有约人类神经元数量的纯人工神经网络能够出奇地成功地生成人类语言。
是的,这仍然是一个庞大而复杂的系统,其神经网络权重数量约等于当前世界上可用文本的单词数。但在某种程度上,仍然难以相信语言的丰富性和它所能谈论的事情可以被封装在这样一个有限的系统中。部分原因在于,计算过程实际上可以大大增加系统的表面复杂性,即使其基本规则是简单的(这在规则30的例子中首次显现出来)。但实际上,正如我们上面所讨论的那样,ChatGPT中使用的神经网络倾向于特别构造以限制这种现象的影响和与之相关的计算不可简化性,以使其训练更易于接受。
那么,像ChatGPT这样的系统是如何实现语言生成的呢?我认为,基本答案是语言在根本上比它看起来要简单。这意味着即使使用了最终相对简单的神经网络结构,ChatGPT也能成功地“捕捉到”人类语言及其背后的思维本质。而且,在其训练中,ChatGPT已经“隐含地发现”了使这一切成为可能的语言(和思维)的规律。
我认为,ChatGPT的成功为我们提供了一项基础和重要的科学证据:它表明我们可以期望有重大的新“语言定律”——实际上是“思维定律”——有待发现。在以神经网络为基础的ChatGPT中,这些定律至多是隐含的。但是,如果我们能够以某种方式使这些定律明确,那么就有可能以更直接、高效、透明的方式做到ChatGPT所能做的事情。
那么,这些定律可能是什么样子的呢?最终,它们必须为我们提供某种方法,描述语言及其表达的东西是如何组合在一起的。稍后我们将讨论“观察ChatGPT内部”可能如何为我们提供一些提示,以及我们从构建计算语言中所知道的是如何前进的。但首先,让我们讨论两个长期以来已知的“语言定律”的例子,以及它们与ChatGPT的操作的关系。
第一条是语言的语法。语言不是一堆随机混合的单词。相反,有相对明确的语法规则来指导不同类型的单词如何组合:例如,在英语中,名词可以被形容词修饰,并且后面可以跟动词,但通常两个名词不能紧挨着。这种语法结构可以(至少近似地)通过定义“语法树”的规则集来捕捉:
ChatGPT没有任何明确的“知识”来描述这样的规则,但在其训练中它隐式地“发现”了这些规则,然后似乎能够很好地遵循它们。那么这是如何工作的呢?在“大局”层面上,这并不清楚。但为了获得一些洞察力,也许看一个更简单的例子会很有启发性。
考虑由(和)序列组成的“语言”,其语法规定括号始终要保持平衡,如下所示的解析树:
我们可以训练一个神经网络来生成“语法正确”的括号序列吗?在神经网络中,处理序列的方式有很多种,但让我们使用变压器网络,就像ChatGPT一样。给定一个简单的transformer网络,我们可以开始将语法正确的括号序列作为训练样本。一个细节(实际上也出现在ChatGPT生成人类语言的情况下)是,除了我们的“内容标记”(在这里是“(”和“)”)之外,我们还必须包括一个“结束”标记,用于指示输出不应再继续(即对于ChatGPT,这意味着已经到达了“故事的结尾”)。
如果我们设置一个只有一个注意块,具有8个头和长度为128的特征向量的简单transformer网络(ChatGPT也使用长度为128的特征向量,但具有96个注意块,每个块有96个头),那么它似乎无法学习太多关于括号语言的知识。但是,使用2个注意块,学习过程似乎会收敛 - 至少在提供了大约1000万个示例后(并且,与transformer网络的常见情况一样,提供更多示例似乎只会降低其性能)。
因此,对于这个网络,我们可以做类似于ChatGPT的操作,并要求它输出下一个标记的概率 - 在括号序列中:
在第一种情况下,该网络“非常确定”序列无法在此结束——这很好,因为如果结束了,括号就会不平衡。然而,在第二种情况下,它“正确地识别”序列可以在这里结束,但它也“指出”可以“重新开始”,放下一个“(”,可能会有一个“)”跟随。但是,糟糕的是,即使有着它那 400,000 个辛苦训练的权重,它也说有 15% 的概率下一个标记是“)”,这是不正确的,因为这必然会导致不平衡的括号。
以下是我们对网络询问括号序列中逐渐变长的最高概率完成情况的结果:
是的,在一定长度范围内,神经网络做得很好。但是随后它开始失败。这是在“精确”情况下使用神经网络(或者说机器学习)时所看到的典型情况。人类“一眼就能解决”的问题,神经网络也能解决。但是对于需要执行“更多算法性操作”的问题(例如显式计算括号数量以查看是否已关闭),神经网络似乎“计算能力不够”,无法可靠地完成任务。(顺便说一句,即使是完整的ChatGPT当前版本在长序列中也难以正确匹配括号。)
那么这对ChatGPT之类的事物以及英语这种语言的语法意味着什么?括号语言是“严格”的,更像是“算法性的故事”。但是在英语中,基于局部单词选择和其他线索来“猜测”语法上合适的东西是更现实的。是的,神经网络在这方面表现得更好——尽管可能会错过一些“形式上正确”的情况,但这也可能是人类会犯的错误。但是主要观点是,语言存在整体句法结构,具有所有规律性的含义,这在某种程度上限制了神经网络需要学习的“程度”。一个关键的“类自然科学”的观察是,像ChatGPT中的转换器体系结构似乎能够成功地学习这种类似于树形嵌套结构的语法结构,这种结构似乎在所有人类语言中都存在(至少是某种近似)。
语法提供了一种对语言的限制。但是还有其他方面的限制。像“好奇的电子在吃鱼的时候吃蓝色的理论”这样的句子在语法上是正确的,但不是人们通常会说的内容,如果ChatGPT生成这样的内容,也不会被认为是成功的,因为这个句子在其常规单词含义下基本上毫无意义.
但是,有没有一般性的方法可以确定一个句子是否有意义?传统上没有一个总体理论可以解决这个问题。但是在被数十亿条(可能有意义的)来自网络等的句子训练之后,人们可以认为ChatGPT已经隐含地“发展了一种理论”。
这种理论会是什么样子呢?在逻辑方面,有一小部分基本上已经被人们了解了两千年,那就是逻辑学。特别是在亚里士多德发现的三段论形式中,逻辑学基本上是一种说法,即遵循某些模式的句子是合理的,而其他句子则不合理。因此,例如,说“所有的X都是Y。这不是Y,所以它不是X”是合理的(例如,“所有的鱼都是蓝色的。这不是蓝色的,所以它不是鱼。”)。就像可以有些幽默地想象亚里士多德通过大量的修辞例子(“机器学习式”)发现三段论逻辑一样,人们也可以想象,在ChatGPT的训练过程中,它会通过查看网络上的大量文本等方式“发现三段论逻辑”(当然,在更复杂的形式逻辑方面,情况会有所不同,并且我认为可以预期它会像匹配括号一样在这里失败)。
但是,在逻辑的狭义例子之外,有什么方法可以系统地构建(或识别)即使是可能有意义的文本吗?是的,有像Mad Libs这样使用非常特定的“短语模板”的东西。但是,一些ChatGPT似乎隐含地有一种更普遍的方法来做到这一点。也许在它的1750亿个神经网络权重下,这种能力似乎是自然而然发生的。但我强烈怀疑,其实有一种更简单而强大的方法。
我们上面讨论过,在ChatGPT内部,任何一段文本都可以被表示为一个数字数组,我们可以把它想象成某种“语言特征空间”中的点的坐标。因此,当ChatGPT继续一段文本时,这相当于在语言特征空间中描绘出一条轨迹。但现在我们可以问,在这个轨迹与我们认为有意义的文本相对应时,什么使它成为有意义的呢?或许会有一些“语义动力学规律”来定义或至少限制着在保持“有意义性”的同时,语言特征空间中的点如何移动呢?
那么这个语言特征空间是什么样子的呢?如果我们将这样一个特征空间投影到二维平面上,以下是单个单词(这里是普通名词)的可能布局示例:
我们在上面看到了另一个基于代表植物和动物的单词的示例。但是在这两种情况下,“语义相似的单词”会被放在附近。
作为另一个示例,这里是不同词性的单词如何排列的:
当然,一个单词通常不仅有“一个意思”(或者并不一定对应于一个词性)。通过查看包含一个单词的句子在特征空间中的布局,人们经常可以“分解”不同的含义-例如,对于单词“crane”(是指鸟还是机器?)在这里的示例中:
好的,所以我们至少可以认为这个特征空间将“在意义上相似的单词”放在空间中靠近的位置。但是在这个空间中,我们可以识别出什么样的额外结构呢?例如,是否有某种“平行输运”的概念,反映了空间的“平直性”?一个了解这个问题的方法是观察类比:
当然,即使我们将空间投影到2D,通常也至少有“平坦的暗示”,尽管它肯定不是普遍存在的。
那么轨迹呢?我们可以查看ChatGPT中一个提示在特征空间中遵循的轨迹,然后看看ChatGPT如何继续它:
这里当然没有“几何上显然”的运动规律。这一点毫不令人惊讶;我们完全期望这是一个更加复杂的故事。例如,即使存在“语义运动规律”,它最自然的表述方式(或者实际上是哪些“变量”)也很不明显。
在上面的图中,我们展示了“轨迹”的几个步骤,其中每一步我们选择 ChatGPT 认为最有可能的单词(“零温度”情况)。但我们也可以询问在给定点上下一个可能出现的单词以及其概率:
我们可以看到,在这种情况下,存在一个“扇形”,其中高概率单词在特征空间中似乎朝着一个或多个方向移动。如果我们继续下去,会发生什么?以下是随着我们“沿着”轨迹“移动”而出现的连续“扇形”:
这是一个三维的图形,共计40步:
是的,这看起来像一团乱麻,并没有特别鼓励人们相信我们可以通过经验研究“ChatGPT内部的工作方式”来识别“数学物理般的”“语义运动定律”。但也许我们只是在看“错误的变量”(或错误的坐标系),只要我们看到正确的变量,我们就会立即看到ChatGPT正在做一些“数学物理简单”的事情,比如遵循测地线。但是目前为止,我们还没有准备好从其“内部行为”中“经验性解码”出ChatGPT已经“发现”的有关人类语言“组合”的信息。
要产生“有意义的人类语言”,需要什么?在过去,我们可能会认为这只能是人类的大脑所能做到的。但现在,我们知道ChatGPT的神经网络也可以做得相当不错。但是,也许这就是我们所能做到的最好的了,没有更简单或更易于理解的东西能够胜任。但我强烈怀疑ChatGPT的成功隐含了一个重要的“科学”事实:有意义的人类语言实际上比我们所知道的更具结构和简单性,在最终可能会有相当简单的规则来描述如何组合这样的语言。
正如我们之前提到的,语法语法为人类语言中的不同词性对应的单词如何组合提供规则。但为了处理意义,我们需要更进一步。其中一种方法是不仅考虑语法语法,还要考虑语义语法。
对于语法,我们可以识别名词和动词等事物。但对于语义,我们需要“更细致的分级”。例如,我们可能会识别“移动”概念和“维持其独立于位置的身份”的“对象”概念。这些“语义概念”有无数具体的例子。但是,对于我们的语义语法,我们将只有一些基本规则,基本上是说“对象”可以“移动”。关于如何处理这一点,有很多要说的(我之前已经说过一些)。但在这里,我会满足于提出一些简要的评论,以表明前进的一些潜在途径。
值得一提的是,即使根据语义语法,一个句子是完全可以的,这并不意味着它已经在实践中实现了(甚至可能无法实现)。“大象去月球旅行”无疑会“通过”我们的语义语法,但它当然还没有在我们实际的世界中实现(至少目前还没有)——尽管它绝对适用于虚构的世界。
当我们开始谈论“语义语法”时,我们很快会问:“它的底层是什么?” 它假设了什么“世界模型”? 语法语法实际上只是关于如何从单词构建语言的方式。 但是语义语法必然涉及某种“世界模型”——某些东西可以作为“骨架”,在其上可以构建由实际单词组成的语言。
直到最近,我们可能认为(人类的)语言是描述我们“世界模型”的唯一一种通用方法。几个世纪以前就开始对特定事物进行形式化,特别是基于数学。但现在有一种更通用的形式化方法:计算语言。
是的,这是我四十多年来的大型项目(现在体现在 Wolfram 语言中):开发精确的符号表示,可以尽可能广泛地谈论世界上的事物,以及我们关心的抽象事物。因此,例如,我们具有城市、分子、图像和神经网络的符号表示,并且我们具有关于如何计算这些东西的内置知识。
现在在 Wolfram 语言中,我们已经内置了大量关于很多事物的计算知识。但是要建立一个完整的符号论述语言,我们还需要建立关于世界上普遍事物的其他“演算法”,例如:如果一个物体从 A 移动到 B,然后从 B 移动到 C,那么它就从 A 移动到 C,等等。
给定一个符号论述语言,我们可以使用它来做“独立的陈述”。但我们也可以像“Wolfram|Alpha”一样使用它来问关于世界的问题。或者我们可以使用它来陈述我们“想要实现的事情”,可能需要一些外部激活机制。或者我们可以使用它来做断言——可能是关于实际世界,或者是关于我们考虑的某个特定的世界,无论是虚构的还是其他的。
人类语言在根本上是不精确的,因为它没有与特定的计算机实现“连接”,它的含义基本上只由其使用者之间的“社会契约”来定义。但是,由于其本质的特性,计算机语言具有一定的基本精度——因为最终它所指定的内容都可以在计算机上“明确地执行”。人类语言通常可以逃避一定的含糊不清(当我们说“行星”时,它是否包括系外行星等等?)。但在计算机语言中,我们必须明确和清楚地表达我们所做的所有区分。
通常情况下,利用普通人类语言来构建计算语言中的名称是很方便的。但是它们在计算语言中的含义必须是精确的,可能涵盖或不涵盖典型的人类语言用法中的某些内涵。
如何确定适用于一般符号话语语言的基本“本体论”?嗯,这并不容易。这或许就是为什么自亚里士多德两千多年前做出原始的开端以来,很少有人在这方面做过什么。但今天我们现在对如何以计算方式思考世界有如此深入的了解,这确实有所帮助(而我们的物理项目的“基本形而上学”的概念也不无帮助)。
但是,这一切在ChatGPT的背景下意味着什么呢?通过训练,ChatGPT已经有效地“拼凑出”了某种(相当惊人的)语义语法数量。但它的成功使我们有理由认为,构建更完整的计算语言形式是可行的。并且,与我们迄今为止已经了解的有关ChatGPT内部的情况不同,我们可以期望设计计算语言,使其易于人类理解。
当我们谈论语义语法时,可以将其类比于三段论逻辑。最初,三段论逻辑本质上是有关用人类语言表达陈述的规则集合。但是(是的,两千年后),当形式逻辑被发展出来时,三段论逻辑的原始基本结构现在可以用于构建巨大的“形式塔”,包括现代数字电路的运算。因此,我们可以期待,更一般的语义语法也会是这样。起初,它可能只能处理简单的模式,比如文本。但一旦它的整个计算语言框架被建立起来,我们可以期待,它将能够被用于建立“广义语义逻辑”的高大塔楼,使我们能够以精确和形式化的方式处理以前从未可及的各种事物,除了普通的人类语言外,它们的含糊不清只能停留在“地面层次”。
我们可以认为计算语言和语义语法的构建代表了一种表示事物的终极压缩。因为它允许我们谈论可能性的本质,而不必处理存在于普通人类语言中的所有“说法”。我们可以将ChatGPT的巨大优势视为类似的东西:因为它也在某种程度上“穿透了”到了可以“以语义方式将语言组合起来”的地步,而不必考虑不同的可能说法。
那么,如果将ChatGPT应用于基础计算语言会发生什么呢?计算语言可以描述可能性。但是仍然可以添加“流行的东西”的感觉,例如基于阅读网络上的所有内容。但是,然后,在计算语言下面运行意味着类似ChatGPT这样的东西具有立即和根本的访问权,可以利用潜在的不可约算的终极工具。这使得它不仅可以“生成合理的文本”,而且可以期望能够解决关于该文本是否实际上对世界或它所要谈论的事情进行“正确”陈述的所有问题。
ChatGPT的基本概念在某种程度上相当简单。首先,从网络、书籍等人类创作的大量文本样本中出发,然后训练一个神经网络生成“类似”的文本。尤其是,使它能够从“提示”开始,然后继续生成“类似于它所训练的内容”的文本。
正如我们所见,ChatGPT中的实际神经网络由非常简单的元素组成——尽管有数十亿个。神经网络的基本操作也非常简单,基本上是将源自其迄今为止生成的文本的输入“传递一次其元素”(不带任何循环等)用于每个新单词(或部分单词)的生成。
但是值得注意的,以及出乎意料的是,这个过程可以生成成功的文本,其“类似于”网络、书籍等的内容。而且,它不仅是连贯的人类语言,而且“表达”了“遵循它的提示”的内容,利用了它“读到”的内容。它并不总是说出“全局上有意义的话”(或对应于正确的计算),因为(如果没有访问Wolfram|Alpha的“计算超级能力”),它只是在根据其训练材料中的“听起来正确”的内容说出一些话。
ChatGPT的具体工程使其变得非常引人注目。但最终(至少在它能够使用外部工具之前),ChatGPT只是从它积累的“常规智慧的统计数据”中提取出一些“连贯的文本线索”。但令人惊奇的是,它的结果非常类似于我们人类会产生的结果。正如我所讨论的,这表明了一些至少在科学上非常重要的事情:人类语言(及其背后的思维模式)在其结构上比我们想象的要更简单、更“有法则性”。ChatGPT已经隐含地发现了这一点。但我们可能可以通过语义语法、计算语言等方式将其明确地暴露出来。
ChatGPT生成文本的能力非常令人印象深刻——其结果通常非常接近我们人类的产出。那么这是否意味着ChatGPT像一个大脑一样工作呢?它的底层人工神经网络结构最终是基于对大脑的理想化建模的。而且当我们人类生成语言时,很多方面正在发生的事情似乎是相当相似的。
当涉及到训练(也就是学习)大脑和当前计算机的不同“硬件”(以及也许一些未开发的算法思想)时,ChatGPT被迫使用一种与大脑相比可能相当不同(在某些方面更不高效)的策略。还有另一件事:与典型的算法计算甚至不同,ChatGPT内部不具有“循环”或“重新计算数据”的能力。这不可避免地限制了它的计算能力,即使相对于当前的计算机,但绝对是相对于大脑而言。
目前尚不清楚如何“修复这个问题”,同时仍保持系统的合理效率。但这样做可能会让未来的ChatGPT能够执行更多“类脑”的任务。当然,大脑和ChatGPT这样的系统在某些方面也有不足之处——尤其是涉及不可简化计算的情况。对于这些问题,大脑和ChatGPT都需要寻求“外部工具”,例如Wolfram Language。
但就目前而言,看到ChatGPT已经能够做到什么是令人兴奋的。从某种程度上说,这是一个很好的例子,说明大量简单的计算元素可以做出非凡和出乎意料的事情。但它也提供了自2000年以来我们更好地理解人类语言和思维过程的基本特征和原则的最好动力。
在过去的43年中,我一直关注神经网络的发展,并与许多人互动过。其中包括:Giulio Alessandrini、Dario Amodei、Etienne Bernard、Taliesin Beynon、Sebastian Bodenstein、Greg Brockman、Jack Cowan、Pedro Domingos、Jesse Galef、Roger Germundsson、Robert Hecht-Nielsen、Geoff Hinton、John Hopfield、Yann LeCun、Jerry Lettvin、Jerome Louradour、Marvin Minsky、Eric Mjolsness、Cayden Pierce、Tomaso Poggio、Matteo Salvarezza、Terry Sejnowski、Oliver Selfridge、Gordon Shaw、Jonas Sjöberg、Ilya Sutskever、Gerry Tesauro和Timothee Verdier。在撰写本文时,我特别要感谢Giulio Alessandrini和Brad Klee的帮助。
本文由闻数起舞和ChatGPT翻译自 https://writings.stephenwolfram.com/2023/02/what-is-chatgpt-doing-and-why-does-it-work/