通俗易懂的 Transformer 入门文章(第二部分):工作原理分步拆解

这篇文章的主题是:通俗易懂的把 Transformer 内部原理理清

这是我 通俗易懂的 Transformer 入门文章 系列的第二篇文章。在第一篇文章中,我们了解了 Transformer 的功能、使用方式、整体架构及其优势。通俗易懂的 Transformer 入门文章(第一部分):功能概述

在本文中,我们将深入底层,详细研究它的具体工作原理。我们会看到数据如何通过实际的矩阵表示与形状在系统中流动,并理解每个阶段所执行的计算。

架构概览

正如我们在第一部分中所见,该架构的主要组件包括:

编码器和解码器的数据输入部分包含:

  • 嵌入层(Embedding layer)

  • 位置编码层(Position Encoding layer)

编码器栈由多个编码器组成。每个编码器包含:

  • 多头注意力层(Multi-Head Attention layer)

  • 前馈层(Feed-forward layer)

解码器栈由多个解码器组成。每个解码器包含:

  • 两个多头注意力层

  • 前馈层

输出层(右上角)------ 生成最终输出,包含:

  • 线性层(Linear layer)

  • Softmax 层

为了理解每个组件的作用,我们以机器翻译任务 为例,走一遍 Transformer 在训练阶段的工作流程。我们使用一组训练样本:

  • 输入序列:英文句子 You are welcome

  • 目标序列:西班牙语句子 De nada

嵌入与位置编码

和所有 NLP 模型一样,Transformer 需要为每个单词获取两类信息:

  • 单词的含义

  • 单词在序列中的位置

  • 嵌入层负责编码单词的含义。

  • 位置编码层负责表示单词的位置。

  • Transformer 通过逐元素相加的方式将这两种编码融合。

嵌入(Embedding)

Transformer 拥有两个嵌入层 。输入序列被送入第一个嵌入层,该层称为输入嵌入层(Input Embedding)

目标序列会先向右偏移一位 ,并在第一个位置插入起始标记(Start token),然后再送入第二个嵌入层。注意,在推理阶段我们没有目标序列,正如第一部分所学,我们会通过循环将输出序列送入这第二层。这也是它被称为 输出嵌入层(Output Embedding) 的原因。

文本序列会通过词表映射为数字形式的单词 ID 。随后,嵌入层将每个输入单词映射为嵌入向量,这是对单词语义更丰富的表示。

位置编码

由于 RNN 采用循环结构、按顺序逐个输入单词 ,它能隐式地感知每个单词的位置

但 Transformer 不使用 RNN,序列中的所有单词都是并行输入 的。这是它相比 RNN 架构的主要优势,但也意味着位置信息会丢失 ,必须额外重新加入

和两个嵌入层一样,Transformer 也有两个位置编码层 。位置编码的计算与输入序列无关 ,是一组只取决于序列最大长度的固定值

例如:

  • 第一个位置对应一个常量编码,表示第 1 位

  • 第二个位置对应一个常量编码,表示第 2 位

  • 依此类推

这些常量通过下面的公式计算,其中

  • pos:单词在序列中的位置
  • d_model:编码向量的长度(与嵌入向量长度相同)
  • i:该向量内部的索引值

换句话说,它交替使用正弦曲线和余弦曲线 :所有偶数索引 使用正弦值,所有奇数索引使用余弦值。

举个例子,如果我们对一个包含 40 个单词的序列进行编码,下图可以看到若干(单词位置,编码索引)组合对应的编码值。

蓝色曲线表示全部 40 个单词位置第 0 号索引 上的编码值,橙色曲线表示全部 40 个单词位置第 1 号索引上的编码值。其余索引值也会有类似的曲线。

矩阵维度

我们知道,深度学习模型会一次性处理一批训练样本 。嵌入层与位置编码层作用于代表一批序列样本的矩阵之上。

嵌入层接收形状为 (样本数,序列长度) 的单词 ID 矩阵,将每个单词 ID 编码为长度等于嵌入维度 的词向量,最终输出形状为 (样本数,序列长度,嵌入维度) 的矩阵。

位置编码使用的编码维度嵌入维度 相等,因此它会生成形状相同的矩阵,可以与嵌入矩阵直接相加

