核心要点

  • 通常每个 head 维度 d_k = d_model / h,h 个头并行后拼接再投影回 d_model

  • 降维让总计算量、参数量与「单个全维注意力」基本相当——分而不增,不是白白多花算力

  • 每个 head 在各自的低维子空间里学不同关系(语法、指代、位置等),靠多样性提升表达力

  • head 不能无限增多:h 越大单头维度越小,单头表达力随之下降

  • 过多 head 会出现冗余、收益递减,且计算/显存调度开销上升,需在「多样性」与「单头容量」间权衡

标准回答

是否需要对每个 head 降维:通常需要,且是刻意设计

标准多头注意力的做法是:把模型维度 d_model 平均分给 h 个 head,每个 head 的维度 d_k = d_model / h。比如 d_model=512、h=8,则每个 head 只在 64 维子空间里计算注意力。这种「降维」不是被迫妥协,而是为了让总开销守恒:h 个 64 维 head 的计算量、参数量加起来,和一个 512 维的单头注意力基本相当。换句话说,多头是把同样的预算「切片」分给多个头,而不是成倍增加成本——这也是它常被称为「分而不增」的原因。

降维带来的好处

把表示拆到多个低维子空间,让每个 head 可以各看一类关系:有的头关注相邻词、有的头捕捉长距离指代、有的头偏语法结构。多个视角并行再拼接,等于让模型在一层里同时建模多种依赖,表达更丰富、更鲁棒。如果只用一个全维大头,注意力被迫用单一分布去平均所有这些关系,反而容易互相干扰。

head 数能否无限增多:不能

在 d_model 固定的前提下,h 越大,每个 head 分到的维度 d_k = d_model/h 就越小。这带来几个问题:

第一,单头表达力下降。 d_k 太小(比如降到 8、4 维),Q·K 能编码的信息有限,每个头能区分的模式变少,注意力退化。

第二,冗余与收益递减。 研究(如对 head 重要性的剪枝实验)发现,相当一部分 head 学到的东西高度相似甚至可被剪掉而几乎不掉点。盲目增多 head 只是制造冗余,边际收益迅速变小。

第三,工程开销上升。 头数过多会让计算切分更碎、kernel 启动与访存调度更零散,并行效率和显存利用未必更优。

结论:在多样性与单头容量之间权衡

head 数的本质是一个权衡:头多 → 视角多样但每头容量小;头少 → 每头容量大但视角单一。实践中 h 一般取 8、12、16 这类中等值,并保证每头维度(如 64)落在「足够编码一类关系」的区间。所以正确说法不是「越多越好」,而是「在固定 d_model 下选一个让 d_k 不至于过小的合理头数」。

常见误区

⚠️ 常见踩坑

别以为多头注意力比单头「多花了好几倍算力」——在 d_k=d_model/h 的标准设计下两者开销基本持平。也别以为 head 越多模型一定越强:d_model 固定时增多 head 会摊薄单头维度,超过某个点后表达力反而下降、冗余增多。真正能让每头都更强的是同时放大 d_model,而不是单纯堆 head 数。

追问

追问 1如果想增加 head 数又不让单头维度变小,应该怎么做?

同步放大 d_model,保持 d_k = d_model/h 不缩水。例如从 d_model=512、h=8(每头 64 维)扩到 d_model=1024、h=16,仍是每头 64 维,这样既增加了视角数量又没牺牲单头容量。代价是参数量和计算量随 d_model 上升,本质是用更大的模型预算换更强的多头能力,而不是在固定预算里硬切。

追问 2既然有些 head 是冗余的,能不能训练后剪掉?

可以,这是 head pruning 的研究方向。通过对每个 head 计算重要性(如基于梯度或掩码的敏感度),把贡献小的头剪掉,往往能去掉相当比例的 head 而精度几乎不降,从而加速推理、省显存。但这说明的是「训练出的部分头冗余」,并不意味着初始就该用很少的头——多头在训练期提供的多样性和优化便利仍有价值。

追问 3MQA、GQA 改的是 head 维度还是 head 数?和这里的权衡有什么关系?

它们主要改的是 K/V 的「头数共享」,不是 Q 的头维度。MQA 让所有 Q head 共享一组 K、V,GQA 让若干 Q head 分组共享 K、V,目的是大幅压缩推理时的 KV Cache 显存与带宽。Q 仍是多头、每头维度不变,所以表达力损失较小。它和本题权衡正交:本题谈的是「Q 头维度与头数的取舍」,MQA/GQA 谈的是「K/V 头如何共享以省显存」。

🔗 相似问题

同一考点的不同问法,面试官可能换着问,一起刷更稳

没找到想看的面试题?把你想看的告诉我们 →

延伸学习

按主题分类的相关资源,便于系统复习