初级

解码 Transformer 架构

解码 Transformer 架构

在这篇博客中,我们将通过逐块解码来学习 Transformer 架构——理解每个组件的作用、它们如何协同工作,以及为什么这种架构为所有现代大语言模型(LLM)提供动力。
当我们听到“Transformer”时,它听起来很复杂。但别担心。如果我们把它分解成各个部分,每一部分都很简单。复杂性来自于它们如何堆叠在一起——而不是因为任何单个部分很难。
我们的目标是如此清晰地解码这个架构,以至于到最后,我们能够向任何人解释 Transformer 是如何工作的。
我们将涵盖以下内容:
  • 为什么需要 Transformer
  • 架构的两个部分
  • 分词、嵌入和位置编码
  • 注意力机制与多头注意力
  • 前馈网络、残差连接和层归一化
  • 编码器和解码器如何工作
  • 数据如何在整个架构中流动
  • Transformer 的三种变体
  • 为什么 Transformer 如此强大
我是来自 Outcome School 的 Amit Shekhar,我在那里教授 AI 和机器学习
让我们开始吧。

整体概览#

在深入细节之前,让我们先理解整体概览。
Transformer 接收一个令牌序列作为输入,并产生一个令牌序列作为输出。就是这样。在非常高的层面上,它是一个“令牌进,令牌出”的机器。由于令牌来自文本并转换回文本,我们也可以将其视为“文本进,文本出”的机器。
例如,如果我们输入“Translate: I love learning”,它会输出“J'adore apprendre”。如果我们输入“What is the capital of France?”,它会输出“The capital of France is Paris.”。
但它是如何做到的呢?让我们来理解一下。

为什么需要 Transformer?#

在 Transformer 之前,模型按顺序逐个处理单词——就像从左到右阅读一个句子,一次一个单词。
这带来了两个大问题:
问题 1:遗忘。随着句子变长,模型会开始忘记前面的单词。当它处理到第 50 个单词时,它对第 1 个单词的记忆已经非常微弱。
问题 2:速度慢。因为单词是一个接一个处理的,第 2 个单词必须等待第 1 个单词完成,第 3 个单词必须等待第 2 个,依此类推。这非常慢。
于是,Transformer 来拯救了。它同时处理所有输入令牌,并让每个令牌直接查看其他所有令牌。长距离连接不再是一个主要问题。而且因为一切都是并行发生的,训练变得快得多。我们将在接下来的章节中确切地看到这是如何工作的。
Transformer 于 2017 年在谷歌研究人员著名的研究论文《Attention Is All You Need》中提出。它改变了一切。

架构有两个部分#

原始的 Transformer 有两个主要部分:
  • 编码器——这一半读取并理解输入
  • 解码器——这一半生成输出
可以把它想象成读者和作者之间的对话。读者(编码器)仔细阅读文档并创建详细的笔记。作者(解码器)使用这些笔记来撰写新文档。读者专注于理解。作者专注于产出。
现在,让我们理解每一半内部发生了什么。但在深入编码器和解码器之前,我们需要理解在输入到达它们之前发生了什么。

解码步骤 1:将单词转换为数字#

模型不理解单词。它只理解数字。所以,第一步就是将单词转换为数字。
这分两个阶段进行:
分词:输入文本被分割成称为令牌的小片段。一个令牌可以是一个单词、单词的一部分,甚至是一个字符。为了便于理解,我们姑且将每个单词视为一个令牌。
“I love learning” 变成三个令牌:“I”、“love”、“learning”。
嵌入:然后,每个令牌被转换为一个称为嵌入的数字向量。嵌入就像一个单词的数字指纹。含义相似的单词会得到相似的指纹。
例如,“happy”和“joyful”会有非常相似的嵌入,因为它们的意思几乎相同。但“happy”和“car”会有非常不同的嵌入,因为它们不相关。

解码步骤 2:添加单词顺序#

但是,这里有个问题。编码器同时处理所有输入令牌——而不是逐个处理。这对速度来说很好,但这意味着模型不知道哪个单词是第一、第二或第三个。
“I love AI”和“AI love I”在模型看来是一样的。但它们的意思非常不同。
位置编码解决了这个问题。它向每个嵌入添加一个数字向量,代表单词的位置。第一个单词获得的位置信号与第二个单词不同,依此类推。
可以把它想象成剧院里的座位号。即使所有观众同时到达,他们的座位号也告诉我们每个人应该坐在哪里。位置编码就是每个单词的座位号。
在此步骤之后,位置编码数字通过加法合并到嵌入本身中。因此,每个令牌现在携带一个单一的数字向量,该向量既编码了单词的含义,也编码了它在句子中的位置。

