一个词一个词的输出
ChatGPT能够自动生成类似于人类书写的文本,这是非常了不起和出乎意料的。但它是如何做到的?为什么会有效果呢?我的目的在于大致概述ChatGPT内部发生了什么,然后探讨它为什么能够很好地生成我们认为有意义的文本。我应该在开始时说一下,我将专注于正在进行的大局,并且虽然我会提及一些工程细节,但我不会深入研究它们。(而且我所说的要点同样适用于其他当前“大型语言模型”[LLMs]以及ChatGPT。)
首先需要解释的是,ChatGPT 始终基本上试图产生一个“合理的延续”,无论它已经得到了什么样的文本,所谓“合理”,我们指的是“在看过数十亿个网页等内容后,人们可能会写出什么”。
假设我们有一段文本:“AI最好的地方在于它的能力”。想象一下扫描数十亿页人类书写的文本(比如网络和数字化图书)并找到所有这个文本出现的实例,然后看接下来出现什么单词以及占比是多少。ChatGPT 实际上做了类似的事情,只不过(我将解释)它不是查看字面文字;而是寻找某种意义上“匹配”的东西。但最终结果是生成一个可能跟随该文本的单词排名列表,并带有“概率”:
而令人惊奇的是,当ChatGPT做一些事情,比如写一篇文章时,它实际上只是一遍又一遍地问自己:“在已有的文本基础上,下一个词应该是什么?”-每次都添加一个单词。(更准确地说,我将解释为什么它会添加“标记”,这可能只是单词的一部分,这就是为什么它有时可以“创造新单词”的原因。)
但是,每一步它都会得到一个带有概率的单词列表。但是它应该选择哪个单词添加到文章(或其他正在编写的内容)中呢?人们可能认为应该选择“排名最高”的单词(即分配了最高“概率”的单词)。但这就是巫术开始渗入的地方。因为出于某种原因——也许有一天我们会对此有科学式的理解——如果我们总是选择排名最高的单词,我们通常会得到一个非常“平淡无奇”的文章,似乎从未表现出任何创造力(甚至有时逐字重复)。但如果偶尔(随机地)选择较低排名的单词,则可以获得更加“有趣”的文章。
这里的随机性意味着,如果我们多次使用相同的提示,每次得到的文章很可能会不同。并且,符合巫术思想的是,有一个特定的所谓“温度”参数来确定使用低排名词汇的频率,在生成文章方面,“温度”为0.8似乎最好。(值得强调的是这里没有使用任何“理论”,只是根据实践发现什么有效而已。例如,“温度”的概念之所以存在是因为指数分布在统计物理学中很常见,但至少就目前而言,并没有与物理学建立起联系。)
在我们继续之前,我应该解释一下,为了说明的目的,我大多数情况下不会使用ChatGPT中完整的系统;相反,我通常会使用一个更简单的GPT-2系统,它有一个很好的特点:它足够小,在标准桌面计算机上运行。因此,对于我展示的所有内容,我都能够包含明确的Wolfram语言代码,并且您可以立即在您自己电脑上运行。(点击这里任何图片以复制其后面的代码。)
例如,这是如何获取上面的概率表格。首先,我们必须检索基础的“语言模型”神经网络:
稍后,我们将深入研究这个神经网络,并讨论它的工作原理。但现在,我们可以把这个“网络模型”视为黑盒子应用于到目前为止的文本中,并询问模型所说的应该跟随的概率最高的前5个单词:
这将获取该结果并将其转换为显式格式的“数据集”:
如果一个人反复“应用模型”,在每一步中添加具有最高概率的单词(在此代码中指定为模型的“决策”),则会发生以下情况:
如果继续下去会发生什么?在这种“零温度”的情况下,很快就会变得混乱和重复。
但是,如果我们不总是选择“顶部”单词,而是有时随机选择“非顶部”单词(其中的“随机性”对应于温度0.8),会怎样呢?同样可以构建文本:”。
每次这样做时,都会进行不同的随机选择,文本也会因此而不同——就像这5个例子一样:
值得指出的是,即使在第一步,也有很多可能的“下一个单词”可供选择(在温度0.8时),尽管它们的概率很快就会下降(是的,在这个对数-对数图上的直线对应于n-1“幂律”衰减,这非常符合语言的一般统计规律):
那么如果一个人继续下去会发生什么?这是一个随机的例子。它比零温度情况更好,但最多也只是有点奇怪。
这是使用最简单的GPT-2模型(来自2019年)完成的。使用更新和更大的GPT-3模型,结果会更好。以下是使用相同“提示”生成的零温度文本中排名第一的词语,但使用了最大的GPT-3模型:
这里是一个在“温度0.8”下的随机示例:
概率从哪里来?
好的,ChatGPT总是根据概率选择下一个单词。但这些概率从哪里来?让我们先考虑一个更简单的问题。我们考虑逐个字母(而不是单词)生成英文文本。我们如何计算每个字母的概率呢?
我们可以做的非常简单的事情是只需取一段英文文本样本,然后计算其中不同字母出现的频率。例如,这个例子统计了维基百科上“猫”条目中字母的数量:
这也同样适用于“狗”:
结果是相似的,但并不完全一样(“o”在“dogs”文章中无疑更常见,因为毕竟它出现在单词“dog”本身中)。然而,如果我们采集足够大量的英文文本样本,最终可以期望得到至少相当一致的结果:
这是一个样例,如果我们只使用这些概率生成一系列字母,就会得到以下结果:
我们可以通过将空格视为带有一定概率的字母来将其分解为“单词”:
我们可以通过强制“单词长度”的分布与英语中的相符来稍微更好地生成“单词”:
我们这里没有得到任何“实际单词”,但结果看起来稍微好一些了。不过,要进一步发展,我们需要做的不仅仅是随机地挑选每个字母。例如,我们知道如果有一个“q”,下一个字母基本上必须是“u”。
以下是各个字母概率的图表:
这里是一个显示典型英文文本中字母对(“2-gram”)概率的图表。可能的第一个字母显示在页面上方,第二个字母则显示在页面下方:
我们在这里看到,例如,“q”列除了“u”行以外都是空白(零概率)。好的,现在不再一次生成我们的“单词”,而是使用这些“2-gram”概率一次生成两个字母。以下是结果样本——其中包括一些“实际单词”:”。
有足够多的英文文本,我们不仅可以得到单个字母或字母对(2-gram)的概率估计,还可以得到更长一段文字的概率估计。如果我们使用逐渐变长的n-gram概率生成“随机单词”,我们会发现它们逐渐变得“更加真实”。
但是现在让我们假设——就像ChatGPT一样——我们正在处理整个单词,而不是字母。英语中有大约40,000个常用单词。通过查看大量的英文文本(比如几百万本书,总共数百亿个单词),我们可以估计每个单词的使用频率。并且利用这些信息,我们可以开始生成“句子”,其中每个单词都是独立随机选择的,并具有它在语料库中出现的相同概率。以下是一个示例:
毫不奇怪,这是无意义的。那么我们该如何做得更好呢?就像处理字母一样,我们可以开始考虑不仅单个词的概率,还要考虑成对或更长的n元组词语的概率。针对成对情况进行此操作时,以下是5个例子,在所有情况下都从“猫”这个词开始:
它看起来变得稍微更加“合理”。我们可以想象,如果我们能够使用足够长的n-gram,基本上就会“获得一个ChatGPT”——也就是说,我们将获得一些生成具有“正确整体文章概率”的长度为论文的单词序列。但问题在于:甚至没有足够的英语文本被写出来以便推断这些概率。
在网络爬虫中可能有数千亿个单词;在已数字化的书籍中可能还有另外数百亿个单词。但是,即使使用40,000个常用单词,所有可能的二元组合也已经达到了16亿之多——而所有可能的三元组合则高达60万亿。因此,我们无法从现有文本中估计出这些概率。当我们考虑包含20个单词的“文章片段”时,其可能性数量已经超过了宇宙中粒子的数量,因此从某种意义上说,它们永远无法全部写下来。
那我们能做什么呢?大的想法是建立一个模型,让我们能够估计序列出现的概率——即使我们在查看的文本语料库中从未明确地看到过这些序列。而 ChatGPT 的核心正是所谓的“大型语言模型”(LLM),它被构建成能够很好地估计这些概率。
什么是模型?
假设你想知道(就像加利略在16世纪末那样)从比萨斜塔的每层楼扔下炮弹需要多长时间才能撞到地面。好吧,你可以在每种情况下进行测量并制作结果表。或者你可以做理论科学的本质:制作一个模型,给出一些计算答案的过程,而不仅仅是测量和记忆每个案例。
让我们想象我们有(有点理想化的)数据,了解炮弹从各个楼层掉落需要多长时间:
我们如何计算从我们没有明确数据的楼层掉落需要多长时间?在这种情况下,我们可以使用已知的物理定律来计算。但是假设我们只有数据,而不知道支配它的基本规律,则可能会进行数学猜测,例如也许应该将直线作为模型:
我们可以选择不同的直线。但这条直线平均上最接近我们所给出的数据。从这条直线,我们可以估计任何楼层的落下时间。
我们怎么知道要在这里尝试使用一条直线?在某种程度上,我们并不知道。这只是数学上简单的事情,而且我们习惯于许多测量到的数据都能够很好地适应数学上简单的东西。 我们可以尝试更复杂的数学方法 - 比如 a + b x + c x2 - 在这种情况下,效果会更好:
事情可能会变得非常糟糕。比如,这是我们在 a + b/x + c sin(x) 上能做到的最好结果:
值得理解的是,从来没有“无模型模型”。您使用的任何模型都具有某些特定的基础结构-然后是一组“可以转动的旋钮”(即可以设置的参数),以适应您的数据。在ChatGPT的情况下,使用了许多这样的“旋钮”-实际上有1750亿个。
但值得注意的是,ChatGPT 的基础结构 - 仅仅拥有如此之多数量级参数 - 足以制作一个计算下一个单词概率足够好以给我们合理长度文本段落。
Human-Like任务模型
我们上面提到的例子涉及制作数值数据模型,这些数据基本上来自简单物理学——几个世纪以来我们已经知道“简单的数学适用”。但是对于ChatGPT,我们必须制作一个人类大脑产生的语言文本模型。而对于这样的东西,我们(至少目前)没有像“简单数学”那样的任何东西。那么它可能是什么样子呢?
在谈论语言之前,让我们谈论另一项类似人类任务:识别图像。作为其中一个经典机器学习示例,让我们考虑数字图像(是的)。
我们可以做的一件事是为每个数字收集一堆样本图片:
然后,为了确定我们输入的图像是否对应于特定的数字,我们可以使用样本进行逐像素比较。但是作为人类,我们似乎做得更好——因为即使数字是手写的,并且具有各种修改和扭曲,我们仍然能够识别它们:
当我们为上面的数字数据建立模型时,我们能够取得给定的数值x,并计算特定a和b的a + bx。因此,如果我们将每个像素的灰度值视为某些变量xi,则是否存在一些所有这些变量的函数可以告诉我们图像所代表的数字?事实证明是可能构造出这样一个函数。但并不奇怪,它并不特别简单。一个典型例子可能涉及大约50万次数学运算。
但最终结果是,如果我们将图像中每个像素点的集合馈送到该函数中,则会输出指定该数字对应于哪个手写数字图像的编号。稍后,我们将讨论如何构建这样一个函数以及神经网络的概念。但现在让我们把这个功能当作黑盒子来处理,在那里我们输入手写数字(作为像素值数组)并获得相应数字:
但是这里真正发生了什么?假设我们逐渐模糊一个数字。一段时间内,我们的函数仍然“识别”它,例如作为“2”。但很快它就会“失去”,并开始给出“错误”的结果:
但是为什么我们说这是“错误”的结果呢?在这种情况下,我们知道通过模糊“2”来得到了所有的图像。但如果我们的目标是产生一个人类识别图像的模型,真正需要问的问题是:如果向人类展示其中一张模糊的图片,并不知道它来自哪里,那么人类会怎样做?
如果我们从函数中获得的结果通常与人类所说的相符,则说明我们有一个“好模型”。而非平凡科学事实是,在像这样的图像识别任务中,我们现在基本上已经知道如何构建能够完成此任务的函数。
那么,我们能否“数学证明”它们有效呢?嗯,并不能。因为要做到这一点,就必须对人类正在进行什么样的数学理论进行解释。拿出“2”号图像并更改几个像素。也许只需少量变化即可将其视为“2”。但应该持续多久呢?这涉及到人类视觉感知问题。而且,确实可以肯定地说对于蜜蜂或章鱼等动物答案可能会有所不同——对于外星生命体则完全不同。
神经网络
神经网络 好的,那么我们通常用于图像识别等任务的模型是如何工作的呢?目前最流行和成功的方法使用神经网络。神经网络在1940年代被发明出来,其形式与今天使用的形式非常接近,可以被认为是大脑运作方式简化后的理想化模型。
人类大脑中有约1000亿个神经元(神经细胞),每个神经元能够产生电脉冲高达一千次/秒。这些神经元以复杂网状连接在一起,每个神经元都有树枝状分支,使其能够向数千个其他神经元传递电信号。粗略地说,在任何给定时刻一个特定的神经元是否会产生电脉冲取决于它从其他不同连接收到了哪些“权重”不同的信号。
当我们“看到一张图片”时,光子从图像落在眼睛后部(“光感受器”)细胞上时会在神经细胞中产生电信号。这些神经细胞与其他神经细胞相连,并最终通过整个序列层级结构传递信号。正是通过这种过程我们才能够“识别”图像,最终“形成思想”,认为我们正在“看到一个2”(也许最后会做出类似于大声说出“二”的动作)。
前一节中的“黑盒子函数”是这种神经网络的数学化版本。它恰好有11层(尽管只有4个“核心层”)。
这个神经网络并没有什么特别的“理论推导”,它只是在1998年作为一种工程构建出来,并被发现可以工作。当然,这与我们描述大脑是通过生物进化过程产生的方式并没有太大不同。
好了,但是这样的神经网络如何“识别事物”呢?关键在于吸引子的概念。想象一下,我们有手写的数字1和2:
我们希望所有的1都“被吸引到一个地方”,所有的2都“被吸引到另一个地方”。或者换一种说法,如果一幅图像在某种程度上比成为2更接近于成为1,我们希望它最终出现在“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维空间的东西。但由于这是一个处理图像的网络,它许多层次的神经元都被组织成了数组,就像它正在查看像素数组一样。
如果我们拿一张典型的猫图片作为例子……
然后,我们可以通过一系列派生图像来表示第一层神经元的状态——其中许多我们可以轻松解释为“没有背景的猫”或“猫的轮廓”。
但总的来说,我们可以说神经网络正在“挑选某些特征”(也许尖耳朵是其中之一),并利用这些特征来确定图像的内容。但这些特征是否具有名称,比如“尖耳朵”?大多数情况下不是。
我们的大脑是否使用类似的特征?大多数时候我们不知道。但值得注意的是,像我们在这里展示的神经网络的前几层似乎会挑选出与人类视觉处理第一层所选择相似(例如物体边缘) 的图像方面。
但假设我们想要一个关于神经网络中猫识别理论。 我们可以说:“看,这个特定网络就能做到”,并立即给我们一些关于“问题难度”的概念(例如需要多少个神经元或层数)。 但至少目前为止,我们没有办法“提供叙述性描述”该网络正在执行什么操作。也许这是因为它真正地计算上不可约简,并且除了明确跟踪每个步骤外,没有通用方法找到它所做的事情。 或者可能只是因为我们还没有“弄清楚科学”,并确定了允许我们总结发生了什么事情 的 “自然规律”。
当我们谈论使用ChatGPT生成语言时,我们将遇到相同类型的问题。同样不清楚是否有方法“总结它正在做什么”。但是语言的丰富性和细节(以及我们对其的经验)可能使我们比图像更进一步。
机器学习和神经网络的训练
到目前为止,我们一直在谈论“已经知道”如何执行特定任务的神经网络。但是,使神经网络如此有用(也应该适用于大脑)的原因不仅在于它们原则上可以执行各种任务,而且还可以通过逐步“从示例中进行训练”来完成这些任务。
当我们制作一个区分猫和狗的神经网络时,我们实际上不必编写一个程序(比如明确查找触须);相反,我们只需展示很多关于什么是猫和什么是狗的例子,并让网络从中“机器学习”,以了解如何区分它们。
而且重要的是,受过培训的网络会从所显示出来的具体示例中“概括”。正如我们之前看到过得那样,并不仅仅是因为该网络识别了其所显示出来图像中特定像素模式上面部分属于哪个类别;相反地,在某种程度上说,就算基础数据发生变化或者噪声干扰等情况下, 神经元能够根据一些被认为具有普遍性质并将其与其他物品区分开来。
那么神经网络的训练实际上是如何工作的呢?基本上,我们一直在尝试找到使神经网络成功复制所给出示例的权重。然后,我们依靠神经网络以“合理”的方式进行“插值”(或“概括”)这些示例之间。
让我们看一个比上面最近点问题更简单的问题。让我们只是尝试让神经网络学习函数:
对于这个任务,我们需要一个只有一个输入和一个输出的网络,例如:
但是我们应该使用什么权重等呢?对于每组可能的权重,神经网络都会计算出某个函数。例如,这里是它在几组随机选择的权重下所做的事情:
是的,我们可以清楚地看到,在这些情况下,它甚至都无法接近我们想要的功能。那么如何找到能够复制该函数的权重?
基本思路是提供大量“输入→输出”示例以供“学习”,然后尝试找到能够复制这些示例的权重。以下是使用逐渐增加的示例进行操作所得出的结果:
在这个“训练”过程的每个阶段,网络中的权重都会逐步调整——我们看到最终得到了一个成功复现所需函数的网络。那么我们如何调整权重呢?基本思想是在每个阶段看一下离目标函数还有多远,然后以更接近目标为方式更新权重。
为了找出“离目标还有多远”,我们计算通常称为“损失函数”(或者有时称之为“代价函数”)的东西。在这里,我们使用简单(L2)损失函数,它只是差值平方和与真实值之间差异的总和。随着训练过程不断进行,我们发现损失函数逐渐减小(遵循不同任务不同的特定“学习曲线”),直到达到一个点,在该点上网络至少可以很好地近似复制所需功能:
好的,最后一个需要解释的关键部分是如何调整权重以减少损失函数。正如我们所说,损失函数给出了我们得到的值与真实值之间的“距离”。但是,“我们得到的值”在每个阶段都由当前版本的神经网络和其中的权重确定。现在想象一下,这些权重是变量——比如wi。我们想找出如何调整这些变量的值来最小化依赖于它们的损失。 例如,在对实际使用中典型神经网络进行极度简化时,假设只有两个权重w1和w2。那么我们可能会有一个损失函数作为w1和w2 的函数看起来像这样:
数值分析提供了各种技术来找到这种情况下的最小值。但是,一个典型的方法就是从我们之前拥有的任何w1、w2开始逐步跟随最陡峭的路径:
就像水流下山一样,唯一保证的是这个过程最终会到达表面的某个局部极小值(“山湖”);它很可能不会达到最终的全局极小值。
找到“权重景观”上最陡峭下降路径似乎并不明显可行。但微积分来拯救了我们。正如我们上面提到的,人们总是可以将神经网络视为计算一个数学函数——该函数取决于其输入和权重。但现在考虑对这些权重进行微分。结果发现,微积分中的链式法则实际上让我们能够“展开”神经网络中连续层所做操作。而结果是,在某种本地逼近意义下,我们可以“反转”神经网络操作,并逐步找到使输出损失最小化的权重。
上图显示了在仅有2个权重时可能需要执行的最小化类型情况(非常简单)。但事实证明即使使用更多权重(ChatGPT使用1750亿),仍然可以进行最小化处理,至少在某种逼近级别上是可能的。事实上,“深度学习”的巨大突破发生在2011年左右,与此相关联:人们发现,在涉及许多权重时(至少近似)最小化可能更容易,而在涉及相当少的权重时则更难。
换句话说——有些违反直觉——使用神经网络解决更复杂的问题可能会更容易。这个粗略的原因似乎是,当一个人拥有许多“权重变量”时,就会有一个高维空间,“很多不同方向”可以引导一个人到达极小值处——而对于较少的变量,则更容易陷入局部极小值(“山湖”),从中没有“出路”。
值得指出,在典型情况下,存在许多不同的权重集合,它们都将给出几乎具有相同性能的神经网络。通常,在实际神经网络培训中进行了大量随机选择——导致产生“不同但等效”的解决方案,如以下所示:
但是每个“不同的解决方案”都会有至少稍微不同的行为。如果我们要求在我们给出训练示例之外进行“外推”,我们可能会得到截然不同的结果:
但这些哪一个是“正确”的呢?实际上没有办法说。它们都“与观察到的数据一致”。但它们都对应着不同的“内在”方式来思考如何“跳出框架”。有些可能对我们人类来说似乎比其他更为合理。
神经网络训练的实践和技巧
特别是在过去十年中,神经网络训练的艺术已经有了很多进展。而且,它基本上就是一门艺术。有时候——尤其是事后——人们可以看到至少有一个“科学解释”来解释正在进行的某些事情。但大多数情况下都是通过试错发现的,添加想法和技巧逐渐建立了关于如何处理神经网络的重要传说。
其中有几个关键部分。首先,对于特定任务应该使用什么样的神经网络结构这个问题非常重要。然后就是如何获取用于训练神经网络的数据这个关键问题。越来越多地不再需要从头开始训练一个新网:相反,新网可以直接包含另一个已被训练好的网,或者至少可以使用那个网为自己生成更多的训练示例。
人们可能认为每种特定类型任务都需要不同架构设计的神经网络才能完成。但所发现的是,在表面上看起来完全不同任务中甚至相同架构似乎也能够工作得很好。在某种程度上这使人想起通用计算(以及我的计算等价原理)的想法,但正如我稍后将讨论的那样,我认为这更多地反映了我们通常试图让神经网络完成“类似人类”的任务——而神经网络可以捕捉相当普遍的“类人过程”。
在神经网络的早期,人们倾向于认为应该“尽可能让神经网络做得少”。例如,在将语音转换为文本时,人们认为应该先分析语音,将其分解成音素等。但是发现,在至少“类似于人类任务”的情况下,最好只是尝试在“端到端问题”上训练神经网络,并让它自己“发现”必要的中间特征、编码等。
还有一个想法是应该向神经网络引入复杂的单个组件,以使其实际上“明确地实现特定算法思想”。但同样地,这大多数情况下都不值得;相反,最好只处理非常简单的组件,并让它们(虽然通常以我们无法理解的方式)自行“组织”,从而达到(可能)与那些算法思想等效的结果。
这并不意味着没有适用于神经网络的“结构性思想”。例如,在图像处理的早期阶段使用具有局部连接的2D神经元数组似乎非常有用。并且具有集中于“回顾序列”的连接模式似乎很有用——正如我们稍后将看到——在处理诸如人类语言之类的事物时, 例如在ChatGPT中。
但神经网络的一个重要特征是,就像计算机一样,它们最终只处理数据。而当前的神经网络——使用当前的神经网络训练方法——具体处理数字数组。但在处理过程中,这些数组可以完全重新排列和重塑。例如,在上面用于识别数字的网络从2D“类似图像”的数组开始,迅速“加厚”到多个通道,然后“集中”成一个1D数组,最终包含表示不同可能输出数字的元素:
但是,好吧,如何确定特定任务所需的神经网络大小呢?这有点像一门艺术。在某种程度上,关键是要知道“任务有多难”。但对于类似人类的任务来说,通常很难估计。是的,可能有一种系统化的方法可以通过计算机非常“机械地”完成任务。但很难知道是否存在可以让人以至少“与人类水平”轻松完成任务的技巧或捷径。可能需要枚举一个巨大的游戏树才能“机械地”玩某个游戏;但可能会有更简单(“启发式”的)方法来实现“人类级别”的游戏。
当处理微小神经网络和简单任务时,有时候可以明确看到自己无法从此处开始解决问题。例如,在前面章节中使用几个小型神经网络进行该任务时最好做到了什么。
我们看到的是,如果神经网络太小,它就无法复制我们想要的功能。但是在某个大小以上,只要训练足够长时间并提供足够多的示例,它就没有问题了。顺便说一下,这些图片说明了神经网络传说中的一个部分:如果中间有一个“挤压”,强制所有东西都通过较少数量的中间神经元,则通常可以使用更小的网络。(值得一提的是,“无中间层”或所谓“感知器”网络只能学习基本上线性函数——但只要有一个中间层即可原则上任意逼近任何函数,并且至少具备足够多神经元时总是可能实现这一点;不过为了使其可行地进行训练,通常需要某种形式的正则化或归一化。)
好吧,假设我们已确定了某种神经网络架构。现在存在获取用于训练该网络数据方面的问题。对于神经网路和机器学习等领域很多实际挑战都集中在获取或准备必要训练数据方面。(在很多情况下(“监督学习”),人们希望获得输入和期望输出之间明确示例)。例如,在图像分类任务中,人们可能希望对图像进行标记。也许需要明确地经过大量努力进行标记。但是很多时候,事实证明可以利用已有的东西或将其用作某种代理。例如,在网络上提供了图片的alt标签;在不同领域中,人们可能会使用为视频创建的闭式字幕;或者在语言翻译培训方面,可以使用存在于不同语言中的网页或其他文档的平行版本。
需要多少数据来展示神经网络以训练它完成特定任务?从第一原理出发很难估计。当然,通过使用“迁移学习”将已在另一个网络中学习的重要特征列表“转移”,可以大大减少要求。但通常情况下,神经网络需要“看到很多例子”才能进行良好的训练。对于某些任务而言,至少有一个关键点是例子可能会非常重复。实际上,只需向神经网络显示所有现有的例子即可成为标准策略,在每个这样的“训练轮次”(或“时代”)中,神经网络都将处于至少稍微不同的状态,并且以某种方式提醒它记住特定示例对于使其记住该示例是有用的。(是的,“也许这类似于人类记忆中重复性所具有的用处。”)
但仅仅反复显示相同示例并不足够。还需要向神经网络展示该示例变化版本。而且作为神经网路传说中一项功能,“数据增强”的变化并不必须精密才能派上用场。只需使用基本图像处理轻微修改图像即可使其在神经网路培训方面与新的图像一样好。同样,当用于训练自动驾驶汽车的实际视频等数据已经耗尽时,可以继续在模型类似于电子游戏环境中运行的仿真中获取数据,而不需要所有实际现实场景的详细信息。
那么ChatGPT之类的东西呢?嗯,它有一个很好的特点,即它可以进行“无监督学习”,这使得从中获得示例以进行培训变得更加容易。回想一下ChatGPT的基本任务是找出如何延续给定文本片段。因此,要获得“培训示例”,只需获取一段文本,并屏蔽其末尾部分,然后将其用作“输入来进行培训”——输出为完整未屏蔽文本片段。我们稍后会进一步讨论这个问题,但主要观点是与例如学习图像内容相比,“没有明确标记”的必要性; ChatGPT 实际上可以直接从任何给定文本示例中学习。
好的,那么神经网络中的实际学习过程怎样呢?最终目标是确定哪些权重能够最好地捕捉到所给出的训练示例。有各种详细选择和“超参数设置”(因为权重可以被视为“参数”)可用于调整如何完成此操作。有不同选择的损失函数(平方和、绝对值之和等)。有不同的损失最小化方法(每步在权重空间移动多远等)。然后还有像展示多少个“批次”的示例来获得每个连续估计要尽量减小的损失这样一类问题。是的,我们可以应用机器学习(例如 Wolfram 语言中所做的)来自动化机器学习,并自动设置诸如超参数之类的东西。
但归根结底,整个训练过程可以通过观察损失逐渐减少来描述(就像这个 Wolfram 语言进度监视器显示了一个小型训练)。
通常情况下,我们会看到损失函数在一段时间内逐渐减小,但最终会趋于某个固定值。如果这个值足够小,则可以认为训练成功;否则就意味着需要尝试改变网络结构。
有人能说出“学习曲线”要平稳需要多长时间吗?就像许多其他事情一样,似乎存在大致的幂律缩放关系,这取决于使用的神经网络大小和数据量。但总体结论是训练神经网络很难,并且需要大量计算工作。实际上,其中绝大部分工作都花费在对数字数组进行操作上,而这正是GPU擅长的领域——这也是为什么神经网络训练通常受到GPU可用性限制的原因。
在未来,训练神经网络或者说完成神经网络所做的事情是否会有根本性的改进?我认为几乎肯定会。神经网络的基本思想是利用大量简单(基本上相同)组件创建一个灵活的“计算结构”,并使这个“结构”能够通过逐步修改从示例中学习。在当前的神经网络中,人们基本上使用微积分理论——应用于实数——来进行逐步修改。但越来越清楚地是,高精度数字并不重要;即使使用当前方法,8位或更少可能已经足够了。
使用计算系统,如元胞自动机,在许多个体位于并行操作的情况下,如何进行这种增量修改一直不太清楚,但没有理由认为这是不可能的。实际上,就像“2012年深度学习突破”一样,在更复杂的情况下进行这种增量修改可能会更容易。
神经网络——也许有点像大脑——被设置为具有基本固定的神经元网络,并且所修改的是它们之间连接的强度(“权重”)。 (也许在至少年轻人脑中可以显着增长全新连接数。)但是虽然这对生物来说可能是一个方便的设置,但它根本不清楚是否接近我们需要实现功能性所需最佳方法。而涉及等效于渐进式网络重写(也许类似于我们物理项目)的某些东西最终可能会更好。
但是,即使在现有神经网络的框架内,目前仍存在一个关键限制:神经网络训练现在基本上是顺序进行的,每个示例批次的影响被传播回来更新权重。实际上,在当前计算机硬件(即使考虑到GPU)中,大部分神经网络在训练期间都处于“空闲”状态,只有一部分正在更新。从某种意义上说,这是因为我们当前的计算机往往具有与其CPU(或GPU)分离的存储器。但在大脑中可能不同——每个“记忆元素”(即神经元)也可以成为潜在的活动计算元素。如果我们能够以这种方式设置未来的计算机硬件,则可能会更有效地进行培训。
一个足够大的网络一定可以做任何事情
像ChatGPT这样的东西的能力似乎非常令人印象深刻,以至于人们可能会想象,如果可以“继续前进”并训练更大的神经网络,那么它们最终将能够“做任何事情”。如果一个人关心那些对立即人类思考容易获得的事情,那么这很有可能是真的。但过去几百年科学所教导我们的教训是:有些问题可以通过形式化过程解决,但不一定容易被立即理解。
非平凡数学就是一个很好的例子。但总体来说实际上是计算。最终问题在于计算不可约性现象。有些计算看起来需要多个步骤才能完成,但实际上可以“简化”为某种相当直接的东西。然而发现了计算不可约性意味着这种方法并不总是奏效。相反地存在一些过程——可能像下面这个——无论如何都需要基本追踪每个计算步骤才能弄清楚会发生什么:
我们通常用大脑做的事情,可能是有意选择避免计算不可简化的。在脑中进行数学运算需要特别努力。而且,在实践中,“思考”任何非平凡程序操作步骤只靠大脑基本上是不可能的。
但当然我们有电脑可以解决这个问题。通过电脑,我们可以轻松地完成长时间、计算不可简化的任务。关键点在于一般来说没有捷径。
是的,我们可以记忆许多某些特定计算系统中发生了什么事情的具体例子。也许我们甚至能够看到一些(“计算可简化”的)模式,从而使我们能够进行少量泛化推理。但重要的是,计算不可简化意味着我们永远无法保证出现意外情况——只有通过明确地执行计算才能确定任何特定情况下实际发生了什么。
最终,在学习和计算不可简约之间存在根本性张力。学习实质上涉及利用规律压缩数据。但是,计算不可简约意味着最终存在规律性所限制的极限。
作为实际问题,人们可以想象将小型计算设备(如元胞自动机或图灵机)构建到可训练的系统中,例如神经网络。事实上,这些设备可以作为神经网络的良好“工具”,就像 Wolfram|Alpha 可以成为 ChatGPT 的良好工具一样。但是计算不可约性意味着我们不能指望“进入”这些设备并使它们学习。
换句话说,在能力和可训练性之间存在最终权衡:您希望系统充分利用其计算能力越多,则它会显示出更多的计算不可约性,并且它将变得越来越难以训练。而基本上易于训练的系统则无法进行复杂的计算。
对于当前版本的 ChatGPT 来说,情况实际上更加极端,因为用于生成每个输出标记的神经网络是纯“前馈”网络,没有循环结构,因此无法执行任何具有非平凡“控制流”的计算。)
当然,人们可能会想知道是否真正重要能够进行不可约化运算。事实上,在人类历史大部分时间里都不是特别重要。但我们现代技术世界已经建立在至少使用数学计算的工程基础之上,而且越来越多地使用更一般的计算。如果我们观察自然界,它充满了不可约化运算——我们正在逐渐理解如何模拟和利用这些运算以实现技术目的。
是的,神经网络肯定可以注意到自然界中我们也可以轻松注意到的那些规律。但是,如果我们想解决数学或计算科学范畴内的问题,除非它有效地“使用”一个“普通”的计算系统作为工具,否则神经网络将无法完成这项任务。
但是所有这些可能会让人感到困惑。过去有很多任务——包括写文章——我们认为电脑在某种程度上“根本太难了”。现在我们看到像ChatGPT这样的东西完成了这些任务,就突然认为电脑一定变得更加强大了——特别是超越了它们已经基本能够做到的事情(比如逐步计算细胞自动机等计算系统的行为)。
但这不是正确的结论。计算不可约化过程仍然是计算不可约化过程,并且对于电脑来说仍然基本上很难——即使电脑可以轻松地计算它们各个步骤。相反,我们应该得出结论:像写文章之类的任务虽然人类能够做到,但我们并没有认为电脑能够做到,在某种意义上实际上比我们想象中要容易处理。
换句话说,神经网络能够成功地写一篇文章的原因是因为写作事实上比我们想象中更浅显易懂。从某种意义上讲,这使我们更接近“拥有一个理论”,即如何像人类那样处理语言或撰写文章。
如果你有足够大的神经网络,那么你可能能够做到人类可以轻松完成的任何任务。但你不会捕捉到自然界普遍具备的特性——或者说我们从自然界中创造出来的工具所能做到的事情。正是使用这些工具——无论是实用还是概念性的——在最近几个世纪里使我们超越了“纯粹依靠人类思维”的边界,并为人类目标捕获了更多物理和计算宇宙中存在着什么。
embedding的概念
神经网络——至少目前的设置是基于数字的。因此,如果我们要用它们来处理文本之类的东西,我们需要一种用数字表示文本的方法。当然,我们可以像ChatGPT一样(实质上)为字典中的每个单词分配一个数字。但有一个重要的想法——例如ChatGPT所关注的那个——超越了这一点。这就是“embedding(嵌入)”的概念。人们可以将嵌入视为通过一系列数字尝试以某种方式表达事物“本质”的方法,并且具有“附近事物”由相邻数字表示的属性。
因此,例如,我们可以将单词embedding视为在某种意义上接近于含义空间中排列单词,在该空间中,“意思相近”的单词会出现在embedding附近。实际使用的嵌入(比如ChatGPT)往往涉及大量数字列表。但是如果我们投影到2D,则可以展示单词如何被embedding布局:
是的,我们所看到的确实非常好地捕捉了典型的日常印象。但是我们如何构建这样一个embedding呢?大致上的想法是查看大量文本(这里来自网络的50亿个单词),然后观察不同单词出现在其中“环境”有多相似。因此,例如,“鳄鱼”和“鳄鱼”通常几乎可以互换使用在其他类似句子中,这意味着它们将被放置在嵌入附近。但是,“萝卜”和“老鹰”不太可能出现在其他类似句子中,因此它们将被放置在embedding远处。
但是如何使用神经网络实际实现这样的事情呢?让我们先谈论一下图像而不是单词的嵌入。我们希望以某种方式通过数字列表来表征图像,使得“我们认为相似”的图像被分配相似的数字列表。
我们如何判断是否应该“认为图像相似”?如果我们的图像是手写数字,则如果它们属于同一个数字,则可以“认为两个图像相似”。早些时候,我们讨论过一个用于识别手写数字的神经网络。 我们可以将这个神经网络看作是设置了一个最终输出,将图像放入10个不同的箱中,每个数字一个。
但是如果我们在“它是‘4’”决定之前“拦截”神经网络内部正在发生的事情呢?我们可能会预期,在神经网络内部有一些数字来表征图像为“大多数类似于4但有点2”的形式。而这个想法就是挑选出这样的数字用作嵌入中的元素。
这里是概念。与其直接尝试表征“哪个图像靠近哪个图像”,我们反而考虑一个明确定义的任务(在这种情况下是数字识别),为此我们可以获得明确的训练数据,然后利用事实,在完成这项任务时神经网络隐含地必须做出类似于“接近性决策”的决策。因此,我们不需要明确谈论“图像的接近程度”,而只需谈论关于一张图片代表什么数字的具体问题,然后将“神经网络”留给它来隐含地确定这意味着关于“图像接近程度”的内容。
那么,对于数字识别网络,这个工作的详细过程是怎样的呢?我们可以将该网络看作由11个连续层组成,我们可以用如下图标示来概括(其中激活函数显示为单独的层):
在开始时,我们将实际图像输入到第一层中,这些图像由表示为2D像素值数组的数据组成。在最后一层,我们得到一个包含10个值的数组,可以认为是网络对每个数字0到9所对应的图像“确定性”的度量。
输入图像4,最后一层神经元的值为:
换句话说,神经网络此时“非常确定”这张图片是一个4——为了得到输出的“4”,我们只需要找出具有最大值的神经元位置。
但如果我们往前看一步呢?网络中最后一个操作是所谓的softmax,它试图“强制确信”。但在应用之前,神经元的值是:
代表“4”的神经元仍然具有最高的数值。但是其他神经元的值中也包含了信息。我们可以期望这个数字列表在某种程度上可以用来描述图像的“本质”,从而提供一些可用作嵌入的东西。因此,例如,在这里每个4都有略微不同的“签名”(或“特征嵌入”)-与8完全不同:
在这里,我们基本上使用10个数字来描述我们的图像。但是通常最好使用更多的数字。例如,在我们的数字识别网络中,通过访问前一层,我们可以获得一个包含500个数字的数组。这可能是一个合理的用作“图像嵌入”的数组。
如果我们想要对手写数字进行“显式可视化”,则需要通过将我们获得的500维向量投影到三维空间中来“降低维度”。
我们刚刚讨论了如何创建图像的表征(从而嵌入),方法是通过确定它们是否(根据我们的训练集)对应于相同的手写数字来有效地识别图像的相似性。如果我们有一个标识每个图像属于哪种5000种常见物体类型(猫、狗、椅子等)的训练集,那么我们可以更普遍地为图像做同样的事情。这样,我们就可以制作一个由我们对常见物体进行识别“锚定”的图像嵌入,但是根据神经网络行为“泛化”。关键在于,在这种行为与人类感知和解释图像方式一致时,这将成为一个“看起来正确”的嵌入,并且在实践中用于执行“类似人类判断”的任务。
基于大量文本语料库(比如网络文本内容),哪些不同的单词可能填补空白?或者换句话说,“___ black ___”中不同“侧翼单词”的概率是多少?
我们如何为神经网络设置这个问题?最终,我们必须用数字来表达所有东西。一种方法就是为英语中约50,000个常见单词中的每一个分配一个唯一编号。例如,“the”可能是914,“cat”(前面有一个空格)可能是3542。(这些都是GPT-2使用的实际数字)。因此,在“the ___ cat”问题上,我们的输入可能为{914、3542}。输出应该像什么呢?好吧,它应该是一个包含大约50,000个数字列表,有效地给出了每个可能填充字眼所对应概率。再次寻找嵌入时,我们希望在神经网络“达成结论之前截取其内部”,然后获取发生在那里并且可以认为代表每个单词特征的数字列表。
好的,那这些特征是什么样子的呢?在过去的10年中,已经开发了一系列不同的系统(如word2vec、GloVe、BERT、GPT等),每个系统都基于不同的神经网络方法。但最终它们都将单词转化为由数百到数千个数字组成的列表来进行表征。
在它们的原始形式下,这些“嵌入向量”是相当无信息的。例如,以下是GPT-2为三个特定单词生成的原始嵌入向量:
如果我们像测量这些向量之间的距离一样做事情,那么我们就可以找到词语之间的“接近程度”。稍后我们将更详细地讨论这种嵌入可能具有的“认知”意义。但现在主要观点是,我们有一种有效的方法将单词转化为“神经网络友好”的数字集合。
实际上,我们不仅可以通过数字集合来描述单词,还可以对单词序列或整个文本块进行此操作。而 ChatGPT 内部正是这样处理事情的。它获取到目前为止所拥有的文本,并生成一个嵌入向量来表示它。然后其目标是找到可能出现下一个单词的不同概率。并且它将其答案表示为一系列数字列表,这些数字基本上给出了每个可能单词中大约 50,000 种可能性中各自发生概率。
(严格来说,ChatGPT 不处理单词,而是处理“标记”——方便的语言单位,可能是整个单词,也可能只是像“pre”、“ing”或“ized”这样的片段。使用标记使 ChatGPT 更容易处理罕见、复合和非英语单词,并且有时候为了好坏不一地发明新单词。)
深入ChatGPT
好的,我们终于准备讨论一下ChatGPT内部是什么了。最终,它其实就是一个巨大的神经网络——目前使用的是1750亿个权重版本的所谓GPT-3网络。在很多方面上,这个神经网络与我们之前讨论过的其他神经网络非常相似。但它特别适用于处理语言,并且它最显著的特点是一种名为“transformer”的神经网络架构。
在我们上面讨论过的第一个神经网络中,每个层次上的每个神经元基本上都与前一层次上所有其他神经元(至少有某些权重)连接起来。但如果要处理具有特定已知结构数据,则这种完全连接型网络可能会导致资源浪费。因此,在处理图像时通常会使用所谓卷积神经网(”convnets”),其中将神经元有效地布置在类似于图像中像素排列方式并仅与附近格子中其他单元相连。
Transformer 的想法则是对组成文本片段序列标记进行类似操作, 但不同之处在于 Transformer 引入了“注意力”概念和更加关注某些序列片段而非全部. 或许总有一天只需启动通用神经网络并通过训练进行所有自定义就足够了,但至少目前来看,在实践中“模块化”事物似乎是至关重要的——正如 Transformer 所做的那样,也可能与我们的大脑所做的类似。
好的,那么ChatGPT(或者更确切地说,它所基于的GPT-3网络)到底是做什么的呢?请记住,它的总体目标是根据其训练过程中看到的内容(即查看了来自Web等数十亿页文本),以“合理”的方式继续文本。因此,在任何给定时刻,它都有一定数量的文本,并且其目标是为下一个要添加的标记提供适当选择。
它分为三个基本阶段。首先,它获取与迄今为止已有文本相对应的标记序列,并找到表示这些标记序列的嵌入式数组(即一组数字)。然后,在神经网络中进行操作——通过在网络中连续层之间传播值——以生成新嵌入式数组(即新一组数字)。接着,它取该数组最后部分并从中生成大约50,000个值得出不同可能下一个标记概率的数组。(是啊,“恰好”使用了与英语常用单词数量相同数量级左右个令牌/片段作为输入数据)
关键点在于管道中每个部分都由神经网络实现,并且该神经网络通过端对端训练确定权重。换句话说,在效果上除了整体架构外,“显式工程”几乎没有什么东西;一切都是从训练数据中“学习”的。
然而,管道设置方面有很多细节——反映了各种经验和神经网络知识。尽管这肯定会变得非常复杂,但我认为谈论其中的一些细节是有用的,至少可以对构建ChatGPT所需付出的努力有一个大致了解。
首先是嵌入模块。以下是GPT-2的Wolfram语言示意图:
输入是一个由n个标记组成的向量(如前一节所述,表示为1到约50,000的整数)。每个标记都被转换为嵌入向量(通过单层神经网络),长度为768(对于GPT-2)和12,288(对于ChatGPT的GPT-3)。同时,还有一个“次要路径”,它将标记的整数位置序列作为输入,并从这些整数创建另一个嵌入向量。最后,将来自令牌值和令牌位置的嵌入向量相加,以产生来自嵌入模块的最终嵌入向量序列。
为什么只需将令牌值和令牌位置嵌入向量相加?我认为这并没有特别科学之处。只是尝试了各种不同的方法,这似乎是有效的其中之一。而且,在神经网络领域中,“大致正确”的设置通常足以通过充分训练找到细节,而无需真正理解神经网络如何配置自己在工程水平上运行。
以下是嵌入模块的操作,它作用于字符串“hello hello hello hello hello hello hello hello hello bye bye bye bye bye bye bye bye bye”。
每个标记的嵌入向量元素显示在页面下方,横跨页面我们首先看到一系列“hello”嵌入,然后是一系列“bye”嵌入。上面的第二个数组是位置编码器 - 其略微随机的结构正好是所学习到的(在这种情况下为GPT-2)。
好吧,在嵌入模块之后就来到了变形金刚的“主要事件”:所谓的“注意力块”的序列(对于GPT-2有12个,对于ChatGPT’s GPT-3有96个)。这一切都非常复杂,并且让人想起典型的大型难以理解工程系统或生物系统。但无论如何,以下是单个“注意力块”的示意图(适用于GPT-2):
在每个这样的注意力块中,都有一组“注意头”(GPT-2为12个,ChatGPT的GPT-3为96个),每个头独立地在嵌入向量中不同的值块上运行。 (是的,我们不知道将嵌入向量分成几部分或其不同部分的含义是一个好主意;这只是那些已经被发现有效的事情之一。)
那么,注意力头做什么?基本上它们是一种“回顾”标记序列(即迄今为止生成文本),并以对于找到下一个标记有用形式来“打包过去”。 在上面第一节中,我们讨论了使用二元概率根据其直接前驱选择单词。转换器中的“关注”机制允许甚至更早期单词进行“关注”,从而可能捕获动词可以引用出现在句子之前多个单词处名词等方式。
更详细地说,注意力头所做的就是重新组合与不同标记相关联的嵌入向量块,并带有某些权重。例如,在第一个关注块(在GPT-2中)中具有以下针对以上字符串”hello, bye” 的(“回溯到标记序列开端”的) “重新组合权重”模式:
经过注意力头的处理后,生成的“重新加权嵌入向量”(对于GPT-2长度为768,对于ChatGPT的GPT-3长度为12,288)通过标准的“全连接”神经网络层传递。很难掌握这个层正在做什么。但是这里有一个使用它的768×768权重矩阵绘图(这里是针对GPT-2):
取64×64移动平均值,一些(类似随机游走的)结构开始显现:
这个结构是由什么决定的?最终,可能是人类语言特征的某种“神经网络编码”。但目前为止,这些特征可能还不太清楚。实际上,我们正在“打开ChatGPT(或至少是GPT-2)的大脑”,发现它非常复杂,并且我们并不理解——尽管最终它产生了可识别的人类语言。
好吧,在经过一个注意力块之后,我们得到了一个新的嵌入向量——然后依次通过其他注意力块(对于GPT-2总共有12个;对于GPT-3则有96个)。每个注意力块都有自己独特的“关注”和“全连接”权重模式。在这里,对于第一个关注头,“hello, bye”输入序列中的关注权重顺序如下:
这里是全连接层的(移动平均)“矩阵”:
有趣的是,尽管不同注意力块中的这些“权重矩阵”看起来非常相似,但权重大小分布可能会有所不同(并且并不总是高斯分布):
经过所有这些注意力块后,变压器的净效果是什么?本质上,它是将标记序列的原始嵌入集合转换为最终集合。而 ChatGPT 的特定方式是选择此集合中的最后一个嵌入,并“解码”以生成下一个应该出现的标记列表的概率。
所以这就是 ChatGPT 内部大致情况。它可能看起来很复杂(不仅因为其许多必然有些任意的“工程选择”),但实际上涉及到的最终元素非常简单。因为归根结底,我们处理的只是由“人造神经元”组成、每个神经元都执行将数字输入集合与某些权重相结合等简单操作的神经网络。
ChatGPT的原始输入是一组数字(到目前为止令牌的嵌入向量),当ChatGPT“运行”以生成新令牌时,这些数字只是通过神经网络层“涟漪”,每个神经元“做自己的事情”并将结果传递给下一层上的神经元。没有循环或“回溯”。所有东西都只是通过网络“前馈”。
这与典型计算系统(如图灵机)非常不同,在该系统中,结果会被相同的计算元素重复地“重新处理”。在此处-至少在生成给定输出标记方面-每个计算元素(即神经元)仅使用一次。
但在某种意义上,即使是在ChatGPT中仍然存在一个“外部循环”,它重复使用计算元素。因为当ChatGPT要生成新的标记时,它总是“读取”(即将其作为输入)之前出现的所有标记序列,包括ChatGPT自己先前“编写”的标记。我们可以认为这个设置意味着,在最外层至少涉及到一个“反馈循环”,尽管每次迭代都明确可见作为出现在所生成文本中的标记。
但让我们回到ChatGPT的核心:被重复用于生成每个标记的神经网络。从某种程度上来说,它非常简单:一整套相同的人工神经元。网络中有些部分只由(“全连接”)神经元层组成,在给定层上的每个神经元与之前一层上的每个神经元都连接(带有一些权重)。但特别是通过其变压器架构,ChatGPT具有更多结构化部分,在其中只连接不同层上特定的神经元。(当然,“所有神经元都已连接”,但有些权重值为零)。
此外,ChatGPT中神经网络的某些方面并不是最自然地被认为只包含“同质”层。例如,正如上面的标志性摘要所示,在注意力块内部有一些地方会“复制多个”传入数据,每个数据都通过不同的“处理路径”,可能涉及不同数量的层,并且仅在稍后重新组合。但是,虽然这可能是正在发生的事情的便捷表示法,但至少原则上总是可以考虑到“密集填充”的层,只需使一些权重为零即可。
如果看一下ChatGPT中最长路径,则涉及约400(核心)层-在某些方面并不算很多。但有数百万个神经元-共计1750亿个连接因此也就有了1750亿个权重。需要意识到的一件事情是:每次ChatGPT生成一个新令牌时,它都必须进行涉及所有这些权重之间计算。从实现角度来看,“按图层”将这些计算高度并行化成数组操作,并且可以在GPU上轻松完成。但对于每个生成的令牌还需要进行1750亿次计算(最终还要更多),因此使用ChatGPT生成长文本确实需要花费一定时间。
但最终,值得注意的是,所有这些操作——虽然它们各自都很简单——但在一起却能够做出如此出色的“类人”文本生成工作。必须再次强调(至少就我们所知),没有“最终理论原因”可以解释为什么会有这样的结果。事实上,正如我们将要讨论的那样,我认为我们必须把这看作是一个潜在惊人的科学发现:在像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个单词的训练数据来设置这些权重,则根据以上所述,我们可以得出结论:我们将需要大约n²次计算步骤来完成网络的训练——这就是为什么目前需要谈论数十亿美元培训工作量的原因了。
超越基础训练
培训ChatGPT的大部分工作都花在“展示”来自网络、书籍等大量现有文本上。但事实证明,还有另一个——显然相当重要的——部分。
一旦它完成了从原始文本语料库中获得的“原始训练”,ChatGPT内部的神经网络就准备好开始生成自己的文本,从提示信息等继续进行。但是,尽管这样产生的结果通常似乎合理,但对于较长的文本片段而言,它们往往会以非人类方式“偏离”。这不是通过对文本进行传统统计可以轻易检测到的东西。但实际阅读该文本内容时却容易被真正人类注意到。
构建ChatGPT时关键思想之一是,在像网络这样“被动阅读”的事物之后再加入另一个步骤:让真正人类积极与ChatGPT互动,并查看其生成内容,并在效果上给出反馈,“如何成为良好聊天机器人”。但神经网络如何使用该反馈呢?第一步只是让人类评价神经网络产生的结果。然后建立另一个神经网络模型来预测那些评级。但现在可以运行这个预测模型——实质上像一个损失函数——在原始网络上,从而允许该网络通过已经给出的人类反馈进行“调整”。实践中的结果似乎对系统成功产生“类人”输出有很大影响。
总的来说,有趣的是,“最初训练”的网络似乎需要很少的“刺激”就能使其朝特定方向有用地发展。人们可能认为,要使网络表现得好像它“学到了新东西”,必须运行训练算法、调整权重等。
但事实并非如此。相反,似乎只需在您提供的提示中告诉ChatGPT一次即可,并且当它生成文本时可以成功利用您告诉它的内容。再次强调这种方法有效是我认为理解ChatGPT“真正做什么”以及它与人类语言和思维结构之间关系的重要线索。
这确实有点类似于人:至少经过所有预先培训后,你只需告诉它一次某些内容,然后它就可以“记住”——至少“足够长时间”,以使用该信息生成一段文本。那么在这种情况下发生了什么?可能是“你可能会告诉他任何事情都已经存在于其中某个地方”,而你只是引导他到正确位置。但这看起来不太可信。相反,更有可能的是元素已经存在其中,但具体定义由类似于元素之间轨迹之类的东西确定,并且当您告诉它某些内容时,就是在引入这种轨迹。
实际上,就像对于人类一样,如果你告诉它一些奇怪和意外的东西完全不符合它已知的框架,它似乎无法成功地“整合”这个信息。只有当它基本上在已有的框架之上以相当简单的方式运行时,才能够“整合”这个信息。
值得再次指出的是,神经网络所能“捕捉”的内容必然存在“算法限制”。告诉它形式为“这个变成那个”的浅显规则等等,并且神经网络很可能可以很好地表示和复制这些规则——实际上从语言中所了解到的内容将给予其一个立即可遵循的模式。但是如果试图为涉及许多潜在计算不可约步骤的实际深度计算提供规则,则无法正常工作。(请记住,在每一步中,除了生成新标记外,它总是仅向前馈送数据而没有回路。)
当然,该网络可以学习特定“不可约”计算问题的答案。但是一旦存在组合数量级别以上数量级别以上数量级别以上数量级别以上可能性,则此类表格查找方法将无效。因此,请注意:与人类一样,“神经网络”需要使用实际的计算工具。(是的,Wolfram|Alpha和Wolfram Language非常适合,因为它们已经被构建成“谈论世界中的事物”,就像语言模型神经网络一样。)
是什么让ChatGPT真正工作起来?
人类语言以及生成它所涉及的思维过程一直被认为是复杂性的巅峰。事实上,人脑——其“仅有”约1000亿个神经元(和可能达到1万亿个连接)的网络似乎能够负责这一切,这似乎相当不可思议。或许,一个人可以想象,大脑除了神经元网络之外还有其他未被发现的物理层面。但现在我们通过ChatGPT得到了重要新信息:我们知道一个纯粹、人造神经网络与大脑中神经元数量相当多的连接数能够出奇地好地生成人类语言。
没错,这仍然是一个庞大而复杂的系统——其中权重与当前世界上所有文本单词数量相同。但从某种程度上来说,很难相信所有语言丰富性和它所能谈论的事情都可以包含在如此有限的系统中。部分原因无疑反映了普遍现象(最初在规则30示例中首次显现),即计算过程实际上可以极大地放大系统表面复杂性,即使它们基础规则很简单也是如此。但实际上,正如我们上面讨论的那样,ChatGPT中使用的神经网络往往是特别构建的,以限制这种现象及其相关的计算不可约简性,并使它们更易于训练。
那么,像ChatGPT这样的东西如何能够在语言方面取得如此大的进展呢?我认为基本答案是,语言在某种根本层面上比它看起来要简单。这意味着,即使是具有最终直接的神经网络结构的ChatGPT也成功地能够“捕捉”人类语言及其背后思维的实质。而且,在训练过程中,ChatGPT以某种方式“隐含地发现”了使这一切成为可能的语言(和思考)规律。
我认为ChatGPT的成功给我们提供了一个基础和重要科学证据:它表明我们可以期望存在一些全新、重要的“语言法则”,以及有效地探索其中所涉及到“思想法则”。在作为神经网络构建出来的ChatGPT中,这些法则充其量只是隐含存在。但如果我们能够将这些法则变得显式化,则有潜力以更加直接、高效和透明化方式执行类似于ChatGPT所做事情。
那么好吧,这些规律会是什么样子呢?最终它们必须给我们提供一定程度上关于如何组合语言——以及用它说出来之物的指导。稍后我们将讨论“查看ChatGPT内部”可能如何能够给我们一些关于这方面的提示,以及从构建计算语言中所了解到的内容提供前进道路。但首先,让我们讨论两个长期已知的“语言法则”的例子——以及它们与ChatGPT操作之间的关系。
第一个是语言句法结构。语言不仅仅是单词随意组合而成的混乱堆积物。相反,有(相当)明确的文法规则来定义不同类型单词可以如何组合:例如,在英语中,名词可以由形容词修饰并跟在动词后面,但通常两个名词不能紧挨着放置。这种文法结构可以(至少近似地)通过一组规则来捕捉,这些规则定义了类似于“分析树”的东西如何被拼接起来:
ChatGPT并没有明确的了解这些规则。但在其训练中,它会隐含地“发现”它们,并且似乎很擅长遵循它们。那么这是如何工作的呢?从一个“大局”层面来看,还不太清楚。但为了获得一些见解,也许看一个更简单的例子会有所帮助。
考虑由(和)序列组成的“语言”,其语法规定括号应该始终保持平衡,如表示为类似于分析树:
我们能训练神经网络生成“语法正确”的括号序列吗?在神经网络中处理序列的方法有很多种,但我们可以使用变压器网络,就像ChatGPT一样。给定一个简单的变压器网络,我们可以开始将语法正确的括号序列作为训练示例输入。一个微妙之处(实际上也出现在ChatGPT生成人类语言时)是除了我们的“内容标记”(这里是“(”和“)”)外,还必须包含一个“结束”标记,用于指示输出不应再继续下去(即对于ChatGPT来说,已到达故事的“结尾”)。
如果我们只设置一个具有8个头部和长度为128的特征向量的注意块的变压器网络(ChatGPT也使用长度为128 的特征向量,但每个注意块都有96 个头),那么似乎不可能使其学习关于括号语言方面太多知识。但是通过2个注意块进行设置后,在大约提供1000万个示例后学习过程似乎会收敛——并且与变压器网络常见情况相同地表现出更多示例只会降低性能。
因此,在这个网络中,我们可以做类似于ChatGPT所做的操作,并要求计算下一个标记的概率——在括号序列中:
在第一种情况下,网络“非常确定”序列不能在此结束——这很好,因为如果是这样的话,括号将不平衡。然而,在第二种情况下,它“正确地识别出”序列可以在此结束,尽管它也“指出”,可以“重新开始”,放置一个“(” ,可能会跟着一个“)” 。但是糟糕的是,即使有其400,000个左右费力训练的权重,它仍然说有15%的概率将“)”作为下一个标记——这是不正确的,因为那必定会导致括号不平衡。
如果我们要求网络逐渐更长地完成(’s)序列,则会得到以下结果:
是的,网络在一定长度范围内表现得很好。但是随后它开始失败。这是神经网络(或机器学习)中“精确”情况下常见的问题。人类可以“一眼解决”的情况,神经网络也可以解决。但是需要进行“更算法化”的操作(例如显式计数括号以查看它们是否关闭)的情况下,神经网络似乎会“计算能力不足”,无法可靠地执行。(顺便说一句,即使完整的ChatGPT当前版本也很难正确匹配长序列中的括号)
那么对于像ChatGPT和英语这样的语言语法来说意味着什么?括号语言非常简洁 - 更多地属于“算法故事”。但在英语中,根据单词和其他提示局部选择,“猜测”何时符合文法要求更加现实。而且,是的,在这方面神经网络做得更好 - 即使可能会错过某些形式上正确但人类也可能忽略掉的案例。但主要观点是:事实上有一个整体句法结构存在于该语言中,并且具有所有正则性所暗示的限制程度,在某种程度上限制了神经网络必须学习的“程度”。关键的“自然科学式”观察是,像ChatGPT中的变压器架构似乎成功地能够学习类似于嵌套树状句法结构的语言结构(至少在某种近似情况下存在于所有人类语言中)。
语法为语言提供了一种约束。但显然还有更多。像“Inquisitive electrons eat blue theories for fish”这样的句子在文法上是正确的,但不是人们通常会说出来的话,并且如果ChatGPT生成它,则不会被认为是成功 - 因为基本上没有意义。
但是否有一般方法可以判断一个句子是否有意义?传统上没有整体理论。但这是ChatGPT经过数十亿个(可能具有含义)从网络等处训练而隐含“开发出理论”的东西。
这个理论会是什么样子呢?嗯,有一个小角落基本上已经被人们知道了两千年,那就是逻辑。当然,在亚里士多德发现它的三段论形式中,逻辑基本上是一种说法,即遵循某些模式的句子是合理的,而其他句子则不合理。因此,例如,“所有X都是Y。这不是Y, 所以它不是X”(如“所有鱼都是蓝色的。这不是蓝色的,所以它不是鱼。”)就很合理。正如人们可以略微任性地想象亚里士多德通过大量修辞学例子(类似于“机器学习风格”)来发现三段论逻辑一样,我们也可以想象在ChatGPT 的训练中它将能够通过查看网络上的大量文本等方式“发现三段论逻辑”。 (而且,在这方面 ChatGPT 可以产生包含基于三段论逻辑等内容的“正确推断”的文本;但当涉及到更复杂的形式化逻辑时情况完全不同——我认为出现失败可能与括号匹配失败原因相同)
但除了狭窄范围内关于逻辑之外,还能说些什么关于如何系统地构建(或识别)甚至是合理的文本吗?是的,有像 Mad Libs 这样使用非常特定“短语模板”的东西。但不知怎么的 ChatGPT 隐含了一种更普遍的方法来做到这一点。也许除了“当你拥有1750亿个神经网络权重时它就会发生”之外,没有其他可以说的了。但我强烈怀疑存在一个更简单、更强大的故事。
意义空间和语义运动定律
我们上面讨论过,在ChatGPT中,任何一段文本都可以被有效地表示为一个数字数组,我们可以将其视为某种“语言特征空间”中点的坐标。因此,当ChatGPT继续一段文本时,这相当于在语言特征空间中跟踪轨迹。但现在我们可以问:是什么使得这条轨迹对应于我们认为有意义的文本?或者说是否存在某种“语义运动定律”,定义或至少限制了在保持“有意义性”的同时,语言特征空间中的点如何移动?
那么这个语言特征空间是什么样子的呢?如果我们将这样一个特征空间投影到二维平面上,以下是单词(此处为普通名词)可能被排列的示例:
我们在上面看到了另一个例子,基于代表植物和动物的单词。但两种情况的重点都是“语义相似的单词”被放置在附近。
作为另一个例子,这里是不同词性对应的单词如何排列:
当然,一个单词通常不只有“一个意思”(或者不一定对应于一个词性)。通过观察包含某个单词的句子在特征空间中的布局,人们经常可以“分辨出”不同的含义——就像这里针对“鹤”这个词(是指鸟还是机器?)的例子一样。
好的,那么我们至少可以认为这个特征空间将“意思相近的单词”放在了这个空间中靠近的位置。但是我们能够在这个空间中找到什么样的额外结构呢?例如,是否存在某种“平行传输”的概念来反映该空间中的“平坦性”?了解这一点的一种方法是查看类比:
是的,即使我们将其投影到二维平面上,通常也至少有一点“扁平”的迹象,尽管这并不普遍。
那么轨迹呢?我们可以查看ChatGPT提示在特征空间中遵循的轨迹 - 然后我们可以看到ChatGPT如何延续它:
这里显然没有“几何上明显”的运动定律。这一点并不令人惊讶;我们完全预料到这将是一个更加复杂的故事。例如,即使存在“语义运动定律”,它最自然地陈述在哪种嵌入(或实际上是哪些“变量”)也远非明显。
在上面的图片中,我们展示了“轨迹”的几个步骤——每一步我们都选择ChatGPT认为最有可能的单词(“零温度”情况)。但我们还可以询问在给定点时下一个可能出现的单词及其概率是什么:
在这种情况下,我们看到的是一个高概率词汇的“扇形”,似乎在特征空间中朝着更或多或少明确的方向前进。如果我们继续前进会发生什么?以下是随着轨迹“移动”而出现的连续“扇形”:
这是一个包含40个步骤的3D表示:
是的,这似乎很混乱,并且并没有特别鼓励人们期望通过经验研究“ChatGPT内部正在做什么”来确定“数学物理类”的“语义运动定律”。但也许我们只是看错了变量(或坐标系),如果我们只看对了,我们就会立即看到ChatGPT正在做一些像沿着测地线那样的“数学物理简单”事情。但目前为止,我们还没有准备好从其“内部行为”中“经验性解码”,以确定ChatGPT已经发现有关如何将人类语言组合在一起的内容。
语义语法和计算语言的力量
生产有意义的人类语言”需要什么?过去,我们可能认为这只能由人脑完成。但现在我们知道,ChatGPT的神经网络也可以相当好地完成这项任务。不过,也许这就是我们所能达到的极限了,并且没有更简单或更易于理解的方法可行。但我强烈怀疑ChatGPT成功背后隐含着一个重要的“科学”事实:有关有意义的人类语言结构和简单性比我们以往所知道的要多得多——最终可能会有相当简单明了的规则来描述如何组合这种语言。
正如上面提到的那样,句法语法给出了用于将与词性等不同部分对应的单词组合成人类语言中句子结构规则。但为了处理含义,我们需要进一步思考。其中一种做法是不仅考虑句法文法而且还需考虑语义文法。”
为了语法的目的,我们识别像名词和动词这样的东西。但是为了语义学的目的,我们需要“更细微”的分化。因此,例如,我们可能会确定“移动”概念和一个“保持其独立于位置身份不变”的“对象”概念。每个这些“语义概念”都有无数具体例子。但是对于我们语义文法而言,我们只需拥有一些基本规则即可,基本上说,“物体”可以“移动”。关于所有这些如何工作还有很多要说(其中一部分我以前已经说过)。但在此我将满足于仅发表几点评论,并指出一些未来可能性。
值得注意的是,即使根据语义文法句子完全没有问题也并不意味着它在实践中已被实现(甚至可能无法实现)。 “大象去月球旅行”毫无疑问会通过我们的语义文法测试,但它肯定尚未在我们真正存在世界中被实现(至少到目前为止)- 尽管它绝对适用于虚构世界。
当我们开始谈论“语义语法”时,我们很快就会问:“它下面是什么?”它假设了什么样的“世界模型”?句法语法实际上只涉及从单词构建语言。但是,一个语义语法必然涉及某种“世界模型”,这个模型作为一种“骨架”,在其中可以添加由实际单词组成的语言。
直到最近,我们可能认为(人类)语言将是描述我们的“世界模型”的唯一通用方式。几个世纪前已经开始对特定事物进行形式化处理,尤其基于数学。但现在有了更普遍的形式化方法:计算机语言。
而且,没错,在过去四十多年中(现在体现在 Wolfram 语言中),这一直是我的大项目:开发精确的符号表示,能够尽可能广泛地讨论关于事物和抽象概念方面的内容。因此,例如城市、分子、图像和神经网络都有符号表示,并且我们内置了关于如何计算这些东西的知识。
经过几十年的工作后,我们以这种方式覆盖了许多领域。但过去,我们并没有特别处理“日常话题”。 在“I bought two pounds of apples”中,我们可以轻松地表示(并进行营养和其他计算)“两磅苹果”。但是我们还没有一个符号表示“我买了”的方法。
这一切都与语义语法的概念有关——目标是拥有一个通用的符号“构建工具包”来表示概念,这将为我们提供什么可以与什么相配合的规则,从而为我们可能转化成人类语言的“流程”提供规则。
但假设我们已经拥有了这种“符号话语语言”。那么我们会怎样使用它呢?我们可以开始生成“局部意义文本”。但最终,我们很可能希望获得更多“全球意义”的结果——这意味着需要更多地计算实际存在或发生在世界上(或者也许是某个一致的虚构世界)的内容。
现在,在 Wolfram 语言中,我们内置了大量关于各种事物的计算知识。但对于完整的符号话语语言,我们还必须建立关于世界上普遍事物额外的“演算法则”:如果一个对象从 A 移动到 B 再从 B 移动到 C,则它就从 A 移动到 C 等等。
给定一个符号话语语言,我们可以用它来制作“独立声明”。但是,我们也可以像 “Wolfram|Alpha 风格” 一样使用它来询问世界问题。或者使用它来陈述自己“想要实现的事情”,可能需要一些外部激活机制。或者我们可以用它来做出断言——也许是关于实际世界,也许是关于我们正在考虑的某个特定世界,无论是虚构还是其他。
人类语言基本上不精确,这不仅因为它没有与特定计算实现相联系,而且其含义基本上只由其用户之间的“社会契约”定义。但计算语言天生具有一定的精度——因为最终它所指定的内容总能够在计算机上“明确地执行”。人类语言通常可以逃脱一定程度的模糊性。(当我们说 “行星” 时是否包括系外行星等?)但在计算语言中,我们必须对所有区别进行精确定义和清晰表述。
通常,在编写计算语言名称时利用普通人类语言很方便。但他们在计算语言中所具有的意义必然是准确无误,并可能涵盖典型人类使用方式中某些特殊内涵。
如何确定适用于一般符号话语语言的基本“本体论”?嗯,这并不容易。也许这就是为什么自亚里士多德两千多年前做出原始开端以来,在这些方面几乎没有什么进展。但今天我们已经知道如何计算地思考世界(而且从物理项目和ruliad的概念中获得“基础形而上学”),这确实有所帮助。
但在ChatGPT的背景下,所有这些意味着什么?通过其培训,ChatGPT有效地“拼凑”了相当数量(相当惊人)的语义语法。但它非常成功使我们有理由认为构建更完整的计算机语言形式是可行的。与迄今为止我们已经了解到关于ChatGPT内部情况不同,我们可以期望设计计算机语言以便人类能够轻松理解。
当我们谈论语义语法时,可以将其类比为三段论逻辑。起初,三段论逻辑本质上是关于用人类语言表达的陈述的规则集合。但是(是的,在两千年后),当形式逻辑被发展出来时,三段论逻辑的最初基本结构现在可以用于构建巨大的“正式塔”,其中包括现代数字电路运算等操作。因此,我们可以期望更一般化的语义语法也会如此。起初,它可能只能处理简单模式,例如文本表示方式。但是一旦整个计算机语言框架建立起来了,我们就可以期望它能够被用于建立高耸入云、允许我们以精确和正式方式处理各种以前从未可接近过我们、除了通过带有所有含糊性质地“底层”人类语言之外。
我们可以认为计算机语言和语义语法的构造代表着对事物进行终极压缩的一种形式。因为它使得我们能够谈论到可能性实质而不必考虑普通人类口头表达中存在的所有“措辞”。而且我们也可以把ChatGPT 的强大视作某种相似之处:因为在某种意义上,它也已经“钻研到”了这一点,即可以“以语义有意义的方式组合语言”,而不必考虑不同可能的措辞。
那么如果我们将ChatGPT应用于基础计算机语言会发生什么呢?计算机语言可以描述可能性。但是还可以添加一个“流行”的概念——例如基于阅读网络上所有内容。但是然后,在底层操作计算机语言时,像ChatGPT这样的系统就立即和根本地访问了利用潜在不可约简运算的终极工具。这使得它不仅能够“生成合理文本”,而且可以期望解决关于该文本是否实际上对世界或者所谈论的事物做出了“正确”陈述等问题。
那么…ChatGPT在做什么,为什么它有效?
ChatGPT的基本概念在某种程度上相当简单。从网络、书籍等大量人类创作文本样本开始,然后训练神经网络生成“类似于这些”的文本。特别地,使其能够从“提示”开始,然后继续生成“与其训练内容相似”的文本。
正如我们所见,在ChatGPT中实际的神经网络由非常简单的元素组成——尽管有数十亿个。而神经网络的基本操作也非常简单,基本上是对每个新词(或部分词)产生输入时,“将其通过元素”(没有任何循环等)。
但值得注意和意外的是,这个过程可以产生成功“像”网页、书籍等中存在的文本,并且它不仅是连贯的人类语言,还会利用它所阅读到内容来表达一些东西。“它说出来”的东西符合其提示,并且并不总是说出全局意义上正确计算结果——因为(例如没有使用Wolfram|Alpha 的 “计算超级能力”),它只是根据培训材料中听起来像什么来表达自己。
ChatGPT的特定工程使其非常引人注目。但最终(至少在它能够使用外部工具之前),ChatGPT只是从其积累的“传统智慧的统计数据”中提取了一些“连贯的文本线索”。但令人惊奇的是,结果与人类非常相似。正如我所讨论的那样,这表明某些东西至少在科学上非常重要:人类语言(以及背后思考模式)在结构上比我们想象中更简单、更符合“法则”。 ChatGPT已经隐含地发现了这一点。但我们可以通过语义语法、计算机语言等方式来明确地暴露它。
ChatGPT生成文本时所做的事情非常令人印象深刻——结果通常与我们人类产生的内容非常相似。那么这是否意味着ChatGPT像大脑一样工作?它底层的人工神经网络结构最终是基于对大脑理想化建模而得出来的。当我们产生语言时,很可能有很多方面都与此相似。
当涉及到训练(也称为学习)不同类型硬件和当前计算机(以及可能还有一些未开发完善算法思路)的大脑时,ChatGPT被迫使用一种策略,这种策略可能与大脑相比有所不同(在某些方面效率要低得多)。还有另外一件事:与典型的算法计算甚至不同,在ChatGPT内部没有“循环”或“重新计算数据”。这必然限制了它的计算能力——即使是对于当前的计算机来说也是如此,但肯定是相对于大脑而言。
目前尚不清楚如何“修复”这个问题并仍保持系统合理高效地训练。但做到这一点将可能使未来的ChatGPT执行更多类似于大脑的任务。当然,有很多事情人类大脑做得不太好——特别涉及到等价为基本运算量级别的问题。对于这些问题,无论是人类大脑还是像ChatGPT之类的东西都需要寻求“外部工具”,例如Wolfram语言。
但目前来看,看到ChatGPT已经能够做到什么是很令人兴奋的。在某种程度上,这是一个伟大的例子,说明了基本科学事实:大量简单的计算元素可以做出卓越而意想不到的事情。但它也为我们更好地理解人类语言和思维过程这一核心特征及其原则提供了或许有史以来最好的动力。