STAGE 3 前沿探索

Transformer 自注意力

改变 AI 历史的架构 — GPT、BERT、ViT 都建立在它之上

📊 Excel 手推 ⏱️ 25 分钟 🎯 注意力机制
1
📋 本章要点
  • 自注意力机制让每个位置都能直接关注序列中所有其他位置
  • 多头注意力从不同子空间捕获不同类型的依赖关系
  • 位置编码弥补了 Transformer 缺乏序列顺序感知的缺陷
  • Mamba 用选择性状态空间模型实现了线性复杂度的序列建模

什么是自注意力?

自注意力(Self-Attention)的核心思想:让序列中的每个元素都能"看到"其他所有元素,并根据相关性分配不同的关注度。

比如句子 "The cat sat on the mat because it was tired",当模型处理 "it" 这个词时,自注意力能让它特别关注 "cat",从而理解 "it" 指的是猫。

🔑 三个关键角色:Q、K、V

每个输入词都会生成三个向量,就像图书馆找书的比喻:

🔍
Q (Query)
"我在找什么?"
当前词想要了解的信息
🏷️
K (Key)
"我有什么标签?"
每个词能提供的信息描述
📦
V (Value)
"我的实际内容是?"
每个词的实际语义内容

QK 点积 → 得到注意力分数 → Softmax 归一化 → 加权求和 V → 输出

Attention(Q,K,V) = Softmax(Q·KT / √d) · V
2

Excel 手推自注意力

用3个词的简单例子,完整推导自注意力的每一步。

📋 输入:三个词的嵌入向量

句子 "我 爱 AI",假设嵌入维度 d=2(简化演示):

嵌入向量 X
[1, 0]
[0, 1]
AI [1, 1]

矩阵形式 X (3×2) = [[1,0], [0,1], [1,1]]

Step 2a:生成 Q、K、V

通过三个权重矩阵将输入映射为 Q、K、V(维度 d=2):

Wq (2×2)
[[1,0],[0,1]]
(单位矩阵简化)
Wk (2×2)
[[1,0],[0,1]]
(单位矩阵简化)
Wv (2×2)
[[1,0],[0,1]]
(单位矩阵简化)

为简化演示,Wq=Wk=Wv=I(单位矩阵),所以 Q=X, K=X, V=X。实际中这三个矩阵通过训练学到不同的值。

Q = X·Wq K = X·Wk V = X·Wv
[1, 0] [1, 0] [1, 0]
[0, 1] [0, 1] [0, 1]
AI [1, 1] [1, 1] [1, 1]

Step 2b:计算注意力分数 Score = Q · KT

每个词的 Q 和所有词的 K 做点积,得到"相关性分数":

Q · KT 计算过程
Q (query) K (key) 点积计算 分数
我 [1,0] → 我 [1,0] 1×1 + 0×0 1
我 [1,0] → 爱 [0,1] 1×0 + 0×1 0
我 [1,0] → AI [1,1] 1×1 + 0×1 1
爱 [0,1] → 我 [1,0] 0×1 + 1×0 0
爱 [0,1] → 爱 [0,1] 0×0 + 1×1 1
爱 [0,1] → AI [1,1] 0×1 + 1×1 1
AI [1,1] → 我 [1,0] 1×1 + 1×0 1
AI [1,1] → 爱 [0,1] 1×0 + 1×1 1
AI [1,1] → AI [1,1] 1×1 + 1×1 2
Score 矩阵 = [[1, 0, 1], [0, 1, 1], [1, 1, 2]]

Step 2c:缩放 — Score / √d

除以 √d(d=2, √2≈1.414)防止点积过大导致 Softmax 梯度消失:

→ 我 → 爱 → AI
我 (query) 1 / 1.414 = 0.707 0 / 1.414 = 0 1 / 1.414 = 0.707
爱 (query) 0 / 1.414 = 0 1 / 1.414 = 0.707 1 / 1.414 = 0.707
AI (query) 1 / 1.414 = 0.707 1 / 1.414 = 0.707 2 / 1.414 = 1.414

Step 2d:Softmax 归一化 — 得到注意力权重

对每一行做 Softmax,让注意力权重加起来等于 1:

→ 我 → 爱 → AI 求和验证
我 (query) e^0.707 / (e^0.707 + e^0 + e^0.707) = 0.370 e^0 / (…) = 0.260 e^0.707 / (…) = 0.370 1.000 ✓
爱 (query) e^0 / (…) = 0.260 e^0.707 / (…) = 0.370 e^0.707 / (…) = 0.370 1.000 ✓
AI (query) e^0.707 / (…) = 0.289 e^0.707 / (…) = 0.289 e^1.414 / (…) = 0.422 1.000 ✓

