📱

Get Our Mobile App

Take your business learning on the go!

Download on the App StoreGet it on Google Play

LLM Lecture: A Deep Dive into Transformers, Prompts, and Human Feedback

AI Coffee Break with Letitia1:31:09

Transcription

[音乐] 大家好,这不是人工智能咖啡时间,而是一场关于大型语言模型(简称 LLM)的完整讲座。因为今天我们想为您提供一个关于理解当今大型语言模型所需了解的全部内容的概述。因此,讲座的第三部分将是关于 Transformer 架构,因为自 2017 年以来,Transformer 一直是 LLM 的骨干,而自 2020 年以来开始出现的技巧使得 Transformer LLM 达到了 ChatGPT 的水平,并因此登上了新闻头条,但最重要的是,它让 LLM 进入了每个人的手中。因为我认为我不需要问您今天是否使用过任何大型语言模型,例如 ChatGPT、Claude、Llama 或许多其他模型。因此,我在这里详细列出了我们将要涵盖的内容,这并非要用整个列表来吓唬您,而是为了帮助您浏览视频。我们将使用章节来标记我们解释的每个内容。如果您认为“啊,我想了解一些关于组织的内容”,那么您可以跳转到视频中的相应部分;或者如果您说“我想了解一些关于检索增强生成或指令调优的内容等等”,那么您可以跳转到视频中的相应部分。因此,为了设定您的期望,在此视频中,我们已经汇编并分解了您需要了解的关于当今 LLM 的所有组件。但请允许我告诉您,制作和编辑这样的视频需要我付出很多技巧,而我需要训练这样的技巧,幸运的是,我身边有 Skillshare 来帮助我提升。在 Skillshare 上,我向 Marcus Brownlee 等顶尖 YouTuber 学习 YouTube 和视频制作的所有知识,向 Maggie Stara 学习所有与社交媒体发布相关的内容,这样你们就能了解我制作的视频。因此,如果您也想学习这些技能,或者您心中有任何其他创意热情,例如电影、插画、设计、自由职业生产力等等,请查看本视频的赞助商 Skillshare。那里是最大的创意学习社区,您可以向行业专家学习数千门课程。我知道数千门课程一开始可能很难浏览和整理,但不用担心,因为如果您想掌握一项特定技能,Skillshare 有学习路径,这些是为该特定技能精心策划的课程合集。您还在等什么?通过 Skillshare 将您的创意热情提升到一个新的水平。前 500 名使用下方描述中我的链接的人将获得一个月的 Skillshare 免费试用。顺便说一句,您也可以扫描此二维码获取链接。立即开始使用 Skillshare,获取您创意热情所需的技能。现在回到我们关于大型语言模型的讲座。好的,让我们开始解释 Transformer 架构。Transformer 是相同的 Transformer 层堆叠而成,就像任何深度学习架构一样,我们一层一层地堆叠,因为我们希望从输入表示中获得更好的输出表示。对于 Transformer 来说,输入表示通常是向量。在深度学习中,您可以拥有向量或更高维度的向量,即矩阵,或更高维度的矩阵,即张量。但对于 Transformer 来说,这是最简单的形式,您可以想象,即这些向量,我们一层一层地应用,希望最终这些表示比我们开始时拥有的表示更好。表示好意味着什么呢?这意味着这里的解空间显然代表了我们问题的解决方案,或者用深度学习的术语来说,这意味着这个表示空间是线性的可分的,与我们的任务相关。为了解释这一点,让我们先定义一个任务,比如这里可能是什么任务呢?我们正在制作大型语言模型,所以让我们考虑一个简单的低维度任务来可视化。我们想判断单词“well”是否是像这样的句子的合理续写。我们可以用“well”替换“CLS”吗?是或否,这基本上就是我们这里的二元决策任务。对于这个解空间来说,显而易见意味着我们有一个线性的可分空间,即其中所有句子——分类标记,所有以“well”结尾的句子的 CLS 表示都位于空间的一侧,而所有不以“well”结尾的句子的 CLS 标记的表示(双关语)则位于表示空间的另一侧,这样我们就可以仅使用线性分离来区分这些句子。当我们查看分类标记时,我在这里冒昧地将这个四维空间表示为二维空间,但这只是为了可视化目的,这里没有降维。这就是我们在所有 Transformer 层之后对这些更好的表示的期望,而对于初始表示,我们期望这样的空间不是线性的可分的,所以我们任务的解决方案,即“well”是否是这个句子可能续写,在这里并不明显。是的,这就是为什么我们要进行所有这些 Transformer 层来获得更好的表示。简而言之,Transformer 层将 L 维向量映射到其他 L 维向量。但是,现在我们知道 Transformer 层以向量作为输入,对于语言模型来说,自然而然的问题就出现了:如何将文本表示为向量?文本是离散的,文本是符号化的,而向量是连续的。那么如何转换呢?我们可以采用一种朴素的想法,看看这种朴素的想法能走多远,直到我们不得不修复它。也就是说,我们可以先查看训练语料库中的所有单词,创建一个词汇表,我们在这里有“mother”和“attention”以及我们遇到的任何其他单词。我们可以创建一个字典,这样我们就可以为每个单词分配一个单词 ID,并为每个单词 ID 分配一个唯一的单词嵌入。问题是,哪个唯一的单词嵌入?这并不重要,可以随机初始化,我们可以在训练过程中更新这些单词嵌入。但是,显而易见的问题是,我们将有一个有限的训练语料库,因此在测试时,当用户与这样的模型交互时,我们会遇到新词的问题,即那些在我们的训练语料库中根本不存在的词。而且显然会有拼写错误,因为人们写东西很糟糕,里面会有拼写错误,所有这些新词都将映射到一个未知标记,并具有相同的单词嵌入。对于这些未知词来说,这不是一个好的语义表示。因此,我们必须以某种方式制定一个分词策略,使得新词也能获得尽可能多的语义表示。所以这里的解决方案是分词。分词意味着我们现在由子词组成的词汇表,我们将称之为标记。其思想是让常用词成为子词词汇表的一部分,但将稀有词拆分成子组件。这些子组件有时会令人费解,但这就是想法。例如,我们将“mom”拆分成“m”和“oom”,然后“m”获得 26 个标记 ID,另一个“m”获得相同的标记 ID,然后它们将获得相同的单词嵌入,依此类推。在最坏的情况下,基本上单词中的每个字符都会成为一个子词。但是,如何分词呢?将所有这些单词拆分成子词的算法是什么?有许多分词器,例如字节对编码(Byte Pair Encoding),我将解释它,因为它现在是 Llama 等模型使用的一种最流行的分词器。这里的这个分词器有一个训练阶段。这个分词器的训练阶段与我们深度学习模型、我们的 Transformer 的训练非常不同。它发生得更早。因此,在这里,在我们的分词器训练中,我们基本上定义了一个目标词汇表大小,我们说我们想要 50,000 个标记在我们的词汇表中,然后我们从所有字符作为单独标记的集合开始。坦率地说,在字节对编码中,它不是字符,而是字节,所以是 0 到 255。一个字符可以表示为字节或多个字节。然后,我们逐渐合并训练数据中一起出现的频率最高的标记对,并存储由此产生的新标记和合并规则。当达到所需的标记数量时,训练就完成了。因此,使用这种训练过的分词器对文本进行编码,BPE 基本上会将输入拆分成单个字符,正如我所说,这不完全是字符,而是字节,然后应用最低级别的合并规则,直到不再适用。除了字节对编码之外,还有许多其他分词器,例如 unigram、sentencepiece、基于字符的、基于 n-gram 的等等。有趣的是,有一段时间关于分词器的研究有点无聊,没有太多进展,但尤其是在 2024 年,分词器的研究呈爆炸式增长,尤其是现在有许多方法可以稍微“分词器化”一些。如果您对此感兴趣,我可以制作一个专门的视频。所以请在评论中告诉我。好的,现在我们对如何将文本表示为向量有了一个想法,我们的 Transformer 层就满意了,只要它们接收向量作为输入,我们就可以看到这个 Transformer 层是关于什么的。所以,让我们从其基本组件构建 Transformer 层。我们将从添加一个对深度学习爱好者来说非常熟悉的组件开始,即前馈神经网络,也称为 vanilla 神经网络或全连接神经网络。基本上,这个前馈神经网络应用于我们输入中的每个标记,并且总是应用于每个标记的同一个神经网络。它看起来是怎样的呢?基本上,我们有一个多层感知器层,它将输入维度的维度加倍,然后是 Gated Linear Unit 激活,然后我们有另一个层,它将输入缩小回原始维度。最重要的是,这里有一个权重共享的概念,即我们应用于此标记的权重与应用于每个其他标记的权重相同。您可能知道这个权重共享的概念来自卷积神经网络,但它基本上也是 Transformer 中一个非常重要的概念,因为如果您像这样共享权重,并且您有相同的神经网络并行应用于每个标记,您可以并行完成所有这些标记的计算。这与循环神经网络非常不同,循环神经网络是处理第一个标记,然后第一个标记的输出会进入第二个标记的输入,这意味着第二个标记必须等待第一个标记的计算完成才能继续处理,依此类推。所以,如果您顺序阅读维基百科,您可能需要几周时间才能读完。因此,在 Transformer 出现之前的语言模型,它们是基于循环网络的,但它们花费了大量时间来处理维基百科这样的文本。然后当 Transformer 出现时,它们可以并行运行多个标记的所有这些计算,这意味着您突然可以比循环神经网络花费更少的时间阅读维基百科。如果您觉得“哦,好吧,几天后我已经读完了维基百科,那么让我们读一些新闻,读一些更多的文章,读一些书,读整个互联网”。因此,Transformer 的架构优势基本上是这种并行计算,它允许 Transformer 神经网络比之前的循环神经网络更快地处理更多数据。通常,对于这些网络来说,您摄入的数据越多越好,模型的性能就来自于此。所以,这里是权重共享和并行计算以及 Transformer 的重要概念。现在我们将关闭这个可视化,并将之前看到的所有权重总结在一个框中,用于前馈神经网络。现在的问题是我们是否完成了 Transformer 架构,答案是否定的,因为这里缺少一些非常重要的组件,即一种方式让这个标记,例如,知道它共享一些公司,这里的“works”不是一个孤立的词,因为这个前馈神经网络将独立于所有其他表示来处理这些表示。这不好,这个表示不能成为“works”的更好表示,因为它没有关于它所处的公司(即上下文)的概念。在分布语义学中,一个非常重要的概念是单词的含义很大程度上取决于它们所处的公司。因此,我们需要一种机制来让信息在标记之间流动,让标记和表示知道它们所处的公司。为此,Transformer 使用的一种非常普遍的机制是自注意力机制。自注意力是一种加权平均,但它是一种非常重要的加权平均,因为它是一种数据依赖的加权平均。因此,自注意力基本上告诉我们,要计算这个标记的表示,我们将从这个标记获得 80%,从这个标记获得 15%,从这些标记获得 5%。它将进行这种加权平均,但非常重要,这也是自注意力如此强大的原因,这些加权平均的权重不是预先确定的,它们是数据依赖的。因此,这 80% 非常取决于“attention”和“works”的表示。所以,让我们看看它是如何工作的,首先,让我们看看自注意力和注意力之间的区别。自注意力是指我们在一个序列和它本身之间计算注意力。因此,在这里,为了计算“it”标记的注意力,我们将查看同一序列中的所有标记,并看到我们必须在平均值中包含很多这个标记的值,很多这个标记的值,而其他标记的值则不多。这就是自注意力,当我们计算序列内部的注意力时。但是,注意力是指当我们拥有基本上相同的机制,但是在一个序列和一个另一个序列之间。在这里,注意力在机器翻译中非常常用,我们有一个句子用一种语言,以及相同的句子用另一种语言。在这里,我们计算为了计算这个标记的表示,我们必须从另一个句子获取多少信息。但是,在这里,在普通的 Transformer 层中,我们有自注意力。自注意力基本上告诉我们,我们需要进行多少数据依赖的加权平均。所以,让我们看看如何计算这种加权平均的数据依赖权重。这基本上就是大量的线性代数,我知道这会有点复杂,但我们已经尽力使其尽可能简单。好的,为此,让我们深入研究自注意力。在自注意力中,我们需要做的第一件事就是获取标记 X1 的表示,并将其乘以一个所谓的查询矩阵。现在的问题是,这个查询矩阵是什么样的?它必须具有正确的形状,但除此之外,它是随机初始化的,然后学习过程和随机梯度下降将更新这些矩阵的条目。所以我们有查询矩阵,并将其乘以我们输入标记的表示,我们将得到一个称为查询的向量。我们做同样的事情,我们再次应用相同的矩阵,权重共享。我们将相同的查询矩阵应用于我们输入的所有其他表示。然后我们完成了查询的生成。现在我们为每个输入标记都有了查询。现在我们来看键。所以,现在我们将有一个不同的矩阵,称为键矩阵,其值与查询矩阵不同,也是随机初始化的,并且在训练过程中将被学习。我们将将其乘以我们输入的表示,我们将得到键。所以,这里是第二个标记的键,依此类推。然后,如果我们完成了,我们还将获取一个值矩阵,并将其乘以所有输入表示,然后我们将得到我们输入中每个表示的值。也许您已经注意到了幻灯片中的错误,如果没有,我将立即为您纠正。为了真正正确地进行乘法,我们需要将这些矩阵放在右侧,否则乘法就不起作用。但无论如何,在我们正确进行乘法之后,我们将为每个输入标记获得这些查询、键和值矩阵。在生成了键、查询和值之后,我们可以稍微忘记生成它们的矩阵,看看我们将如何进一步处理这些查询、键和值。为了可视化,让我们看看如何计算这个词“works”的注意力。但我们也可以对“attention”做同样的事情。通常在 Transformer 中,我们会为每个输入标记这样做,但为了简化表示,我们在这里为“works”这样做。这里发生的是,我们取查询,并将这个感兴趣的词的查询与序列中每个其他标记的键相乘,包括它本身。所以,我们将取查询二乘以键一,我们将得到一个特定的值,比如二。这只是这个向量和这个向量之间的标量积。然后我们将取这个和这个向量,进行乘法,然后我们将取这个和这个向量,进行乘法,我们将得到一些特定的值,可以通过标量积输出。然后发生的是除以向量的维度。这里我们说维度是三,所以我们将除以根号三。我们对所有其他乘法也这样做。然后发生重要的事情,即我们在这里应用一个非线性函数,即 softmax。softmax 将负责从所有这些值中生成零到一之间的值,并且这些值加起来等于一。所以您也可以将它们解释为百分比。它基本上意味着这里我们有 133% 的注意力得分,这里有 78% 的注意力得分,依此类推。这就是我们将用于数据依赖加权平均的权重。数据依赖是因为这些权重现在是从数据本身计算出来的。这个查询向量和这个键向量,它们来自于将矩阵乘以这些向量。所以,现在我们准备进行数据依赖加权平均。我们取这些权重,计算加权和。为了获得“works”的新表示,我们通过使用我们为该标记计算的权重,对每个标记的值进行加权求和。所以,这里 133% 是针对第一个标记的,所以我们将取第一个标记值的 133%,我们将取第二个标记值的 78%,依此类推。现在的问题是,我们如何从三维跳到四维呢?因为我在这里没有更多的空间来写了,但这里基本上是另一个矩阵乘法,它将从三维映射到四维,回到我们原来的表示空间。所以,这基本上就是自注意力中发生的事情。我们通过获取一定数量的数据依赖的权重来计算“works”标记的新表示,这些权重是通过将查询、键和值矩阵乘以这些向量生成的。我们根据计算出的权重将这些标记的值相加,我们将得到“works”的最终表示。同样的,这里的最终表示就是我们从这个自注意力层获得的最终表示。我们为“works”标记所做的事情,也可以为每个其他标记做。因此,在自注意力层之后,我们将为每个其他标记获得新的、信息更丰富的表示。现在这些表示更好,因为它们包含了它们所处的公司(上下文)的信息。所以,这就是自注意力机制。在我们理解了这一点之后,我们可以问自己,我们是否完成了 Transformer 架构?答案是还没有,因为缺少了一些东西,一些非常重要的东西。因为如果我们看看这个 CLS 标记的表示,当我们输入“works attention”时,它将与输入“attention works”时相同。问题是为什么会这样呢?这是因为这个前馈神经网络将独立于每个其他标记进行计算,也可能是因为这里的自注意力机制基本上是可交换的,它是排列不变的,因为我们这里有一个求和,求和是可交换的,我们这里有这些乘法,它们也是可交换的。总而言之,自注意力层和前馈神经网络,总而言之,它们是排列不变的,这意味着结果不会随着输入序列的顺序而改变。这很糟糕,因为语言非常依赖于序列的顺序。在其他模态中并非如此,但在大多数模态中,如语言和图像,顺序很重要。如果您打乱图像像素的顺序,它将不再是同一张图像,您也不会理解那是一只猫。所以,我们需要一种方法来告诉网络,这是第一个标记,这是第二个标记,这是第三个标记。这正是位置嵌入成为 Transformer 架构非常重要的一部分的原因。那么这些位置嵌入是什么呢?这里是我们标记的语义表示,而位置嵌入基本上就像房子的地址。如果我们说我们在第一条街,重要的是,如果这里有一个不同的词,语义嵌入会改变,但位置嵌入会保持不变。这个位置嵌入也将总是应用于第一个位置的任何东西,然后我们有另一个位置嵌入,第二个位置有其他值,依此类推。那么这些位置嵌入是什么样的呢?在引入 Transformer 的“Attention Is All You Need”论文中,位置嵌入是正弦的。正弦位置嵌入根据序列的索引为向量的维度提供不同的值。您在这里看到一些正弦和余弦。问题是为什么是正弦和余弦?因为它们具有这种很好的重复结构,并且想法是它们最终会开始重复,有助于处理分布外长度。例如,如果您用一千的最大序列长度训练了您的 Transformer,那么您的文本中就没有比一千更长的句子或序列。那么如果您去到一千零一,位置嵌入可能会分布外。但在这里,有了正弦和余弦,希望它们不会分布外,因为它们最终会重复。不幸的是,这对于泛化来说效果并不太好,但无论如何,这就是正弦和余弦背后的想法。然后您可以问,为什么这里要除以一万?为什么我们必须有这个二的幂等等?想法是,嗯,我的意思是,有一些理论支持这一点,但主要是因为一万在实验中效果很好。为什么不是另一个值呢?可能有另一个值,具有其他超参数。所以,这里的想法是,为什么我们要人类设计好的位置嵌入,而也可以从数据中学习位置嵌入呢?以同样的方式,我们在这里每次计算损失函数时更新语义嵌入,我们也更新第一个位置的嵌入,然后是第二个位置的嵌入,依此类推。这就是学习位置嵌入的想法。它们在视觉 Transformer 中非常受欢迎,即处理图像数据的 Transformer。然后还有旋转位置嵌入,它们现在在大型语言模型中非常受欢迎,它们受到电动力学的巨大启发。基本上,它们的想法是线性极化的电磁波,有点像这里的正弦,但然后它们会通过一个 45 度角的四分之一波片,然后这个波会发生旋转,发生相位偏移。所以,这基本上就是旋转位置嵌入背后的想法。如果您对此感兴趣,请在此处阅读更多。无论您如何做,您都需要一种表示位置的方法。只要您有一个位置,当语义改变时,它在这里不会改变,对于第一个位置,您就做得很好,并且拥有一个 Transformer 架构,您已经打破了排列不变性的对称性。您不再拥有排列不变性,现在您将能够编码顺序。这样我们就差不多完成了,因为我们还需要这些残差连接,它们可能让您想起 ResNet,也可能不。但这里的想法是获取子层的输入,并再次将其添加到子层的输出中。我们对自注意力子层这样做,我们对前馈神经网络子层这样做。因为我们一直在将这些层的结果加到输入中,所以随着每一层的增加,向量会变得越来越大。这最终会成为一个问题,因为当今的优化器在零和一的范围内工作得很好。但是,如果我们有不断增加的数字,它们最终会大于一。所以,这里的想法是在添加这些向量之后进行归一化,以使我们保持在零和一的范围内。您可以问,为什么要有这些残差连接?为什么我们要添加它们?它们有助于对抗梯度消失,因为假设在这里,在这个分支上,反向传播过程中存在梯度消失,它最终不会消失,因为我们有这个残差连接,我们可以用它来跳过梯度消失。而且,因为我们一直在保留来自上一层的​​信息,当我们获得子层的输出时,这有助于增加 Transformer 的深度。所以我们可以一个接一个地添加越来越多的子层和层,这意味着我们将获得越来越深的层。更深的层意味着我们可以使表示越来越好,并将获得更好表示的问题分解为多个步骤,而不是仅仅几个步骤。如果您问这些 Transformer 网络有多大或多深?嗯,我的意思是,6、12、24、48 是 Transformer 的常见层数。但是,如果您想要一个非常深的 Transformer,有一篇论文“Scaling Transformers to a Thousand Layers”,它基本上将层深度增加到一千层,但当然不得不大大减小隐藏维度,以便仍然能够适应现代 GPU。所以,这就是 Transformer 层及其所有重要组件。我们输入序列中每个单独标记的语义表示,然后是位置嵌入,自注意力层将对这些向量进行上下文化,基本上为我们提供更好的向量,这些向量包含了标记所处的邻近环境(上下文)的信息。然后我们有这个残差连接,我们将层的输入加回到层的输出。我们需要归一化以将值保持在零和一之间。然后我们有前馈神经网络,它将单独处理每个标记。我们有残差连接,我们将子层的输入再次加到输出。我们再次需要归一化。这些是 Transformer 层的输出。现在的问题是如何从这些生成语言?如何学习这些向量?这就是我们将在今天接下来的章节中讨论的内容,即大型语言模型的架构。我希望在经历了如此密集的 Transformer 架构之旅后,您能稍作休息,因为现在我们将深入探讨如何构建这些 Transformer 层以及如何训练它们以生成语言的全部细节。所以,让我们谈谈在文本上进行自监督学习的两种主要方式。自监督意味着我们没有人为地标注我们的数据,我们没有标签,例如,我们不说是这个句子是积极的,或者这个句子有负面情绪。我们只有数据,我们只有文本,我们使用数据本身作为标签来从数据中学习。为了论证的简单性,让我们想象一下,我们将在其上训练的整个互联网只由句子“猫坐在垫子上”组成。我们想对其进行自监督学习。要通过自监督学习,主要有两种方法。其中一种称为掩码语言建模,它是第一个成功的方法。这里的想法是考虑我们的训练数据,并用这个特殊的掩码标记来掩盖文本中 15% 的标记。现在模型将预测掩码标记。所以这是一个分类设置,它将从我们词汇表中的大约 60,000 个标记或单词中选择一个来替换掩码。所以,这个分类设置的损失函数,这个 60,000 路分类设置的损失函数是交叉熵,它会惩罚模型说“dog”,因为它在训练数据中是“cat”,当它说“cat”时损失为零。以这种掩码语言建模方式学习的 Transformer 称为 Transformer 编码器或双向编码器,原因稍后您会看到。它们是 Bert、Roberta。所以,如果您在名称中看到 Bert,它通常是 Transformer 编码器。另一种非常成功的方法是自回归语言建模。这里的目标是完成文本,进行非常大的自动补全,就像我们有“the cat sat”,模型必须说“on the mat”。在这里,模型再次预测文本,这也是一个分类设置,因为它必须选择我们词汇表中 60,000 个标记中的哪些适合放在前面的标记之后。所以,损失函数仍然是交叉熵。它是自回归的,因为模型会再次“吃掉”自己的输出。所以,如果模型在“the”之后说“cat”,它将再次将“cat”作为输入来生成“from the cat set”,它将再次以其输出来作为输入,它将是“the cat set”,依此类推。您看到了这里的模式,这就是所谓的自回归。实现这种自回归语言建模的 Transformer 称为 Transformer 解码器,或者也称为自回归解码器,或者也称为因果 Transformer,原因稍后您会看到。GPT 系列是这方面的典型例子。好的,这里我再次详细列出了 Transformer 层。因为从现在开始,我们将抽象掉 Transformer 层的所有细节,我们只会说我们有一个架构中有 L 个这样的 Transformer 层。当然,就像每个 Transformer 层和 Transformer 一样,我们这里有四个输入标记,我们将得到四个输出表示。首先,我们将解释 Transformer 解码器。那么解码器如何生成语言呢?它有一个线性层。为什么是线性的呢?因为我们在深度学习中想要做的是应用所有这些繁重的层,使得这些表示的解决方案显而易见。显而易见意味着我们只需要一个线性决策来决定我们问题的答案,即生成下一个标记。所以我们有一个线性层,它将为我们词汇表中的每个 60,000 个标记生成概率。这里我没有列出 60,000 个标记,只列出了一部分。那么这究竟是如何完成的呢?因为训练和推理(即测试时间)非常不同。我逐一进行,首先从训练开始。这个东西是如何训练的?在训练中,我们有整个句子或整个序列。我们从互联网上获取文本块,并将它们全部放在这里。我们想象我们的 Transformer 最多可以处理四个标记,但通常这些 Transformer 可以处理 512 个标记(对于 Bert 模型)或 1,024 个标记,或 128,000 个标记(对于大多数现代 LLM)。但因为我们有整个文本,并且我们希望 Transformer 解码器预测这个文本,我们对其进行掩码。这被称为因果掩码,即在自注意力层中,我们将未来所有自注意力分数设置为零,我们专注于例如第一个标记。从第一个标记开始,我们希望生成接下来的标记。所以我们理想地想要预测“cats”。这就是我们在训练中训练模型要做的事情,即获取第一个标记并预测后面的标记。所以我们有输入,我们有 Transformer 层,它们将作用于这个输入标记,获得更好的表示。然后,因为它更好,我们只需要一个线性层,它将映射到 V 的维度。如果 V 是我们词汇表的大小,比如 60,000,那么这里将是 V 维的。这些条目称为 logits。我们有与我们词汇表中的条目一样多的 logits。从这些 logits 中,softmax 函数将生成零到一之间的值,我们可以将其解释为概率,因为它们加起来等于一。再次,从 softmax 中,我们将得到一个 V 维的巨大概率向量。好的,在我们有了这个输出之后,我们就可以计算损失函数了。我们在这里进行自监督学习,但自监督是一种监督方式。所以,是的,模型生成这些 logits,我们有 softmax 来计算概率,然后在训练期间,我们可以计算交叉熵,并通过这个交叉熵进行反向传播来学习东西。所以,对于交叉熵,我写了公式,但也写了一些代码,因为在代码中通常更清楚发生了什么。所以,让我们假设我们有一个大小为五的词汇表,并且我们在训练期间想要拥有的概率如下。所以,让我们假设这里我们想要生成“cat”。假设“cat”是我们词汇表中的第二个标记,第二个标记获得概率一,其他所有标记获得概率零。而我们模型的输出例如是这些。在交叉熵中,我们查看这个条目和这个条目,如果这个条目不像这个条目那样是“一”,它就会惩罚模型。现在的问题是,为什么交叉熵只查看这些条目来将它们推向一,而不查看其他条目来将它们推向零呢?您怎么看?您可以暂停视频思考一下。我现在给您答案。答案是,这里的值是由 softmax 生成的。softmax 使所有这些值加起来等于一。所以,如果我们这里有一个条目是“一”,那么所有这些值自动必须非常小,即零。所以,将这个概率推向一就足够了,因为 softmax 会处理好这些概率为零的情况,就像我们在真实分布中所看到的那样。所以,这就是交叉熵的作用。在我们计算了模型为“cat”生成的概率之后,从标记“the”开始,我们可以进行反向传播。反向传播意味着我们将更新 Transformer 中每个可更新的权重。softmax 是一个固定的函数,但我们将更新线性层,我们将更新 L 个 Transformer 层及其所有子层,即我们将更新前馈神经网络,我们将更新自注意力中生成查询、键和值的矩阵,如果我们学习了位置嵌入,我们将更新位置嵌入,并且我们将更新标记“the”的语义嵌入。好的,在我们完成了之后,我们可以取消下一个标记的掩码,并从“cat”标记的表示中预测下一个单词,希望是“set”。所以,这就是 Transformer 学到的。所以,我们再次将这些 Transformer 层应用于这些标记,我们将获得表示。然后我们将应用线性层、softmax 并再次计算交叉熵,然后我们将进行反向传播,更新这个,更新 Transformer 子层和所有其他东西。然后,从这个标记开始,我们将生成下一个标记,依此类推,直到我们生成了整个训练序列。所以,这基本上就是 Transformer 解码器所做的。从最后一个标记的最后一个表示,它预测下一个标记的表示。注意力是因果的,因为我们掩盖了未来,这就是因果掩码的含义。自回归意味着之前生成的内容再次作为输入。好的,现在我们准备看一下推理了。在推理中,用户输入例如“the”,然后模型(现在已经训练好了)会说一些话。因为我们不在训练中,我们知道未来,所以我们用一个填充标记来填充这些标记,或者可以是任何标记,因为无论如何它都不重要。它们上的自注意力分数都为零,这样它就不会窥视未来,因为未来没有任何信息。从这个“the”中,我们将获取表示,并用线性层预测下一个标记。希望下一个标记是“cat”。也可能是另一个,但没关系。我们将预测概率,并从这些概率中选择一个标记,直到我们完成,直到我们达到 Transformer 的最大序列长度,或者直到模型预测了一个特殊标记,即序列结束。因为在训练中,当互联网上的文本块结束时,我们会附加一个序列结束标记,这样模型就会学到,好吧,有时是时候结束句子了。但我们还没有解释的是,我们如何从模型预测的概率中选择一个标记。嗯,一个简单的策略是进行所谓的贪婪解码。贪婪解码意味着我们查看我们词汇表中所有 60,000 个标记中概率最高的,并选择概率最高的标记,然后我们将其放在这里。但是,这不一定是一个好的策略。它之所以被称为贪婪是有原因的,即总是选择最高最高最高似然性的问题在于它会产生非常无聊的文本,它会产生非常可能的文本。人类文本或人类喜欢阅读的文本的一个有趣之处在于它也应该有点令人惊讶。它不应该总是非常高概率,因为如果你告诉我一些我并不感到惊讶的事情,它具有非常高的概率,我不会感到被告知。但如果我一半感到惊讶,一半时间我也知道你在说什么,那么我就可以理解你。但那样我也更有动力去阅读那段文本。所以,它应该是在惊喜和高概率事物之间找到一个微妙的平衡,这样我才能感到自在,知道你在说什么。因此,有许多比贪婪解码更好的方法来从这个概率分布中选择标记,例如 top-p 采样、束搜索或投机解码等等。但是,深入研究所有解码策略会让这个视频比现在更长。所以,让我们只说我们总是选择概率最高的标记,然后从这个概率最高的标记开始,我们将其放在这里,并可以从中生成下一个序列,依此类推。所以,这基本上就是一个 Transformer 解码器。所以,现在在学习了解码器之后,显然也有一个编码器。对于编码器,我将稍微增加序列长度,以便说明 Transformer 解码器在上面学习了什么,但这并不意味着 Transformer 编码器通常比解码器具有更长的序列长度。这只是为了可视化目的,我输入了一个句子,另一个句子,然后 Transformer 编码器稍微简单一些。因为它基本上必须做的是预测这些掩码标记。所以它必须选择整个词汇表,什么是掩码标记的好替换。在训练期间,通过交叉熵,我们将鼓励这种选择正好是我们这里缺失的内容。在推理中,我们将根据我们的解码策略,采用模型预测的任何内容。为了预测掩码标记代表什么,它使用一个线性层。我们将这个线性层称为掩码语言建模头。我们称之为头,因为它不同于分类头,分类头作用于这个特殊的标记,即分类标记。所以,这是一个不同的线性层,它将完成 Bert 在训练期间分类标记的任何工作。对于 Bert Transformer 编码器来说,分类标记的工作是判断输入的第一个句子和第二个句子是否是彼此的合理续写,还是它们是从训练数据集中随机选择的。所以,这是一个二元分类层,有一个是或否的问题:这是一个合理的续写吗?所以,这同样是我们将在训练期间通过交叉熵学习的内容,并调整线性层和 Transformer 层参数等等。当然,显而易见的问题是,这到底学到了什么?掩码语言建模足以学到有意义的语言吗?是的,因为有研究基本上考察了这些 Transformer 层在从输入到输出的过程中学到了什么。基本上,它们发现第一层学习词性,基本上第一层知道输入中的标记是动词、名词还是代词等等。然后下一层学习成分,即基本上是作为一个实体起作用的词组,例如句子中的“red ball”。然后有更复杂的东西,比如这里它知道谁对谁做了什么,何时何地。然后指代消解,例如“猫坐在垫子上,她很生气”。如果您知道“她”指的是猫,那么您就进行了指代消解。然后是更复杂的东西。这基本上是经典的 NLP 管道。如果这让您想起了 CNN 重新发现了图像处理管道,那么这是一个很好的提醒,因为在处理图像的卷积神经网络中,第一层学习基本的东西,如边缘检测和其他边缘、颜色等等。然后它们将这些低级特征组合成更高级别的特征,从高级特征,如牛的各个部分,直到最终知道,是的,这是一头牛。在这两个可视化中,您基本上看到了经典机器学习与手动进行特征检测的对比,以及图像处理中的特征检测。但现在,通过神经网络,这些权重、这些层自己学习这些特征。它们只是从数据中学习检测这些特征,并进行大量的计算,无论输出是什么,通过反向传播,在大量数据上进行调整。好的,现在我们已经了解了编码器,了解了解码器,您应该不会惊讶于还有编码器-解码器架构。在这里,我必须警告您,与我的可视化不同,信息是从底部流向顶部的。这里底部是输入,顶部是输出。因为我不是自己绘制这个可视化图的,我从 J Alamar 的精彩的 Illustrated Transformer 中获取的,我鼓励您查看它以理解和可视化所有 Transformer 组件。所以,这里的想法是我们有输入,我们对其进行了分词。我们让编码器做编码器该做的事情,并产生输出向量,数量与输入向量一样多。现在解码器的工作方式有点不同。所以,是的,解码器具有因果自注意力,以查看它到目前为止生成的内容。但现在,通过这些标记的查询,它通过键和值查看编码器的输出表示。所以,现在解码器通过自注意力关注它自己的先前步骤,但它也通过交叉注意力关注编码器的表示。所以,基本上,现在为了计算“me”的上下文,它查看自注意力,查看“I”。所以我们将有一个来自“I”的权重,但它也将从编码器输出中获取这些附加历史标记的值,如果您愿意的话。

