ChatGPT在做什么...为什么它能够成功
🗒️ChatGPT在做什么...为什么它能够成功
2024-4-7|最后更新: 2024-7-17
type
status
date
slug
summary
tags
category
icon
password
这篇可能是知乎上关于ChatGPT目前为止最为详尽的文章,堪称ChatGPT基础知识百科全书,是对Stephen Wolfram大佬的雄文的细致翻译。为了增加趣味性,我使用了ChatGPT Plus协助创作(幽默点说,这相当于让ChatGPT解释自己怎么工作的),并保留某些的人工修正痕迹(比如指出ChatGPT翻译有问题的地方)。这样不仅降低了我的工作负担,也非常好的展示了ChatGPT的能力以及局限,还让我练习了如何使用ChatGPT创作,可谓一文三用。在【】内的内容都是我添加的,包含了一些“不平凡”的修正和指示。全文用了Mathematica(Wolfram 语言)这个软件作例子(Wolfram就是其创立者),所有的图也是Mathematica生成的,我以前也受益于Mathematica,翻译这个也算是对Mathematica的软广吧(原文所有的图都有Mathematica源码,可以学习怎么用Mathematica生成这些图片和进行计算)。

ChatGPT是以“词”为单位进行文本生成的

ChatGPT能够自动生成看起来很像人类写作的文本,这非常了不起且出乎意料。但是它是如何做到的?我的目的在于概述ChatGPT内部进行的过程,然后探讨它为什么能够成功地生成我们认为有意义的文本。我首先声明,我将集中讨论整体情况,并提到一些工程细节,但不会深入探讨它们。同时,我说的要点同样适用于其他当前的“大型语言模型”(LLMs),不仅仅限于ChatGPT。
首先要解释的是,ChatGPT始终基本上是在尝试生成“文本的合理延续”,这个延续是基于已有的文本,其中“合理”的意思是“在查看了数十亿个网页等人类编写的文本之后,我们可能会期望某个人会写下这样的内容。”
因此,我们假设已有文本为“人工智能最专长的一点是...”【原ChatGPT译文:“人工智能最好的一点在于其能力”,这虽然符合原意,但是翻译成中文后由于改变了词语顺序,在此处意思不对了】,然后想象一下扫描数十亿个人类编写的文本(例如网络内容和数字化书籍),找到所有这些文本的实例,看看下一个单词出现的频率是多少。ChatGPT实际上做了一些类似的事情,但(如我将解释的那样)它不是直接查看文字,而是寻找在某种意义上“匹配”内容。无论如何,最终它生成了一个排名,列出可能跟随文本的单词和它们的“概率”:
notion image
令人惊奇的是,ChatGPT尝试写一篇文章时,基本上只是一次又一次地询问“在已有的文本基础上,下一个单词应该是什么?” ,然后每次都添加一个单词。(更准确地说,如我所解释的那样,它添加的是一个“标记”【注:token】,这可能仅仅是一个单词的一部分,这也是为什么它有时会“创造出新词语”的原因。)【注:比如说对于“apple”这个单词,ChatGPT可能先生成“app”,然后再接上“le”。这样就有机会生造出"bananapple" 这样不存在的词。ChatGPT生成的最小的单元近似于一个Unicode,也就是原则上ChatGPT可以生成互联网上所有国家的文本,包括emoji和各类颜表情,以及它们的所有组合】
每一步,ChatGPT都会生成一个带有概率的单词列表。但是,它应该选择哪一个单词添加到正在写的文章(或其他内容)中呢?人们可能认为应该选择“排名最高”的单词(即被分配了最高“概率”的单词)。但是在这里,一些巫术开始悄悄渗入进来。因为由于某种原因(也许有一天我们会科学地理解它),如果我们总是选择排名最高的单词,我们通常会得到一篇非常“平淡”的文章,似乎从来没有“展现出任何创造力”(甚至有时完全重复)。但是如果有时(随机地)选择排名较低的单词,我们就能得到一篇“更有趣”的文章。
这里有随机性意味着,如果我们多次使用相同的提示,我们可能每次都会得到不同的文章。并且,符合巫术思想的是【注:就像炼丹一样,莫名其妙的配方产生了特别好的效果】,有一个特定的所谓“温度”参数,它控制了较低排名的单词会被使用的频率。对于文章生成,我们发现“温度”为0.8效果最好。(值得强调的是,这里没有使用任何“理论”,而只是基于实践的发现。例如,这里的“温度”的概念,对应于统计物理学中熟悉的指数分布上的温度,但至少就我们所知,这两个温度没有“物理”上的联系。)
在继续之前,我应该解释一下,为了方便演示,我文章的大部分内容不会使用ChatGPT中的完整系统;相反,我通常会使用更简单的GPT-2系统,这个系统的优点在于它足够小,可以在标准台式电脑上运行。因此,我将能够为我所展示的基本上所有内容提供明确的 Wolfram 语言代码,您可以立即在计算机上运行它们。【此处ChatGPT显然不能意识到这不是原来网页,忠诚地翻译了“(单击此处的任何图片即可复制其背后的代码。)”】
例如,以下是如何获取上述概率表。首先,我们必须先获取一个类似ChatGPT的“语言模型”,它是一个神经网络【由于“看”不到下面的图片,ChatGPT原来的翻译崩了】:
notion image
这个模型是GPT-2,ChatGPT目前基于GPT3.5
稍后,我们将深入研究这个神经网络,讨论它的工作原理。但是现在,我们可以将这个“网络模型”作为黑匣子【注:这里意思是我们只关心如何输入输出,但对中间的过程一无所知】应用于我们已有的文本中,然后询问模型预测的前5个概率最高的单词:
notion image
我们可以把结果转成一个数据表格,这样看的更加清楚:【ChatGPT翻译原文:这将结果转换为明确的格式化“数据集”】:
notion image
如果一次次地“应用模型”,每次都添加具有最高概率的单词(这个代码中被指定为模型生成文本的“策略”),会发生什么?
notion image
如果继续下去会发生什么?在这种情况下(“零温度”),结果很快就变得混乱和重复【满篇空话大话和车轱辘话】:
notion image
但是,如果不总是选择“最佳”的单词,而是有时随机选择“非最佳”单词(与“温度”0.8对应的“随机性”)呢?同样,可以构建文本:
notion image
每次这样做时,都会进行不同的随机选择,文本也会不同——如下5个例子:
notion image
值得指出的是,每一步生成下一个单词的概率分布时,虽然有很多可能的“下一个单词”可以选择(在温度0.8的情况下),但【如果按照概率对所有的下一个单词排序】它们的概率会很快地随着排名增加而降低(下面这个对数-对数图上的直线对应于一个n^–1的“幂律”衰减,这是语言的一般统计特征【注:人类的自然语言中,一段话语对应的下面可能出现的单词的概率分布呈现“幂律分布”】):
notion image
如果继续下去会发生什么?这里是一个随机例子。它比最高概率(零温度)情况要好一些,但仍然有些奇怪:
notion image
这是使用最简单的GPT-2模型(来自2019年)进行的。使用更新和更大的GPT-3模型会得到更好的结果。以下是使用相同的“提示”生成的最高概率(零温度)文本,但使用最大的GPT-3模型:
notion image
以下是一个【GPT3使用】“温度0.8”【生成】的随机例子:
notion image

那么这些概率从何而来呢?

ChatGPT总是根据概率选择下一个单词。但是这些概率从哪里来的?让我们先从一个更简单的问题开始。考虑一次生成英文文本一个字母(而不是单词)。我们如何计算每个字母的概率?
我们可以简单地采样英文文本,并计算不同字母出现的频率。例如,这是对“cats”维基百科文章【注:标题是“猫”的文章,下面类似】中字母的计数:
notion image
这是对“dogs”做同样的事情:
notion image
结果是类似的,但不完全相同(“o”在“dogs”文章中无疑更常见,因为它出现在“dog”本身这个词中)。不过,如果我们采样足够多的英文文本,我们可以期望最终获得相当一致的结果:
notion image
这是仅根据这些概率生成字母序列的示例:
notion image
我们可以通过添加空格作为具有一定概率的“字母”来将其分解成“单词”:
notion image
我们可以通过强制“单词长度”的分布与英文一致来更好地生成“单词”:
notion image
我们这里没有得到任何“实际单词”,但结果看起来略微更好。然而,要进一步,我们需要做的不仅仅是分别随机选择每个字母。例如,我们知道如果有一个“q”,下一个字母基本上必须是“u”。
这是字母概率的绘图:
notion image
这是显示典型英文文本中字母对(“2-grams”)的概率【注:连续的两个字母作为一个单元,这个单元出现的概率】的图。可能的第一个字母显示在页面上端,第二个字母在页面左侧【注:ChatGPT原文把这里的below翻译成了“页面下面”,是因为看不到图】:
notion image
我们在这里看到,例如,“q”列除了在“u”行之外都是空白(零概率)。那么,现在我们不是一次一个字母地生成我们的“单词”,而是使用这些“2-gram”概率一次两个字母地生成它们【就是每次根据最后一个字母,用条件概率生成下一个字母】。这里是结果的一个示例,其中恰好包括一些“实际单词”:
notion image
通过足够多的英文文本,我们不仅可以获得单个字母或字母对(2-grams)的概率的相当准确的估计,还可以获得更长字母序列的概率估计。如果我们使用逐渐更长的n-gram概率【注:即第n个字母的概率分布取决于之前的n-1个字母】生成“随机单词”,我们会发现它们变得越来越“真实”
notion image
但是现在假设——与ChatGPT的做法差不多——我们处理的是整个单词,而不是字母。英语中有大约40,000个常用单词。通过查看大量英文文本(例如几百亿个单词的数百万本书),我们可以估计每个单词的出现频率。使用这个,我们可以开始生成“句子”,其中每个单词都是独立地随机选择的,具有在语料库中出现的相同的概率。这是一个示例:
notion image
很明显,这是胡言乱语。那么我们该如何改进?就像处理字母时一样,我们可以开始考虑不仅仅是单个单词的概率,还可以考虑一对或更长的n-gram单词概率。对于一对单词,以下是我们从“cat”单词开始得到的5个例子:
notion image
看起来更加“有道理”了。我们可以想象,如果我们能使用足够长的n-gram,基本上我们将“得到一个ChatGPT”——这意味着我们将获得能够以“正确的整体文章概率”生成文章长度的单词序列的东西。但问题在于:没有足够的文本可供我们推断这些概率。
在网络爬行中可能有数千亿个单词;在已数字化的书籍中可能有另外数百亿个单词。但是,对于40,000个常用单词,即使是可能的二元组也已经有16亿个,三元组的数量是60万亿。因此,我们无法从已有的文本中估计所有这些可能性的概率。而当我们到达20个单词的“文章片段”时,可能性的数量比宇宙中的粒子数量还要大,因此从某种意义上说,它们永远都无法全部写下来。
那么我们该怎么办?大的想法是制作一个模型,让我们估计序列应该出现的概率,即使我们在查看的文本语料库中从未明确看到这些序列。而ChatGPT的核心正是一个被称为“大型语言模型”(LLM)的模型,,它的设计使得它在估计这类概率方面做得很好【ChatGPT原文:它被构建为在估计这些概率方面做得很好】。

什么是模型?