解读注意力权重:

  • "我" 最关注自己和 "AI"(各0.370),对 "爱" 关注较少(0.260)
  • "爱" 最关注自己和 "AI"(各0.370),对 "我" 关注较少(0.260)
  • "AI" 最关注自己(0.422),因为它的向量 [1,1] 和自己最匹配

Step 2e:加权求和 — Output = Attention · V

用注意力权重对 V 做加权求和,得到每个词的新表示:

"我" 的输出 = 0.370 × V_我 + 0.260 × V_爱 + 0.370 × V_AI
分量 0.370 × [1,0] + 0.260 × [0,1] + 0.370 × [1,1] 结果
维度 1 0.370 + 0 + 0.370 0.740
维度 2 0 + 0.260 + 0.370 0.630
"爱" 的输出 = 0.260 × V_我 + 0.370 × V_爱 + 0.370 × V_AI
分量 0.260 × [1,0] + 0.370 × [0,1] + 0.370 × [1,1] 结果
维度 1 0.260 + 0 + 0.370 0.630
维度 2 0 + 0.370 + 0.370 0.740
"AI" 的输出 = 0.289 × V_我 + 0.289 × V_爱 + 0.422 × V_AI
分量 0.289 × [1,0] + 0.289 × [0,1] + 0.422 × [1,1] 结果
维度 1 0.289 + 0 + 0.422 0.711
维度 2 0 + 0.289 + 0.422 0.711

最终输出(每个词的新表示):

"我"[0.740, 0.630]
"爱"[0.630, 0.740]
"AI"[0.711, 0.711]

注意:现在每个词的向量都融合了其他词的信息!这就是"注意力"的魔力。

2f

多头注意力 — Multi-Head Attention

一个"头"只能从一个角度看问题。多头注意力让模型同时从多个角度理解句子

🎯 核心思想

把 Q、K、V 拆成多个"头"(head),每个头独立做注意力计算,最后把结果拼接起来,再通过一个线性变换整合。

类比:就像你读一句话时,同时用"语法视角"、"语义视角"、"情感视角"去理解它,最后综合所有视角得出全面理解。

📐 简化例子:2 个头,每头维度 d=1

沿用上面 "我 爱 AI" 的例子。原始 Q/K/V 维度为 2,我们拆成 2 个头,每个头只看一个维度:

Step 2f-1:拆分 Q、K、V
原始 Q (d=2) Head 1 Q (第1维) Head 2 Q (第2维)
[1, 0] 1 0
[0, 1] 0 1
AI [1, 1] 1 1

K 和 V 同样按维度拆分(此处 Wq=Wk=Wv=I,所以 K 和 V 与 Q 相同)。

Step 2f-2:Head 1 独立做注意力(只看第1维)
Q (query) K (key) Q·K (标量) Softmax 权重 加权 V
我: 1 我:1 / 爱:0 / AI:1 1, 0, 1 0.370, 0.260, 0.370 0.370×1 + 0.260×0 + 0.370×1 = 0.740
爱: 0 我:1 / 爱:0 / AI:1 0, 0, 0 0.333, 0.333, 0.333 0.333×1 + 0.333×0 + 0.333×1 = 0.667
AI: 1 我:1 / 爱:0 / AI:1 1, 0, 1 0.370, 0.260, 0.370 0.370×1 + 0.260×0 + 0.370×1 = 0.740
Step 2f-3:Head 2 独立做注意力(只看第2维)
Q (query) K (key) Q·K (标量) Softmax 权重 加权 V
我: 0 我:0 / 爱:1 / AI:1 0, 0, 0 0.333, 0.333, 0.333 0.333×0 + 0.333×1 + 0.333×1 = 0.667
爱: 1 我:0 / 爱:1 / AI:1 0, 1, 1 0.212, 0.394, 0.394 0.212×0 + 0.394×1 + 0.394×1 = 0.788
AI: 1 我:0 / 爱:1 / AI:1 0, 1, 1 0.212, 0.394, 0.394 0.212×0 + 0.394×1 + 0.394×1 = 0.788
Step 2f-4:拼接 + 线性变换
Head 1 输出 Head 2 输出 Concat 后
0.740 0.667 [0.740, 0.667]
0.667 0.788 [0.667, 0.788]
AI 0.740 0.788 [0.740, 0.788]

最后通过一个线性矩阵 Wo 做变换,整合所有头的信息:

MultiHead(Q,K,V) = Concat(head₁, head₂) · Wo

每个头关注了不同的维度模式,拼接后模型能同时捕获多种关系。

3

Transformer 完整结构

自注意力只是 Transformer 的一个组件。完整的 Transformer 结构如下:

