第三章 Transformer架构详解¶
导读¶
Transformer 是过去 8 年最重要的深度学习架构——所有主流 LLM(GPT、Claude、Llama、Qwen、DeepSeek)都基于它。本章解释它的核心机制:Self-Attention、Multi-Head、Positional Encoding、Encoder/Decoder。读完后,你应该能看懂 model.forward() 里发生的事。
3.1 为什么需要 Transformer¶
2017 年之前,自然语言处理的主流是 RNN/LSTM。RNN 的核心问题是:
- 顺序计算:必须从左到右逐 token 处理,无法并行;
- 长程依赖弱:信息要经过很多步传递,远端 token 的关联会衰减;
- 训练慢:上面两个问题导致 GPU 利用率低。
Transformer 用一个关键想法同时解决两者:让每个 token 直接"看"所有其他 token——通过 Self-Attention。
3.2 Self-Attention:核心公式¶
公式:
直觉解释:
- Q(Query):当前 token 在"问什么";
- K(Key):所有 token 在"匹配什么";
- V(Value):所有 token 在"提供什么内容";
- \(QK^T\):得到每个 token 对当前 token 的重要性权重(一个 L×L 矩阵);
- softmax:归一化为概率;
- 乘 V:按权重加权聚合。
为什么除以 \(\sqrt{d_k}\)?当 \(d_k\) 大时,\(QK^T\) 数值方差变大,softmax 会进入梯度饱和区(接近 one-hot),导致梯度消失。除以 \(\sqrt{d_k}\) 让方差稳定在 1 附近。
伪代码:
def attention(Q, K, V):
scores = Q @ K.transpose(-1, -2) / math.sqrt(d_k) # [B, H, L, L]
if causal:
scores = scores + causal_mask # 下三角保留
weights = softmax(scores) # [B, H, L, L]
output = weights @ V # [B, H, L, d_k]
return output
3.3 Multi-Head Attention¶
把 Q、K、V 切成 h 份,分别做 attention,再拼接:
def multi_head_attention(x, W_q, W_k, W_v, W_o, num_heads):
B, L, D = x.shape
d_head = D // num_heads
Q = x @ W_q # [B, L, D]
K = x @ W_k
V = x @ W_v
# 切头
Q = Q.view(B, L, num_heads, d_head).transpose(1, 2) # [B, H, L, d_head]
K = K.view(B, L, num_heads, d_head).transpose(1, 2)
V = V.view(B, L, num_heads, d_head).transpose(1, 2)
out = attention(Q, K, V) # [B, H, L, d_head]
out = out.transpose(1, 2).reshape(B, L, D) # 合并头
return out @ W_o
为什么多头?
- 不同 head 学习不同子空间的关系(语法、共指、语义、位置);
- 总参数量不变(h × d_head = d_model);
- 计算量不变,但表达力提升。
变体(重要!):
- MHA(标准):每 head 独立 Q/K/V,KV Cache 大;
- MQA(Multi-Query):所有 head 共享 1 个 K/V,KV Cache 极小,质量略降;
- GQA(Grouped-Query):折中——多 head 共享 K/V 组。Llama-3、Qwen 等现代模型标配。
3.4 位置编码¶
Attention 本身是"集合操作"——没有顺序概念。但语言显然有顺序。所以需要额外注入位置信息。
绝对位置编码(原论文):用 sin/cos 函数生成不同位置的固定向量,加到 token embedding 上。
RoPE(Rotary Position Embedding,旋转位置编码)——现代 LLM 事实标准:
- 不加在 input 上,而是**乘在 Q、K 上**——通过旋转矩阵 \(R(\theta_m)\) 让 \(Q_m \cdot K_n\) 仅依赖相对位置 \(m - n\);
- 优点:外推性好——训练 4K 可推到 32K+,无需重训;
- 通过 YaRN、NTK-aware scaling 等技巧,可推到 1M。
3.5 Feed-Forward Network(FFN)¶
每个 Attention 之后接一个 FFN:
现代变体:SwiGLU
引入"门控"机制,比 ReLU 表现更好但参数稍多。Llama、Qwen 都用 SwiGLU。
关键事实:FFN 占模型参数量的约 2/3。Attention 的计算随 L² 增长,FFN 随 L × d² 增长。
3.6 Layer Normalization 与残差连接¶
LayerNorm:对一个样本的所有特征做归一化(减均值、除标准差、再仿射变换)。让训练更稳定。
RMSNorm:LayerNorm 简化版——不算均值,只算 RMS(root mean square)。计算更快,效果接近。现代 LLM 标配。
def rmsnorm(x, weight, eps=1e-6):
rms = x.pow(2).mean(-1, keepdim=True).add(eps).sqrt()
return x / rms * weight
残差连接(Residual Connection):
让梯度能"短路"回流,缓解深层网络梯度消失。Transformer 每个子层(attention / FFN)都包残差。
3.7 完整的 Transformer Block¶
伪代码(一个 decoder block):
def transformer_block(x):
# 子层1:Attention
h = rmsnorm(x)
x = x + attention(h, params_attn)
# 子层2:FFN
h = rmsnorm(x)
x = x + ffn(h, params_ffn)
return x
将这个 block 堆叠 N 层(Llama-3 8B 是 32 层,70B 是 80 层,GPT-4 估 120+层),就是 LLM 的主干。
3.8 Encoder vs Decoder vs Encoder-Decoder¶
原始 Transformer(2017)是 Encoder-Decoder 结构,用于翻译:
- Encoder:双向注意力,看完整句,输出表示;
- Decoder:单向(causal)注意力 + cross-attention 到 encoder 输出,自回归生成。
后续演化:
- BERT:纯 Encoder,双向注意力,适合理解任务(分类、检索);
- GPT 系列:纯 Decoder,单向注意力,自回归生成,当前 LLM 主流;
- T5、BART:Encoder-Decoder,适合翻译/摘要。
为什么 Decoder 主导了 LLM?因为:
- 自回归 + next-token 预测是**通用任务**——所有文本都可用;
- 可无监督训于海量原始文本,不需要标注;
- Scaling laws 友好(越大越好)。
3.9 Causal Mask:让 Decoder 看不见未来¶
Decoder 训练时,整个序列一次性前向,但要保证"预测第 i 个 token 时只能看前 i-1 个"。实现方式是**下三角 mask**:
mask = torch.triu(torch.full([L, L], float('-inf')), diagonal=1)
scores = scores + mask # 上三角变 -inf,softmax 后变 0
这样每个位置只看到自己和之前的位置。生成时则逐 token 生成,每次新 token 的 K/V append 到 KV Cache(第 8 章详述)。
3.10 参数量估算¶
一个 Transformer 模型的参数大致分布在:
| 部分 | 参数量 | 占比 |
|---|---|---|
| Embedding | V × d | 与词表正相关 |
| Attention 每层 | 4d²(Q/K/V/O 各 d²) | ~30% |
| FFN 每层 | ~8d²(SwiGLU 三个矩阵) | ~60% |
| LayerNorm 等 | 几个 d | <1% |
粗略公式:N_params ≈ 12 × L_layers × d_model²(含 FFN)。
例:Llama-3 8B:L=32, d=4096 → 12×32×4096² ≈ 6.4B,加上 embedding 与 head 约 8B。
3.11 计算量估算¶
每个 token 前向算力 ≈ 2 × N_params FLOPs(粗估,含 attention 与 FFN)。
- 7B 模型,1 token ≈ 14 GFLOPS;
- 一次推理 1K tokens ≈ 14 TFLOPS;
- 训练 1T tokens ≈ 14 EFLOPS。
这就是为什么训练需要上万 GPU·月的算力——而推理成本相对便宜。
工程实战要点¶
- 不要手写 attention——用 FlashAttention、sdpa 等优化实现;
- GQA 是现代模型默认——评估开源模型时关注是否用 GQA,影响 KV Cache;
- RoPE 外推——若要扩上下文,了解 YaRN、NTK;
- Causal Mask 不能漏——训练数据中混入非 causal 实现会导致 loss 不降;
- **参数量与计算量**估算能力是基础——估不出量级就无法判断硬件可行性。
小结¶
- Transformer 用 Self-Attention 让每 token 直接看所有 token,解决 RNN 并行与长程依赖问题;
- Attention 公式:softmax(QK^T/√d)·V;
- Multi-Head 切分 Q/K/V 学习不同子空间;GQA 是现代主流折中;
- RoPE 注入位置信息,外推性好;
- FFN(SwiGLU)占 2/3 参数,是表达力主体;
- 残差 + RMSNorm 让深层网络可训;
- Decoder-only + Causal Mask 是当前 LLM 标准结构;
- 参数量 ≈ 12 × L × d²,算力 ≈ 2 × N × tokens。
练习题¶
- 写出 Attention 的完整公式,解释每一项的含义。
- 为什么 Attention 要除以 √d_k?
- 解释 MHA、MQA、GQA 的区别。为什么 GQA 是折中?
- RoPE 与绝对位置编码相比,关键优势是什么?
- 为什么 FFN 占模型参数量大头(约 2/3)?
- 解释 Causal Mask 是如何让 Decoder "看不见未来"的。
- 估算 Llama-3 70B 的参数量(L=80, d=8192),并与真实值对比。
- 一个 7B 模型,前向处理 1 个 token 大约多少 FLOPs?处理 4096 tokens 呢?
- 残差连接在深层 Transformer 中起什么作用?