前面算过 decode 阶段是访存瓶颈(KV cache 复杂度那篇),批量大小被显存里那坨 K/V 张量卡死。GQA/MQA 的思路很直接:Q 可以有很多头,但 K/V 真的需要每个 Q 头一份吗?这篇从 cache 字节数出发,把这个"共享"的性价比算清楚。
账本:KV cache 占多少字节
解码到第 $t$ 个 token 时,每层要为之前所有位置存 K 和 V。设层数 $L$、Q 头数 $n_h$、每头维度 $d_h$、KV 头数 $n_{kv}$、序列长度 $s$、每元素字节数 $b$(bf16 时 $b=2$),cache 总量为:
$$ \text{KV bytes} = 2 \times L \times n_{kv} \times d_h \times s \times b. $$
代入 Llama-2-70B 的规格($L=80, n_h=64, d_h=128$,bf16):全 MHA 下每 token 每层的 K+V 是 $2\times 64\times 128\times 2 = 32\text{KB}$,80 层就是 2.5MB/token。4k 上下文的单条请求 10GB,8 卡 A100 的 80GB 显存除去权重(约 140GB 的一半靠张量并行摊开,每卡 ~17.5GB)剩下的量只够几十条并发。这就是 2023 年前后推理服务真正的天花板:不是算力,是 cache。
MQA(Multi-Query Attention,Shazeer 2019《Fast Transformer Decoding: One Write-Head is All You Need》)把 $n_{kv}$ 从 64 压到 1:cache 直接除以 64。GQA(Grouped-Query Attention,Ainslie et al. 2023)取折中,$n_{kv} = n_h / g$,g 个 Q 头共享一份 K/V(Llama-2-70B:$n_h=64, n_{kv}=8$)。三者的每 token cache:MHA 2.5MB,GQA(8) 312KB,MQA 39KB。
为什么质量几乎不掉
直觉上砍 KV 头是在砍表达力:原来 64 个 Q 头可以在 64 个不同的 K/V 子空间里检索,共享后只剩 8 个。但推理的实测是 GQA 与 MHA 基本打平(Ainslie 等的 uptraining 实验),MQA 略有下降。原因在注意力的工作方式里:
Q 头的多样性主要来自 query 投影 $W_Q$——不同头学的是"问什么问题",而 K/V 提供的是"被问的内容"。把 K/V 头分组共享,等价于所有组内 Q 头在同一份内容上做不同角度的检索。NLP 里 key 的表示冗余度本来就高(很多头的 K 注意力模式高度相关,多头多样性那篇有实证),砍 K/V 头比砍 Q 头便宜得多。GQA 论文的关键实验支撑是这个:拿已训好的 MHA checkpoint,把每组的 K/V 投影做均值初始化成共享头,只在小数据上继续训(uptraining),质量就追回来了——说明 MHA 解里本来就躺着近似 GQA 的解,微调只是在收敛过去。
MQA 掉到 1 个 KV 头时,所有 Q 头挤在同一个内容空间里,检索角度再多也只有一个"书架",长检索类任务开始掉点。LLaMA-3、Qwen 系列都停在 GQA 的 8 个 KV 头上,这不是巧合,是质量-显存的帕累托拐点附近。
为什么省 cache 就是省延迟
回到 decode 的 roofline:每生成一个 token,GPU 要把全部 KV cache 从 HBM 读一遍参与注意力计算。每 token 的访存量正比于 cache 字节数,而每 token 的计算量(一次小 GEMV 加注意力)几乎不随 cache 变。decode 阶段 batch 内的请求是逐 token 同步推进的,显存带宽 / cache 字节数 = 吞吐上限。GQA 把 cache 除以 8,等效于把同样的带宽换成 8 倍并发空间;或者等价地看,固定并发下每 token 读的字节少 8 倍,首 token 之后的流式速度(TPOT)直接受益。
还有一个次要但真实的收益:张量并行切分时 KV 头数影响通信模式。$n_{kv}=8$ 配合 8 卡 TP 时每个 KV 头恰好落在一张卡上,all-reduce 的通信图干净;$n_{kv}=1$(MQA)时 K/V 变成复制或单卡瓶颈。工程细节上 GQA 的 8 又赢一次。
小结
GQA/MQA 是"解码是访存瓶颈"这个诊断的直接推论:cache 字节数决定并发和延迟,而 K/V 的表达能力冗余足够扛住共享。工程上 GQA 凭 uptraining 兼容已有 checkpoint、质量几乎无损、TP 切分友好,成为 Llama-2/3 之后事实上的标配。更深一层的启示是注意力的非对称性——Q 侧管"怎么问",KV 侧管"有什么",砍冗余永远先砍供给端。这个"非对称压缩"的思路在下一篇 MLA 里被推到极致:不共享头,而是把 K/V 整体压进一个低维潜向量。