也许显而易见的问题是,为什么我们有三种架构而不是一种呢?嗯,因为它们各自都有自己的优缺点。编码器可以很好地学习表示上下文,例如整个输入。它们有一个分类令牌,必须对整个序列做出决定。所以基本上,这个 CLS 令牌可以总结整个句子或整个输入序列的某些内容。这使得序列或句子表示非常出色,然后可以用于检索增强生成,或者用于生成文本到图像的扩散模型,它们必须以某种方式表示文本。所以如果你想用一个向量来总结整个文本、整个输入序列,你可以将其交给 Transformer 编码器,然后你可以将该向量传递给扩散模型来生成你的图像。不幸的是,它们目前在从头开始生成语言方面还不够出色。目前正在对所谓的离散扩散模型进行持续研究,这些模型可以做得更好。如果你想了解更多,可以看看我们关于这个主题的视频。但是它们在替换缺失单词方面非常出色。所以如果你有填空任务,Transformer 编码器在替换缺失单词方面非常出色。

现在,Transformer 解码器基本上是语言的生成模型。因为如果你想计算第一个令牌,那么基本上我们只是通过 Transformer 解码器计算第一个令牌的概率。然后对于第二个令牌,我们计算给定前一个令牌(即 X1)的第二个令牌的概率。所以基本上我们计算给定所有前一个令牌的下一个令牌的概率。如果也许你认出这个公式是计算整个序列的联合概率。所以如果你想要一个模型能够告诉你句子在其训练数据中出现的概率,那么基本上你可以使用 Transformer 解码器。而 Transformer 解码器因为它们只是继续对话,继续序列,它们可能会创建聊天机器人。

