一、Self-Attention:Transformer的基石
说实话,我第一次接触Self-Attention时,脑子里就一个想法:这玩意儿凭什么能取代RNN?后来在项目中踩了不少坑,才慢慢理解它的精妙之处。今天咱们就来聊聊这个改变了NLP格局的核心机制。
1.1 Self-Attention的定义与计算流程
Self-Attention,说白了就是让序列中的每个位置都能“关注”到其他所有位置。我习惯把它理解成一种“全局信息聚合器”。
计算流程其实就三步:
- 生成Q、K、V:每个输入向量通过三个不同的线性变换,得到Query、Key、Value
- 计算注意力分数:Q与所有K做点积,再除以√d_k做缩放
- 加权求和:softmax归一化后,对V做加权平均
公式长这样:
Attention(Q, K, V) = softmax(QK^T / √d_k) V
嗯,这里有个细节要注意——为什么要除以√d_k?我在项目中曾经忽略了这个缩放因子,结果训练直接炸了。因为当d_k很大时,点积的值会变得非常大,softmax的梯度会趋近于0。说白了就是防止梯度消失。
核心要点:Self-Attention的计算复杂度是O(n²·d),n是序列长度。这意味着长序列场景下,计算量会爆炸式增长。这也是后来各种优化方法的出发点。
1.2 多头注意力机制(Multi-Head Attention)
你想想看,单头注意力只能捕捉一种关系模式。但实际文本中,词与词之间的关系是多元的——比如语法关系、语义关系、指代关系等等。
多头注意力就是解决这个问题的。它把Q、K、V拆成h份,每份独立做注意力计算,最后再拼起来。我习惯用8个头,这是Transformer论文里的经典配置。
MultiHead(Q, K, V) = Concat(head₁, ..., headₕ) W_O
其中 headᵢ = Attention(QW_Qᵢ, KW_Kᵢ, VW_Vᵢ)
我的经验:头数不是越多越好。我曾经试过32个头,结果模型反而变差了。一般来说,8-16个头是个安全区间。每个头的维度建议在64-128之间。
多头注意力的好处很明显:
- 每个头可以学到不同的注意力模式
- 计算可以并行,效率高
- 模型容量更大,表达能力更强
1.3 位置编码(Positional Encoding)的必要性
这里有个关键问题:Self-Attention本身是置换不变的。什么意思?就是你把输入顺序打乱,输出结果完全一样。但语言是有顺序的——"我打你"和"你打我"意思完全不同。
所以我们需要给模型注入位置信息。Transformer用的是正弦余弦位置编码:
PE(pos, 2i) = sin(pos / 10000^(2i/d_model))
PE(pos, 2i+1) = cos(pos / 10000^(2i/d_model))
为什么选这个?我个人的理解是:
- 正弦余弦函数的值域在[-1, 1],不会引入数值问题
- 不同频率的组合可以编码不同粒度的位置关系
- 可以外推到更长的序列(虽然效果会打折扣)
避坑指南:我曾经在项目中直接用可学习的位置编码,结果训练到一半发现序列长度变了,位置编码矩阵得重新初始化,导致模型需要重新训练。如果你不确定序列长度是否固定,建议用正弦余弦编码。
1.4 Transformer Encoder-Decoder架构概览
Transformer的整体架构,说白了就是Encoder吃输入,Decoder吐输出,中间通过Cross-Attention连接。
我画了一张图,帮你理清整体脉络:
这张图里,Encoder和Decoder各自堆叠了N层(论文里N=6)。Decoder里有个关键设计——Masked Self-Attention,它确保当前位置只能看到之前的位置,不能偷看未来的信息。这在生成任务中至关重要。
架构要点总结:
- Encoder:双向上下文,适合理解任务(如分类、NER)
- Decoder:单向上下文,适合生成任务(如翻译、摘要)
- Cross-Attention:连接Encoder和Decoder的桥梁
- 每个子层都有残差连接和LayerNorm,这是训练稳定的关键
我记得第一次自己实现Transformer时,在Cross-Attention的维度匹配上卡了整整两天。Q的维度来自Decoder,K和V的维度来自Encoder,这三者的维度必须对齐。如果你也遇到维度不匹配的错误,先检查这里。
实用建议:刚开始学Transformer时,我建议你先从单层Encoder开始实现,跑通一个简单的分类任务。等理解了Self-Attention的输入输出形状变化,再扩展到完整的Encoder-Decoder架构。一步到位容易把自己绕晕。
好了,这一章的内容就到这里。Self-Attention和Transformer的基石已经打好了,后面的章节我们会深入各种优化技巧——稀疏注意力、线性注意力、Flash Attention等等。这些都是在实际项目中真正能帮你省显存、提速度的硬核技术。