跳至主要内容
返回文章列表
约 10 分钟阅读

千问如何越跑越快:从 MHA、GQA 到混合注意力

沿着 Qwen 的公开结构变化,理解 KV cache 为什么拖慢生成,以及 GQA、Gated DeltaNet、MoE 与多 token 预测分别优化了什么。

博客目录 →

千问最初采用的是 MHA,也就是多头注意力。后来,为了让模型生成得更快、同时服务更多用户,它逐渐减少需要保存和读取的历史信息,并在部分模型中改变了计算这些信息的方式。

这条演进主线可以概括为:先让多个 Query 头共享 K/V,再让一部分注意力层用递推状态处理历史;与此同时,用 MoE 减少每个 token 激活的计算,用多 token 预测配合推测解码减少串行生成的开销。

本文以初代 Qwen、Qwen1.5/2/2.5/3,以及 Qwen3-Next、Qwen3.5 的公开配置为例。它们足以说明主要思路,但并不覆盖千问家族的所有型号,也不把某个分支的设计当成全家族统一的结构。

一、先理解:生成一句话,为什么需要反复读历史?

注意力机制中的三个字母,可以先这样理解:

  • Q(Query):当前这个位置想寻找什么信息。
  • K(Key):历史各个位置提供什么索引,用来判断与当前问题的相关性。
  • V(Value):找到相关位置后,实际取回的信息。

例如生成“我把苹果放进了……”时,模型要参考前面的词,决定接下来写“篮子”还是别的内容。不同的注意力头可以关注不同关系:物体、动作、指代、语法等。这些是直观类比,实际的头并没有预先分配好的固定职责。

推理通常分为两个阶段:prefill 一次处理输入提示词,decode 则逐个生成新 token。为了避免每次都重新计算旧 token 的 K/V,模型会把它们存起来,这就是 KV cache。

缓存节省了重复计算,但每生成一个新 token,全注意力仍需要访问已有的 K/V。上下文越长,缓存越大,读历史的成本也越高。在很多 decode 场景中,瓶颈不仅是“算得多”,还包括“显存里的数据搬得慢”。

输入词先计算并缓存 K 和 V,生成新 token 时使用新 Query 读取历史缓存,缓存随序列增长
图 1:KV cache 避免重复计算历史 K/V,但全注意力生成新 token 时仍要读取历史。原创概念图,省略投影、残差和前馈网络。

二、第一步:从 MHA 到 GQA,少存几份 K/V

MHA:每个头都有自己的 K/V

初代 Qwen-7B 的配置有 32 个注意力头;其实现把输入投影成等宽的 Q、K、V,并按同样的头数拆分。这才是判断它采用 MHA 的依据,而不只是看配置里有没有某个字段。

MHA 的特点是:每个 Query 头都有对应的 Key 头和 Value 头。表达自由度较大,但缓存也需要为这些 K/V 头分别保存历史。

MQA 与 GQA:共享程度不同的两个方案

**MQA(Multi-Query Attention)**让所有 Query 头共享一组 K/V,缓存很省,但共享程度也最高。

**GQA(Grouped-Query Attention)**采用折中方案:Query 头分组,每组共享一组 K/V。例如 32 个 Q 头搭配 8 个 KV 头,就是每 4 个 Q 头共享一组 K/V。

这里的“8 个 KV 头”意味着 8 个 K 头和 8 个 V 头,不是把两者加起来只有 8 个。共享 K/V 也不意味着 Q 头被合并:每个 Q 头仍有自己的查询和注意力结果。

GQA 论文对比 MHA、GQA 和 MQA:Query 头数量保持不变,Key 和 Value 从每头独立变为分组共享,再变为所有头共享
图 2:MHA、GQA、MQA 的头共享方式。来源:Ainslie 等人的 GQA 论文,图 2。MQA 在这里用于对照,并不代表千问经历过“MHA → MQA → GQA”的路线。

GQA 最直接的收益,是减少 K/V 投影的输出量、KV cache 容量,以及读取缓存所需的数据量。它尤其有利于长上下文生成和高并发服务。

不过,缓存缩小几倍,不等于整台模型加速几倍。Q 头仍然存在,仍然要与历史位置计算注意力;模型还有权重读取、前馈网络、通信等其他开销。

千问是哪一代开始使用 GQA 的?

准确的说法是:Qwen1.5 的部分大模型先采用,Qwen2 再推广到所有尺寸。 Qwen2 官方介绍明确指出,Qwen1.5 中此前采用 GQA 的是 32B 和 110B。

代表模型Q 头数KV 头数注意力方式相对同头维度、同层数 MHA 的缓存比例
Qwen-7B3232MHA1
Qwen1.5-7B3232MHA1
Qwen1.5-32B408GQA1/5
Qwen2-7B284GQA1/7
Qwen2.5-7B284GQA1/7
Qwen3-8B328GQA1/4

表格依据各模型官方配置,链接见文末。最后一列比较的是“该模型若改用同条件 MHA”的理论缓存量,不是这些真实模型之间的显存或速度对比。各代模型的层数、隐藏维度和参数量并不完全相同。

还可以看到,Qwen3-8B 的共享比例比 Qwen2-7B 小。这说明演进并不是一味减少 KV 头,而是在质量、规模和效率之间重新选择配置。配置里的 model_type: qwen2 也不能单独证明使用 GQA,必须检查 Q 头和 KV 头的实际数量。

三、算一笔账:GQA 到底省在哪里?

对采用全注意力、各层配置相同的模型,未量化 KV cache 的主要存储量近似为:

KV cache 字节数 ≈ 2 × 批大小 × 层数 × 序列长度 × KV头数 × 每头维度 × 每元素字节数