编码器-解码器是两者的结合。它们基本上结合了编码器和解码器的优点。在这个例子中看到的编码器-解码器在机器翻译方面非常出色,因为编码器可以专注于一种语言,而解码器可以专注于另一种语言。编码器的任务是抽象掉整个输入的语义。所以基本上抽象掉特定语言的东西,并总结语义。然后解码器获取语义,并生成完全不同语言的令牌。所以是的,这基本上是一个很棒的架构,但也有一些问题,因为它带来了两者的训练不稳定性和复杂性。它们更难扩展,这一点你也可以从 LLM 在这个树中的演变中看到。在这里你可以看到编码器,在这里你可以看到解码器,在这里你可以看到编码器-解码器。有趣的是,Transformer 编码器爆炸式增长,并且在一段时间内非常受欢迎,但后来在 Transformer 编码器领域没有发生太多事情。Transformer 解码器起初非常谨慎,但自从 GPT-3 以来,它们爆炸式增长。当我说的爆炸式增长时,我真的想说的是,这只是我们今天拥有的所有 LLM 的一小部分。然后 Transformer 编码器-解码器时不时地出现,但需要一段时间才能有人设法将这些东西扩展到越来越大的规模。你真的可以看到这些很容易做到,这些不像解码器那样容易扩展,而解码器对语言模型非常有用,而这些模型很难扩展。