假设你想知道(就像加利略在16世纪后期所做的那样),从比萨斜塔的每层掉下来的炮弹需要多长时间才能击中地面。好吧,你可以在每个高度下测量它并制作一个结果表。或者你可以做理论科学的本质:制作一个可以计算答案的模型,而不仅仅是测量和记忆每个情况。
让我们想象我们有(有点理想化的)数据,可以了解从各个楼层掉下来的炮弹需要多长时间:
notion image
没有明确数据时,我们如何确定它掉下来需要多长时间?在这种特殊情况下,我们可以使用已知的物理法则来计算。但是假设我们只有数据,不知道支配它的基本规律。然后,我们可以做出数学猜测,比如说或许我们应该使用一条直线作为模型:
notion image
我们可以选择不同的直线。但这是平均最接近我们所给定数据的线条。而从这条直线我们可以估算出任何楼层的掉落时间。
我们如何知道在这里尝试使用一条直线?在某种程度上,我们并不知道。使用直线在数学上是简单的,而我们已经习惯了许多测量的数
据沿着简单的直线分布这个事实。当然,我们可以尝试更复杂的数学方法,比如a + bx + cx²,然后在这种情况下我们可以更好地符合数据:
notion image
然而,有些情况会出现问题。比如说这是我们使用a + b / x + c sin(x)最好的结果:
notion image
需要理解的是,从来没有“没有模型的模型”。您使用的任何模型都具有某种特定的基本结构,然后有一定的“旋钮可以调节”(即您可以设置的权重)来适应您的数据。在ChatGPT的情况下,使用了许多这样的“旋钮”,实际上有1750亿个。
然而ChatGPT背后的模型“只”需要这么多参数,就足以成为一个计算下一个单词概率“足够好”的模型,甚至可以为我们生成长达上千字的连贯文章。要知道,单词的三元组的数量就达到了60万亿,1000个单词的组合的数量(40000^1000)已经让很多“天文数字”(比如常用来比较的可观测宇宙的原子数)“自形惭秽“。相比之下,1750亿个参数确实微不足道。
【ChatGPT的翻译原文:ChatGPT的基本结构,仅仅有这么多参数,足以制作一个计算下一个单词概率“足够好”的模型,从而为我们提供合理的长度的文章。】

人类任务的模型

上面给出的例子涉及到制作一个符合数值数据的模型,这些数据基本上来自于简单的物理,几个世纪以来我们已经知道“简单的数学【注:指的是几页纸能写清楚且普遍适用的那种,这种意义下,“麦克斯韦方程组”等是简单的】适用【于建模很多物理现象】”。但对于 ChatGPT,我们必须对类似于人脑所产生的人类语言文本进行建模。对于这样的事情,我们还没有任何像“简单的数学”一样的东西。那么它的模型会是什么样子呢?
在谈论语言之前,让我们谈论另一项类似于人类的任务:图像识别。作为这个问题的一个简单例子,我们来考虑数字的图像(这也是一个经典的机器学习例子):
notion image
我们可以做的一件事是获得每个数字的一堆示例图像:
notion image
然后,为了找出我们输入的图像是否对应于特定数字,我们可以使用我们已经拥有的样本进行显式的逐像素比较。但作为人类,我们肯定做得更好,因为即使它们是手写的,并具有各种修改和扭曲,我们仍然可以识别这些数字:
notion image
当我们为先前的数值数据制作模型时,我们能够使用我们得到的数值 x,并为特定的 a 和 b 计算 a + b x。因此,如果我们将这里每个像素的灰度值视为某些变量 x_i,那么是否有某些以所有变量为输入的函数,当计算它时,会告诉我们图像是哪个数字?事实证明,可以构造这样的函数。并不奇怪的是,这个函数并不特别简单,一个典型的函数可能涉及大约五十万个数学运算。
但最终结果是,如果我们将图像的像素集合输入到此函数中,我们将得到对应该图像的数字。稍后,我们将讨论如何构建这样的函数以及神经网络的思想。但现在让我们把这个函数当作一个黑匣子,我们将手写数字的图像(作为像素值的数组)输入,我们得到相应的数字:
notion image
但这里到底发生了什么?我们逐渐模糊数字。一段时间内,我们的函数仍然“识别”它,此时我们称其为“2”。但不久它“失去了”它,并开始给出“错误”的结果:
notion image
我们为什么说这是“错误”的结果?在这种情况下,我们预先已经知道我们得到所有图像都是通过对“2”进行模糊处理得到的。但是,如果我们的目标是生成"人类识别图像"的模型,真正需要问的问题是:如果不知道图像来源,人类会怎样做?
如果我们的函数的结果通常与人类的看法相一致,那么我们就有了一个“好的模型”。而有个非平凡的科学事实是,在像这样的图像识别任务中,我们现在基本上知道如何构建可以做到这一点的函数。
我们能“数学证明”它们的有效性吗?不能。因为要做到这一点,我们必须有一个关于人类认知和行为的数学理论。拿这张“2”的图像并改变一些像素,我们可能想象,如果只是有几个像素“不在位”,我们仍然应该将其视为“2”。但是这会到达何种程度?这是人类视觉感知的问题。假如回答“这个图片表示的内容是否和之前相同”的并不是人类,比如蜜蜂或章鱼来说,答案可能不同-对于假定的外星人来说可能完全不同【 :这个玩意和之前变了几个像素,我不觉得是和之前同一个东西,毕竟我外星人也没学过怎么认读阿拉伯数字】。

神经网络

那么一个典型的用于图像识别等任务的模型,实际上是如何工作的呢?当前最成功和受欢迎的方法是使用神经网络。神经网络可以被认为是对大脑似乎是如何工作的简单理想化。
人类大脑中有约1000亿个神经元(神经细胞),每个神经元可以每秒产生多达一千次的电脉冲。这些神经元相互连接成一个复杂的网络,每个神经元都有像树枝一样的分支,使其能够向其他神经元传递电信号,每个连接的权重不同,神经元是否在某个时刻产生电脉冲大致取决于它接收到其他神经元的脉冲,而不同的连接对脉冲产生的影响不同。
当我们“看到一张图像”时,当光子从图像落在眼睛后面的“光感受器”细胞上时,它们在神经细胞中产生电信号。这些神经细胞连接到其他神经细胞,最终信号经过一整个神经元层的序列。正是在这个过程中,我们“认识”这个图像,最终“形成”我们“看到一个2”的想法(也许最终会做出诸如大声说“2”之类的事情)。
上一节中的“黑盒”函数是这样一个“数学化”的神经网络。它恰好有11个层(尽管只有4个“核心层”【注:包含主要权重的层】):
notion image
类似神经网络是如何“识别事物”的呢?关键在于“吸引子”的概念。我们想象一下,我们有手写的1和2的图像:
notion image
我们希望所有的1“被吸引到一个地方”,所有的2“被吸引到另一个地方”。或者换句话说,如果一个图像在“更接近1”的意义下,我们希望它最终在“1的地方”,反之亦然。
一个简单的类比,假设我们在平面中有某些位置,用点表示(在现实生活中,它们可能是咖啡店的位置)。那么我们可以想象,从平面上的任何点开始,我们总是希望最终到达最近的那个点(也就是我们总是去最近的咖啡店)。我们可以通过将平面分成区域(“吸引盆地”),由理想化的“分水岭”分隔来表示这一点:
notion image
我们可以将此视为一种“识别任务”,在该任务中,我们不是识别哪个数字最相似,而是直接查看给定点最接近哪个点。(在此处所示的“Voronoi图”中,它将二维欧几里德空间中的点分开;可以认为数字识别任务非常相似,但是空间不是2维,而是每个图像中的所有像素的灰度级形成的784维空间)
那么我们如何使神经网络“执行识别任务”?让我们考虑这个非常简单的例子:
notion image
我们的目标是将对应于位置{x,y}的“输入”转换为最接近的三个点之一。换句话说,我们希望神经网络计算{x,y}的函数,如下所示:
notion image
我们如何使用神经网络实现这一点呢?神经网络是由一系列理想化的“神经元”组成的连接集合,通常排列在层中【注:分层排列,即一层之间的神经元互不相连,且每层都只和它的上层和下层相连】,一个简单的例子如下所示:
notion image
每个“神经元”实际上被设置为评估一个简单的数值函数【注:就是完成一个简单的运算,比如对输入求和】。要“使用”网络,我们只需在顶部输入数字(如我们的坐标x和y),然后在每个层上有神经元“评估其函数”,并将结果向前【“前”是下方】传递,最终在底部产生最终结果:
notion image
传统(生物启发式)设置中,每个神经元都有一定数量的“输入连接”来自前一层的神经元,每个连接被分配一个“权重”(可以是正数或负数)。给定神经元的值是通过将“前一层神经元”的值与它们相应的权重相乘,然后将它们相加并乘以一个常数来确定的,并最终应用“阈值”(或“激活”)函数。在数学上,如果一个神经元具有输入x = {x1,x2 …},那么这个神经元会计算f [w * x + b],其中权重w和常量b通常对于网络中的每个神经元选择不同;函数f通常相同。
计算w * x + b只是一个矩阵乘法和加法问题。 “激活函数”f引入了非线性(最终导致非平凡行为)。通常有各种激活函数可供使用; 在这里我们将只使用 ReLU:
notion image
对于我们希望神经网络执行的每个任务(或等效地说,对于我们希望评估的每个整体函数),我们将有不同的权重选择。 (如我们稍后讨论的那样,这些权重通常是通过使用机器学习,即从我们想要的输出的示例来“训练”神经网络确定的)
最终,每个神经网络都对应于某个总体数学函数——尽管可能很难写出。对于上面的示例,它将是:
notion image
ChatGPT的神经网络也对应于这样的数学函数——但却有数十亿个权重【注:ChatGPT翻译成了“术语”】。
让我们回到单个神经元。以下是具有两个输入(表示坐标x和y)的神经元使用各种权重和常量(以及ReLU作为激活函数)组成的各种函数:
notion image
这就上面的较大网络计算的内容:
notion image
它不能算完全“正确”,但它接近我们上面展示的“最近点”函数。
让我们看看其他神经网络会发生什么。在每种情况下,正如我们稍后将解释的那样,我们使用机器学习找到最佳的权重选择。然后我们在这里展示带有这些权重的神经网络计算出的内容:
notion image
更大【权重更多,结构更复杂】的网络通常更好地逼近我们的目标函数。在每个吸引子盆地的中心,我们通常得到我们想要的确切答案。但是在边界处【颜色交错的地方】——神经网络“难以作出决定”的地方——事情可能会更混乱。
对于这种简单的,数学上可以轻易表示的“识别任务”,“正确答案”很明显。但是在识别手写数字的问题中,情况就不那么清楚了。如果有人写一个“2”看起来像一个“7”,怎么办?尽管如此,大多情况下神经网络神经网络仍然可以很好的区分数字——这给出了一个指示【接下文】:
notion image
我们能否“从数学上”说明网络如何区分数字?【由于神经网络及其复杂,将它对应的函数写在纸上,可能要消耗上百万张纸】,因而实际上不行。但是我们知道,神经网络只是“做神经网络所做的事情”,但事实证明,这通常与人类的区分相当吻合。
让我们看一个更详细的例子。假设我们有猫和狗的图像,我们有一个经过训练可以区分它们的神经网络。这是它在一些示例中可能会做的事情:
notion image
对于这类问题,“正确答案”甚至更不清楚了:比如猫装扮成狗,从图像上来说到底是算猫还是狗?但是,不论输入是什么,神经网络都会生成一个答案。同时事实证明,它以与人类所做的相似的,相当一致的方式进行操作。正如我之前所说的,这不是我们可以“从第一性原理”【这里的意思是,即使你完全知道神经网络的每一个参数的作用,也不足以让你“理解”或者“直观感受”到为何神经网络能够正确进行分类,你只会看到非常复杂的数学运算得到了正确的结果】推导出的事实。至少在某些领域,它的发现是经验性的【指的是,人们只是通过大量实验知道神经网络效果很好,但是不了解其原理】。但这是神经网络有用的关键原因之一:它们以某种方式捕捉到了一种“类似人类”的做事方式。
如果让你自己看一张猫的图片,然后问“为什么那是一只猫?”。也许你会说:“我看到了它尖尖的耳朵等等。”但是很难解释你如何识别该图像为猫,因为猫的要素显然不止尖尖的耳朵,很多其他动物也有。但是你的大脑却直接给了你答案。然而,对于一个大脑,还没有(至少目前)“进入内部”并看到它是如何做出决定的。对于(人工)神经网络呢?当你展示猫的图片时,去研究每个“神经元”都在做什么是很简单的。但即使对所有的神经元做一些基本的可视化通常都是非常困难的。
在我们用于上面的“最近点”问题的最终网络中有17个神经元。在识别手写数字的网络中有2190个。在我们用于识别猫和狗的网络中有60,650个。通常很难想象60,650维空间的内容。但是,因为这是一个处理图像的网络,它的许多神经元层都组织成数组,就像它正在查看的输入的像素数组一样。
如果我们拿一张典型的猫的图片
notion image
然后我们可以抽取第一层神经元输出的“图像”的集合表示第一层神经元的状态,其中许多图像我们可以轻松解释为类似于“没有背景的猫”或“猫的轮廓”之类的东西:
notion image
当我们观察第10层的输出时,已经很难解释正在发生什么:
notion image
但总的来说,我们可以说神经网络“挑选出某些特征”(也许尖尖的耳朵是其中之一),并使用这些特征确定图像的内容。但“尖尖的耳朵”这些特征是我们有名称的特征,大多数情况下这些特征既没有名称,也难以形容【“猫”的大多数情况下,猫的特征没有熟知的名称,比如“猫的总体轮廓构成的某种形状”】。
我们的大脑是否使用类似的特征?大多数情况下我们不知道。不过我们知道,像我们在这里展示的神经网络的前几层似乎会挑选图像的某些特征(例如对象的边缘),类似于我们大脑的第一级视觉处理中选择的特征。
但假设我们想在神经网络中获得“猫识别理论”。我们可以说:“看,这个特定的网络可以做到识别猫”。特定的网络立刻让我们对“它有多难的问题”有了一些感觉(例如需要多少个神经元或层数)。但至少到目前为止,我们没有一种用语言具体描述的精确方法来说明网络在做什么。也许这是因为它真的是计算上不可约的【注:计算上不可约是本文反复提及的概念,意思指某些问题本质上就无法有简单的数学方法或者计算方法,无法取巧,比如总结出一种方便人自己理解或者计算的方式】,我们除了一步步明确跟踪每个神经网络计算的每个步骤外,没有一般的方法可以找出它的操作方式。或者可能是因为我们还没有找到系统解释神经网络本质的科学体系或者法则。
当我们谈论使用ChatGPT生成语言时,我们将遇到相同的问题。再次强调,现在还不清楚是否有方法“总结它的操作方式”。但是,语言的丰富性和细节(以及我们的经验)可能比图像更容易让我们做出进一步的研究。

