Transformer 模型深度详解
Transformer 模型由 Google Brain 团队在 2017 年的论文 “Attention Is All You Need” 中提出。它彻底改变了自然语言处理 (NLP) 领域,并成为了当前大语言模型 (LLM) 的基石。Transformer 模型以其强大的并行计算能力和卓越的长距离依赖建模能力,取代了传统的循环神经网络 (RNN) 和长短期记忆网络 (LSTM) 结构,成为了序列建模任务的主流架构。
核心思想:Transformer 放弃了传统的循环和卷积结构,完全依赖于注意力机制 (Attention Mechanism)来捕捉输入序列中的依赖关系。通过精心设计的自注意力 (Self-Attention) 机制,模型能够同时关注输入序列中的所有位置,从而实现高效的并行计算和对任意距离依赖的有效建模。
一、为什么需要 Transformer?
在 Transformer 出现之前,RNN 及其变体 (如 LSTM 和 GRU) 是序列建模任务的主流。然而,它们存在一些固有的局限性:
- 顺序依赖:RNN 必须顺序地处理序列中的每个元素,后一个元素的计算依赖于前一个元素。这导致:
- 难以并行化:限制了训练速度,尤其是在处理长序列时。
- 长距离依赖问题:随着序列长度增加,信息在传播过程中逐渐衰减,模型难以捕捉到相距较远元素之间的关联,即“梯度消失”或“梯度爆炸”问题。
- 计算效率低下:每个时间步的计算都需要等待前一个时间步的结果,导致训练和推理速度慢。
Transformer 模型通过引入自注意力机制,有效地解决了这些问题,实现了序列建模的范式转变。
二、Transformer 架构概览
Transformer 模型遵循经典的编码器-解码器 (Encoder-Decoder) 结构,但其内部实现完全基于注意力机制。
整体结构:
- 编码器 (Encoder):由
N个相同的编码器层堆叠而成。它负责将输入序列(例如,源语言句子)转换为一系列连续的表示。 - 解码器 (Decoder):由
N个相同的解码器层堆叠而成。它负责将编码器的输出和之前生成的输出序列(例如,目标语言句子)作为输入,生成下一个输出序列的元素。
graph LR
subgraph Transformer
Input[输入序列] --> InputEmbedding[输入嵌入 + 位置编码];
subgraph Encoder Stack
E1[编码器层 1] --> E2[编码器层 2] --> ... --> EN[编码器层 N];
end
InputEmbedding --> E1;
EN --> EncoderOutput[编码器输出];
OutputEmbedding[输出嵌入 + 位置编码] --> D1[解码器层 1];
D1 --> D2[解码器层 2] --> ... --> DN[解码器层 N];
EncoderOutput --> D1;
DN --> Linear[线性层] --> Softmax[Softmax];
Softmax --> Output[输出概率分布];
end
三、编码器 (Encoder) 详解
每个编码器层包含两个主要的子层:
- 多头自注意力机制 (Multi-Head Self-Attention)
- 前馈神经网络 (Feed-Forward Network, FFN)
每个子层之后都跟着一个残差连接 (Residual Connection) 和层归一化 (Layer Normalization)。
3.1 输入嵌入 (Input Embedding) 与位置编码 (Positional Encoding)
在将输入序列送入编码器之前,每个词(token)首先被转换成一个词向量 (Word Embedding)。由于 Transformer 模型不包含循环或卷积,它自身无法感知输入序列中词的顺序信息。因此,需要引入位置编码来注入词的位置信息。
位置编码公式:
我们使用不同频率的正弦和余弦函数来生成位置编码:
$$
PE_{(pos, 2i)} = \sin(pos / 10000^{2i/d_{model}}) \
PE_{(pos, 2i+1)} = \cos(pos / 10000^{2i/d_{model}})
$$
其中:
pos是词在序列中的位置 (0 到max_sequence_length - 1)。i是位置编码向量的维度索引 (0 到d_model/2 - 1)。d_model是词向量的维度。
最终的输入是词嵌入和位置编码的简单求和。
3.2 多头自注意力机制 (Multi-Head Self-Attention)
这是 Transformer 的核心,允许模型在处理序列的某个词时,同时关注序列中的其他词,并计算它们之间的关联性。
a. 自注意力 (Self-Attention)
对于输入序列中的每个词,自注意力机制会计算三个向量:查询 (Query, Q)、键 (Key, K) 和值 (Value, V)。它们通过将词嵌入向量与三个不同的权重矩阵 $W^Q, W^K, W^V$ 相乘得到。
一旦有了 Q、K、V 向量,我们就可以计算自注意力的输出了:
- 计算注意力分数:将查询向量 $Q$ 与所有键向量 $K$ 进行点积,得到注意力分数。点积衡量了查询与每个键之间的相似度。
- 缩放 (Scaling):为了防止点积结果过大导致 softmax 函数进入梯度饱和区,将注意力分数除以 $\sqrt{d_k}$ (键向量的维度)。
- Softmax:对缩放后的分数应用 Softmax 函数,将其转换为概率分布,表示每个词对当前词的关注程度。
- 加权求和:将 Softmax 结果(注意力权重)与所有值向量 $V$ 相乘并求和,得到当前词的自注意力输出。
Scaled Dot-Product Attention 公式:
$$
Attention(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V
$$
其中:
- $Q$ 是查询矩阵 (queries, 维度 $n \times d_k$)。
- $K$ 是键矩阵 (keys, 维度 $m \times d_k$)。
- $V$ 是值矩阵 (values, 维度 $m \times d_v$)。
- $n$ 是输出序列长度, $m$ 是输入序列长度。在自注意力中,$n=m$。
- $d_k$ 是键向量的维度。
b. 多头注意力 (Multi-Head Attention)
多头注意力是自注意力机制的扩展。它将 Q、K、V 投影到 $h$ 个不同的子空间中($h$ 为头的数量),然后独立地并行执行 $h$ 次自注意力计算。每个头都可以学习到不同的关注模式。最后,将所有头的输出拼接起来,再通过一个线性投影得到最终输出。
多头注意力使得模型能够:
- 在不同的表示子空间中捕捉到不同类型的依赖关系。
- 提高模型捕捉复杂模式的能力。
graph TD
Input_X[输入 X] --> Linear_Q[线性变换 WQ];
Input_X --> Linear_K[线性变换 WK];
Input_X --> Linear_V[线性变换 WV];
Linear_Q --> Q[Q];
Linear_K --> K[K];
Linear_V --> V[V];
subgraph Head_1
Q -- 1 --> Attn_1[Scaled Dot-Product Attention];
K -- 1 --> Attn_1;
V -- 1 --> Attn_1;
Attn_1 --> Output_1[输出 1];
end
subgraph Head_2
Q -- 2 --> Attn_2[Scaled Dot-Product Attention];
K -- 2 --> Attn_2;
V -- 2 --> Attn_2;
Attn_2 --> Output_2[输出 2];
end
subgraph Head_h
Q -- h --> Attn_h[Scaled Dot-Product Attention];
K -- h --> Attn_h;
V -- h --> Attn_h;
Attn_h --> Output_h[输出 h];
end
Output_1 & Output_2 & ... & Output_h --> Concat["拼接 (Concatenate)"];
Concat --> Linear_Output[线性变换 WO];
Linear_Output --> Final_Output[多头注意力输出];
3.3 Add & Norm (残差连接与层归一化)
每个子层(多头自注意力或前馈网络)的输出都会与该子层的输入进行残差连接,然后进行层归一化。
- 残差连接:$x + \text{Sublayer}(x)$。有助于解决深度网络中的梯度消失问题,使信息能够更容易地在网络中传播。
- 层归一化 (Layer Normalization):对每个样本的特征维度进行归一化,稳定了深层网络的训练过程。
3.4 前馈神经网络 (Feed-Forward Network, FFN)
FFN 是一个简单的两层全连接网络,通常包含一个 ReLU 激活函数:
$FFN(x) = \max(0, xW_1 + b_1)W_2 + b_2$
它对每个位置独立地进行相同的转换。
四、解码器 (Decoder) 详解
每个解码器层包含三个主要子层:
- 遮盖多头自注意力机制 (Masked Multi-Head Self-Attention)
- 多头编码器-解码器注意力机制 (Multi-Head Encoder-Decoder Attention)
- 前馈神经网络 (Feed-Forward Network, FFN)
同样,每个子层之后也跟着一个残差连接和层归一化。
4.1 遮盖多头自注意力 (Masked Multi-Head Self-Attention)
与编码器中的自注意力类似,但它在 Softmax 之前引入了一个“遮盖”机制。
遮盖 (Masking):确保解码器在预测当前位置的输出时,只能关注当前位置及之前的词,而不能“看到”未来的词。这模拟了序列生成的顺序性。
4.2 多头编码器-解码器注意力 (Multi-Head Encoder-Decoder Attention)
这个注意力层用于连接编码器和解码器。
- 查询 (Q) 向量来自前一个解码器层的输出。
- 键 (K) 和 值 (V) 向量来自编码器层的输出。
这使得解码器在生成输出时,能够关注输入序列中的相关部分。
4.3 最终输出层
解码器的输出经过一个线性层 (Linear Layer) 和一个 Softmax 层,转换为词汇表上每个词的概率分布,从而预测下一个词。
五、Transformer 的训练
Transformer 通常通过最大化下一个词的对数似然进行训练,即一个标准的序列到序列任务的交叉熵损失函数。优化器常采用 Adam,并结合自定义的学习率调度策略。
六、Transformer 的优缺点与应用
6.1 优点
- 并行计算能力:自注意力机制允许模型同时处理序列中的所有词,极大地提高了训练效率。
- 有效捕捉长距离依赖:通过注意力机制,模型可以轻松地连接相距很远的词,克服了 RNN 的长距离依赖问题。
- 更少的归纳偏置 (Inductive Bias):相较于 CNN 和 RNN,Transformer 对数据结构的假设更少,理论上可以学习更广泛的模式。
- 模型可解释性:注意力权重可以部分揭示模型在决策时关注了哪些输入部分。
6.2 缺点
- 计算复杂度:自注意力机制的计算复杂度是序列长度 $L$ 的平方 ($O(L^2)$),对于非常长的序列,计算成本非常高。
- 位置编码依赖:Transformer 本身不具备处理顺序的能力,必须依赖于位置编码。
- 内存消耗:Q、K、V 矩阵以及注意力矩阵的存储需要大量内存,尤其是在处理长序列时。
6.3 典型应用
Transformer 模型及其变体已成为各种 AI 任务的核心:
- 自然语言处理 (NLP):
- 机器翻译 (Machine Translation)
- 文本摘要 (Text Summarization)
- 问答系统 (Question Answering)
- 情感分析 (Sentiment Analysis)
- 预训练语言模型 (如 BERT, GPT 系列, T5)
- 计算机视觉 (CV):
- 图像分类 (Vision Transformer, ViT)
- 目标检测 (DETR)
- 图像生成
- 语音识别 (Speech Recognition)
- 多模态任务 (结合文本和图像等)
七、核心组件 Go 语言代码示例 (概念性)
由于 Go 语言在深度学习模型构建方面不如 Python (TensorFlow/PyTorch) 常用,以下提供一个概念性的 Go 语言实现,着重展示 Scaled Dot-Product Attention 的核心计算逻辑。实际的矩阵运算在 Go 中通常会依赖专门的线性代数库。
1 | package transformer |
八、总结
Transformer 模型以其完全基于注意力机制的创新设计,彻底改变了深度学习在序列建模领域的应用。它通过并行计算能力和对长距离依赖的有效捕捉,超越了传统 RNN 模型的局限性,成为 NLP、CV 等众多领域的核心模型。从机器翻译到大语言模型,Transformer 及其变体持续推动着人工智能技术的发展。理解其编码器-解码器架构、多头自注意力机制和位置编码是理解现代 AI 模型工作原理的关键。
