上一篇我们拆开了自注意力机制——Q 提问、K 回答、V 传递内容、softmax 算权重、加权求和得到输出。一个注意力头能做到这些,已经很了不起了。但只用一头,就像一个人只从一个角度看问题——难免有盲区。
多头注意力(Multi-Head Attention)就是回答这个问题:如果一种角度不够,为什么不并排放多个头,每个头学不同的事?
一个头的局限
在单头自注意力中,整个模型只有一套 Q、K、V 矩阵。这意味着所有位置的关系只能通过「同一套标准」来衡量。但在自然语言里,词与词之间的关系远不止一种:
- 语法关系——「吃」的主体是谁、宾语是什么
- 语义关系——「苹果」和「水果」是上下位关系
- 位置关系——「这个」和它指代的名词隔了几个词
- 情感关系——「太棒了」和前面的话是正向呼应
一套权重矩阵很难同时捕获这么多不同类型的模式。强行让一个头学所有,每个都学不精。
核心思想:把模型分成多组
多头注意力的做法很简单:用多组独立的 Q、K、V 权重矩阵,每组(每个头)独立计算注意力,最后把结果拼起来。
在实际实现中,模型并不复制多个完整的注意力模块。而是把 embedding 维度拆成 h 份。以 GPT 等常用配置为例:
- 总维度 d_model = 512
- 头数 h = 8
- 每个头的维度 d_k = 512 / 8 = 64
也就是说,不是 8 个完整的 512 维注意力,而是将 512 维空间切分成 8 个 64 维的子空间,每个子空间独立计算注意力。
数学形式
多头注意力的完整公式:
MultiHead(Q, K, V) = Concat(head1, head2, ..., headh) × W_O 其中每个头: headi = Attention(Q × Wi^Q, K × Wi^K, V × Wi^V)
其中 Wi^Q、Wi^K、Wi^V 是第 i 个头的 Q/K/V 投影矩阵(形状为 d_model × d_k),W_O 是输出投影矩阵(形状为 h·d_k × d_model)。
注意:总参数量和单头一模一样。因为 h × d_k = d_model,8 个 64 维的投影矩阵,和 1 个 512 维的投影矩阵,参数量完全相等。多头不是「多加参数」,而是「重新分配参数」——把同一个大空间拆成多个小空间,每个小空间专注一种关系。
直观理解:八位专家
想象一个项目评审会,需要评估一份代码的质量。如果你只让一个人从头看到尾,他可能只关注了性能,忽略了安全漏洞。但如果你请八位评审:
- 一位专门看性能
- 一位专门看安全性
- 一位专门看代码风格
- 一位专门看可维护性
- 一位专门看测试覆盖
每位只关注自己擅长的维度,最后把所有人的意见汇总。这就是多头注意力在做的事——每个头分管一种关系模式,最后汇总成一个更完整的表示。
实验证据
在 Transformer 原始论文(Attention Is All You Need, Vaswani et al. 2017)中,作者通过可视化证明不同注意力头确实学到了不同的模式:
- 有的头专注于句法依赖关系(动词→名词、介词→宾语)
- 有的头关注长距离依赖(句首词和句尾词的关联)
- 有的头几乎只关注相邻词(局部上下文)
这意味着多头注意力不是冗余——每个头的确在做不一样的事情。去掉任何一个头,模型性能都会下降。
实现细节:为什么先拆分后拼接
在实践中,多头注意力的实现通常不走「先分 8 个头分别算」的循环,而是用矩阵运算一次搞定:
- 将 Q、K、V 通过投影矩阵映射到 d_model 维
- 把最后维度 reshape 成 (batch, seq_len, h, d_k) 的形状
- 转置为 (batch, h, seq_len, d_k)——相当于把「头」提到序列长度前面
- 对每个头在最后两个维度上做标准的 scaled dot-product attention
- 把结果转置回来,reshape 回 (batch, seq_len, h×d_k)
- 通过 W_O 投影回 d_model 维
这种实现充分利用了 GPU 的并行能力——8 个头同时算,速度远快于串行。这也是 Transformer 能规模化训练的关键工程技巧之一。
总结
多头注意力就是自注意力的进阶版——不改变计算本质(还是 Q·K^T·V 那套),但通过拆分维度让模型能同时学习多种关系模式。它用「分而治之」的思路,把一大捆关系拆成多个子任务,每个头专精一种,最后拼成更全面的理解。
下一篇我们讲位置编码(Positional Encoding)——自注意力本身没有顺序概念,一个词在句首还是句尾对它来说完全一样。位置编码就是告诉模型「这个词是第几个」。这是让 Transformer 理解语序的关键技术。