GQA 的原理是什么,如何在效果、速度和显存之间折中?
未标记
考查重点:分组共享 KV 与质量、显存取舍。一组 Query 头共享一组 K/V:相较 MHA 减少缓存,相较 MQA 保留更多 KV 组,用任务效果与解码吞吐确定组数
本题目录
参考答案
核心回答
GQA 把多个查询头分成若干组,一组查询头共享一组 K、V 头。查询头仍各自计算注意力,但需要生成和缓存的 K、V 更少,因此能减少生成阶段的缓存容量与读取带宽。它介于每个查询头都有独立 K、V 的 MHA,以及全部查询头共享一组 K、V 的 MQA 之间。
折中点是 K、V 的组数:共享越多,缓存越小,但表示能力和任务质量可能受影响。组数应结合模型训练后的任务效果、实际解码吞吐和显存来选,不能把缓存减少四倍直接说成整机推理快四倍。
三种结构怎样对应
以32个查询头、各头维度相同为例:
| 结构 | 查询头数 | K、V 各自的头数 | 共享方式 |
|---|---|---|---|
MHA |
32 | 32 | 每个查询头独立使用 K、V |
GQA |
32 | 8 | 每4个查询头共享一组 K、V |
MQA |
32 | 1 | 全部查询头共享一组 K、V |
均匀分组通常要求查询头数能被 K、V 头数整除。算子也要支持相应布局,例如 MindSpore 的增量注意力接口分别接收 num_heads 与 num_key_value_heads,并对整除关系做限制;这只是一个具体实现的约束说明,不表示所有推理后端的支持范围相同。
Qwen3 的稠密模型采用了这种结构,但某个模型使用 GQA,并不能推出所有组数都能保持同样质量。
缓存到底能省多少
只计算各层历史 K、V 的裸存储,假设不量化、不复制,且所有层和请求长度相同:
缓存字节数 = 2 × 批量 × 层数 × 序列长度 × KV头数 × 单头维度 × 每元素字节数
其中2来自 K 和 V。假设批量为1、32层、序列长度4096、单头128维,每元素2字节:
| 结构 | KV头数 | 理论缓存 |
|---|---|---|
MHA |
32 | 2048MiB |
GQA |
8 | 512MiB |
MQA |
1 | 64MiB |
该例中 GQA 的裸缓存是 MHA 的四分之一。实际占用还会受到分页预留、并行复制、量化元数据和实现缓冲影响,这不是模型总显存或训练峰值。
为什么速度和质量还要实测
查询头仍要计算与历史键的匹配,前馈网络等部分也没有按相同比例减少。长序列解码常受缓存带宽影响,缓存缩小可能明显受益;具体收益还依赖批量、硬件和内核。
把已训练的 MHA 模型改成 GQA,也不是只改配置。原论文将组内 K、V 头的权重取均值,并继续训练来恢复质量;这是其转换实验的方法,不是所有模型都能无损套用的保证。比较方案时,应在相同任务、生成设置和负载下同时看质量、延迟、吞吐与缓存占用。
参考资料
- 国内:WeThinkIn:模型架构与工作原理:采用查询头数量与 K、V 共享方式的比较,说明三种结构的差异以及权重需要随结构调整。
- 国内:WeThinkIn:大模型部署技术:采用缓存随 KV 头数变化的存储分析,展开显存和带宽收益及其与总推理开销的区别。
- 国内:Qwen 团队:Qwen3 Technical Report:采用第2节的稠密模型架构,给出分组查询注意力的真实模型应用。
- 国内:MindSpore:incre_flash_attention:采用查询头、KV 头和张量布局的接口约束,说明均匀分组需要兼容实际算子。
- 国外:Ainslie 等:GQA: Training Generalized Multi-Query Transformer Models from Multi-Head Checkpoints:采用分组定义、权重取均值及继续训练的方法,限定缓存、质量和转换成本的权衡。
- 国外:Hugging Face:Caching:采用各层保存历史键和值以及缓存张量维度的说明,构造只计算裸缓存的容量例子。