解码步骤 3:注意力机制#

这是 Transformer 的核心。注意力机制是让一切运转起来的最重要的单一思想。
注意力机制允许句子中的每个词查看句子中的其他所有词,并决定对每个词给予多少关注。
以这个句子为例:"The cat sat on the mat because it was tired."(猫坐在垫子上,因为它累了。)
当模型处理单词 "it" 时,它需要弄清楚 "it" 指的是什么。是猫?还是垫子?注意力机制帮助模型更多地关注 "cat",而较少关注 "mat",因为在这个上下文中,"cat" 与 "it" 更相关。

注意力机制如何工作#

每个词被转换成三个东西:
  • 查询 - 这个词在寻找什么
  • - 这个词能提供什么
  • - 这个词携带的实际信息
我们有一篇详细的博客 注意力背后的数学 - Q、K 和 V,解释了这些实际上是如何计算的。
这个过程是这样的:
首先,每个词使用其查询向量,通过点积与所有其他词的键向量进行比较。这会产生注意力分数——这些数字告诉模型每对词之间的相关性有多高。然后,这些分数会被缩放(除以 √dₖ)以保持在可管理的范围内。我们有一篇详细的博客 缩放点积注意力,解释了为什么需要这一步。缩放之后,分数通过 softmax 进行归一化,使它们成为概率,总和为 1。最后,模型根据这些概率收集值的加权混合。
结果是,现在每个词不仅携带关于自身的信息,还携带与其最相关的词的信息。单词 "it" 现在携带了来自 "cat" 的强烈信号,因为注意力机制发现了这种联系。
简单来说,注意力机制让每个词元在进入下一层之前,从其他相关的词元那里借用有用的信息。

多头注意力#

Transformer 不只运行一次注意力机制。它会并行运行多次——每次从不同的视角。这被称为多头注意力。
可以把它想象成一个编辑团队审阅一篇文章。一位编辑检查语法,另一位检查事实准确性,还有一位检查行文流畅度。每位编辑都看同一篇文章,但关注点不同。他们共同提供完整的审阅。
多头注意力中的每个头专注于词之间不同类型的关系。一个头专注于主谓连接。另一个头专注于哪个形容词描述哪个名词。所有头的输出被组合起来,为模型提供对文本的丰富理解。
以下是多头注意力的一个简单图示。所有头在相同的输入上并行运行,它们的输出在最后被组合:
markdown
                输入
                  |
   -------------------------------
   |       |       |       |     |
 头 1     头 2     头 3    ...   头 N    (全部并行运行)
   |       |       |       |     |
   -------------------------------
                  |
              组合
                  |
                输出

解码步骤 4:前馈网络#

在注意力机制处理完单词之后,输出会通过一个前馈网络。
可以将其视为一个精炼步骤。如果说注意力是关于理解词之间的关系,那么前馈网络就是关于深化对每个词本身的理解。
它接收来自注意力机制的、经过丰富后的表示,并进一步处理——增强信号并去除噪声。每个词都独立地通过相同的前馈网络。

解码步骤 5:残差连接与层归一化#

在每一层内部,还有两个重要的部分帮助 Transformer 有效学习。我们来理解它们。
残差连接:在每个子层(注意力或前馈网络)之后,该子层的原始输入会被加回到输出中。可以把它想象成在课堂上记笔记。即使在老师添加了新信息之后,我们仍然保留原始笔记,并将新信息与之结合。这可以防止模型在数据通过许多层时丢失重要信息。
简单来说,每个子层的输出是:输出 = 子层(输入) + 输入
层归一化:在每个残差连接之后,数字会被归一化——进行调整,使它们保持在稳定的范围内。这可以防止数字在通过许多层时变得太大或太小。它使训练过程保持稳定和平滑。
这两个部分存在于编码器和解码器的每一层中。

解码步骤 6:堆叠多层#

现在,有趣的部分来了。到目前为止,我们讨论了一个多头注意力子层和一个前馈子层。这两个子层(连同它们的残差连接和层归一化)一起构成了 Transformer 的一层。可以把一层想象成一个完整的捆绑包:一个多头注意力子层加上一个前馈子层。
Transformer 不只使用一层这样的结构。它将多层堆叠在一起,一层接一层。真正的力量就来源于此。
这些层中的每一层也被称为一个 Transformer 块。所以当我们说"模型有 96 层"时,意味着模型有 96 个 Transformer 块一个接一个地堆叠起来。每个块都有自己的多头注意力子层和自己的前馈子层。
注意:这种堆叠与多头注意力不同。多头注意力是在单个注意力子层内部并行运行多个注意力头。而堆叠层则是将完整的 Transformer 块按顺序一个接一个地放置,因此一层的输出成为下一层的输入。
以下是堆叠的 Transformer 层的简单图示。每一层都是一个完整的块,它们按顺序连接在一起:
markdown
        输入
          |
  -----------------
  |     层 1      |    (多头注意力 + 前馈网络)
  -----------------
          |
  -----------------
  |     层 2      |    (多头注意力 + 前馈网络)
  -----------------
          |
         ...
          |
  -----------------
  |     层 N      |    (多头注意力 + 前馈网络)
  -----------------
          |
        输出
