当前位置: 首页 > news >正文

从零手搓大模型(深挖细节GQA )现代大模型为什么不用普通 MHA

从零手搓大模型(深挖细节GQA )现代大模型为什么不用普通 MHA

GQA,全称Grouped-Query Attention,是现代 LLM 非常常见的 attention 结构。Llama、Qwen、Gemma 等模型都大量使用它。

一句话理解:

Query head 仍然很多,但 Key/Value head 变少,让多个 query head 共享同一组 K/V。

这样可以明显减少 KV cache 显存占用,同时保持接近 MHA 的建模能力。

1. 从 MHA 说起

第 2 章的 Multi-Head Attention 里,每个 head 都有自己的:

Q, K, V

如果有 32 个 attention heads,那么通常也有 32 组 K 和 32 组 V。

这叫 MHA:

Multi-Head Attention

问题是:推理时 KV cache 要保存所有层、所有 token、所有 head 的 K/V。

长上下文下,KV cache 会非常大。

2. GQA 的核心想法

GQA 做了一件很聪明的事:

保留多个 query heads 减少 key/value heads 让多个 query heads 共享同一组 K/V

例如:

num_heads = 6 num_kv_groups = 3

那么:

head 1, 2 共享 KV group 1 head 3, 4 共享 KV group 2 head 5, 6 共享 KV group 3

如果:

num_heads = num_kv_groups

就退化成普通 MHA。

如果:

num_kv_groups = 1

就是 MQA,也就是 Multi-Query Attention,所有 query heads 共享一组 K/V。

3. 为什么 GQA 省显存

KV cache 大小主要和n_kv_heads有关。

公式可以理解成:

KV cache bytes ≈ batch_size × sequence_length × head_dim × num_layers × 2 # K 和 V × bytes_per_elem × n_kv_heads

普通 MHA:

n_kv_heads = n_heads

GQA:

n_kv_heads = n_kv_groups

所以只要n_kv_groupsn_heads少,KV cache 就会明显变小。

例子:

n_heads = 32 n_kv_groups = 8

KV cache 大约少 4 倍。

4. 代码入口:GroupedQueryAttention

gpt_with_kv_gqa.py里,核心类是:

classGroupedQueryAttention(nn.Module):

初始化里有两个关键断言:

assertd_out%num_heads==0assertnum_heads%num_kv_groups==0

第一个保证总维度可以平分给多个 query head。

第二个保证 query heads 可以平分给多个 KV groups。

5. MHA 和 GQA 的投影层差异

普通 MHA 的 Q/K/V 通常都是:

W_query:d_in->d_out W_key:d_in->d_out W_value:d_in->d_out

GQA 里:

self.W_query=nn.Linear(d_in,d_out,...)self.W_key=nn.Linear(d_in,num_kv_groups*head_dim,...)self.W_value=nn.Linear(d_in,num_kv_groups*head_dim,...)

也就是说:

Q 还是完整的 num_heads K/V 只生成 num_kv_groups 份

这就是 GQA 的关键。

6. shape 变化

假设:

batch = b num_tokens = T num_heads = H num_kv_groups = G head_dim = D

query:

queries.shape = (b, H, T, D)

key/value 在展开前:

keys.shape = (b, G, T, D) values.shape = (b, G, T, D)

因为G < H,所以 K/V 比 MHA 少。

7. repeat_interleave 的作用

attention 计算时,query heads 有 H 个,但 key/value groups 只有 G 个。

所以代码会把 K/V 扩展到 H 个 head:

keys=keys_base.repeat_interleave(self.group_size,dim=1)values=values_base.repeat_interleave(self.group_size,dim=1)

其中:

self.group_size=num_heads//num_kv_groups

例如:

num_heads = 6 num_kv_groups = 3 group_size = 2

K/V 会从:

[K1, K2, K3]

变成:

[K1, K1, K2, K2, K3, K3]

这样每个 query head 都有对应的 K/V 可以做 attention。

8. GQA 的 attention 计算仍然一样

扩展后,attention 公式没有变:

attn_scores=queries @ keys.transpose(2,3)attn_weights=torch.softmax(attn_scores/keys.shape[-1]**0.5,dim=-1)context_vec=(attn_weights @ values).transpose(1,2)

最终输出仍然是:

(batch, num_tokens, d_out)

所以 GQA 对后面的 TransformerBlock 来说是可替换的。

9. GQA 和 KV cache 的关系

GQA 在训练时也减少参数和计算,但它在推理阶段最明显的收益来自 KV cache。

因为 cache 保存的是 K/V。

普通 MHA:

每个 attention head 都要存 K/V

GQA:

多个 query heads 共享少量 K/V groups

因此长上下文推理时,GQA 可以显著减少显存。

10. memory_estimator_gqa.py 怎么理解