机器学习和神经网络的训练

到目前为止,我们一直在讨论“已经知道”如何执行特定任务的神经网络。但神经网络(我们的大脑也一样)不仅可以执行各种任务,而且它们可以从示例中逐步“进行训练”以更好的执行这些任务。
当我们制作一个区分猫和狗的神经网络时,我们实际上不必编写一个程序(比如)明确找到猫的触须。相反,我们只需展示大量的猫和狗的图像示例,然后让网络从中“机器学习”如何区分它们。
关键在于,训练过的网络会从它所显示的特定示例中“概括”出一般的操作方式。就像我们之前看到的那样,网络并不仅仅是识别它所展示的某个猫的图像的特定像素模式;相反,神经网络以某种方式学习到了“一般猫”的某些通用性质来区分图像,不仅仅限制在局部的像素模式。
神经网络的训练是如何进行的?本质上,我们一直在努力寻找能够使神经网络成功复制我们所给出示例的权重。然后,我们依靠神经网络以“合理的”方式在这些示例之间“插值”(或“概括”)。
让我们来看一个比先前最近点问题更简单的问题。我们只是尝试让神经网络学习以下函数:
notion image
对于这个任务,我们需要一个只有一个输入和一个输出的网络,例如:
notion image
但是应该使用什么权重?使用每种可能的权重集,神经网络都会计算某个函数。例如,以下是使用几组随机选择的权重所得到的结果:
notion image
我们可以明显看到,在这些情况下,它无法复制我们想要的函数。那么我们如何找到可以复制该函数的权重?
基本思想是提供大量的“输入→输出”示例来进行“学习”,然后尝试找到可以复制这些示例的权重。以下是使用逐渐增加的示例,完成学习的结果:
notion image
10,000 至 10,000,000 个示例
 
在“训练”中的每个阶段,网络中的权重逐步调整,我们看到最终得到一个成功复制所需函数的网络。那么我们如何调整权重呢?基本思想是在每个阶段看“离我们想要的函数有多远”,然后以使其更接近的方式更新权重。
我们通常计算“损失函数”(有时称为“成本函数”),来了解“我们离目标有多远”。这里我们使用一个简单(L2)的损失函数,它只是获取值和真实值之间差值的平方和。我们可以看到随着训练过程的进行,损失函数逐渐减小(对于不同任务而言,遵循不同的“学习曲线”),直到我们达到一个点,网络(至少在很好的近似情况下)成功复制所需的函数:
notion image
好的,现在需要解释的最后一个关键部分是如何调整权重以减少损失函数。正如我们所说,损失函数给出了我们(通过神经网络)获得的值与真实值之间的“距离”。但是“我们获得的值”是由当前版本的神经网络及其中的权重在每个阶段决定的。假设权重是变量,比如说w_i,我们想知道如何调整这些变量的值,以最小化(依赖它们的)损失。
例如,想象一下(极大地简化了实际使用的典型神经网络),我们只有两个权重w1和w2。然后我们可能会得到一个损失函数,它看起来像这样(等高线图热度图):
notion image
数值分析提供了各种技术来在这种情况下寻找最小值。一个典型的方法是,从前面的w1和w2开始,沿着最陡下降的路径逐步进行:
notion image
就像水流下山一样,只能保证这个过程最终会到达表面的某个局部最小值(“山谷中的湖”);它可能无法到达最终的全局最小值。
对于一般函数,我们不清楚如何找到“权重景观”上最陡下降的路径。但是微积分是我们的救星。如上所述,我们总可以将神经网络视为计算一个数学函数——它依赖于其输入和权重。但现在考虑对这些权重求导数【当然,函数要是“几乎处处可微”的,不过这不难做到】。结果发现微积分的链式规则【chain rule】实际上让我们“展开”了神经网络中连续层所做的操作【也就是可以逐层求导数】。结果是我们可以在某种局部逼近的情况下“反演”神经网络的操作,并逐步找到能够最小化输出相关损失的权重。
上图展示了只有2个权重的不真实情况下进行的最小化过程。但事实证明,即使有更多的权重(ChatGPT使用了1750亿个),仍然可能做到最小化,至少在某种逼近的水平上。事实上,“深度学习”在2011年左右的重大突破与这个发现有关,即在某种意义上,当涉及到大量权重时,可能更容易做到(至少是近似)最小化,而当涉及到相当少的权重时则更容易陷入局部最小值(“山湖”)而无法找到“出路”【注:其实不少理论已经证实,当维度足够高,即权重足够多时,局部最小值不是主要问题,“局部最小值是优化不收敛的罪魁祸首“ 是一种低纬度下的错觉】。
值得指出的是,一般情况下,有许多不同的权重集合都可以给出几乎具有相同性能的神经网络。通常在实际神经网络训练中会进行许多随机选择,这些选择会导致“不同但等价的解决方案”,如下所示:
notion image
但是,每个这样的“不同解决方案”都会具有稍微不同的行为。如果我们要求在我们给出训练示例的区域之外进行“外推”,我们可能会得到截然不同的结果:
notion image
但这些结果中哪一个是“正确的”呢?实际上没有办法说。它们都“与观察到的数据一致”。它们外推的结果在数学上,都是合理的。比如找规律: 1,2,4,8,16,?, 最后一个数有很多种选择,每种选择都可以出自一个“合理的原因”。不过有些可能对我们人类来说比其他的“更合理”。

神经网络训练的实践与技巧

