NLP 中的 Transformer 注意力机制
什么是 Transformer 注意力机制
Transformer 是当前自然语言处理(NLP)领域最重要的模型架构,而它的核心正是“注意力机制”。注意力机制让模型能够动态地评估一个句子中每个词与其他词之间的关联程度,不再像传统 RNN 那样只能按顺序处理信息。这种并行、全局的关联能力使得 Transformer 在翻译、问答、文本生成等任务中取得了突破性表现。
本教程将从最基础的概念入手,带你理解 Transformer 中注意力机制的运作原理,包括缩放点积注意力、多头注意力的设计意图,以及它们在完整 Transformer 架构中的作用。
为什么需要注意力机制
早期的序列模型(如循环神经网络)通过隐藏状态一步一步传递信息。当序列变长时,前面的信息很容易被“遗忘”,而且无法并行计算。注意力机制直接在所有位置之间建立关联权重,模型可以聚焦到输入中任意重要位置的关系,不受距离限制。
在 Transformer 中,注意力机制替代了循环结构,允许一次性看到整个序列,因此计算效率极高,捕捉长距离依赖的能力也显著增强。
自注意力:查询、键、值的直观理解
自注意力(Self-Attention)是 Transformer 注意力的基础形式。它的思想是:对于句子中的每个词,生成三个向量——查询(Query)、键(Key) 和 值(Value)。
- 查询:表示“我在找什么信息”。
- 键:表示“我是什么信息”。
- 值:表示“我实际包含的内容”。
通过查询和所有键的相似度,计算出每个位置应该分配多少“注意力”给其他位置的值。最终每个词的输出是所有位置的值的加权和。
步骤拆解:
- 从输入词向量通过线性变换得到 Q、K、V。
- 计算注意力分数:用 Q 与所有 K 做点积,得到未归一化的相似度。
- 缩放:点积结果除以 (\sqrt{d_k})((d_k) 是 K 的维度),防止梯度消失。
- Softmax:将分数转换为注意力权重(概率分布,和为 1)。
- 加权求和:用注意力权重对 V 进行加权求和,得到输出向量。
这整个过程可以并行完成,公式如下:
[ \text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right) V ]
缩放点积注意力的细节
为什么除以 (\sqrt{d_k}) ?当 (d_k) 较大时,点积结果的方差会变得很大,导致 softmax 后的分布更加尖锐(趋向于 one-hot),梯度很小,不利于学习。缩放因子将方差控制在 1 左右,使梯度更加稳定。
代码示例(伪代码):
scores = torch.matmul(Q, K.transpose(-2, -1)) # 计算点积
scores = scores / math.sqrt(d_k) # 缩放
attention_weights = F.softmax(scores, dim=-1) # 权重
output = torch.matmul(attention_weights, V) # 加权求和
多头注意力:多个视角的信息融合
单次自注意力只能学习一种关联方式,但语言中的词语之间可能存在多种关系(语法关系、语义相似、指代等)。多头注意力通过使用多组不同的 Q、K、V 线性变换,并行计算多个注意力“头”,每个头可以关注不同的表示子空间。
最后将所有头的输出拼接起来,再经过一个线性变换得到最终输出。
多头注意力公式:
[ \text{MultiHead}(Q, K, V) = \text{Concat}(\text{head}_1, \dots, \text{head}_h) W^O ] 其中每个头: [ \text{head}_i = \text{Attention}(QW_i^Q, KW_i^K, VW_i^V) ]
这种设计让模型能够在不同位置的不同表示维度上共同关注信息,显著提升了表征能力。
位置编码:让注意力理解顺序
自注意力本身对词的位置不敏感,“我打你”和“你打我”在纯粹的注意力视角下可能得到相似的表示。为了解决这个问题,Transformer 加入了位置编码,向输入词向量中添加关于位置的信息。
原始 Transformer 使用基于正弦和余弦函数的固定位置编码:
[ PE_{(pos, 2i)} = \sin\left(\frac{pos}{10000^{2i/d_{\text{model}}}}\right) ] [ PE_{(pos, 2i+1)} = \cos\left(\frac{pos}{10000^{2i/d_{\text{model}}}}\right) ]
其中 (pos) 是位置,(i) 是维度索引。这种编码让模型能够学习到相对位置关系。现代实现中也常使用可学习的位置嵌入。
Transformer 整体架构与注意力的位置
标准的 Transformer 由编码器(Encoder)和解码器(Decoder)组成。编码器将输入序列映射为一个连续的表示,解码器基于编码器的输出和已生成的部分序列逐个生成输出。
- 编码器层:包含一个多头自注意力子层 + 一个前馈网络,每个子层外用残差连接与层归一化。
- 解码器层:包含掩码多头自注意力(防止注意到未来位置)+ 编码器-解码器注意力 + 前馈网络。
编码器-解码器注意力中,Query 来自解码器的输出,Key 和 Value 来自编码器的最终输出,使得生成的每一步都能“参考”整个输入序列。
注意力可视化与可解释性
注意力权重天然提供了模型决策的可视化方式。通过绘制热力图,可以看到在翻译“The cat sat on the mat”时,解码器生成“猫”时主要关注源句中的“cat”和“The”。这种透明度帮助研究人员理解模型是否学到了合理的词对齐,以及是否捕捉到了长距离依赖关系。
自注意力的计算复杂度与优化
标准自注意力的复杂度为 (O(n^2 \cdot d)),其中 (n) 是序列长度,(d) 是表示维度。当 (n) 很大时,内存和计算开销巨大。为此出现了多种优化变体,如稀疏注意力、线性注意力、分块注意力等,旨在保留长距离建模能力的同时降低复杂度,例如 Longformer、BigBird 等模型。
上手实践与学习路径
- 从基础实现入手:用 PyTorch 手动实现缩放点积注意力和多头注意力,加深理解。
- 阅读原始论文:《Attention Is All You Need》篇幅精炼,值得精读。
- 使用 Hugging Face 库:加载一个预训练的 Transformer 模型,观察注意力权重,修改参数进行实验。
- 延伸学习:掌握 BERT、GPT 等变体中注意力的不同应用方式(如 BERT 使用双向注意力,GPT 使用因果注意力)。
总结
Transformer 注意力机制通过查询-键-值的交互,让每个词都能直接从整个序列中收集相关信息,从而突破了传统序列模型的瓶颈。多头机制增强了表征多样性,位置编码补足了顺序信息,缩放操作保证了数值稳定。这一设计已成为现代 NLP 的基石,并拓展到计算机视觉、语音等多个领域。理解注意力机制,等于握住了进入前沿模型大门的钥匙。