1. 从大模型推理说起
Attention 是 Transformer 的核心计算模块。
对于 LLM 部署来说,很多看似不同的问题,其实都和 Attention 有直接关系:
为什么 LLM 推理需要 KV Cache?
为什么 Decode 阶段越来越受内存带宽限制?
为什么 MQA/GQA 可以降低 KV Cache?
为什么部分 Qwen、Llama 系列模型采用 GQA?
为什么 Prefill 和 Decode 的 Attention 计算方式不同?
为什么 FlashAttention 能提升 Attention 性能?
为什么长上下文会带来巨大的显存压力?
它们分别描述 Attention 的:
数据来源
可见范围
Q/K/V Head 组织方式
计算实现方式
因此它们可以组合在一起。
2. 一次 Attention 计算发生了什么
标准 Attention:

可以拆成三个步骤。
2.
2.1 Q 与 K:计算相关性
可以简单理解为:
Q:我现在想找什么?
K:我这里有什么?
QK:我和你相关吗?
2.2 缩放、掩码与 Softmax
表示当前 Query 更关注 Token B。
2.3 用权重聚合 V
因此可以记住:Q 和 K 决定注意力权重,V 提供被加权汇总的信息。缩放、掩码与 Softmax 决定这些权重如何计算。
3. Self-Attention:同一序列内部的信息交换
例如:
Self 决定 Q/K/V 的来源,是否能看见未来由 Mask 单独决定。
另一方面,KV Cache 保存的是已经计算得到的 Key/Value,它随缓存 Token 数量线性增长,注意与上面的Attention 计算区分开来。
3.1 Causal Mask:同一序列也不能偷看未来
LLM 是自回归生成:
对应 Causal Mask:
3.2 Self 与 Causal 是两个维度
这是最容易混淆的地方。
- Self-Attention 描述的是:Q/K/V 来自哪里?
- Causal Attention 描述的是:Q 可以看到哪些 K?
因此二者不是互斥关系。

4. Cross-Attention:从另一序列读取信息
4.1 Cross-Attention简介
以 Encoder–Decoder 翻译模型为例:输入英文句子后,Encoder 先把原文变成一组上下文表示。Decoder 逐步生成中文。假设 Decoder 正准备生成某个中文位置,它可以从自身当前的 hidden state 生成 Q;Encoder 的原文表示则提供 K 和 V。Q 会判断哪些原文位置更相关,再取回相应的 V,供 Decoder 形成该位置的新表示和后续预测。

上图:Decoder 产生 Q,Encoder 产生 K/V,Cross-Attention 汇总后的信息再交回 Decoder。
Decoder 通常还会有自己的 Causal Self-Attention,用来读取已生成的目标序列;这与读取 Encoder 信息的 Cross-Attention 是两个不同步骤。
如果 Q、K、V 都来自同一段序列,这是 Self-Attention;
如果 Q 来自 Decoder,而 K/V 来自 Encoder 输出,就是 Cross-Attention。
至于能看到对方哪些位置,要继续看模型的 Attention Mask 和具体实现;“Cross”本身不等于“无条件看到全部 Token”。
4.2 什么时候会用到 Cross-Attention
5. 多头与 KV 共享:MHA、GQA、MQA
前面讲的是 Attention 的基本形式。
实际上 Transformer 通常不会只计算一次 Attention,而是拆成多个 Head。
例如:一个 hidden state 会分别投影出多个 Q、K、V Head。每个 Q Head 在允许的位置上计算自己的注意力,再将多个 Head 的结果拼接、经输出投影融合。以 32 个 Q Head 的 MHA 为例,通常也有 32 个 K Head 与 32 个 V Head。
每个 Head 都有自己的:Q、K、V,例如:
5.1 多 Head 能学习什么
不同 Head 可以学习不同类型的关系。例如:
某个 Head 更关注:主语 ↔ 谓语
另一个 Head 更关注:代词 ↔ 前文实体
还有 Head 可能关注:局部 Token
因此,多 Head 可以提供更丰富的表示能力。
5.2 多 KV Head 的缓存代价
那么 KV Cache 也需要保存 32 组 K/V。随着:
Batch 增大
Context 变长
Layer 增多
KV Cache 会迅速膨胀。因此出现了 MQA 和 GQA。
5.3 MQA:所有 Q Head 共享一组 KV
也就是说:MQA 仍有 32 条独立 Q,但这些 Q 共享同一组 K/V;减少的是 KV Head 数,而不是把 32 条 Q 变成一条。所有 Query Head 共享同一组 K/V。
MHA:32 KV Heads
MQA:1 KV Head
因此 MQA 可以降低:
KV Cache 显存
KV Cache 读取量
Memory Bandwidth 压力
5.4 GQA:分组共享 KV
Q:32 Heads
KV:8 Heads
可以理解为:

5.5 同一例子看清三种 Head 布局
可以用这下表记忆:
结构 | Q Head | KV Head |
|---|---|---|
MHA | 32 | 32 |
GQA | 32 | 8 |
MQA | 32 | 1 |
在相同前提下,KV Head 越少,缓存占用与读取量通常越低,Q 对 KV 的共享程度越高。
模型质量是否受到影响取决于架构与训练,不能仅由 Head 数判断。
在其他条件相同(层数、序列长度、每头维度和缓存精度)时,KV Cache 与 KV Head 数近似成正比;头数减少与模型质量之间是设计权衡,不意味着 MQA 一定掉点或 GQA 一定最优。
5.6 为什么 KV Head 数影响 Decode
LLM Decode 阶段有一个特点:每次通常只生成 1 个 Token,但是这个 Token 需要访问大量历史 KV。
降低 KV Head 数可以减少需要存取的历史 K/V。对相同缓存宽度、长度与数据类型的模型,GQA 减少 KV Head,可直接减轻这一部分的缓存压力。
对于给定缓存精度和 Head 维度,更少的 KV Head 通常意味着更小的 KV Cache 和更低的 KV 读取量。
6. 总结
用一张图统一起来:

将术语放在四个相互独立的维度:
Q/K/V 来自同一序列还是不同序列(Self/Cross);
每个 Query 能访问哪些位置(Causal/双向/局部);
Q 与 KV 各有多少 Head(MHA/GQA/MQA);
实现如何组织计算与缓存(具体 Attention Kernel、KV 分页与前缀复用)
前面三项是结构或可见性语义,最后一项是工程实现。
概念 | 解决什么问题 |
Self-Attention | Q/K/V 来自同一序列 |
Cross-Attention | Q 与 K/V 来自不同序列 |
Causal Attention | 限制不能看到未来 Token |
MHA | 每个 Q Head 有独立 KV |
GQA | 多个 Q Head 共享 KV |
MQA | 所有 Q Head 共享 KV |