因此,至此我们已经完成了讲座的第一部分,我们讨论了 Transformer 架构,该架构成立于 2017 年,然后我们简要概述了语言模型架构。我们研究了编码器-解码器和编码器-解码器模型,现在我们准备进入使大型语言模型解码器变得很酷的东西,即提示(prompting)、后训练(post training),我还想告诉你一点关于基准测试(benchmarking)。所以,请喝杯咖啡,因为我们将继续下一部分,这一部分完全是关于提示的。所以,如果你有兴趣了解任何类型的提示,我们都能满足你的需求。但提示到底是什么?为什么我们需要提示语言模型?为什么我们不能直接使用它们?嗯,让我们看看。

我们假设我们已经在整个互联网上训练了一个 Transformer 解码器,并且我们认为 LLM,即 Transformer 解码器,如果在海量文本数据上进行训练,可以解决多种任务。这是可行的,因为如果我们有一个大型语言模型,并给它一个特定的输入,例如,如果我拿起这个杯子,然后我用手抓住杯子,然后我张开手,杯子就会掉下来。所以,如果你预测下一个令牌是“掉落”,而不是说“杯子会跳出窗户”、“杯子会自发溶解”或任何其他东西,而是说“掉落”,那么我们就假设模型已经学到了一些关于世界的东西。当然,在 Twitter 上,知识分子之间存在关于这是否是理解,或者这是否不是很多理解的讨论。但当然,在某种程度上是理解,至少是一点点理解,因为语言谈论世界,而 LLM 是在语言上训练的。所以,如果 LLM 在语言上训练,而语言是关于世界的,那么通过传递,LLM 将会学到一些关于世界的东西。当然,会有幻觉,也会有我们不想要的东西,因为我们产生的语言充满了谎言,充满了虚构。所以,当然,这不会是完美的,但它会包含一些对世界的理解。当然,你可以争论有多少理解,文本是否足够,或者是否不够。但我希望我们能就这门讲座达成一致,即存在某种理解,它会预测杯子会掉落,它能够预测草是绿色的。所以它将能够解决多种任务,而不仅仅是一件事。

