Transformer 与注意力机制
本教程共 60 篇 · 第 23 篇 · 更新于 2026-08-17 · 约 3 分钟阅读
本节目标:理解注意力机制(Attention)的核心思想,搞懂 Transformer 的结构——自注意力、多头注意力、位置编码、编码器-解码器,并会用 PyTorch 内置模块搭一个最小 Transformer。
2017 年,论文《Attention is All You Need》提出了 Transformer。标题的意思是:注意力就是你所需要的全部。如今 GPT、BERT、各种大模型,底层都是这套结构。这一章,我们把它拆开看。
从翻译的瓶颈说起
上一章的 RNN/LSTM 做翻译,常见结构是编码器-解码器(Encoder-Decoder):编码器把整句话压成一个固定长度的向量,解码器再从这个向量里「翻译」出来。
问题来了:句子一长,一个向量装不下全部信息。就像让一个人扫一眼长文章就复述,必然丢三落四。这叫信息瓶颈。
注意力的思路很朴素:解码器每生成一个词,都回头看一眼原文的所有词,谁相关就多看谁。翻译「bank」时是「河岸」还是「银行」,全靠这一步。
注意力机制:搜索与加权
注意力机制(Attention)可以概括成一个搜索引擎。每个词向量被投影成三个角色:
- 查询(Query):我在找什么。
- 键(Key):我是什么标签。
- 值(Value):我的实际内容。
计算分三步:用 Q 和每个 K 做点积算相似度;除以 √d_k 缩放;softmax 变成权重,对 V 加权求和。公式写出来是:
Attention(Q, K, V) = softmax(QK^T / √d_k) V
为什么要除以 √d_k?维度一大,点积结果就大,softmax 的梯度趋近于 0。缩放一下,训练才稳。
Tip把 Q 想成搜索框里的关键词,K 是网页标题,V 是网页正文。搜出来的结果,就是按相关度加权后的内容。
自注意力与多头注意力
自注意力(Self-Attention)指 Q、K、V 都来自同一句话。句子里的每个词都能直接和所有词「打招呼」,距离不再是障碍。
这是它比 RNN 强的地方:RNN 要一步步接力传信息,自注意力一步到位。代价是计算量随序列长度平方增长,长文本要靠后面讲的 SDPA 优化。
多头注意力(Multi-Head Attention)则是多请几个人从不同角度观察:有的头看语法,有的头看指代。把 d_model 切成 h 份,每个头在子空间里算注意力,最后拼起来再投影。
位置编码:给词发座位号
自注意力对顺序不敏感:「猫吃鱼」和「鱼吃猫」的词向量集合完全一样。但顺序显然重要。
位置编码(Positional Encoding)就是给每个位置的向量加一个独特的「座位号」。原论文用不同频率的正弦余弦函数生成,PyTorch 里也常用可学习的位置编码。
Transformer 的整体结构
Transformer 由编码器和解码器堆叠而成,原论文各 6 层。打个比方:编码器是读书人,把原文读透变成一组向量;解码器是翻译官,看着读书人的笔记,一个词一个词往外蹦。
编码器每层有两个子层:多头自注意力,加一个前馈网络。解码器每层有三个:掩码自注意力(生成时不许偷看后面的词)、编码器-解码器注意力(去原文里查信息)、前馈网络。
每个子层后面都有残差连接和层归一化。残差让梯度有「近道」可走,层归一化稳住训练。深层网络能训得动,全靠这两样。
PyTorch 实现
PyTorch 把组件都封装好了。最常用的是编码器部分:
import torch
import torch.nn as nn
encoder_layer = nn.TransformerEncoderLayer(
d_model=64, nhead=8, batch_first=True)
encoder = nn.TransformerEncoder(encoder_layer, num_layers=2)
x = torch.randn(4, 10, 64) # batch=4,序列长 10,每个词 64 维
out = encoder(x)
print(out.shape) # torch.Size([4, 10, 64])
需要编码器加解码器时,直接用 nn.Transformer:
transformer = nn.Transformer(d_model=64, nhead=8,
num_encoder_layers=2, num_decoder_layers=2)
src = torch.randn(10, 4, 64) # (src_len, batch, d_model)
tgt = torch.randn(8, 4, 64) # (tgt_len, batch, d_model)
out = transformer(src, tgt)
print(out.shape) # torch.Size([8, 4, 64])
Note性能敏感时用
torch.nn.functional.scaled_dot_product_attention(SDPA)。它在 GPU 上自动选择 FlashAttention 等融合实现,又快又省显存,PyTorch 2.0 起开箱即用。
从 Transformer 到今天的 AI
学完这章,再看 GPT 就不神秘了:GPT 是只保留解码器的 Transformer,BERT 是只保留编码器的。视觉领域有 ViT(Vision Transformer),把图片切成小块当「词」来用。
注意力这块积木,撑起了现代深度学习的大半边天。理解了它,你就拿到了理解大模型的钥匙。