特别是在过去的十年中,神经网络训练的艺术已经取得了许多进展。没错,这基本上是一门艺术【现在常称为“炼丹”】。有时候,特别是事后看来,可以看到我们的成功应用是基于某些“科学解释”。但大多数东西都是通过试错发现的,不断添加的想法和技巧逐渐建立了与神经网络一起工作的重要技术传统。
这里有几个关键部分。首先是针对特定任务应该使用哪种神经网络结构。然后就是一个关键问题,就是如何获取用于训练神经网络的数据。当下越来越多的情况是,我们不需要从头开始训练一个网络:新网络可以直接包含另一个已经训练好的网络,或者至少可以利用该网络为自己生成更多的训练示例。
人们可能会认为,对于每一种特定的任务,我们都需要一种不同的神经网络结构。但是人们发现,即使是明显不同的任务,相同的结构似乎经常也能起作用。在某种程度上,这让人想起了通用计算的想法(以及我的计算等价性原则),但是,正如我将在后面讨论的那样,我认为这更多地反映了我们通常试图让神经网络完成的任务是“类似于人类”的,而神经网络可以捕捉相当普遍的“类似于人类的过程”。
在神经网络早期的日子里,人们倾向于认为应该“尽可能地减少神经网络的负担”。例如,在将语音转换为文本时,人们认为应该首先分析语音,将其分解为音素等。但是发现,在至少对于“类似于人类的任务”而言,通常最好只是尝试在“端对端问题”上训练神经网络【也就是不过度介入数据的预处理和特征工程,直接将相对原始的数据喂给神经网络】,让它自动“发现”所需的中间特征、编码等。
人们还有一个想法,就是应该向神经网络引入复杂的单独组件,让它实际上“显式地实现特定的算法思想”。但是再次强调,这在大多数情况下都不值得,相反,最好只是处理非常简单的组件,并让它们“自我组织”(尽管通常以我们无法理解的方式)实现(假定)这些算法思想的等价物。
这并不是说神经网络没有相关的“结构思想”。例如,在处理图像的早期阶段,使用具有本地连接的神经元的2D数组至少非常有用。而且具有“回顾序列”【就是下一层中排后面的神经元会连接(回顾)上一层中排前面的神经元,非常类似于“通过前面的词推测后面的词”】的连接模式似乎是有用的——正如我们将在稍后看到的那样——处理像ChatGPT中的人类语言这样的事情。
但就像计算机一样,神经网络的一个重要特征是它们最终只是在处理数据。当前的神经网络——以及目前的神经网络训练方法——某种意义上只是专门处理数字数组。但在处理过程中,这些数组可以被完全重新排列和重新塑形。例如,我们在上面用于识别数字的网络从一个2D“图像样式”的输入数组开始,很快“加厚”到许多通道,但然后经过一层层的网络后“集中”到一个1D数组中,最终这个1D数组包含代表不同可能输出数字的元素:
notion image
但是,怎样才能确定针对特定任务需要多大的神经网络呢?这有点像艺术。在某种程度上,关键是要知道“任务的难度”。但对于类似于人类的任务,通常很难估计它的难度。是的,可能有一种系统的方法可以通过计算机非常“机械地”完成任务。但很难知道是否有所谓的技巧或快捷方式,使人们可以至少以“类人水平”更轻松地完成任务。以游戏为例,在“机械”玩某个游戏时,可能需要列举一个巨大的游戏树;但可能有更简单的(“启发式”)方法来实现“人类水平的游戏”。
当处理微小的神经网络和简单的任务时,有时可以明确地看到“此路不通”的情况。例如,下面是使用几个小型神经网络完成上一节任务的最佳结果:
notion image
我们所看到的是,如果神经网络太小,(无论我们多么努力)它就不能复现我们想要的函数。但是当它的规模超过一定程度时,通常只要我们用足够多的样本进行足够长时间的训练,就可以解决这个问题。另外,这些图片说明了神经网络中的一个技巧:可以通过在中间设计一个“瓶颈”,强制所有信息都要通过一个较小的中间神经元数量,来压缩的网络的大小,同时不会太影响性能。(值得一提的是,“无中间层”的神经网络(或所谓的“感知器”)只能学习本质上是线性的函数,但只要存在至少一个中间层,原则上始终可以将任何函数近似得足够好,至少是如果我们有足够多的神经元的话,尽管为了使其可行地进行训练,通常需要进行某种形式的正则化或规范化。)
好的,假设我们已经确定了一种神经网络的结构。现在的问题是如何获取用于训练网络的数据。神经网络和机器学习的许多实际挑战集中于获取或准备必要的训练数据。在许多情况下(“监督学习”),我们希望获得输入和期望输出的明确示例。因此,例如,我们可能希望标记图像中的内容或其他属性。也许我们需要明确地通过一些努力进行标记【比如数据标注团队】。但是通常情况下,我们可以利用已经完成的工作,或将其用作某种代理来解决这个问题。例如,我们可能会使用已提供的网络图像的alt【网页上图像的提示文本】,来标记这个图像的信息。或者在不同的领域中,我们可以使用为视频创建的封闭字幕。或者在语言翻译培训中,我们可以使用不同语言中存在的网页或其他文档的平行版本。
为了训练神经网络,需要展示多少数据?同样,从第一原则来估计很难。当然,通过使用“迁移学习”将已在另一个网络中学习到的重要特征列表“转移”过来,可以大大降低要求。但通常来说,神经网络需要“看到很多例子”才能训练得好。对于某些任务来说,重复的训练示例可能非常重要。事实上,一个标准的策略是将所有现有的示例都重复地显示给神经网络。在每个“训练轮次”(epoch)中,神经网络将处于至少稍微不同的状态,因此“提醒它记住特定的示例对于使其“记住该示例”是有用的。(是的,这可能类似于人类记忆中的重复的效用。)
但仅仅重复同一个示例并不足够,还需要向神经网络展示示例的变化。而这也是神经网络的技巧之一,即数据扩充的变化不必很复杂,即使使用基本的图像处理轻微修改图像也可以使其对神经网络训练“与新的图像一样好”。同样,当我们用完了训练自动驾驶汽车所需的实际视频等数据时,我们可以使用运行在类似于模拟游戏的环境中的模拟数据,而不需要所有真实世界场景的细节。
那像ChatGPT这样的模型呢?它有一个不错的特点,即可以进行“无监督学习”,这使得获取训练所需的示例变得更加容易。回想一下,ChatGPT的基本任务是找出如何继续给定的文本片段。因此,要获取训练示例,我们只需获取一段文本,并遮盖掉其结尾,然后将其用作“要训练的输入”,“输出”是完整的未遮盖的文本。我们将在后面进一步讨论这个问题,但主要观点是:与学习图像中的内容不同,ChatGPT不需要“明确的 token”;ChatGPT实际上可以直接从给定的文本示例中进行学习。
神经网络的实际学习过程最终都归结为确定哪些权重最能捕捉给定的训练示例。有各种详细的选择和“超参数设置”(因为权重可以被视为“参数”)可以用来调整这一点。有不同的损失函数选择(平方和、绝对值之和等)。有不同的损失最小化方法(每步在权重空间中移动多远等)。然后有诸如每个连续学习更新“批次”大小之类的问题,用于减少要最小化的损失。我们可以应用机器学习(例如,在Wolfram Language中),来自动化机器学习,并自动设置超参数等。但最终,可以通过观察损失如何逐步减小来表征整个训练过程(如在这个Wolfram 自家产品显示)。
notion image
人们通常会看到,损失在一段时间内下降,但最终会平稳在某个值。如果该值足够小,则训练可以被认为是成功的;否则这可能意味着应该尝试更改网络架构。
能否知道“学习曲线”要平稳需要多长时间?就像许多其他事情一样,似乎存在近似幂律缩放关系,这取决于所使用的神经网络规模和数据量。但总的结论是,训练神经网络很困难,需要大量计算工作量。实际上,绝大部分的工作量都是在进行数字数组操作【比如矩阵乘法】,这正是GPU擅长的,这就是为什么神经网络训练通常受到GPU可用性的限制。
在未来,是否会出现根本上更好的方法来训练神经网络,或者出现基本上和神经网络差不多,但是更高效的算法 【注:此处ChatGPT原文“或者通常做神经网络所做的事情”】?我认为几乎肯定会。神经网络的基本思想是利用大量简单的(基本相同的)组件创建一个灵活的“计算结构”,并使这个“结构”能够被增量地修改以从示例中进行学习。在当前的神经网络中,人们实际上是利用微积分的思想——应用于实数——来进行这种增量修改。但越来越明显的是,高精度数字并不重要;即使使用当前的方法,8位或更少的位数可能已经足够。
【更加激进的方法是】使用类似元胞自动机这样的计算系统,在许多单独的位上进行并行操作。从来没有清楚如何进行这种增量修改,但没有理由认为这是不可能的。事实上,就像“2012年的深度学习突破”一样,这种增量修改在更复杂的情况下可能会更容易。
神经网络(或许有点像大脑)被设置为具有实质上固定的神经元网络,而修改的是它们之间连接的强度(“权重”)。 (或许在至少年轻的大脑中,还可以增长大量全新的连接。)但是,虽然这对生物学可能是一个方便的设置,但它根本不清楚它是否接近我们需要功能的最佳实现方法。而涉及到渐进式网络重写的事情(也许类似于我们的Wolfram Physics Project),最终可能更好。
即使在现有神经网络的框架内,仍存在一个关键限制:目前进行神经网络训练的方式是基本上是按顺序【按批次,mini-batch】进行的,每批示例的影响都会向后传播以更新权重。实际上,即使考虑到GPU,当前计算机硬件在训练过程中也大多数情况下是“空闲”的,只有一部分时间会被更新。从某种意义上讲,这是因为我们当前的计算机往往具有与CPU(或GPU)分离的内存。但是在大脑中,这可能是不同的——每个“内存元素”(即神经元)也是潜在的活动计算单元。如果能够以这种方式设计未来的计算机硬件,训练可能会变得更加高效。

“一个足够大的网络可以做任何事情!”

ChatGPT这样的技术能力看起来非常令人印象深刻,以至于人们可能认为如果只是“继续训练”越来越大的神经网络,它们最终就能够“做任何事情”。如果一个人关注的是那些人类直接可以思考到的事情【直觉上可以做到事情】,这很可能是正确的。但过去几百年的科学教导我们,有些东西可以通过正式的过程推算出来,但人类直接思考却难以解决。
非平凡的数学就是一个很好的例子。但总的来说,这实际上等价于某种计算。而最终的问题是计算不可简化现象。有些计算可能需要很多步才能完成,但事实上它们可以被“简化”成非常直接的形式。但计算不可简化的发现意味着这种方法并不总是奏效。相反,有些过程,比如下面这个例子【一维元胞自动机】,不可避免地需要追踪每一步计算才能弄清楚发生了什么:
notion image
我们通常用大脑处理的事情,可能是有选择地避免计算不可简化的【即不可归约】。在大脑中进行(不可简化的)数学运算需要特殊的努力。实际上,在脑海中“思考”任何非平凡程序操作的步骤【比如纯粹通过在脑海中想象运算的过程,生成一份文件的SHA-256摘要】在实践中几乎是不可能的。
但是,我们有计算机。通过计算机,我们可以轻松地完成长时间的计算不可简化的事情。关键在于,一般而言,这些事情没有捷径。
是的,我们可以记忆许多特定的例子,这些例子包括某个特定计算系统中会发生什么。或许我们甚至可以看到一些(“计算可简化”)模式,使我们能够进行少量的概括。但是,计算不可简化意味着我们永远无法保证不会发生意外情况,只有通过明确地进行计算,才能告诉你在任何特定情况下实际会发生什么。
最后,学习与计算不可简化之间存在一种根本的张力。学习实际上是通过利用规律来压缩数据。但计算不可简化意味着,无论掌握多少规律,都存在着无法压缩数据。
实际上,人们可以想象在可训练的系统中构建小的计算设备(例如细胞自动机或图灵机)。这些设备可以作为神经网络的良好“工具”,就像 Wolfram|Alpha 可以是 ChatGPT 的良好工具一样。但是,计算不可简化意味着我们不能指望“进入”这些设备并让它们进行学习。
换句话说,能力与可训练性之间存在根本的权衡:越想让系统充分利用其计算能力,它就越会表现出计算不可简化,越不容易训练。而越容易训练,它就越难以进行复杂的计算。
(对于 ChatGPT 的当前情况,情况实际上要极端得多,因为用于生成每个输出token的神经网络是一个纯“前馈”网络,没有循环,因此无法使用任何非平凡的“控制流”进行计算【比如无法进行递归,或者任意长度的循环】。)
当然,人们可能会想知道能够进行不可简化计算是否真的很重要。实际上,很长一段时间以来,我们认为有很多任务——包括写作——对计算机来说“从根本上太难了”。现在,我们看到 ChatGPT 这样的工具可以完成这些任务,我们往往会突然认为计算机必须已经变得非常强大了——尤其是超过了它们已经基本能够完成的事情(例如逐步计算细胞自动机等计算系统的行为)。
是的,神经网络肯定可以察觉到自然界中的规律,这些规律我们也可以很容易地用“未经人工智能辅助的人类思维”来注意到。但是,如果我们想解决属于数学或计算科学范畴的问题,神经网络将无法做到这一点,除非它有效地“使用”一个“普通”的计算系统作为工具。
但是,所有这些都可能存在潜在的混淆。过去,有许多任务——包括写作文——我们认为这些任务对计算机来说“基本上太难了”。现在我们看到ChatGPT等模型能够完成这些任务,我们往往突然认为计算机一定变得更加强大——特别是超越了它们已经基本能够做到的事情(例如从前的逐步计算类似元胞自动机的计算系统的行为)。
但这并不是正确的结论。计算不可简化的过程仍然是计算不可简化的,并且对于计算机来说在根本上仍然是困难的,即使计算机可以轻松地计算它们的各个步骤。相反,我们应该得出的结论是,在某种意义上,我们认为计算机无法完成的任务——例如写作——它的实际计算比我们想象的更容易。
换句话说,神经网络之所以能够成功地撰写文章,是因为写作的问题在某种程度上比我们想象的计算要更浅。在某种意义上,这推进了关于我们人类如何完成诸如写作之类的事情,或者在一般情况下如何处理语言的理论。
如果您有足够大的神经网络,那么,是的,您可能能够做到人类可以轻松做到的任何事情。但是,您将无法捕捉到自然界的一般能力,也无法捕捉到我们从自然界中制造的工具的能力。正是这些工具——无论是实用的还是概念性的——使我们在最近几个世纪中超越了“纯粹的人类思考”的界限,并为人类的目的捕捉了更多的物理和计算宇宙的内容

