深入理解 Transformer 架构:从注意力机制到完整计算流程

Transformer 是当今所有大语言模型(GPT、BERT、LLaMA、Claude……)的基础架构。2017 年,Vaswani 等人在论文 Attention Is All You Need 中提出了它,此后它几乎替代了 RNN 和 CNN,成为 NLP 乃至视觉、语音等领域的通用模型骨架。

这篇文章尝试从零讲清 Transformer 的完整计算流程:输入一个句子,数据在模型内部经历了什么?每一步的数学是什么?为什么这样设计?

建议搭配 3D 交互式模型阅读Transformer Architecture 3D Explorer——可以在浏览器中旋转、点击每个组件查看内部结构和计算细节。

1. 整体架构:Encoder-Decoder

原始 Transformer 采用 Encoder-Decoder 结构:

  • Encoder(编码器):读取输入序列,逐层提取表示。每一层包含两个子层:多头注意力 + 前馈网络。层数通常为 6-24 层(原始论文 6 层)。
  • Decoder(解码器):逐个生成输出 token。每一层包含三个子层:掩码自注意力 + 交叉注意力 + 前馈网络。
  • Nx:Encoder 和 Decoder 各重复 N 次,每层有独立的参数。
Encoder                          Decoder
┌──────────────────┐    ┌──────────────────────────┐
│  Add & Norm      │    │  Add & Norm               │
│  Feed Forward    │    │  Feed Forward             │
│  Add & Norm      │    │  Add & Norm               │
│  Multi-Head      │    │  Cross-Attention ← Encoder│
│   Attention      │    │  Add & Norm               │
│  Add & Norm      │    │  Masked Multi-Head        │
│  Pos Encoding    │    │   Attention               │
│  Input Embedding │    │  Pos Encoding             │
│                  │    │  Output Embedding          │
└──────────────────┘    └──────────────────────────┘
     ↑ 输入                      ↑ 输出

注意图中每条线除了串行连接外,还有残差连接(Skip Connection)——输入直接跳接到子层输出后面,这是一个关键设计。

2. 输入处理:从文字到向量

2.1 分词(Tokenization)

模型不直接处理文字,而是先将句子切分为 token。以「今天天气怎么样」为例:

今天天气怎么样  [, , , , , , ]
               Token IDs: [1025, 2098, 2098, 3841, 5563, 3789, 4102]

分词方式可以是字级别、子词级别(BPE、WordPiece)或词级别。现代模型多用 BPE,将常见词保持完整,罕见词拆成子词。

2.2 输入嵌入(Input Embedding)

每个 token ID 通过查表得到一个 d_model 维的向量:

$$E(x_i) = W_{\text{emb}}[x_i] \in \mathbb{R}^{d_{\text{model}}}$$

其中 $W_{\text{emb}}$ 是一个 (vocab_size, d_model) 的嵌入矩阵,通过训练学习。语义相近的 token 在向量空间中距离更近——比如「猫」和「狗」的向量会比「猫」和「汽车」更接近。

典型值:d_model = 512(原始论文)到 4096(GPT-3),vocab_size = 30,000 ~ 50,000

2.3 位置编码(Positional Encoding)

Transformer 没有循环结构(不像 RNN 天然有序),需要额外注入位置信息。原始论文用正弦/余弦函数生成固定编码:

$$PE_{(pos, 2i)} = \sin\left(\frac{pos}{10000^{2i/d_{\text{model}}}}\right)$$

$$PE_{(pos, 2i+1)} = \cos\left(\frac{pos}{10000^{2i/d_{\text{model}}}}\right)$$

不同维度使用不同频率的正弦波——低维度变化快(区分相邻位置),高维度变化慢(区分远距离位置)。最终的输入是嵌入向量 + 位置编码的逐元素相加:

$$\text{Input} = E(x_i) + PE_{pos_i}$$

3. 核心机制:多头注意力(Multi-Head Attention)

这是 Transformer 的心脏。自注意力让模型在看每个词时,能动态关注序列中的其他词。

3.1 单头注意力的计算

给定输入 $X$,先通过三个线性投影得到 Query、Key、Value:

$$Q = X W^Q, \quad K = X W^K, \quad V = X W^V$$

然后计算注意力:

$$\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right) V$$

直觉理解:假设你在读「今天天气怎么样,今天晴天」这句话,遇到「是」这个词时,注意力机制让模型回头看句子中每个词,计算「是」和每个词的关联度(QK 点积),然后用这个关联度加权求和(·V),得到「是」的上下文表示。

为什么除以 $\sqrt{d_k}$? 当维度 $d_k$ 较大时,点积的方差会很大,导致 softmax 输出接近 one-hot(梯度消失)。缩放后分布更平滑,梯度更稳定。

3.2 多头的意义

单头注意力只能学一种关联模式。多头注意力并行运行 h 个独立的注意力头,每个头用不同的 $W^Q, W^K, W^V$ 投影到不同的子空间:

$$\text{head}_i = \text{Attention}(QW_i^Q, KW_i^K, VW_i^V)$$

$$\text{MultiHead}(Q, K, V) = \text{Concat}(\text{head}_1, …, \text{head}_h) W^O$$

每个头可以关注不同的关系:一个头关注语法关系(主语-谓语),另一个关注语义关系(代词-指代对象),还有一个关注位置关系(相邻词)。