🎯 输出概率 (Softmax)
📐 输出线性层
🔁 Decoder × N
前馈网络 FFN
交叉注意力 (Encoder-Decoder)
掩码自注意力 (Masked)
🔁 Encoder × N
前馈网络 FFN
⚡ 多头自注意力 (Multi-Head)
📍 位置编码 (Positional Encoding)
📝 输入嵌入 (Token Embedding)
原始输入序列
📍 位置编码

Transformer 没有循环结构,需要额外注入位置信息。用正弦/余弦函数生成位置向量加到词嵌入上。

⚡ 多头注意力

把 Q/K/V 拆成多个"头",各自独立做注意力,再拼接。就像同时从不同角度理解句子。

🔮 前馈网络 FFN

两层 MLP + ReLU/GELU,对注意力输出做非线性变换。就是我们上一章学的 MLP!

🔗 残差连接 + LayerNorm

每个子层都有残差连接和层归一化,保证梯度流通和训练稳定性。

4

PyTorch 实现

用 PyTorch 实现自注意力机制。

self_attention.py
import torch
import torch.nn as nn
import math

class SelfAttention(nn.Module):
    def __init__(self, d_model=2):
        super().__init__()
        self.d_model = d_model
        # Q, K, V 的线性变换
        self.Wq = nn.Linear(d_model, d_model, bias=False)
        self.Wk = nn.Linear(d_model, d_model, bias=False)
        self.Wv = nn.Linear(d_model, d_model, bias=False)

    def forward(self, x):
        # x: (seq_len, d_model)
        Q = self.Wq(x)  # (seq_len, d_model)
        K = self.Wk(x)  # (seq_len, d_model)
        V = self.Wv(x)  # (seq_len, d_model)

        # 计算注意力分数
        scores = torch.matmul(Q, K.T) / math.sqrt(self.d_model)
        # Softmax 归一化
        attn_weights = torch.softmax(scores, dim=-1)
        # 加权求和
        output = torch.matmul(attn_weights, V)
        return output, attn_weights

# 手动设置为单位矩阵,复现手算结果
model = SelfAttention(d_model=2)
model.Wq.weight.data = torch.eye(2)
model.Wk.weight.data = torch.eye(2)
model.Wv.weight.data = torch.eye(2)

# 输入: "我 爱 AI"
x = torch.tensor([
    [1.0, 0.0],  # 我
    [0.0, 1.0],  # 爱
    [1.0, 1.0],  # AI
])

output, weights = model(x)
print("注意力权重:")
print(weights)
print("输出:")
print(output)
5

📝 总结

自注意力的完整流程

输入 X
词嵌入
Q, K, V
线性变换
Q·KT/√d
点积分数
Softmax
归一化
× V
加权求和
输出
新表示
💡

为什么 Transformer 革命性?

抛弃了 RNN 的顺序处理,所有位置可以并行计算,训练速度快几十倍。

🌍

无处不在的架构

GPT、BERT、ViT、DALL-E、Whisper… 几乎所有 SOTA 模型都基于 Transformer。

🧩

MLP 是它的组成部分

Transformer 的 FFN 层就是两层 MLP。学好 MLP → 理解 Transformer 的一半。

🔮

下一步

理解了自注意力,就可以探索多头注意力、位置编码、Transformer 完整训练流程。

+

扩展阅读:Mamba 与状态空间模型

Transformer 并不是序列建模的唯一选择。Mamba(2023)基于状态空间模型(State Space Model, SSM),提供了一种全新的序列建模范式。

SSM 的核心思想来源于控制论:用一个隐藏状态来压缩历史信息,每个时间步根据输入更新状态并产生输出。Mamba 的创新在于让更新参数依赖于输入本身("选择性"),从而实现了类似注意力的内容感知能力。

Transformer vs Mamba 对比

特性 Transformer Mamba
核心机制 注意力机制 (Attention) 选择性 SSM (Selective SSM)
时间复杂度 O(n²) O(n)
长序列处理 有瓶颈(显存随长度平方增长) 擅长(线性增长)
并行训练 完全并行 完全并行
推理速度 需要缓存 KV(显存占用大) 线性扫描(固定状态大小)
全局信息 任意位置直接交互 通过状态间接传递
代表模型 GPT、BERT、ViT Mamba、Mamba-2、Vision Mamba

Mamba 不是要取代 Transformer,而是为不同场景提供了新选择。实践中两者各有优势,甚至可以组合使用。

🔗 相关章节推荐
  • RNNTransformer 替代了 RNN 的序列建模
  • CLIPCLIP 使用 Transformer 编码器
  • DeepSeekDeepSeek 的 MLA 优化了 Transformer 注意力
?

小测验

1. Q 和 K 的点积代表什么?

2. 为什么要除以 √d?

3. Multi-Head Attention 的作用是什么?

4. Transformer 相比 RNN 的最大优势是什么?

Easy Deep Learning · 用 Excel 手推理解每一个公式