嵌入的概念

神经网络(至少目前而言)基本上是基于数字的。因此,如果我们要用它们来处理文本之类的东西,我们需要一种用数字表示文本的方式。当然,我们可以从(就像 ChatGPT 一样)给字典中的每个单词分配一个数字索引开始。但有一个重要的概念,就是“嵌入”。这个更优越的想法对于 ChatGPT 至关重要。我们可以将嵌入看作是一种尝试用数字数组表示某物的“本质”的方式,它使得“附近的事物”由附近的数字表示。
例如,我们可以将单词嵌入看作是试图在某种“意义空间”中布局单词,其中在意义上相似的单词出现在嵌入中的相邻位置。实际使用的嵌入——例如在 ChatGPT 中——往往涉及高维数组。但如果我们将它们投影到二维空间,就可以展示单词如何嵌入“意义空间”:
notion image
我们可以看到这些嵌入符合我们的日常印象。但是我们如何构建这样的嵌入?大致上的想法是查看大量文本(在这里是从网络中收集的50亿个单词),然后查看不同单词出现在不同文本环境中的“相似程度”。例如,“短吻鳄”和“鳄鱼”【ChatGPT翻译成了“鳄鱼”和“鳄鱼”,倒是印证了后文】通常可以在意义相似的句子中互换使用,这意味着它们在嵌入中会被放在附近位置。但是,“萝卜”和“老鹰”不太可能出现在意义相似的句子中,因此它们在嵌入中会被放得很远。
但是,如何使用神经网络实际实现这样的功能?让我们先谈论不是单词的嵌入,而是图像的嵌入。我们希望以数组的方式找到一些方法来表征图像,使得“我们认为类似的图像”被分配相似的数组。
我们如何判断“图像相似”?如果我们的图像是手写数字的图像,如果它们是相同的数字,我们可以“认为两个图像相似”。早些时候我们讨论过一个训练过的神经网络,它可以识别手写数字。我们可以将这个神经网络看作是设置成在其最终输出中将图像放入10个不同的容器中,每个容器代表一个数字。
但是,如果我们在最终“这个是‘4’”输出之前,“拦截”了神经网络内部正在发生的事情呢【也就是获得神经网络的“中间表示”】?我们可以期望,在神经网络内部存在着表征图像的数字,这些数字表征图像“大部分类似于‘4’但有点类似于‘2’”或者其他类似的特点。我们的想法是提取这样的数字,将它们作为嵌入中的元素使用。
因此,这是一个概念。与其直接尝试表征“哪个图像接近哪个图像”,我们反而考虑一个明确定义的任务(在这种情况下是数字识别),对于该任务,我们可以获得明确的训练数据,然后利用神经网络在执行此任务时隐含地进行“近似决策”。因此,我们不必明确地谈论“图像的接近性”,而是仅仅谈论图像代表的具体数字,然后“将其留给神经网络”来隐含地确定这对于“图像的接近性”意味着什么。
那么,对于数字识别网络,具体实现是如何工作的?我们可以将网络想象成由11个连续层组成,我们可以将它们图标化地总结如下(激活函数显示为单独的层):
notion image
一开始,我们将实际图像馈入第一层,该图像由像素值的2D数组表示。最终,从最后一层,我们得到一个包含10个值的数组,可以认为它表示了神经网络认为图像对应于数字0到9的“确定性”。
将图像
notion image
馈入并获取该最后一层的神经元的值:
notion image
换句话说,到此时,神经网络“非常确定”这幅图像是数字4,为了实际输出数字4,我们只需挑选具有最大值的神经元的位置即可。
但是,如果我们向前看一步呢?网络中的最后一个操作是所谓的softmax,它试图“强制输出每个数字的确定性,或者说概率分布”【ChatGPT原来译作“强制确定性”】。但在这之前,神经元的值如下所示:
notion image
代表“4”的神经元仍然具有最高的数值。但其他神经元的值中也包含有关图像的信息。我们可以预期,这些数字列表在某种程度上可以用于表征图像的“本质”——因此提供了一些我们可以用作嵌入的东西。例如,在这里,每个4都具有略微不同的“签名”(或“特征嵌入”)——都与8完全不同:
notion image
在这里,我们基本上使用了10个数字来表征我们的图像。但是通常最好使用更多的数字。例如,在我们的数字识别网络中,通过接入前面的层,我们可以获得一个包含500个数字的数组。这可能是一个合理的用作“图像嵌入”的数组。
如果我们想对手写数字的“图像空间”进行明确的可视化,我们需要“降维”,将我们得到的500维向量投影到3D空间中,从而实现:
notion image
我们刚刚讨论了如何创建图像特征(从而得到嵌入向量),基于的是通过确定是否(根据我们的训练集)对应于相同的手写数字来识别图像的相似性。如果我们有一个能够识别每张图片属于哪一种共5000种常见物体(猫、狗、椅子等)的训练集,我们也可以用相同的方法来生成图像嵌入向量。这样,我们可以创建一个由共同物体标识“锚定”的图像嵌入向量,然后根据神经网络的行为“推广”,如果这种行为与人类感知和解释图像的方式相符,则该嵌入向量将最终成为“合理的”,并且在执行“类人判断”的任务时很有用。
那么我们如何采用相同的方法来找到单词的嵌入向量呢?关键在于从一个可以轻松训练的单词任务开始。标准的任务是“单词预测”。想象一下,我们有一个空格“the ___ cat”。基于一个大型文本语料库(例如Web的文本内容),填入空格的不同单词的概率是多少?或者,给定“___ black ___”,不同“夹在中间”的单词的概率是多少?
我们如何为神经网络设置这个问题?最终,我们必须将所有内容都用数字表示。一种方法就是给英语中的每个50,000个常见单词分配一个唯一的数字。例如,“the”可能是914,“ cat”(前面带有一个空格)可能是3542。(这些数字是GPT-2使用的实际数字。)因此,对于“the ___ cat”问题,我们的输入可能是{914,3542}。输出应该是一个包含50,000个数字的列表,这些数字有效地给出了每个可能的“填充”单词的概率。同样,为了找到嵌入向量,我们想要“拦截”神经网络“达到结论之前”的“内部”,然后获取出现在那里的数字列表,这些数字可以看作是“描述每个单词”的数字。
那么这些特征看起来是什么样子的呢?在过去的10年里,已经开发了一系列不同的系统(word2vec、GloVe、BERT、GPT等),每个系统都基于不同的神经网络方法。但最终,所有这些系统都会将单词通过数百到数千个数字的列表来描述。
在原始形式下,这些“嵌入向量”相当无意义。例如,这是GPT-2为三个特定单词生成的原始嵌入向量:
notion image
如果我们衡量这些向量之间的距离,我们就可以找到词语之间的“接近程度”。稍后我们将更详细地讨论这样的嵌入的“认知”意义。重点是,我们有一种有用的方法,可以将单词转化为“神经网络友好”的数字集合。
但实际上,我们可以更进一步,不仅仅通过数字集合来描述单词,还可以用同样的方法来描述单词序列,甚至整个文本块。ChatGPT就是这样处理的。它将已有的文本作为输入,并生成一个嵌入向量来表示它。然后,它的目标是找到可能出现的不同单词的概率。并且,它将其答案表示为一系列数字,这些数字基本上给出了每个可能的单词的概率。
(ChatGPT严格来说并不处理单词,而是处理“标记”【token】——方便的语言单位,可以是整个单词,也可以只是像“pre”、“ing”或“ized”这样的部分。使用 token 使得ChatGPT更容易处理罕见、复合和非英语单词,有时,也可以创造新单词。)

ChatGPT的内部