典型值:h = 8(原始论文)到 96(GPT-3),$d_k = d_v = d_{\text{model}} / h$。

3.3 三种注意力类型

Transformer 中有三种注意力,用途不同:

类型 Q 来源 K,V 来源 用途
自注意力 Encoder 当前层 Encoder 当前层 理解输入序列内部关系
掩码自注意力 Decoder 当前层 Decoder 当前层 理解已生成的输出(下三角掩码防止看到未来)
交叉注意力 Decoder 当前层 Encoder 最后一层 Decoder 在生成时参考 Encoder 的理解

掩码自注意力的掩码是一个下三角矩阵:

$$M_{ij} = \begin{cases} 0 & \text{if } i \geq j \ -\infty & \text{if } i < j \end{cases}$$

softmax 之前加上 $M$,使得位置 $i$ 只能看到位置 $\leq i$ 的信息——因为生成第 $i$ 个词时,第 $i+1$ 个词还没生成。

4. 残差连接与层归一化(Add & Norm)

每个子层(注意力或 FFN)都被包裹在一个 Add & Norm 结构中:

$$\text{output} = \text{LayerNorm}(x + \text{SubLayer}(x))$$

残差连接($x + \text{SubLayer}(x)$)的作用是:

  • 梯度可以不经过子层直接回传,缓解深层网络的梯度消失
  • 模型至少能学到恒等映射(skip 子层),不会比浅层网络更差
  • 训练更稳定、收敛更快

层归一化(LayerNorm)对每个样本的特征维度做归一化:

$$\text{LN}(x) = \gamma \odot \frac{x - \mu}{\sqrt{\sigma^2 + \epsilon}} + \beta$$

其中 $\mu$ 和 $\sigma^2$ 是该样本在特征维度上的均值和方差,$\gamma$ 和 $\beta$ 是可学习的缩放和偏移参数。归一化稳定了每层输出的数值范围,加速训练收敛。

5. 前馈网络(Feed Forward Network)

每个层的第二个子层是一个逐位置的全连接网络:

$$\text{FFN}(x) = \max(0, xW_1 + b_1)W_2 + b_2$$

先从 $d_{\text{model}}$ 升维到 $d_{\text{ff}}$(通常 $4 \times d_{\text{model}}$),经过 ReLU(或 GELU)激活,再降回 $d_{\text{model}}$。

$$d_{\text{model}} \xrightarrow{W_1} 4 \times d_{\text{model}} \xrightarrow{\text{ReLU}} 4 \times d_{\text{model}} \xrightarrow{W_2} d_{\text{model}}$$

为什么需要 FFN? 注意力层负责信息混合(不同位置之间的交互),FFN 负责非线性变换(增加模型的表达能力)。两者缺一不可。

注意 FFN 是「逐位置」的——它对每个 token 独立作用,不同位置之间没有信息交换。信息交流完全由注意力层完成。

6. 输出层:线性投影 + Softmax

Decoder 最后一层的输出经过一个线性变换,投影到词汇表大小:

$$\text{logits} = X_{\text{final}} W_{\text{out}} + b$$

然后 Softmax 得到概率分布:

$$P(\text{token}_i) = \frac{e^{\text{logits}_i}}{\sum_j e^{\text{logits}_j}}$$

概率最高的 token 就是当前位置的预测输出。生成时通常用 beam searchtop-k sampling 而不是简单的贪心选择。

训练时的损失函数是交叉熵:

$$\mathcal{L} = -\sum_i \log P(\text{token}_{\text{correct}}^{(i)})$$

7. 完整计算流程示例

以机器翻译为例,输入「今天天气怎么样」→ 输出「How is the weather today」:

Step 1: 分词 → Token IDs
Step 2: 查表得到嵌入向量 E(x_i)
Step 3: 加上位置编码 PE → Input = E + PE
Step 4: Encoder ×6 层(每层: Multi-Head Attention → Add&Norm → FFN → Add&Norm)
Step 5: Decoder 逐步生成:
  - 输入已生成的 token(初始只有 <BOS>)
  - Masked Self-Attention(只看已生成的部分)
  - Cross-Attention(Q 来自 Decoder,K/V 来自 Encoder 输出)
  - FFN → Add&Norm
  - Linear → Softmax → 预测下一个 token
  - 重复直到生成 <EOS>

可以在 3D 交互式 Explorer 中点击「📊 开始数据流演示」按钮,看一个完整的数值计算示例(输入「今天天气怎么样」→ 输出「今天是晴天」),每一步都有具体的假想数值(d_model=4 简化展示)。

8. 变体与发展

原始 Transformer 之后出现了多种变体:

模型 架构变化 特点
BERT 只用 Encoder 双向理解,适合分类、NER
GPT 只用 Decoder 自回归生成,适合文本生成
T5 Encoder-Decoder 文本到文本统一框架
LLaMA Decoder-only,改进归一化和激活函数 开源大模型标杆
Mixture of Experts FFN 替换为多个专家子网络 稀疏激活,参数效率更高

现代大模型几乎都是 Decoder-only 架构(GPT 路线),原因是:

  1. 生成任务更通用(prompt + completion 统一了理解和生成)
  2. Encoder-Decoder 在大规模训练中效率不如纯 Decoder
  3. 自回归训练更简单,易于扩展

参考