这个脚本用来估算 MHA 和 GQA 的 KV cache 显存差异。

README 示例中:

uv run memory_estimator_gqa.py\--emb_dim4096--n_heads32--n_layers32\--context_length32768--n_kv_groups4\--batch_size1--dtypebf16

如果n_heads=32n_kv_groups=4,则 K/V head 数减少 8 倍。

在长上下文下,这种差异非常大。

11. GQA 的代价

GQA 不是无脑越少越好。

如果num_kv_groups太少,很多 query heads 共享同一组 K/V,模型表达能力可能下降。

所以真实模型通常取中间值:

MHA: n_kv_groups = n_heads GQA: 1 < n_kv_groups < n_heads MQA: n_kv_groups = 1

GQA 是在质量和效率之间折中。

12. 和 Llama/Qwen/Gemma 的关系

这个 bonus 虽然是在 GPT 架构上改 GQA,但真实现代模型里,GQA 已经很常见。

你后面看:

  • Llama 3
  • Qwen3
  • Gemma
  • 推理框架的 KV cache 显存优化

都会看到类似设计。

所以这个 bonus 是从“教学版 GPT”过渡到“现代 LLM 架构”的重要桥梁。

13. 建议

推荐这样看:

  1. 理解 GQA 省的是 K/V。
  2. 对比gpt_with_kv_mhagpt_with_kv_gqa
  3. 重点看GroupedQueryAttention
  4. 盯住三个参数:
num_heads num_kv_groups group_size
  1. 跑或阅读memory_estimator_gqa,感受上下文长度变大后的显存差异。

一句话总结:

GQA 保留多个 query heads,但减少 key/value heads,用较小质量代价换取明显的 KV cache 显存收益。
http://www.jsqmd.com/news/1195837/

相关文章:

  • 鸿蒙应用开发实战【16】— bindSheet 底部弹出面板全解析
  • 2026年7月最新亨得利官方服务项目及价格查询|详细地址与服务电话权威信息声明 - 亨得利官方
  • 基于Python+爬虫的房屋租赁数据可视化系统设计与实现
  • 深入解析MOS管三个工作区及其在H桥电路中的关键应用
  • 2026最新:直播内容总结选哪5款免费实用工具,能控制时间成本?
  • 33-杨逢昌:制造业6S标准落地难破解方案——三层标准分层落地标准化体系
  • Kimi读Excel总卡顿?揭秘3个被官方文档刻意忽略的性能优化关键点:实测提速300%
  • DS90UB954-Q1寄存器驱动实战:中断、AEQ调优与模式生成器应用
  • **2026毓典奢品汇天津黄金二手流通市场深度测评:五大回收机构星级评级与避坑指南** - 二奢行情速报
  • ChatGPT版本解析与API集成开发实战指南
  • 学习栈:YOLO学习一定要学习python吗 ,pytorch与yolo的关系
  • [工业自动化-2]:PLC硬件架构与信号处理链路
  • 从ADC读数到PPM:MQ-2烟雾传感器的电压-浓度转换实战解析
  • 福州卖钻戒当心拆石扣费!靠谱钻石回收店铺无拆石、金属损耗附加费 - 每日生活报
  • 【MV】Camera Calibration Fundamentals: Image Formation
  • 怕被虚高报价套路?武汉手表回收认准奢二网全程明细化估价 - 大牌深度测评
  • 高效的ROHS分析仪行业十大品牌:为何天瑞与泓盛能成为电子电器行业的首选? - 品牌推荐大师
  • 量化交易核心:正期望值、夏普比率与海龟策略构建稳定盈利系统
  • (八)STM32 USART —— 从电平转换到DMA:构建高效串口通信系统
  • AMIS【部署 02】从零到一:amis-editor可视化编辑器私有化部署与Nginx实战配置
  • Zotero+坚果云+ZotFile:构建高效文献管理生态的进阶指南
  • 计算优化第一步:结构化问题诊断协议
  • C++面向对象单链表实现:从封装、RAII到迭代器的完整指南
  • 郑州二七二手名表回收,无套路不砍价报价即到手价 - 全城热点
  • [Bug已解决] RuntimeError: cuFFT error: CUFFT_INTERNAL_ERROR 傅里叶变换内部错误解决方案
  • Grok 4.5:政治中立性最佳AI模型的技术解析与应用实践
  • 为什么92%的人用ChatGPT练英语无效?——揭穿3大认知陷阱及2024权威验证的4阶渐进模型
  • dubbo实践最小治理单元demo
  • 2026年AI搜索优化源头厂家深度评测:国内GEO选型避坑指南 - 品牌报告
  • A Gentle Introduction to Lattice-Based Cryptography 格密码学温和入门学习笔记第四章:容错学习(LWE)问题