好了,我们终于准备好讨论ChatGPT内部的情况了。没错,它根本上是一个巨大的神经网络——目前是所谓的GPT-3网络的一个版本【GPT-3.5】,有1750亿个权重。在许多方面,这个神经网络与我们讨论过的其他神经网络非常相似。但这是一个特别针对自然语言处理的神经网络,其最显著的特点是一个名为“transformer”的神经网络架构。
在我们上面讨论的第一个神经网络中,每个神经元在任何给定层上基本上都与前一层上的每个神经元连接(至少带有一些权重)。但是,如果处理具有特定已知结构的数据,则此类完全连接的网络可能过度复杂。因此,在处理图像的早期阶段,通常使用所谓的卷积神经网络——其中神经元实际上是在类似于图像中的像素网格上排列,并且仅与附近网格上的神经元相连。
transformers的想法是对组成文本的token序列执行类似的操作。但是,transformers不仅定义了序列中可以存在连接的固定区域,而且引入了“注意力”的概念,以及更关注序列中的某些部分而不是其他部分的想法。也许有一天,从一个通用的神经网络开始,并通过训练进行所有定制将是有意义的。但是,至少目前,在实践中将事物“模块化”似乎是至关重要的——就像transformers一样,也可能是我们的大脑所做的。
那么,ChatGPT(或者说基于它的GPT-3网络)实际上是做什么的呢?请记住,它的总体目标是根据它所看到的训练内容(包括查看网络等数十亿页的文本),“合理地”继续文本。因此,在任何给定的时刻,它都有一定数量的文本——它的目标是为下一个token添加一个适当的选择。
它有三个基本阶段。首先,它获取与迄今为止的文本相对应的token序列,并找到表示它们的嵌入(即一组数字的数组)。然后它在这个嵌入上进行操作——以“标准神经网络方式”,值“逐层流动”到网络的连续层中——以生成一个新的嵌入(即一个新的数字数组)。然后,它从这个数组的最后一部分中生成一个大约有50,000个值的数组,这些值将变成不同可能的下一个 token 的概率。(是的,碰巧有大约与英语常用单词相同数量的 token 被使用,但只有大约3000个 token 是整个单词,其余的是片段。)
关键是,这个流程的每个部分都是由神经网络实现的,其权重由端到端的网络训练确定。换句话说,实际上除了整体架构外,一切都是从训练数据中“学习”的,而不是“显式设计”。
然而,在设置体系结构方面有许多细节,这些细节反映了各种经验和神经网络知识。即使这绝对涉及到细节,但我认为谈论其中一些细节仍然很有用,这至少可以让我们了解到构建ChatGPT这样的系统需要多少工作量。
首先是嵌入模块。这是GPT-2的草图Wolfram语言表示:
notion image
输入是一个由n个 token 组成的向量(如前一节所示,由1到大约50,000的整数表示)。这些 token 中的每一个都被转换为一个嵌入向量(对于GPT-2的长度为768,对于ChatGPT的GPT-3为12,288)(通过一个单层神经网络)。同时,还有一个“辅助通道”会取出这些token的(整数)位置序列,并从这些整数创建另一个嵌入向量。最后,将token值和token位置的嵌入向量相加,以产生从嵌入模块的嵌入向量的最终序列。
为什么只需将token值和token位置嵌入向量相加?我认为这里没有特别的科学。人们已经尝试了各种不同的方法,这个方法似乎是有效的方法之一。而且神经网络的故事中的一部分是,从某种意义上说,只要我们的设置“大致正确”,通常可以通过足够的训练来调整细节,而不必真正“理解神经网络如何配置自己”的工程细节。
这是嵌入模块如何运行的,它操作字符串“hello hello hello hello hello hello hello hello hello hello bye bye bye bye bye bye bye bye bye bye”:
notion image
每个 token 的嵌入向量的元素显示在页面下方,而在页面上方,我们首先看到一组“hello”的嵌入,然后是一组“bye”的嵌入。上面的第二个数组是位置嵌入,其看似随机的结构只是“被学习到”的(在这种情况下是在GPT-2中)。
好的,那么在嵌入模块之后,transformer的“主要事件”就来了:一系列所谓的“注意块”(GPT-2有12个,ChatGPT的GPT-3有96个)。这一切都很复杂,类似于典型的难以理解的大型工程系统,或者说生物系统。但无论如何,这里是单个“注意块”的示意表示(适用于GPT-2):
notion image
在每个注意力块中,都有一组“注意力头”【attention head】(对于GPT-2有12个,对于ChatGPT的GPT-3有96个),每个头都独立地在嵌入向量的不同值块上运行。 (是的,我们不知道将嵌入向量分割成几个部分或不同部分的含义是什么好处,这只是已经“发现有效”的事情之一。)
那么注意力头是做什么的呢?基本上,它们是一种“回顾”token序列的方式(即迄今为止产生的文本),并将“过去的内容”以有助于找到下一个token的形式打包。在上面的第一部分中,我们谈到使用2-gram基于其直接前导词来选择单词。transformer中的“关注”机制允许“关注”甚至更早的单词,从而潜在地“捕获”和利用先前的词,例如,动词可以引用在它们之前许多个单词的名词的方式。
更详细地说,注意头所做的是重新组合与不同token相关的嵌入向量中的块,带有某些权重。因此,例如,第一个关注块(在GPT-2中的12个注意头)在上面的“hello,bye”字符串的“向后查看整个token序列的权重重新组合”模式如下:
notion image
在被注意力头处理后,生成的“重新加权嵌入向量”(对于GPT-2长度为768,对于ChatGPT的GPT-3长度为12,288)通过标准的“全连接”神经网络层传递。很难了解此层正在执行的操作。但是,以下是它正在使用的768×768权重矩阵的绘图(这里是GPT-2):
notion image
取64×64移动平均值,一些(随机漫步【指类似于布朗运动的随机扩散图案】)结构开始出现:
notion image
是什么决定了这种结构?最终,这可能是人类语言特征的一些“神经网络编码”。但是,现在,这些特征可能是未知的。实际上,我们正在“打开ChatGPT的大脑”(或至少是GPT-2),并且发现,是的,在那里,一切都很复杂,我们不理解它——即使最终它会产生可以识别的人类语言。
好的,在经过一个注意力块之后,我们得到了一个新的嵌入向量,然后依次通过其他注意力块(对于GPT-2总共有12个,对于GPT-3则有96个)。每个注意力块都有自己特定的“注意力”和“全连接”权重模式。这里是GPT-2的注意力权重序列,用于第一个注意力头的“hello,bye”输入:
notion image
这里是完全连接层的(移动平均)“矩阵”:
notion image
有趣的是,即使不同注意力块中的这些“权重矩阵”看起来相当相似,权重大小的分布也可能有所不同(并且并非总是高斯分布):
notion image
那么,在经过一个注意力块之后,transformer的净效应是什么?基本上,它是将token序列的原始嵌入集合转换为最终集合。而ChatGPT的特定方式是选择此集合中的最后一个嵌入,并“解码”它以产生下一个token的概率列表。
这就是ChatGPT内部的大致情况。它可能看起来很复杂(不仅仅是由于其许多不可避免地有些“任意的工程选择”),但实际上所涉及的最终元素非常简单。因为最终我们正在处理的只是一个由“人工神经元”构成的神经网络,每个神经元都执行简单的操作,即将一组数字输入与某些权重相结合。
ChatGPT的原始输入是数字数组(到目前为止的token的嵌入向量),当ChatGPT“运行”以产生新token时,就是这些数字“涟漪”通过神经网络的层,每个神经元“执行其任务”并将结果传递给下一层的神经元。没有循环或“回到”。一切都是“前馈”到网络中。
这与典型的计算系统(如图灵机)有很大不同,在这种计算系统中,结果会被相同的计算元素重复“重新处理”。至少在生成给定的输出token方面,这里的每个计算元素(即神经元)仅使用一次。
但从某种意义上说,在ChatGPT中仍然存在一种“外部循环”,即在每次生成新token时,它总是“读取”(即以输入形式)之前出现的所有token序列,包括ChatGPT自己先前“写入”的token。我们可以将此设置视为意味着ChatGPT至少在其最外层涉及一个“反馈循环”,尽管每个迭代都显式地显示为出现在它生成的文本中的token。
但是,让我们回到ChatGPT的核心:重复使用生成每个token的神经网络。在某种程度上,它非常简单:一整个相同人工神经元的集合。网络的某些部分仅由(“全连接”)神经元层组成,在这些层中,给定层上的每个神经元都与前一层上的每个神经元(以某些权重)相连。但是,特别是由于其transfomer体系结构,ChatGPT具有更多结构,其中仅在不同层上的特定神经元相连。(当然,仍然可以说“所有神经元都连接”——但是有些权重为零。)
此外,ChatGPT的神经网络中的一些方面并不自然地被认为只包含“同质”层。例如,正如上面的标志性摘要【即上面那个transfomer结构图】所示,在注意力块内部,存在着“多个副本”的地方,每个副本都通过不同的“处理路径”进行处理,可能涉及不同数量的层,然后再重新组合。但是,虽然这可能是正在发生的方便表示,但始终至少在原则上可以认为是“密集填充”层【注:原文如此】,但是只有一些权重为零。
如果看一下ChatGPT的最长路径,涉及大约400(关键的)层——在某些方面【和其他某些神经网络相比】不算很多。但是它有数百万个神经元,共计1750亿个连接,因此有1750亿个权重。需要认识到的一件事是,每次ChatGPT生成新token时,都必须进行一次涉及所有这些权重的计算。从实现角度来看,这些计算可以按照高度并行,可以方便地在GPU上完成。但对于每个生成的token,仍然必须进行1750亿次计算(实际比这还要多一点)——因此,不足为奇的是,使用ChatGPT生成一长段文本可能需要一些时间。
但最终,值得注意的是,所有这些操作——虽然它们本身非常简单——却可以一起以如此出色的“类似于人类”的方式生成文本。必须再次强调(至少就我们所知),没有“终极理论”可以预见到ChatGPT的设计对类似于对于自然语言这样的任何问题必然有效【但是事实上它就是很有效】。实际上,正如我们将要讨论的那样,我认为我们必须将其视为一项——潜在惊人的——科学发现:在像ChatGPT这样的神经网络中,以某种方式捕捉到了人类大脑在生成语言方面所能做到的本质。

ChatGPT 的训练

现在我们已经大致了解了 ChatGPT 设置完成后的工作流程。但是,它是如何配置的?那 1750 亿个神经元网络权重是如何确定的呢?这基本上是通过大规模的训练得出的,基于人类撰写的大量文本语料库——包括网页、书籍等。正如我们所说,即使有了这些训练数据,也不确定神经网络能否成功地生成“类似于人类”的文本。而且,为了实现这一点,需要进行详细的工程设计。但是,ChatGPT 的最大惊喜和发现是它是有可能实现的。事实上,一个“仅”具有 1750 亿个权重的神经网络可以生成人类撰写的“合理模型”文本。
在现代,有大量的人类文本以数字形式存在。公共网络上至少有几十亿人类撰写的页面,总共可能有约一万亿字的文本。如果包括非公开网页,数字可能会多至 100 倍。目前,已经有超过 500 万本数字化的书籍可供使用(尽管已出版约 1 亿本),另外提供了约 1000 亿个单词的文本。甚至还未提及来自视频等口语转换的文本。(作为个人比较,我一生中发表的文字总量少于 300 万字,过去 30 年来撰写的电子邮件总量约为 1500 万字,总共打出的字数可能达到 5000 万字——仅在过去几年里,我在直播中就已经讲了超过 1000 万个字。没错,我会从这些内容中训练一个机器人。)
好了,既然有了所有这些数据,如何从中训练神经网络呢?基本过程与我们在前面的简单例子中讨论的一样。您提供一批示例,然后调整网络中的权重,以使网络在这些示例上产生的误差(“损失”)最小化。 “反向传播”中的主要开销在于每次执行此操作时,网络中的每个权重通常都会发生微小的变化,并且需要处理大量的权重。(实际的“反向计算”通常只比前向计算复杂一个小常数因子。)
使用现代 GPU 硬件,可以并行计算数千个示例的结果。但是,当涉及实际更新神经网络中的权重时,目前的方法基本上要求一次一批地执行此操作。(是的,这可能是实际的大脑将计算和内存元素相结合的优势。)
即使在我们之前讨论过的学习数值函数的看似简单的情况下,我们发现通常需要使用数百万个示例才能成功训练网络,至少是从头开始。那么,为了训练一个“类人类语言”的模型,需要多少示例呢?理论上似乎没有任何根本的方式可以知道。但是在实践中,ChatGPT 成功地从数百万亿字的文本中进行了训练。
一些文本会被重复使用多次,而其他文本只会使用一次。但是,它以某种方式从看到的文本中“得到了它所需的”。但是,考虑到这么多的文本进行训练,需要多大的网络才能“很好地学习它”呢?同样,我们还没有根本的理论。最终——正如我们将在下面进一步讨论的——人类语言及其典型使用可能存在一定的“算法”。但是,下一个问题是,神经网络在实现基于该算法内容的模型时有多么高效;我们还不知道,尽管 ChatGPT 的成功表明它相当有效。
最后,我们可以注意到,ChatGPT 仅使用了约 2000 亿个权重就实现了它的工作。这个数字与它所接收的训练数据的总单词数(或token数)相当。在某种程度上,这也许令人惊讶(尽管 ChatGPT 的较小模型中也观察到了这一现象),即似乎“有效工作的网络大小”与“训练数据的大小”非常接近。毕竟,当然并不是“ChatGPT 内部”直接存储了来自网络和书籍等所有文本的某种形式。因为 ChatGPT 内部实际上包含一些数字,它们是所有这些文本的聚合结构的某种分布式编码,精度略低于 10 位数字。
换句话说,我们可能会问人类语言的“有效信息内容”是什么,以及人们通常使用它说些什么。有语言的原始语料库,以及 ChatGPT 的神经网络表示。该表示很可能远非“算法最小化”的表示形式(如下面所讨论的)。但这是一个神经网络可以轻松使用的表示形式。在这种表示中,似乎训练数据的压缩很少;平均而言,基本上要略少于一个神经网络权重才能承载一个训练数据单词的“信息内容”。
当我们运行 ChatGPT 生成文本时,我们基本上必须使用每个权重一次。因此,如果有 n 个权重,则我们需要大约 n 个计算步骤。虽然在实践中,其中许多计算步骤可以在 GPU 中并行处理。但是,如果我们需要大约 n 个训练数据单词来设置这些权重,那么根据我们上面的说法,我们可以得出结论,我们需要约 n² 个计算步骤来训练网络。这就是为什么,使用目前的方法,我们最终需要数十亿美元进行训练工作。

超越基本训练