由嵌入层和位置编码层生成的形状为 (样本数,序列长度,嵌入维度) 的矩阵,在数据流经编码器栈和解码器栈的整个过程中都会保持不变,直到最终被输出层重塑形状。

这让我们对 Transformer 中的三维矩阵维度有了直观认识。不过,为了简化可视化展示,从现在起我们将去掉第一个维度(样本数),只使用二维表示来描述单个样本。

输入嵌入层(Input Embedding)将输出送入编码器。同样,输出嵌入层(Output Embedding)将输出送入解码器。

编码器

编码器栈和解码器栈分别由若干个(通常是 6 个)编码器和解码器依次串联组成。

栈中的第一个编码器 接收来自嵌入层与位置编码 的输入。栈中的其他编码器 接收来自上一个编码器的输出作为输入。

编码器将其输入传入多头自注意力层 。自注意力的输出被传入前馈网络层 ,然后前馈层将其输出向上传递给下一个编码器

自注意力层和前馈层这两个子层,外部都带有残差跳跃连接 ,之后再进行层归一化(Layer Normalization)

最后一个编码器的输出,会被送入解码器栈中的每一个解码器,具体过程如下所述。

解码器

解码器的结构与编码器非常相似,但存在几处不同。

与编码器一样,栈中的第一个解码器 接收来自输出嵌入层和位置编码 的输入。栈中的其他解码器 接收来自上一个解码器的输入。

解码器先将输入传入多头自注意力层 。这一层的工作方式与编码器中的略有不同:它只能关注序列中已经出现的位置 。这是通过屏蔽未来位置实现的,我们稍后会详细讲解。

与编码器不同,解码器拥有第二个多头注意力层 ,称为编码器‑解码器注意力层 。编码器‑解码器注意力层的工作方式与自注意力类似,唯一的区别是它会融合两路输入:下方自注意力层的输出,以及编码器栈的输出。

自注意力的输出会被传入前馈网络层,然后前馈层再将输出向上传递给下一个解码器。

自注意力、编码器‑解码器注意力、前馈网络,这三个子层都带有残差跳跃连接,之后都会经过层归一化。

注意力机制

在第一部分中,我们讲过为什么注意力机制在处理序列时如此重要。在 Transformer 中,注意力主要用在三个地方:

  • 编码器中的自注意力 ------ 输入序列关注自身

  • 解码器中的自注意力 ------ 目标序列关注自身

  • 解码器中的编码器‑解码器注意力 ------ 目标序列关注输入序列

注意力层接收三个形式为参数的输入,分别称为查询(Query)、键(Key)和值(Value)

在编码器的自注意力中,编码器的输入会同时被送入Query、Key、Value这三个参数。

在解码器的自注意力层中,解码器的输入会被同时传入查询(Query)、键(Key)和值(Value) 这三个参数。

在解码器的编码器‑解码器注意力层中:

  • 编码器栈中最后一个编码器 的输出被传入 值(Value)键(Key)参数。

  • 其下方自注意力(及层归一化)模块的输出被传入 查询(Query)参数。

多头注意力

Transformer 将每个注意力计算单元称为一个注意力头(Attention Head) ,并将多个注意力头并行重复 执行。这一结构被称为多头注意力(Multi-head Attention) 。它通过组合多个相似的注意力计算,让模型的分辨与建模能力更强

查询(Query)、键(Key)和值(Value)分别通过独立的线性层 ,每层都有各自的权重,生成三个结果,分别称为 Q、K 和 V 。然后使用下面所示的注意力公式 将它们组合在一起,得到注意力分数(Attention Score)

这里需要重点理解的是:Q、K、V 中都携带了序列里每个单词的编码表示 。注意力计算会将每个单词与序列中所有其他单词进行融合 ,因此最终的注意力分数会为序列中的每个单词编码出一个权重分值。

刚才在讲解解码器时,我们简单提到过掩码(Masking)。掩码也显示在上面的注意力结构图中。下面我们来看它的工作原理。

注意力掩码(Attention Masks)

在计算注意力分数时,注意力模块会执行一个掩码步骤。掩码主要有两个作用:

  1. 编码器自注意力编码器‑解码器注意力 中:掩码用于将输入句子中填充(padding)位置 的注意力输出置为 0,确保填充部分不会对自注意力产生影响。(注:由于输入序列长度可能不同,和大多数 NLP 任务一样,会用填充标记补齐长度,以便向 Transformer 输入固定长度的向量。)

