RNN 的痛点
序列任务里,第 100 步要看第 1 步的信息,必须经过 99 个中间步。信息会衰减。
Transformer 的核心想法:让任意两个位置直接互相"看"。
自注意力(Self-Attention)的核心
每个位置算三个向量:
- Q(Query 查询):我想找什么
- K(Key 键):我能被什么找到
- V(Value 值):我提供什么内容
注意力分数:
score(i, j) = Q_i · K_j / sqrt(d)
weights = softmax(scores) # 归一化成概率
output_i = sum(weights_ij × V_j) # 加权求和
每个位置的输出 = 所有位置 V 的加权平均——权重由 Q 和 K 的相似度决定。
直观理解
句子 "猫坐在垫子上",处理"坐"这个词时:
- "坐" 的 Q 和 "猫" 的 K 相似度高 → 多看猫
- "坐" 的 Q 和 "垫子" 的 K 也高 → 也看垫子
- "在" 的 K 不相关 → 几乎不看
Self-attention 学会哪些词之间该互相关注。
多头注意力(Multi-Head)
把 Q/K/V 拆成多组,并行算多个 attention,最后拼起来:
import torch.nn as nn
attn = nn.MultiheadAttention(embed_dim=512, num_heads=8, batch_first=True)
x = torch.randn(2, 10, 512) # batch=2, seq_len=10, dim=512
out, weights = attn(x, x, x) # Q, K, V 都用 x(自注意力)
不同 head 学不同方面的关系(一个学语法、一个学语义)。
完整 Transformer Block
Input
↓
Multi-Head Self-Attention
↓
Add & LayerNorm ← 残差连接(和 ResNet 一样的思路)
↓
Feed-Forward (MLP)
↓
Add & LayerNorm
↓
Output
位置编码
self-attention 没有顺序概念——所以要把"我是第几个"的信息加进 embedding:
import torch
import math
def pos_encoding(seq_len, dim):
pe = torch.zeros(seq_len, dim)
pos = torch.arange(0, seq_len).unsqueeze(1)
div = torch.exp(torch.arange(0, dim, 2) * -(math.log(10000.0) / dim))
pe[:, 0::2] = torch.sin(pos * div)
pe[:, 1::2] = torch.cos(pos * div)
return pe
GPT/Claude 用 RoPE(旋转位置编码),原理类似。
Encoder vs Decoder
| 类型 | 任务 | 例子 |
|---|---|---|
| Encoder Only | 分类、抽取信息 | BERT |
| Decoder Only | 生成 | GPT / Claude / Llama |
| Encoder-Decoder | 翻译、摘要 | T5、BART |
2026 主流是 Decoder Only——GPT 系所有。
自己写一个迷你 Transformer 块
import torch.nn as nn
class TransformerBlock(nn.Module):
def __init__(self, dim, heads):
super().__init__()
self.attn = nn.MultiheadAttention(dim, heads, batch_first=True)
self.norm1 = nn.LayerNorm(dim)
self.ff = nn.Sequential(
nn.Linear(dim, dim * 4),
nn.GELU(),
nn.Linear(dim * 4, dim),
)
self.norm2 = nn.LayerNorm(dim)
def forward(self, x):
# 自注意力 + 残差
out, _ = self.attn(x, x, x)
x = self.norm1(x + out)
# MLP + 残差
x = self.norm2(x + self.ff(x))
return x
GPT-4 / Claude 内部就是堆几十层这种块。
为什么 Transformer 取代 RNN
| 维度 | RNN | Transformer |
|---|---|---|
| 训练并行 | 串行 | 全并行 |
| 长依赖 | 衰减 | O(1) 距离 |
| 上下文长度 | 几百 | 几十万 |
| 大模型扩展 | 难 | 自然 |
Transformer 让"大模型"成为可能——这是 GPT 革命的根。
实践中:直接用 Hugging Face
不需要从头实现——下一篇起进入实用环节。