开头的 2 表示 K 和 V 两份。这个公式不包括模型权重、临时张量、缓存管理开销,也不适用于直接估算混合注意力的所有状态。

假设批大小为 1,模型有 32 层、32 个 Q 头,每头维度 128,上下文为 8192 个 token,K/V 使用 FP16 或 BF16(每元素 2 字节):

相同假设下 MHA 的 KV cache 为 4 GiB,8 个 KV 头的 GQA 为 1 GiB,单个 KV 头的 MQA 为 128 MiB
图 3:只改变 KV 头数时的理论缓存容量。原创计算图;这是控制变量的示例,不是某个 Qwen 型号的实测,也不是速度测试。

同样的空间,现在可以容纳更长的上下文,或者服务更多请求。缓存更小,也让每一步生成少读取一些数据。但如果任务瓶颈主要在其他部分,实际提速就不会与缓存缩减成正比。

四、更进一步:让部分层不再保存完整历史

GQA 仍属于全注意力:只是每个历史 token 保存的 K/V 少了,上下文越长,缓存仍越大。

Qwen3-Next 走了另一条结构上的优化路线。其 80B-A3B 官方模型卡给出了混合结构:48 层中,重复 12 次“3 层 Gated DeltaNet + 1 层 Gated Attention”,每层再接 MoE。

Qwen3-Next 每四层包含三层 Gated DeltaNet 和一层带门控的全注意力,每层接 MoE;36 个递推层与 12 个全注意力层共存
图 4:Qwen3-Next-80B-A3B 的混合层结构,按官方模型卡重绘。图中只展示主干类型,省略归一化、残差与门控内部细节。

Gated DeltaNet:把历史维护成递推状态

可以把全注意力想成保存一份可以逐条查阅的历史档案,而 Gated DeltaNet 更像持续更新的一份工作记录:新信息进入时,用门控和更新规则调整状态,后续 token 从状态中提取信息。

这个类比的关键是:在逐 token 解码时,线性/递推层的历史状态大小由结构决定,不会像完整 KV cache 那样随 token 数一直增长。因此,长上下文下这些层能减少历史存储和访问开销。

代价是它改变了表示和读取历史的方式,并不等价于对所有旧 token 做完整的 softmax 注意力。保留间隔出现的全注意力层,就是一种能力与效率的折中。

整个模型也没有变成“恒定显存”:12 个全注意力层仍需维护随上下文增长的 KV cache,输入处理和其他运行内存也仍然存在。

Gated Attention:门控不等于 GQA

在这些全注意力层中,Gated Attention 为注意力输出加入门控,用来调节通过的信息。GQA 解决的是 K/V 如何共享;门控解决的是输出如何调节,两者可以同时使用。

Qwen3-Next-80B-A3B 的全注意力层有 16 个 Q 头、2 个 KV 头,因此它本身也使用 GQA。不能因为名称里出现“Gated”,就认为它不再扫描历史,或把门控本身当作主要的缓存压缩手段。

后续 Qwen3.5-397B-A17B也采用这一类混合思路:60 层中有 45 个线性注意力层和 15 个全注意力层。这说明“让部分层递推、保留部分全注意力”成为了千问部分后续模型的重要方向,而不是所有型号都只在 GQA 上继续减少头数。

五、另外两项优化:少激活计算,少走串行步骤

MoE:每个 token 只调用部分专家

注意力之外,Transformer 的前馈网络也很消耗计算。**MoE(混合专家)**准备多个专家网络,再由路由器为当前 token 选择部分专家参与计算。

例如 Qwen3-Next-80B-A3B 总参数约 80B,每个 token 激活约 3B。它的 MoE 包含 512 个路由专家,每个 token 选中 10 个,并有 1 个共享专家。这让模型保留较大的总容量,同时控制每一步的活跃计算量。

但“激活 3B”不意味着只需存放 3B 权重:不同 token 会选择不同专家,部署仍要安排全部权重的存储与访问。路由、专家负载不均和跨设备通信,也会影响实际吞吐。MoE 优化的是前馈计算,不能直接替代 KV cache 优化。

MTP:为一次推进多个 token 提供支持

普通自回归生成需要一步接一步地运行模型。**MTP(Multi-Token Prediction,多 token 预测)**通过训练模型预测未来多个位置,为多 token 草拟和推测解码提供支持。

推测解码可以先草拟多个候选 token,再由目标模型验证,接受符合规则的部分,继续生成。它不是无条件一次输出多个独立答案;能省多少串行步骤,取决于草稿接受率和推理实现。

Qwen3-Next 和上述 Qwen3.5 的官方模型卡都介绍了 MTP。要让它在部署时真正加速,还需要后端支持相应的推理路径;普通加载模型不一定自动启用这项能力。

六、别把所有“更快”都归因于结构变化

实际使用千问时,还会看到 FlashAttention、PagedAttention、量化等名词。它们也很重要,但优化的位置不同:

方法主要改变什么与本文主线的关系
GQAK/V 的头共享方式减少缓存和 K/V 数据访问
混合注意力部分层处理历史的机制用递推状态替代部分完整历史缓存
MoE前馈网络的专家激活方式减少每 token 的活跃计算
MTP + 推测解码多 token 草拟与验证流程有机会减少串行生成开销
FlashAttention注意力算子的计算与访存实现不等于改变 MHA/GQA;初代 Qwen 已使用
PagedAttention服务端 KV cache 的分页管理改善缓存利用和请求调度
量化权重或缓存的数据精度减少字节数,需要区分量化对象

因此,千问从 MHA 出发后的结构优化,可以记成三个问题:历史要保存几份?是否每层都要保存完整历史?生成一个 token,需要激活多少计算、走多少串行步骤? GQA、混合注意力、MoE 与 MTP 分别给出了不同层面的回答。

参考资料

打开原图