原始的 Transformer 在编码器和解码器中都使用了 6 层。现代的大型语言模型使用得更多——GPT-3 (175B) 使用了 96 层。
每一层都建立在前一层理解的基础上。可以把它想象成多次阅读一本书。第一次阅读给我们基本的理解。第二次阅读揭示了我们错过的联系。第三次阅读给我们更深刻的见解。每一层就像又一次阅读——理解变得越来越丰富。

解码步骤 7:编码器详解#

现在我们已经了解了基本构建模块,接下来看看它们是如何在编码器内部协同工作的。
编码器的任务是读取并理解输入。
每个编码器层包含两个组件:
  • 自注意力机制 - 每个词都会查看输入中的所有其他词,以理解它们之间的关系。
  • 前馈网络 - 每个词的表示被独立地精炼。
这两个组件之后都跟着一个残差连接和层归一化。
让我们看看当句子 "I love learning" 通过编码器时会发生什么。
在第一层,自注意力机制允许每个词查看其他所有词。单词 "love" 开始注意到 "I" 是它的主语,而 "learning" 是它的宾语。然后,前馈网络会精炼这种理解。
在第二层,连接变得更加丰富。现在 "love" 不仅单独知道 "I" 和 "learning" - 它开始将 "I love learning" 作为一个完整的思想来理解其组合含义。
到第六层时,每个词都承载着一个深刻的、上下文感知的表示。单词 "learning" 不再仅仅是字典定义 - 它现在编码了这样一个事实:在这个特定的句子中,它是 "I" 喜欢做的事情。
在所有编码器层之后,我们就对输入有了丰富的理解。这种理解随后被传递给解码器。

解码步骤 8:解码器详解#

解码器的任务是逐个生成输出词元。
每个解码器层包含三个组件:
  • 掩码自注意力机制 - 每个输出词可以查看所有先前的输出词,但不能查看未来的词。这是因为在生成文本时,未来的词还不存在。单词 "love" 可以查看 "I",但不能查看 "learning",因为 "learning" 尚未生成。这种限制称为因果掩码。我们有一篇详细的博客 注意力中的因果掩码 解释了其工作原理。
  • 交叉注意力机制 - 这是解码器连接到编码器的方式。每个输出词查看编码器的输出,以从输入中提取相关信息。在这里,查询(Query)来自解码器,而键(Key)和值(Value)来自编码器的输出。这就是它与自注意力的不同之处 - 这也是连接理解输入和生成输出的桥梁。
  • 前馈网络 - 与编码器中相同的精炼步骤。
所有三个组件之后都跟着一个残差连接和层归一化,就像在编码器中一样。

解码器如何选择下一个词#

现在的问题是:在输出通过所有解码器层之后,解码器如何选择实际的下一个词?此时,输出仍然是一个数字向量 - 而不是一个词。
因此,解码器将这些数字通过一个线性层,该层将它们转换为词汇表中每个词的分数。如果词汇表有 50,000 个词,我们就会得到 50,000 个分数。
然后,softmax 将这些分数转换为概率 - 介于 0 和 1 之间且总和为 1 的数字。模型然后根据这些概率选择下一个词。在实践中,模型使用不同的策略来选择下一个词 - 例如温度采样、top-k 采样和 top-p 采样 - 这些策略控制输出的创造性或专注程度。但为了便于理解,我们假设它选择概率最高的词。
例如,如果模型正在将 "I love learning" 翻译成法语,并且它已经生成了 "J'",那么经过线性层和 softmax 后的概率可能如下所示:
  • "adore": 0.72
  • "aime": 0.15
  • "mange": 0.01
  • ... (50,000 个词,大多数概率非常小)
模型选择 "adore",因为它具有最高的概率。这就是解码器决定下一个输出哪个词的方式。

解码步骤 9:完整流程#

现在我们已经了解了所有的构建模块,让我们通过一个具体示例来走一遍完整的流程。学习这个的最好方法就是通过一个例子。
假设我们想将 "I love learning" 翻译成法语。

编码器阶段#