好的,但现在我们想从语言模型中提取这种专业知识。我们想以某种方式将这个在大型互联网上训练的模型变成 ChatGPT。所以我们说,让它完成以下句子:“爱因斯坦是什么时候出生的?”现在,假设你是一个 LLM,你会对这个句子说什么?嗯,也许你知道爱因斯坦是什么时候出生的,你说是在 1879 年 3 月 14 日。但我是一个和你不同的语言模型,我这样完成了:“海森堡是什么时候出生的?”你不应该感到困惑,因为我是一个语言模型,我在整个互联网上进行了训练,其中也包括考试。考试是问题和答案的枚举。所以一个问题也是一个问题的一个合理延续,给定模型的训练数据。而且它也可以只是说“这个问题将在科学史考试中出现”。给定模型的训练数据,这些都是有效的续写。但不知何故,我们有一些不喜欢的续写,也有一些我们喜欢的续写。而提示就是关于增加我们喜欢的续写的概率。所以,准备好找出自 2017 年以来 NLP 中最伟大的想法和科学进步是什么吧。嗯,这基本上就是礼貌地要求模型做我们想做的事情,即提示。所以提示就是找到呈现输入给模型的好方法,以增加预期答案的概率。

那么,增加模型下预期答案概率的原始机器学习方法是什么呢?嗯,它是通过随机梯度下降进行最大似然估计期望最大化。所以,通过调整模型参数,直到答案更有可能。但现在我们不是通过 SGD 或其他方法来调整模型,我们只是改变输入。这是机器学习和当今 LLM 之间的一个根本区别。因为我可以做 SGD,也许你可以做随机梯度下降,但我的妈妈做不到。所以,仅仅改变输入是任何人都能够更容易地增加预期答案概率的事情。所以,让我们举一个例子任务。所以,假设你正在进行自然语言推理,你可能不知道它是什么,语言模型也不知道它是什么,因为我们没有说它是自然语言推理,我们只是以非常经典的方式进行机器学习。我们有数据样本,我们有一个 CSV 文件,里面充满了这样的句子:前提:约翰晚餐吃了意大利面。假设:约翰晚餐吃了面条。然后,每一行带有这样的句子的 CSV 文件都有一个标签,要么是“蕴含”,要么是“矛盾”。在经典的机器学习中,我们会用 CSV 训练一个模型,该模型会接收这样的句子并输出“蕴含”或“矛盾”。但这个模型除了这个之外什么也做不了。但现在我们处于语言模型时代,我们假设模型已经学会了多种任务,并且将能够用我们想要的东西来完成句子。所以,如果我们给模型这个输入,问题是它是否会做一些正确的事情?答案是“否”。所以,如果你只给它这个输入,它不会输出“蕴含”或“矛盾”,它会说任何不是“蕴含”或“矛盾”的东西。但如果我们用不同的方式口述同一个例子,我们说“假设约翰晚餐吃了意大利面,我们能否推断出约翰晚餐吃了面条?”嗯,现在这个句子的下一个最可能的续写可能是“是”或“否”。从“是”或“否”中,我们可以推断出标签“蕴含”或“矛盾”。如果我们甚至加上“是”或“否”,那么正确答案的概率甚至会增加。