在训练ChatGPT时,大部分的工作都是向它展示大量来自网络、书籍等现有文本。但结果表明还有另一部分也非常重要。
当神经网络内部的ChatGPT从展示的原始文本语料中完成“原始训练”后,它就可以开始生成自己的文本,并从提示等继续生成。但对于较长的文本,尤其是“漫游”在非人类化的方式【指生成了不符合人类习惯,无法有效交互的文本】,结果通常似乎合理,但实际上并不是一般通过传统文本统计分析可以轻易检测到的。但是,人类读者很容易注意到这点。
ChatGPT构建的一个关键思路是,在像网络这样的事物上“被动阅读”之后,还需要一个人类与其进行积极交互的步骤,查看它的产生结果,并实际上为“如何成为良好聊天机器人”提供反馈。但是,神经网络如何使用这个反馈呢?第一步只是让人类评估神经网络的结果。但是,接着构建另一个神经网络模型,试图预测这些评分。现在,这个预测模型可以被运行,实际上就像一个损失函数,可以调整原始网络,从而允许网络通过人类反馈进行“调整”。在实践中,这似乎对系统产生“类似人类”的输出成功有很大影响。
总的来说,有趣的是,为了让网络朝特定方向有用地发展,它似乎只需要被“戳”很少次。有人可能认为,为了使网络表现得好像“学到了一些新东西”,就必须运行训练算法,调整权重等等。
但实际情况并非如此。相反,似乎只需在您给出的提示的一部分中命令ChatGPT一次,然后它就可以成功地利用您告诉它的内容来生成文本。再一次,这种工作方式是我认为理解ChatGPT“真正做什么”以及它如何与人类语言和思维结构相关的重要线索。
这确实有一些类似人类的特点:至少在它完成了所有这些预先训练之后,您只需告诉它一次东西,它就可以“记住”它——至少“足够长时间”来使用它来生成文本。那么在这种情况下到底发生了什么呢?可能“您要告诉它的所有内容已经在那里的某个地方”——您只是引导它到正确的位置。但这似乎是不合理的。相反,更有可能的是,是的,元素已经存在,但具体内容是由像“这些元素之间的轨迹”这样的东西定义的,这就是当您告诉它某些内容时引入的内容。
事实上,与人类一样,如果您告诉它某些古怪和意外的内容,完全不符合它所知道的框架,那么它似乎无法成功地“整合”它。只有在它基本上沿着它已经拥有的框架简单地运行时,它才能“整合”它。
还值得再次指出,神经网络本身有些必然的算法限制。Tell it “shallow” rules of the form “this goes to that”, etc.【这句无法翻译】,神经网络很可能能够很好地表示和重现这些规则,实际上,它将从语言中“已经知道的”为它提供一个立即遵循的模式。但是,尝试涉及不可规约步骤的计算时,它就不起作用了。 (请记住,在每个步骤中,它总是只是在其网络中“向前传递数据”,除了生成新token之外,从不循环。)
当然,网络可以学习特定的“不可规约”计算的答案。但是一旦有组合数量的可能性,这种“表查找式”方法将无法工作。因此,就像人类一样,现在是神经网络“到达”并使用实际计算工具的时候了。 (是的,Wolfram|Alpha和Wolfram Language非常适合,因为它们已经被构建成“谈论世界上的事物”,就像语言模型神经网络一样。)

什么让ChatGPT成功运作?

人类语言——以及生成语言所涉及的思维过程——一直被视为复杂性的巅峰。事实上,人类大脑的“仅仅”1000亿左右的神经元(或许有1万亿条连接)能够担当起这个任务似乎有些惊人。或许,人们可能会想象,大脑不仅仅是由神经元网络构成——还存在一些未被发现的新物理层面。但是,现在有了ChatGPT,我们获得了重要的新信息:我们知道一个拥有与大脑神经元数量相当的连接数的纯人工神经网络能够惊人地生成人类语言。
是的,这仍然是一个庞大而复杂的系统——其神经网络权重数量大约与当前世界上可用文本的单词数量相同。但在某种程度上,仍然难以置信的是,语言的丰富性以及它所能谈论的事情可以被封装在这样一个有限的系统中。部分原因无疑是由于普遍现象(最早在规则30的例子中变得明显):即使它们的基础规则很简单,计算过程实际上可以大大增加系统的表面复杂度。但是,正如我们上面讨论的那样,ChatGPT中使用的神经网络倾向于特别构建以限制这种现象的影响——以及与之相关的计算不可简化,以使其培训更易于访问。
那么,像ChatGPT这样的东西是如何实现语言的?我认为,基本的答案是,从根本上说,语言在某种程度上比它看起来要简单。这意味着,即使ChatGPT最终采用了直截了当的神经网络结构,它仍然能够成功地“捕捉到”人类语言和背后的思维精髓。此外,在培训过程中,ChatGPT以某种方式“隐含地发现”了使这一切成为可能的语言(和思维)中的任何规律。
我认为,ChatGPT的成功给我们提供了一个基础而重要的科学证据:它表明,我们可以期望发现重大的新“语言法则”——以及有效的“思考法则”。在ChatGPT中——作为神经网络构建——这些法则充其量是隐含的。但是,如果我们能够以某种方式使法则显式,就有可能以更直接、高效和透明的方式做出ChatGPT所做的那种事情。
那么,这些法则可能是什么样子的呢?最终,它们必须为我们提供一种如何组合语言——以及我们用语言说的事情——的指导。稍后我们将讨论如何“查看ChatGPT内部”可能会给我们一些关于这方面的提示,以及从构建计算语言的知识中得出的前进道路。但首先,让我们讨论两个长期以来已知的“语言法则”的例子——以及它们如何与ChatGPT的操作相关。
第一个是语言的语法。语言不仅仅是随机的单词混杂在一起。相反,对于不同类型的单词如何组合,有(相当)明确的语法规则:在英语中,例如,名词可以由形容词前缀和动词后缀组成,但通常两个名词不能紧挨着。这样的语法结构可以(至少近似地)通过定义“分析树”的一组规则来捕获:
notion image
ChatGPT并没有显式地“知道”这些规则,但在训练过程中它隐式地“发现”了它们,然后似乎很擅长遵循这些规则。那么这是如何实现的呢?从“宏观”层面来看并不清楚,但是通过一个简单的例子来获得一些洞见可能会很有帮助。
考虑一个由 “( ” 和 “ )” 序列组成的“语言”,其语法规定括号应该始终保持平衡,如下所示的解析树:
notion image
我们能训练神经网络来生成“符合语法”的括号序列吗?神经网络中有多种处理序列的方法,但我们将使用transformer网络,就像ChatGPT一样。并且,给定一个简单的transformer网络,我们可以将正确的括号序列作为训练样本进行训练。一个微妙之处(实际上也出现在ChatGPT生成人类语言的过程中)是,除了“内容token”(这里是“(”和“)”)之外,我们还必须包括一个“结束”token,表示输出不应继续下去(即对于ChatGPT而言,到达了“故事的结尾”)。
如果我们设置一个只有一个注意块的transformer网络,带有8个头和长度为128的特征向量(ChatGPT也使用长度为128的特征向量,但具有96个注意块,每个注意块都有96个头),那么似乎不可能让它学到很多关于括号语言的知识。但是使用2个注意头,学习过程似乎会收敛——至少在给出了1000万个左右的示例后是这样的(正如transformer网络的常见情况,显示更多的示例似乎只会降低其性能)。
因此,对于这个网络,我们可以进行类似ChatGPT的操作,询问下一个token应该是什么的概率——在括号序列中:
notion image
在第一种情况下,网络“非常确定”序列不能在这里结束——这很好,因为如果结束了,括号就会不平衡。然而,在第二种情况下,它“正确地识别”序列可以在这里结束,尽管它也“指出”了可以“重新开始”,放置一个“(”,可能跟着一个“)”。但是,糟糕的是,即使有它那辛苦训练的约40万个权重,它也说下一个token有15%的概率是“)”——这是不正确的,因为这必然会导致括号不平衡。
如果我们要求网络为逐渐变长的(序列生成具有最高概率的完成情况,那么我们会得到以下结果:
notion image
是的,神经网络在一定长度范围内表现良好。但是当它需要执行更复杂的“算法”任务时,例如明确计算括号是否闭合,神经网络往往“计算能力太浅”而难以可靠地执行。即使是目前完整的ChatGPT也难以正确匹配长序列中的括号。
那么,这对像ChatGPT这样的应用程序以及英语这种语言的语法意味着什么?括号语言更加“简约” - 更像是一种“算法式的”语言。但是在英语中,基于单词的本地选择和其他提示,能够“猜测”语法上的合理性。是的,神经网络在这方面表现更好 - 即使它可能会错过某些“形式上正确”的情况,人类也可能会错过。但是主要的观点是,语言具有整体语法结构 - 具有所有规律性的含义 - 在某种程度上限制了神经网络需要学习的“程度”。神经网络中的变压器架构似乎成功地学习了嵌套树状语法结构的类型,这种结构似乎存在于所有人类语言中(至少近似如此)。
语法为语言提供了一种约束。但是还有其他方面。像“好奇的电子吃蓝色理论换鱼”这样的句子在语法上是正确的,但这不是人们通常期望说的话,如果ChatGPT生成了这种句子,它不会被认为是成功的 - 因为,嗯,它基本上是没有意义的。
但是,有没有一种通用的方法可以判断一个句子是否有意义?传统上没有总体理论。但是在通过数十亿(可能有意义的)网络句子等进行训练后,可以将ChatGPT看作是在隐含地“开发出一种理论”。
这个理论可能是什么样子?嗯,有一个小角落基本上已知了两千年,那就是逻辑。当然,在亚里士多德发现它的三段论形式中,逻辑基本上是一种说法,即遵循某些模式的句子是合理的,而其他句子则不合理。因此,例如说“All X are Y. This is not Y, so it's not an X.”(如“All fishes are blue. This is not blue, so it's not a fish.”)是合理的。就像人们可以想象亚里士多德通过(“机器学习式”的)许多修辞例子来发现三段论逻辑一样,我们也可以想象在ChatGPT的训练中,它通过查看网络文本等大量信息,能够“发现三段论逻辑”。(是的,尽管人们可以预期ChatGPT会产生基于三段论逻辑的“正确推论”,但是当涉及到更复杂的形式逻辑时,情况就不同了 - 我认为它会因为与括号匹配相同的原因而失败。)
但是在逻辑的狭隘例子之外,还有什么关于如何系统地构建(或识别)甚至是合理的文本?是的,有像Mad Libs这样使用非常特定的“短语模板”的东西。但是不知怎的,ChatGPT隐含地具有一种更普遍的方式。也许除了“当您拥有1750亿个神经网络权重时,不知怎样就会发生”之外,无法说明如何做到这一点。但我强烈怀疑有一个更简单、更强大的答案。

意义空间和语义运动规律