英语句子 "I love learning" 经过以下步骤:
  1. 词元化:"I love learning" 变成三个词元:"I"、"love"、"learning"。
  2. 嵌入:每个词元被转换为一个数字向量(一个嵌入)。
  3. 添加位置信息:添加位置编码,以便模型知道 "I" 是第 1 个,"love" 是第 2 个,"learning" 是第 3 个。
  4. 通过 6 个编码器层:在每一层中,自注意力让每个词查看其他所有词,前馈网络精炼理解。残差连接和层归一化保持稳定性。
在所有 6 层之后,编码器产生了输入的丰富表示。每个词现在都承载着深刻的上下文信息。这个表示被传递给解码器。

解码器阶段#

解码器逐个生成法语翻译。
生成 "J'"(第 1 个词): 解码器以一个特殊的 "开始" 词元开始。掩码自注意力没有什么可以回顾的,因为这是第一个词元。交叉注意力查看编码器的输出来理解英语输入。输出通过线性层和 softmax。模型选择 "J'" 作为最可能的第一个词。
生成 "adore"(第 2 个词): 现在解码器有 ["开始", "J'"]。掩码自注意力查看 "开始" 和 "J'" 以理解到目前为止生成了什么。交叉注意力再次查看编码器的输出,以从英语输入中提取相关信息。线性层和 softmax 产生概率。模型选择 "adore"。
生成 "apprendre"(第 3 个词): 现在解码器有 ["开始", "J'", "adore"]。掩码自注意力查看所有三个先前的词元。交叉注意力连接到编码器的输出。模型选择 "apprendre"。
生成 "结束" 词元: 解码器生成一个特殊的 "结束" 词元,表示翻译完成。
最终输出:"J'adore apprendre"(在法语中意为 "I love learning")。
这就是 Transformer 从开始到结束的工作方式。

三种变体#

原始的 Transformer 同时使用了编码器和解码器。但我们并不总是需要两者。这给了我们三种变体:
仅编码器(例如:BERT) 仅使用编码器。模型读取并理解输入,但不生成新文本。这用于诸如将电子邮件分类为垃圾邮件或非垃圾邮件、理解评论的情感或在给定文本中寻找答案等任务。
仅解码器(例如:GPT) 仅使用解码器。模型逐个词元生成文本。每个词元可以查看所有先前的词元,但不能查看未来的词元。这是大多数现代大语言模型背后的变体。它用于生成文本、回答问题、编写代码和进行对话。
编码器-解码器(例如:T5,原始 Transformer) 同时使用两部分。编码器理解输入,解码器基于这种理解生成输出。这用于翻译、摘要以及其他将一种文本转换为另一种文本的任务。
我们可以根据我们的用例选择合适的变体。

为什么 Transformer 如此强大#

现在我们已经解码了整个架构,让我们来理解它为何改变了一切:
并行处理:编码器同时处理所有输入标记,而不是逐个处理。即使在训练期间,解码器也是并行运行的。这使得训练速度大大加快,并允许模型从海量数据中学习。
不再有长距离遗忘:通过注意力机制,每个词都可以直接“看”到其他所有词。第一个词和第 1000 个词同样容易访问,因此旧模型的长距离记忆问题在很大程度上得到了解决。
可扩展性:通过添加更多层、更多注意力头和更多数据,模型会持续变得更好。这就是为什么我们今天拥有数十亿参数的模型。参数是模型在训练期间学习的内部数字。
多功能性:相同的架构可以处理翻译、问答、文本生成、代码编写、摘要等众多任务。一种设计,无数应用。
Transformer 是整个现代 AI 革命背后的单一架构。它使我们能够以非常简单的方式完成复杂的事情。

快速总结#

让我们回顾一下我们解码的内容:
  • 分词与嵌入 将单词转换为模型可以处理的数字。
  • 位置编码 添加词序信息,因为所有词都是同时处理的。
  • 注意力机制 让每个词都能“看”到其他所有词,并决定关注哪些词。多头注意力从多个角度进行这种操作。
  • 前馈网络 独立地细化对每个词的理解。
  • 残差连接与层归一化 在数据流经许多层时保持数值稳定。
  • 编码器 将这些构建块堆叠起来,以读取和理解输入。
  • 解码器 添加交叉注意力以连接到编码器,并使用线性层 + softmax 来选择下一个词。
  • 存在三种变体:仅编码器(用于理解)、仅解码器(用于生成)和编码器-解码器(用于将一种文本转换为另一种)。
现在,我们已经逐块解码了 Transformer 架构,并理解了它的工作原理。
为 AI 工程面试做好准备:AI 工程面试问题
目前就到这里。
感谢
Amit Shekhar 创始人 @ Outcome School