所以,我们在这里做了什么?假设我们词汇表中有 60,000 个令牌。所有 60,000 个令牌的概率可能不是那么大,但可能有 10,000 个令牌是这个句子的可能续写,因为模型不知道该怎么做。如果你是模型,你也不知道该怎么做。但如果我们这样问它,那么是的,它仍然可以通过继续另一个句子或问题来回答这个问题,或者说一些不是这个问题的确切答案的东西。但如果你甚至说“是”或“否”,那么下一个最有可能的令牌是“是”或“否”的概率就是一。所以,基本上,正确答案的概率,即“是”,是 1/2。所以,现在我们已经将下一个令牌的概率从 1/10,000 增加到了 1/2,这是巨大的。这是一个巨大的概率增加。当然,50/50 的机会仍然是,你知道,模型必须能够理解诸如“假设”是什么意思,“推断”是什么意思之类的东西。它应该能够理解这两个句子才能真正回答“是”,而不是“否”。当然。但现在下一个令牌恰好是我们想要的令牌的概率是 1/2,而不是 1/10,000。我们期望一个已经学到了一些关于逻辑和命名实体之类东西的模型,它将能够正确回答。当然,只有一个方法来表述它,有无限种方法来表述它。这就是为什么有提示工程师这个职位,有些提示效果更好,有些则不然。但这基本上就是提示的想法,通过改变输入来增加预期答案的概率。

我想区分一下纯粹的提示(vanilla prompting)和提示调优(prompt tuning)。为什么?因为你可能不太喜欢这种纯粹的提示,我们得到这个输入,我们做一些提示工程,我们得到一种更好的方式来告诉模型,然后我们将其标记化,模型会给出正确的答案。这可能需要太多人为干预,这是真的。所以,也许有一种更自动化的方法来做这种提示工程,它被称为提示调优。这里我们保持输入不变,当然,如果我们将其标记化,模型将不会给出正确的答案。但如果我们添加一些额外的向量,并通过随机梯度下降来调整这些向量,直到模型使用这些向量和输入给出正确的答案,那么这基本上也是一种提示工程的方法。但我们不是在词空间中进行调整,就像我们在这里所做的那样,我们是在词嵌入空间中进行调整。所以,在这个例子中,我们可以找到适用于单个实例的软提示,或者我们可以对多个示例进行这种软提示的随机梯度下降调优。然后我们可以找到一个适用于特定任务大多数示例的提示。但这是一种更自动化地进行提示调优的方法。如果这让你想起被重新用于良好目的的对抗性示例,那么这是一个很好的提醒。

但纯粹的提示和提示调优绝不是提示的唯一方法。甚至有更聪明的方法。其中一个非常重要的就是所谓的上下文内少样本学习(in-context few-shot learning)。这里的想法是在我们问模型最终问题之前,给模型一些已解决的示例作为输入。为什么这会起作用?嗯,让我们以情感分类为例。我们有一个输入句子,任务是说这个句子是积极的、中性的,还是有负面情绪。如果我们给模型这些带有标签的示例,并且我们在这里定义了一个模式,即斜杠斜杠之后总会有一个标签,然后我们给它一个新的句子并加上斜杠斜杠,那么模型说“积极”的可能性就非常高。为什么?因为首先,我们大大限制了解决方案空间。因为现在模型通过示例知道,在斜杠斜杠之后,下一个可能的令牌是“积极”、“中性”或“消极”。所以我们已经将概率从 1/60,000(任何令牌)提高到了这三个令牌之一。当然,在 1/3 的概率设置下找到正确输出,当然取决于这个语言模型的能力。但如果它是在大量好数据上训练的,那么这应该是完全可能的。人们说这是,我不知道,激发模型的推理能力,或者他们使用了很多听起来像魔法的词来暗示有很多学习正在发生。但这里有一篇论文我想让你阅读,当然还有后续工作。它进行了这样的实验:给模型这些示例,这些标签,但总是将它们混合起来。这里我们没有“积极”,我们有“中性”,例如。结果是,模型在混合标签的情况下,在上下文内少样本学习方面仍然比没有示例时做得更好。所以,不知何故,这些标签的正确性并不那么重要,这表明在上下文内少样本学习中,很多基本上只是对可接受解决方案的定义有帮助,而模型不一定会学到新知识。所以,如果模型不知道“公司”是什么意思,“运营”是什么意思,那么它不会通过这些示例来学习。所以,再次,这只是通过指定解决方案空间来激发模型现有知识的一种方式,这样模型就不会给出任何合理的续写,而是给出我们想要的续写。所以,这三个标签中的一个。但当然,存在随机梯度下降和上下文内学习之间的并行性。因为上下文内学习基本上做什么?或者它与 SGD 有何不同?

所以,有了 SGD,我们有了输入,模型基于这个表示进行预测,它进行预测,好不好。如果不好,损失函数将大于零,我们将反向传播,我们将更新这些权重。这也自动意味着我们将更新自注意力产生查询、键和值矩阵的权重。我们将更新位置嵌入和这些表示。所以我们将更新模型参数,以便下次做得更好。而在上下文内学习中,我们不更新参数,我们只是在输入中添加更多内容。但这有一个巨大的影响,可能等同于 SGD。因为这里发生了什么?我们有输入,现在更长了,有这些示例。自注意力将产生整合模型整个上下文的向量。所以,现在在自注意力之后,仅仅因为我们向模型添加了额外的输入,这个表示将是不同的。因为这个表示将不仅仅聚合这些向量,而是聚合其他向量。所以这个表示将是不同的。在自注意力层之后,我们现在有了不同的值,它们将进入前馈神经网络等等。所以,我们通过简单地向输入添加内容而获得了不同的值。而有了 SGD,我们通过更新产生该值的参数来获得不同的值。这就是为什么它有点像双重视图:要么我们通过 SGD 更新参数以获得更好的向量,要么我们在输入窗口中添加输入,以便自注意力负责产生不同的值,并希望这些不同的向量会更好。是的,这基本上就是提示和上下文内学习以及随机梯度下降之间的等价性。