编码器‑解码器(Encoder-Decoder)注意力的原理也是如此。

在解码器自注意力中:掩码的作用是防止解码器在预测下一个单词时,提前 "偷看" 目标句子的后续内容

解码器处理源语言序列,并利用它来预测目标语言序列的单词。在训练过程中,这是通过教师强制(Teacher Forcing)实现的,即把完整的目标序列作为解码器的输入。因此,在预测某个位置的单词时,解码器既可以看到该位置之前 的目标单词,也能看到该位置之后的目标单词。这会让解码器利用未来 "时间步" 的目标单词进行 "作弊"。

例如,在预测第 3 个单词时,解码器应该只能参考目标序列中的前 3 个输入单词,而不能看到第 4 个单词 "Ketan"。

因此,解码器会屏蔽掉序列中出现在后面的输入单词

在计算注意力分数时(参考之前展示计算过程的图),掩码会在 Softmax 之前直接作用于分子部分 。被屏蔽的元素(白色方块)会被设置为负无穷大,这样经过 Softmax 后,这些值就会变为 0。

生成输出

解码器栈中的最后一个解码器 将其输出传递给输出组件,由输出组件将其转换为最终的输出句子。

线性层(Linear layer) 将解码器向量投影为单词分数 :对句子中的每个位置,都为目标词表中的每个唯一单词分配一个分数值。例如,如果最终输出句子有 7 个单词,而西班牙语目标词表有 10000 个唯一单词,我们就会为这 7 个位置中的每一个位置生成 10000 个分数值。这些分数表示词表中每个单词出现在句子该位置的概率大小

然后 Softmax 层 将这些分数转换为概率 (所有概率之和为 1.0)。在每个位置上,我们找到概率最高 的单词对应的索引,再将该索引映射回词表中对应的单词。这些单词就构成了 Transformer 的输出序列

训练与损失函数

在训练过程中,我们使用交叉熵损失等损失函数,将模型生成的输出概率分布与目标序列进行对比。该概率分布表示每个单词出现在对应位置的概率。

假设我们的目标词表只包含四个单词。我们的目标是生成一个概率分布 ,使其与我们期望的目标序列 "De nada END" 相匹配。

这意味着:

  • 第一个单词位置的概率分布中,"De" 的概率应为 1,词表中所有其他单词的概率为 0。

  • 第二个和第三个单词位置的概率分布中,"nada""END" 的概率应分别为 1。

与往常一样,我们使用损失函数计算梯度 ,并通过反向传播训练 Transformer 模型。

总结

希望这篇内容能让你对 Transformer 在训练阶段 的内部运行过程有一个直观认识。正如我们在上一篇文章中讨论的,它在推理阶段会以循环方式运行,但大部分处理流程保持不变。

多头注意力模块是 Transformer 的核心能力所在。在下一篇文章中,我们将继续深入,真正拆解注意力机制的具体计算细节。

最后,如果你喜欢这篇文章,你可能也会喜欢我其他关于深度学习 的系列教程。用直白语言讲透 Transformer

相关推荐
Daydream.V2 小时前
Opencv——图片旋转及多模板匹配
人工智能·opencv·计算机视觉
我材不敲代码2 小时前
OpenCV 项目实战:多方向箭头识别与模板匹配优化
人工智能·opencv·计算机视觉
IT研究所2 小时前
从工单到智能分析:AIGC运维助手应用价值
大数据·运维·数据库·人工智能·科技·低代码·自动化
小真zzz2 小时前
导入生成PPT评测:全链路AI闭环工具
人工智能·ai·aigc·powerpoint·chatppt
忧郁的橙子.2 小时前
01-深度学习基础原理
人工智能·深度学习
桂花饼2 小时前
官方已开放Sora视频编辑和创建角色接口
人工智能·gpt·qwen3-next·sora2pro·gemini-3.1pro
生活予甜3 小时前
MINISH科技宣布迈向健康科技企业的新阶段
大数据·人工智能·科技
catchadmin3 小时前
用 Laravel AI SDK 构建多智能体工作流
人工智能·php·laravel