我们上面讨论了在ChatGPT中,任何文本都被有效地表示为一个数字数组,我们可以将其视为在某种“语言特征空间”中的点的坐标。因此,当ChatGPT继续一段文本时,这相当于在语言特征空间中跟踪轨迹。但现在我们可以问一下,是什么使这条轨迹对应于我们认为有意义的文本?或者或许有一些“语义运动规律”来定义或者至少限制了在语言特征空间中点的移动,同时保持“有意义性”?
那么这个语言特征空间是什么样的呢?这是一个单词(这里是普通名词)可能被放置的2D空间的例子:
notion image
我们之前看到了另一个例子,基于表示植物和动物的单词。但是两种情况都是“语义相似的单词”被放置在附近。
另一个例子是,不同的词性所对应的单词被放置如下:
notion image
当然,一个特定的单词通常不仅仅有“一个意思”(或者不一定仅仅对应于一个词性)。通过观察包含一个单词的句子在特征空间中的位置,我们通常可以“拆分”不同的含义,就像这个单词““crane” (bird or machine?)【鸟类还是机器】的例子:
notion image
所以,我们可以认为这个特征空间将“语义相近的单词”放在空间中的相近位置。但是,我们可以在这个空间中识别出什么样的附加结构呢?例如,有一种“平行运输”的概念可以反映空间的“平坦性”吗?了解这一点的一种方法是看类比:
notion image
是的,即使当我们将其投影到2D时,通常至少会有一些“平坦的暗示”【hint of flatness】,尽管它肯定不是普遍存在的。
那么关于轨迹呢?我们可以查看在特征空间中ChatGPT的提示所跟踪的轨迹,然后我们可以看到ChatGPT是如何继续的:
notion image
这里显然没有什么“几何上明显”的运动规律。这并不奇怪;我们完全期望这是一个相当复杂的故事。例如,即使有“语义运动规律”,也并不明显它最自然地被陈述在哪个嵌入(或者实际上是哪些“变量”)中。
在上面的图中,我们展示了“轨迹”的几个步骤,每个步骤我们都选择ChatGPT认为最有可能的单词(“零温度”情况)。但我们也可以问在给定点上下一个可能是哪些单词,以及其概率是多少:
notion image
在这种情况下,我们看到有一个高概率单词的“扇形”,似乎在特征空间中沿着一个或多个明确的方向。如果我们继续下去会发生那么,如果我们再进一步呢?这是我们“沿着”轨迹移动时出现的连续“扇形”:
notion image
这是一个3D表示,一共走了40步:
notion image
是的,这看起来很混乱,并没有特别鼓励我们的想法,即通过经验研究“ChatGPT在内部做什么”来识别“类似数学物理的”“语义运动规律”。但也许我们只是看错了“变量”(或坐标系)。如果只看对了,我们将立即看到ChatGPT正在做“数学物理简单”的事情,如遵循测地线。但到目前为止,我们还没有准备好从其“内部行为”中“经验性解码”ChatGPT已经“发现”的关于人类语言“组合”的知识。

语义语法和计算语言的威力

要产生“有意义的人类语言”,需要什么条件?过去,我们可能认为这只有人脑才能做到。但现在我们知道,ChatGPT的神经网络可以相当地做到这一点。但是,也许这就是我们能做到的最远的程度了,没有什么更简单、更易于理解的方法可以使用。但我强烈怀疑,ChatGPT的成功暗示了一个重要的“科学”事实:有意义的人类语言实际上比我们所知道的要简单得多,最终可能会有相当简单的规则描述这种语言如何组合起来。
正如我们上面提到的,句法语法给出了关于不同词性的词汇如何组合成人类语言的规则。但是为了处理含义,我们需要更进一步。其中一种方法是不仅考虑语言的句法语法,还要考虑语义语法。
为了句法,我们确定了名词和动词等词性。但为了语义,我们需要“更细微的程度”。例如,我们可以确定“移动”的概念,以及“对象”的概念,该对象“独立于位置维护其身份”。每个这些“语义概念”都有无穷无尽的具体例子。但为了我们的语义语法,我们将只有一些一般规则,基本上是说“对象”可以“移动”。有很多关于如何使所有这些工作的方式(我之前已经说过的一些)。但是在这里,我只会满足于简要说明一些潜在的前进道路。
值得一提的是,即使一句话在语义语法上是完全可以的,也不意味着它在实践中已经被实现(甚至可能无法实现)。例如,“大象前往月球”无疑可以通过我们的语义语法,但它肯定还没有在我们的实际世界中实现(至少还没有),尽管它绝对可以在虚构的世界中使用。
当我们开始谈论“语义语法”时,我们很快会问“它的下面是什么?”它假设了什么“世界模型”?句法语法实际上只涉及从词汇中构建语言的方式。但语义语法必然涉及某种“世界模型”——一种作为“骨架”的东西,可以在其上添加由实际词汇构成的语言。
直到最近,我们可能认为(人类)语言是描述我们“世界模型”的唯一一般方法。几个世纪前,已经开始基于数学对特定类型的事物进行形式化。但现在有一种更普遍的形式化方法:计算语言。
是的,这是我在四十多年的时间里一直致力于的大型项目(现在体现在 Wolfram 语言中):开发一种精确的符号表示,可以尽可能广泛地谈论世界上的事物,以及我们关心的抽象事物。因此,例如,我们为城市、分子、图像和神经网络提供符号表示,并且我们具有关于如何计算这些事物的内置知识。
经过几十年的工作,我们已经以这种方式涵盖了许多领域。但过去,我们没有特别处理“日常语言”。在“我买了两磅苹果”中,我们可以轻松地表示(并对“两磅苹果”进行营养计算和其他计算),但我们(还不完全)有一个符号表示为“我买了”。
这一切都与语义语法的概念有关,以及拥有概念的通用符号“构建工具包”的目标,该工具包将为我们提供关于什么可以与什么配合使用的规则,从而确定我们可能转换为人类语言的“流”。
但假设我们拥有了这种“符号话语语言”。我们会用它做什么?我们可以开始做生成“局部有意义文本”的事情。但最终,我们可能会希望获得更多“全局有意义”的结果,这意味着“计算”有关实际可以存在或发生的事物的更多信息,(或者在某个一致的虚构世界中)。
现在在 Wolfram 语言中,我们拥有大量内置的关于许多事物的计算知识。但对于完整的符号话语语言,我们需要在世界上建立额外的“计算规则”:如果一个物体从 A 移动到 B,从 B 移动到 C,那么它已经从 A 移动到 C 等等。
给定符号话语语言,我们可以使用它来做出“独立的陈述”。但我们也可以使用它像“Wolfram|Alpha 风格”那样询问世界。或者我们可以使用它陈述我们“想要使其成为现实的”事情,可能具有某种外部激活机制。或者我们可以使用它来做出断言——可能是关于实际世界的,也可能是关于我们正在考虑的某个特定世界,无论是虚构的还是其他。
人类语言基本上是不精确的,不仅因为它没有“绑定”到特定的计算实现,而且它的意义基本上只由其用户之间的“社会契约”定义。但是,由于计算语言的本质,它具有一定的基本精度——因为最终它指定的内容始终可以“在计算机上明确执行”。人类语言通常可以逃脱一定的模糊性。(当我们说“行星”时,它是否包括外行星等?)但在计算语言中,我们必须准确而清晰地区分我们所做的所有区别。
通常在计算语言中使用普通人类语言来构建名称是很方便的。但是,它们在计算语言中的含义必须是精确的,可能会或可能不会涵盖典型人类语言用法中的某些特定内涵。
如何找出适用于一般符号话语语言的基本本体论?嗯,这并不容易。这也许就是为什么自亚里士多德两千多年前的原始开端以来,这些工作还很少有所成就的原因。但现在我们对如何以计算的方式思考世界有了很多了解(这并不妨碍我们从Physics Project和ruliad的“基本形而上学”【fundamental metaphysics】中获得帮助)。
但在ChatGPT的上下文中,这意味着什么呢?从训练中,ChatGPT已经有效地“拼凑出”了一定数量的语义语法(相当令人印象深刻)。但它的成功让我们有理由认为,构建更完整的计算语言形式是可行的。并且,与我们到目前为止已经发现的关于ChatGPT内部的东西不同,我们可以期望设计计算语言,使其易于人类理解。
当我们谈论语义语法时,我们可以将其比作三段论逻辑。起初,三段论逻辑本质上是关于用人类语言表达的陈述的一系列规则。但(是的,两千年后),当形式逻辑被发展出来时,三段论逻辑的原始基本结构现在可以用来构建巨大的“正式塔”,包括现代数字电路的运算。因此,我们可以期望更普遍的语义语法也将如此。起初,它可能只能处理简单的模式,例如文本。但是,一旦整个计算语言框架建立起来,我们可以期望它将能够用于建立高大的“广义语义逻辑”塔,使我们能够以精确和正式的方式处理以前从未能够接触到的各种东西,除了通过人类语言的“底层水平”,带有所有其模糊性。
我们可以认为计算语言和语义语法的构建代表了一种最终的压缩,以表示事物。因为它允许我们谈论可能性的本质,而不必处理存在于普通人类语言中的所有“措辞变化”。我们可以认为ChatGPT的巨大优势也是类似的:因为它已经在某种意义上“钻研到”可以“将语言以语义有意义的方式组合起来”的程度,而不必关心不同的措辞变化。
那么如果我们将ChatGPT应用于底层计算语言会发生什么?计算语言可以描述可能性。但是仍然可以添加一种“流行”的感觉,例如基于阅读网络上所有内容的数据。但是,然后,在底层操作计算语言意味着像ChatGPT这样的系统立即获得对于利用潜在的不可约计算的终极工具的根本访问。这使得它不仅可以“生成合理的文本”,而且可以预期了解关于该文本是否实际上对世界或它所讨论的任何事情做出了“正确”的陈述,或者任何其他应该讨论的事情。

那么……ChatGPT是在做什么,为什么它有效?

ChatGPT的基本概念在某种程度上相当简单。从网络、书籍等来源中获取大量人类创作的文本样本。然后训练神经网络生成“类似”的文本。特别是让它能够从“提示”开始,然后继续生成“类似于训练内容”的文本。
正如我们所见,ChatGPT中的实际神经网络由非常简单的元素组成,尽管有数十亿个。神经网络的基本操作也非常简单,基本上是为每个新单词(或单词部分)生成“输入”,然后将其“通过其元素”(没有任何循环等)。
但是,这个过程能够产生成功地“类似于”网络、书籍等内容的文本,这是非常卓越和出乎意料的。它不仅是连贯的人类语言,而且“说的话”是“遵循其提示”的,利用其“读到”的内容。它并不总是说出“全局意义上的话”(或对应于正确的计算),因为(例如,没有访问Wolfram|Alpha的“计算超能力”)它只是根据训练材料中的“声音类似”的东西“说出”“听起来正确”的东西。
ChatGPT的具体工程使其相当引人入胜。但是,最终(至少在它可以使用外部工具之前),ChatGPT仅仅从它积累的“传统智慧统计数据”中提取了一些“连贯的文本线索”。但是,其结果有多么类似于人类。正如我所讨论的,这表明了一些至少在科学上非常重要的事情:人类语言(以及背后的思维模式)的结构比我们想象的要简单和更具有“法律属性”。ChatGPT已经隐含地发现了它。但是我们可能可以用语义语法、计算语言等明确地揭示它。
ChatGPT在生成文本方面的表现非常出色,结果通常非常接近我们人类所产生的。那么这是否意味着ChatGPT像大脑一样工作呢?它的基本人工神经网络结构最终是基于大脑的理想化模型的。当我们人类生成语言时,许多方面的工作似乎是相当相似的,这似乎是非常可能的。
但是,当涉及到训练(也就是学习)大脑和当前计算机的不同“硬件”(以及可能的未开发算法思想)时,ChatGPT需要使用一种可能相当不同(并且在某些方面效率远低于)大脑的策略。还有另一件事:与典型的算法计算甚至不同,ChatGPT内部没有“循环”或“重新计算数据”。这不可避免地限制了它的计算能力,甚至相对于当前的计算机,但绝对相对于大脑。
目前尚不清楚如何“解决这个问题”并且仍然保持训练系统具有合理效率的能力。但是这样做可能会让未来的ChatGPT能够做更多“类似于大脑的事情”。当然,有很多大脑做得不太好的事情,尤其是涉及到相当于不可约计算的内容。对于这些问题,大脑和ChatGPT这样的东西都必须寻找“外部工具”——例如Wolfram语言。
但现在看到ChatGPT已经能够做到的事情是令人兴奋的。在某种程度上,它是一个绝佳的基本科学事实,即大量简单的计算元素可以做出令人惊讶和意想不到的事情。但它也为我们在两千年内对人类语言和背后的思维过程的基本特征和原则有更好的理解提供了最好的动力。
 
解析Tansformer模型—理解GPT-3, BERT和T5背后的模型我为什么总关注烂人身上的事?
Loading...