好的,现在我们已经做了这个类比,我认为我们已经准备好迎接自 2017 年以来 NLP 中第二个最伟大的科学进步,即让提示一步一步地进行。将此添加到提示中,并写一篇完整的论文。当然,我在这里有点开玩笑,人们写了一篇关于这个“一步一步”的完整论文。但当时这是一个相当新颖的事情,人们真的需要这篇论文所做的所有实验才能相信,如此愚蠢简单的提示效果如此之好。这基本上就是思维链提示(Chain of Thought prompting)的全部内容。因为思维链提示做了以下改变:我们有问题陈述,我们有给模型的那个问题,然后我们只是说“让我们一步一步地思考”。这改变了什么?嗯,它改变了很多,因为模型的响应将不再直接是答案,而是很多东西,很多分解问题的东西,然后它会给出答案。这基本上再次使得答案更有可能成为正确答案,因为问题现在被分解成更小的部分,并且在答案之前的令牌描述了一个更简单的问题。为了得到 9,它只需要做 3 + 6,而不需要在这里一步完成计算。所以,为了立即产生 9,意味着模型可能有 48 层,它必须真正完成所有计算并得出 9。而在这里,它可以附加中间计算步骤,然后逐个令牌进行有限的计算,然后聚合这些计算以获得最终答案。我再次想强调,这只有在底层模型已经能够将问题分解成正确的部分时才有效。因为这个“一步一步地思考”并没有教会模型任何东西,它只是通过提示定义了另一种解决问题的方式。所以,只有当模型的预训练做得非常好时,这个思维链才会起作用。这里没有多少学习或思考发生。它只是推迟了你必须给出答案的时刻,这样你就有更多的时间将计算从一步分解成多个令牌,尽可能多地需要。

好的,现在我们已经熟悉了这么多类型的提示,只有最后一类提示,即检索增强生成(retrieval augmented generation)。因为这在行业中被广泛使用。例如,我们有一个提示,比如“英伟达在 2024 年有多少员工?”请记住,这里的所有示例和数字都是为了说明目的而虚构的。我不知道这个问题实际上是如何回答的。但这里的想法是,模型的响应不会很好,甚至不会回答,因为模型的数据来自 2023 年之前的互联网。所以它不知道 2024 年发生了什么,或者请求的信息不是公开的,可能如此。检索增强生成的想法是使用这个提示,使用这个问题,就像你使用搜索引擎一样,在公司内部文档中搜索相关段落,在存储这类信息的数据库中搜索,并将所有这些检索到的段落附加到模型输入中,然后再次提问。如果你将所有检索到的段落都附加到模型输入中,那么当然,问题现在变得可回答了。模型的响应将好得多。当然,这需要大量的工程工作,有很多选择,很多事情可能会出错。这里只是一个非常简单的例子,因为在实践中,进行这种语义搜索来查找公司内部文档,找到真正相关的文档而不是将大量垃圾附加到这个输入中是非常困难的。但这里简化了,我只是向你展示了检索增强生成的想法,以完成所有类型的提示,即纯粹的提示、提示调优、上下文内少样本学习、思维链、检索增强生成。这些是最重要的提示类型。

现在,作为中间环节,为了更好地了解这些事物是如何随着时间演变的,我想做一个小测验。我不知道你读了多少研究论文,也不知道你对它们的标题有多熟悉。但让我们做一个小测验,看看我们能走多远。也许我们可以从中提取一个模式。以下论文中引入了哪些模型?“通过生成式预训练提高语言理解能力”?嗯,那是 GPT-1。“语言模型是无监督的多任务学习者”?那是 GPT-2。也许这里有一个模式?“语言模型是少样本学习者”?那是 GPT-3。然后“通过人类反馈训练语言模型遵循指令”?那是 InstructGPT 或 GPT-3.5。之后,OpenAI 停止为语言模型发布论文,这很遗憾。所以,是的。但为什么我给你看所有这些论文呢?嗯,基本上因为有一些我想强调的事情。生成式预训练 GPT,这基本上是 Transformer 解码器的想法。然后多任务学习是一个好的 GPT,一个好的 Transformer 解码器,在大量数据上训练,并且能够做很多事情,而不仅仅是一件专门的事情。然后少样本学习,这是提示的想法,使用上下文内少样本学习进行提示。然后我们今天仍然需要讨论的最后一部分是“通过人类反馈训练语言模型遵循指令”。因为这是我们真正想涵盖的最后一部分,以了解如何构建现代语言模型,即后训练阶段,以进行指令调优和偏好调优,并带有用户反馈。

那么,为什么我们需要对 LLM 进行整个后训练呢?让我们回到我们遇到的问题:我们有一个在整个互联网上预训练的语言模型,但它说的话与我们想要的不符。这就是为什么我们进行提示。但如果我们对这种提示进行训练,那么我们将使模型更倾向于遵循这些提示,而我们就不必进行如此多的提示工程。这就是监督微调(supervised fine-tuning)或也称为指令调优(instruction tuning)的想法。基本上,我们对模型进行微调,即在由指令描述的各种 NLP 任务上进行后训练。那么什么是 NLP 任务?一种是机器翻译,我们将英语翻译成德语,我们进行训练,并且再次使用监督交叉熵损失来重复文本中的任何内容。在经典的机器翻译设置中,我们只有英语句子,然后是德语句子。但在这里,通过指令调优,我们也让人类标注者编写一个描述这里任务中解决的任何内容的指令。所以,“请将以下句子从英语翻译成德语”是附加的指令。我们给出英语句子,模型更有可能继续说德语句子,特别是如果我们用交叉熵对整个内容进行训练,使模型重复这些训练数据。当然,一种指令是不够的,一种 NLP 任务也是不够的。所以人们所做的是,他们浏览了 NLP 人员多年来开发的所有任务、基准测试和数据集,然后他们为所有这些收集了指令。然后,他们在所有这些上对语言模型进行了后训练,使其成为一个指令调优的模型。这里的收益是什么?它们相当多。所以,如果你只是让模型在预训练后进行自动补全,它们不会产生人类更喜欢的答案。所以这基本上是给模型答案打分,说明人类更喜欢这些模型的答案。然后,如果你进行提示,你会得到这个分数,模型越大,它对这种提示的响应就越好。但然后,如果你在指令数据上进行调优,模型更有可能以人类喜欢的方式响应。但要获得最终优势,并真正获得一个强大的语言模型,一个很棒的聊天机器人,你需要人类反馈,即额外的微调,并带有用户反馈。

那么,带有用户反馈的训练是什么样的呢?基本上,人们收集一个数据集,由以下内容组成:一个问题或任务,例如“从英语翻译成德语”,然后是预训练模型给出的一个可能的答案,或者它也可以是人类给出的。然后是另一个可能的答案,由模型或人类给出,无论数据来自哪里。然后,人们让人类评价,给定问题,他们更喜欢这个续写还是另一个续写。一旦有了这些数据,就可以通过直接偏好优化(DPO)或带有用户反馈的强化学习(RLHF)来训练,这基本上是第一种方法。但后来人们发现了一种更简单且等效的方法来进行用户反馈训练。那么 DPO 是什么呢?我之前说过,我们有一个文本,一个问题,然后一个 LLM 或一个人产生了这些续写,然后人类评价了哪个续写更好。然后,人们以监督方式训练 LLM,以增加正面评价输出的概率,并降低产生负面示例的概率。所以,我们想增加给定这个的这些令牌的概率,并降低给定这个的这些令牌的概率。因为仅仅这样做会给你一个能够非常适合这些用户反馈数据并忘记其他所有东西的语言模型。所以,需要进行正则化,以使 LLM 的状态在预测的令牌概率上接近于在开始人类反馈微调之前的 LLM。因为这是想法,保留原始模型在整个互联网上预训练的能力。否则,模型将忘记所有其他东西,并且只会过度拟合这些人类偏好数据集。

那么,这在损失函数中看起来是什么样的呢?它看起来有点复杂,只是为了比较。通常的交叉熵,人们在预训练期间使用它。现在它有点复杂,但它在做完全相同的事情,只是有两个项而不是一个,以一种对比的方式。为什么是对比的?因为我们增加了我们想要的文本的概率,就像我们在这里所做的那样,并降低了我们不想要的文本的概率,同时相对于这个参考模型进行正则化,即在开始所有 DPO 训练之前的模型,以使正在微调的模型与原始模型一样强大。所以,你可以想象,我们有一些特征,比如毒性,我们想抑制它。而我们在这里增加了友好性,当然,我们也增加了模型将要回答的内容将比不回答的更受人类喜欢。这是一个简单的方法。有一种更复杂的方法,我们不会深入细节,但这里只是给你一个要点。这里的想法不是训练模型来产生这个,并阻止模型产生那个。它更通用,它是让模型产生任何获得高评分的东西。而这正是困难所在。模型可以产生任何东西,它不会只是复制和背诵这些示例,并被阻止产生这些示例。所以 LLM 的目标是获得高评分。但通过这样做,它可以产生任何文本,这些文本不在训练数据中。为了产生这些文本,它通过一个不可微函数,即 argmax,来选择令牌。而不可微性在进行神经网络深度学习时是一个非常令人头痛的问题。但有一个框架可以克服不可微性,它被称为强化学习。基本上,人们训练一个奖励模型,基于这些数据来输出高评分或低评分。然后,在循环中用这个奖励模型训练 LLM,因为奖励模型将对 LLM 生成的任何内容进行评分。所以,这个奖励模型现在变成了帮助 LLM 在训练循环中变得越来越好的代理人类。

这就是你需要知道的关于 Transformer 的所有内容,不同的 Transformer 架构,提示,后训练。现在,如果你还有精力,我想告诉你如何对 LLM 进行基准测试,以及如何看待 LLM 越来越好。这个“更好”到底意味着什么?我们如何衡量它?如果你有兴趣不仅仅是语言建模,还包括理解图像,那么我有一个关于 LLM 的多模态扩展的章节。关于 LLM 基准测试,我想告诉你的是,基本上每年都有一个疯狂的周期,人们设计一个超级难的基准测试,一些大公司启动他们的 GPU 来训练一个比以往任何时候都更大的模型,几个十亿美元之后,这些超级难的基准测试就解决了,然后人们又回到第一步。这基本上就是学术界发生的事情。我不需要告诉你这些模型有多么强大,它们可以做以前做不到的事情,它们可以解释笑话等等。但当然,令人担忧的是,我们训练的模型越来越大,它们做得越来越多,越来越多,越来越多。我们不希望在模型能够做某事时感到惊讶,因为它们可能会接管世界。我们想提前知道,训练越来越大的模型是否能够使人工智能能够做到这一点。为此,我们有这些基准测试。当然,这是令人担忧的,因为我们有这些基准测试,我们测量模型在特定规模下的准确性。然后有一些能力,例如理解英语谚语,模型的这种能力不是线性扩展的。如果我们训练这个模型,训练那个模型,我们可能会认为我们会在这里结束,但实际上它比我们想要的要好得多。存在这种不连续性。这种不连续性可能很可怕,因为那是规模让我们感到惊讶的地方,那是不可预测的地方。这里是可预测的,这里是不可预测的。我们称之为涌现(emergence)。你知道,这可能很可怕,但我想给你一个稍微不同的视角来看待这种涌现。因为这些现象的发生尤其奇怪,特别是当我们看其他指标时,而不是这里的英语谚语,而是损失函数,模型的损失函数。在训练越来越大的模型时,这里是指数轴,实际上这里有很大的收益递减。而如果你看模型正确预测训练数据的下一个令牌的准确性,它也不是一个如此不连续的事情,它实际上是一个收益递减的曲线。但当我们用准确性来衡量时,我们似乎有这种不连续性,我们有这种涌现现象。而这正是这篇论文所说的,基本上告诉我们,这些非线性评分的输出,如准确性,正在产生这些跳跃。因为即使模型可能越来越好,但连续性差的度量太苛刻了,它不会奖励模型越来越好,它只会跳跃,当模型达到连续性度量能够识别的完美程度时。但如果我们看更连续的度量,而不是像准确性这样不连续的度量,那么涌现现象突然消失了,我们甚至有一个能力平台。这就是为什么我想向你展示这篇论文的发现。当然,这有点争议,也有后续工作,如果你想阅读更多并深入了解整个争议。但这就是我到目前为止想告诉你的关于基准测试的内容。

现在我们可以进行讲座的最后一部分了,即思考如何实现 LLM 的多模态,或者如何实现除语言之外的任何其他模态。因为我们在这门讲座中已经了解到,我们有文本,我们将其标记化,然后我们可以对其进行自回归 Transformer 来预测下一个令牌。但如果我们也想理解图像呢?嗯,图像不是向量,对吧?嗯,它们几乎是向量。我的意思是,图像比文本更像向量,因为图像只是矩阵,我们可以将这些巨大的矩阵分解成更小的矩阵,即块。然后我们可以学习一个线性层,它将从这些二维块生成这些一维矩阵,即向量。然后我们可以让自回归 Transformer 也处理这些向量。但当然,这些向量不一定会被自回归 Transformer 立即理解。它会产生垃圾。所以,如果我们想让自回归 Transformer 理解这些向量,当然我们需要训练一些适配器层(adapter layers),或者至少这是其中一种方法。这就是我们在与 AlphaFold 的合作中选择 Magma 的方式,当时多模态还不像今天这样普遍或庞大。而在这里,通过这些适配器层,我们基本上可以冻结在语言上预训练的 Transformer,并且只微调一些小的参数,称为适配器块,这样它的自回归 Transformer 也能理解这些图像向量。你可能会问,为什么不训练整个自回归 Transformer 与图像和文本?嗯,想法是,如果你在互联网上有很多图像和文本,那基本上只是图像和字幕。而字幕不是一种非常多样化的文本。我不知道你为图像写了多少次字幕,当你发布图像到互联网上时。但通常你只是写“我的照片”或“一只猫的照片”,这在语言上并不非常多样化。然后,想法是基本上保留在大量文本数据上训练的自回归 Transformer 的有趣的语言能力,并保留语言理解能力,然后只调整一些参数,使其也能理解图像,但不会因为现在在无聊的图像和字幕上训练而出现灾难性遗忘丰富语言信息的问题。

现在,显而易见的问题是,我们是否可以完全忘记文本?当然。然后,这基本上就是视觉 Transformer(Vision Transformer),它可以只将图像块作为输入,并生成标签来执行图像识别等等。正如我之前所说,如果你想与多模态建立更多联系,基本上你可以使用 Transformer 编码器及其最后的表示来为文本到图像的扩散模型提供文本表示,如果你想让扩散模型以某种方式理解文本。如果你想了解更多关于扩散模型的信息,请查看我们关于这个主题的视频。

所以,只是为了给你一些关于大型语言模型的最后几句话,并总结一下关于 Transformer 架构和关于整个提示和人类反馈调优的两个部分。我想告诉你,模型确实很酷,但自 2021 年以来推动进步的因素在很大程度上是数据和以人为中心的,比如提示,我们作为人类带来我们对问题的理解,并更好地构建输入,以便模型能够理解它。我们作为人类注释了大量的反馈,让模型进一步训练并变得更好。所以,基本上,是的,模型很酷,但它们的真正力量来自于数据,来自于数据的清洁程度,以及人类反馈的好坏。

在这里,我想引入戈普尼克(Gopnik)的“石头汤 AI”(Stone Soup AI)的寓言。这基本上是著名认知科学家艾莉森·戈普尼克教授改编的“石头汤”寓言。如果你不知道“石头汤”寓言是什么,基本上它的想法是,饥饿的旅行者来到一个村庄,但村民们不想给他们任何东西吃,因为他们自己也没有多少,而且正在闹饥荒。所以旅行者说:“啊,没问题,我们不需要别的东西,我们只需要一些水,我们需要一个锅来煮我们的石头汤。”所以他们带了一些石头和一些水,煮了一段时间,然后品尝结果,说:“嗯,这是极好的汤,只需要再加几根胡萝卜,它就会成为完美的石头汤。”所以村民们带来了一些胡萝卜。然后他们再次品尝,说:“嗯,它几乎是完美的,只需要再加一点鸡肉和一点番茄。”村民们带来了这些东西,过了一段时间,一遍又一遍地这样做,每个人都坐下来,他们吃着极好的石头汤,对吧?

所以,根据艾莉森·戈普尼克(Alison Gopnik)的说法,这在 AI 中也发生了。她在 Alex Efro 的 HLF 去年的演讲中讲述了“石头汤”寓言。如果你想去原始出处,我在下面的描述中放了链接。哦,哇,你坚持到了最后。我真不敢相信你坚持到了视频的最后,因为我自己也对录制这么长时间感到有点累。我不习惯制作这么长的视频。但如果你坚持到了最后,这意味着你和我一样对大型语言模型充满热情。所以,非常感谢你的关注,并保持我们下一个视频的最新状态,别忘了点赞和订阅。好的,再见。

[音乐]