从Transformer到MHA→MQA→GQA的注意力机制演进,详解KV cache优化对大模型推理内存带宽的影响。
大家好,我是 Shrijith Venkatramana。我正在构建 git-lrc,一款运行在每次提交上的 AI 代码审查工具。给我们点个 Star,帮助开发者发现这个项目。一定要试试看,并把反馈分享给我们,帮助改进产品。
如果你曾疑惑为什么一个拥有数十亿参数的 LLM 推理却会被内存带宽严重限制,注意力机制是一个很好的切入点。
真正的瓶颈往往是模型在逐 token 生成时必须通过内存传输的状态量。
这一观察催生了 Transformer 架构的一次小型但意义重大的演进:
多头注意力(MHA)→ 多查询注意力(MQA)→ 分组查询注意力(GQA)。
三种机制执行的概念操作本质上相同——查询查找键并检索值——但在使用多少份键和值的副本方面做出了截然不同的选择。
2017 年 Vaswani 等人提出的 Transformer 用注意力机制取代了循环。该论文《Attention Is All You Need》引入的架构成为了现代 LLM 的基础。
基本的注意力操作是:
Attention(Q, K, V) = softmax((Q * K^T) / sqrt(d_k)) * V
一个对开发者友好的解读是:
Q(查询):"我在寻找什么信息?"
K(键):"我包含什么样的信息?"
V(值):"这是信息本身。"
假设模型正在处理这句话:
The server rejected the request because it lacked a valid certificate.
在处理过程中,注意力机制可以发现 server 是一个有用的先行词。
单一的注意力机制给模型提供了一种学习而来的查找方式。
多头注意力则给了它多种。
不是一组 Q、K、V,而是:
Q1, K1, V1
Q2, K2, V2
...
Qh, Kh, Vh
然后将它们的输出拼接起来。
原始 Transformer 在基础模型中使用 8 个头,在更大的模型中使用 16 个头。每个头在学习的子空间中运作,允许不同的头专门处理不同的关系。
可以把它想象成让多位专家同时阅读同一份文档:
一位可能学习句法关系, 另一位学习位置关系, 还有一位学习语义关联, 最后一位学习长距离依赖。
模型学习这些专家实际上应该代表什么。
在训练期间,Transformer 是高度并行化的。
给定一个 4,000 个 token 的序列,模型基本上可以同时处理整个序列。
但生成的工作方式不同。
比如:
Explain how TCP congestion control works.
模型生成的输出类似:
TCP
TCP congestion
TCP congestion control
TCP congestion control works
...
在每个生成步骤中,模型需要关注它已经生成的所有内容。
重新计算所有先前 token 的键和值会极其浪费,因此推理系统会维护一个 KV 缓存。
对于每个先前的 token,每个 Transformer 层都存储它的:
K 和 V
然后,在生成下一个 token 时,模型计算新的查询,并对缓存的键和值进行注意力计算。
这就是工程问题出现的地方。
使用常规的多头注意力,每个注意力头都有自己独立的 K 和 V。
如果有 32 个头,实际上需要为每个 token 和每个层维护:
K1 V1
K2 V2
...
K32 V32
而且缓存随上下文长度线性增长。
这是 Noam Shazeer 2019 年论文《Fast Transformer Decoding: One Write-Head is All You Need》中的关键观察。Shazeer 识别出在增量解码过程中反复加载大型 K 和 V 张量的内存带宽成本是一个主要瓶颈。
这一观察产生了下一步的架构演进。
Shazeer 的想法非常简单。
保留多个查询头:
Q1, Q2, ..., Qh
但使用一个共享的 K 和一个共享的 V:
K, V
Q1 -> K1,V1
Q2 -> K2,V2
Q3 -> K3,V3
Q4 -> K4,V4
Q1 --+
Q2 --+
Q3 --+--> K,V
Q4 --+
这就是多查询注意力(MQA)。
查询保持独立。模型仍然有多种不同的提问方式。
所有这些问题都搜索先前 token 的相同表示。
这对 KV 缓存产生了巨大的影响。
32 个 Transformer 层
使用常规 MHA,KV 缓存大约是:
2 * 32 * 32 * 128 * 2 * 8192 bytes
这大约是 4 GB 每个序列。
使用 MQA,只有一个 KV 头:
2 * 32 * 1 * 128 * 2 * 8192 bytes
大约是 128 MB。
相同的模型深度。相同的查询头。相同的上下文。
KV 缓存缩小了 32 倍。
这改变了服务提供的经济学。
在自回归解码期间,历史的 K/V 张量被反复加载。减小它们的大小会减少内存传输。Shazeer 的实验表明,与常规多头注意力相比,解码速度显著提升,而质量下降很小。
在 MHA 中,每个头有:
K1,V1,K2,V2,...,Kh,Vh
这些不同的 K/V 投影可以编码不同的表示。
MQA 将它们全部折叠为:
K,V
查询保持多样性,而它们查询的信息是共享的。
一个有用的心智模型是:
MHA 给每位专家自己的数据库。
MQA 给所有专家一个数据库。
共享数据库在内存中保存起来要便宜得多。但专家也失去了更多的表示独立性。
工程问题变成了:
我们愿意为内存效率牺牲多少表示独立性?
这个问题自然引向了第三种架构。
2023 年,Google 的 Joshua Ainslie 和同事们在 EMNLP 论文《GQA: Training Generalized Multi-Query Transformer Models from Multi-Head Checkpoints》中引入了分组查询注意力(GQA)。
一旦 MHA 和 MQA 都摆上台面,这个想法几乎简单得令人尴尬。
考虑三种配置:
32 个查询头
32 个 KV 头 <- MHA
32 个查询头
1 个 KV 头 <- MQA
32 个查询头
8 个 KV 头 <- GQA
每个 KV 头服务一组查询头。
Q0 Q1 Q2 Q3 --> K0,V0
Q4 Q5 Q6 Q7 --> K1,V1
Q8 Q9 Q10 Q11 --> K2,V2
...
32 个独立查询头
每个 KV 头被 4 个查询头共享
因此 GQA 是 MHA 和 MQA 之间的连续体。
KV 头的数量成为一个可调的架构旋钮。
Ainslie 等人明确将 GQA 描述为多头注意力和多查询注意力之间的插值,每个查询端子组有一个共享的 K/V 头。
这为模型设计者提供了一个有用的频谱:
MHA MQA
|---------------------------|
32 个 KV 头 1 个 KV 头
^
|
GQA
对于推理工程师来说,这可能是整篇讨论中最有用的公式。
忽略次要的实现细节,每个序列的 KV 缓存大约是:
Memory =
2 * L * n_KV * d_head * T * bytes
L = Transformer 层数
n_KV = KV 头数量
d_head = 头维度
T = 缓存的 token 数量
bytes = 每个元素的字节数
注意这个重要变量:
n_KV
查询头的数量不直接决定 KV 缓存大小。
这就是架构的妙处。
考虑一个假设的模型:
32 个查询头
128 维头
32 层
FP16
8192 token 上下文
KV 缓存比较变为:
MHA ~= 4.0 GB
GQA ~= 1.0 GB
MQA ~= 0.125 GB
计算很直接。
2 * 32 层 * 32 KV 头 * 128 维
* 8192 token * 2 字节
~= 4.0 GB
2 * 32 * 8 * 128 * 8192 * 2
~= 1.0 GB
2 * 32 * 1 * 128 * 8192 * 2
~= 0.125 GB
缓存随序列长度线性缩放:
8K -> 4 GB
16K -> 8 GB
32K -> 16 GB
针对上述假设的 MHA 配置。
这就是注意力架构成为运维问题的地方。
假设你的 GPU 有 80 GB 可用内存。
你的模型权重可能消耗 60 GB。
剩余大约 20 GB 用于:
因此注意力架构影响了 GPU 可以同时容纳多少个序列。
它还影响 GPU 在每个解码步骤中需要读取多少数据。
这就是为什么 LLM 服务会在计算之外同时受到内存容量和带宽的约束。
Ainslie 等人的动机是一个实际问题。
MQA 使解码更便宜,但其质量权衡可能很重要。从头训练一个完全使用 MQA 推理特性的模型也代表了巨大的成本。
Their 2023 paper demonstrated a way to uptrain existing MHA checkpoints into MQA or GQA models using approximately 5% of the original pre-training compute. They found that GQA could achieve quality close to MHA while delivering inference speed comparable to MQA.
他们的 2023 年论文展示了一种方法,可以利用约 5% 的原始预训练计算量,将现有的 MHA 检查点升级训练为 MQA 或 GQA 模型。他们发现 GQA 可以在达到接近 MHA 质量的同时,实现与 MQA 相当的推理速度。
This is an important detail in the history.
这是历史中一个重要的细节。
The progression followed a practical engineering path:
这一演进遵循了一条实用的工程路径:
Build a powerful architecture -> discover an inference bottleneck -> remove expensive redundancy -> measure the quality trade-off -> introduce a tunable sharing scheme.
构建强大架构 → 发现推理瓶颈 → 消除昂贵冗余 → 评估质量权衡 → 引入可调节的共享方案。
The evolution looks like this:
演进过程如下:
2017
Transformer
|
| Multiple independent K/V projections
v
MHA
|
| "Why are we carrying so many K/V tensors?"
v
2019
MQA
|
| "One shared KV representation can affect quality."
v
2023
GQA
|
| "Let's share K/V within groups."
v
Modern LLM serving
There is a broader systems lesson here.
这里还有一个更广泛系统层面的教训。
Good systems engineering often consists of finding expensive redundancy and deciding how much of it you can safely remove.
优秀的系统工程通常包含:找出昂贵的冗余,并决定可以安全移除多少。
Attention provides a particularly clean example because the redundancy has a direct relationship to GPU memory traffic.
注意力机制提供了一个特别清晰的例子,因为这种冗余与 GPU 内存带宽有直接关系。
If you are implementing or operating an LLM, I would remember the three architectures this way.
如果你正在实现或运营一个 LLM,可以用这种方式来记忆三种架构。
MHA — maximum independence
MHA — 最大独立性
Q0 -> K0,V0
Q1 -> K1,V1
Q2 -> K2,V2
...
Q31 -> K31,V31
Mental model: every attention head has its own memory.
心智模型:每个注意力头都有自己的内存。
You pay the most in KV-cache memory.
你需要为 KV 缓存付出最多的内存代价。
MQA — maximum sharing
MQA — 最大共享
Q0 --+
Q1 --+
Q2 --+--> K,V
... |
Q31-+
Mental model: all attention heads share one memory.
心智模型:所有注意力头共享一块内存。
KV-cache efficiency is excellent, with the strongest sharing of K/V representations.
KV 缓存效率极佳,K/V 表示的共享程度最高。
GQA — grouped sharing
GQA — 分组共享
Q0 Q1 Q2 Q3 -> K0,V0
Q4 Q5 Q6 Q7 -> K1,V1
Q8 Q9 Q10 Q11 -> K2,V2
...
Mental model: teams of attention heads share memory.
心智模型:注意力头 teams 共享内存。
You choose the team size.
你来选择 team 大小。
n_Q = 32
n_KV = 8
then each KV head serves:
那么每个 KV head 服务:
32 / 8 = 4
n_Q / n_KV
is a useful number to keep in your head when reading modern LLM architectures.
是在阅读现代 LLM 架构时值得记住的有用数字。
A model architecture that says:
一个声明如下配置的模型架构:
Attention heads: 32
KV heads: 8
immediately tells you that the model is using GQA with four query heads per KV group.
立即告诉你该模型正在使用 GQA,每个 KV 分组四个查询头。
There is a tendency to think about neural-network architecture in terms of accuracy and FLOPs.
有一种倾向是围绕准确率和 FLOP 来思考神经网络架构。
For training, those metrics are fundamental.
对于训练而言,这些指标是根本性的。
For production inference, the system has another layer of economics:
对于生产推理而言,系统还有另一层经济考量:
Model
|
GPU memory
|
KV cache
|
Memory bandwidth
|
Batch size
|
Tokens/sec
|
Users/GPU
|
$/million tokens
Changing MHA to GQA can therefore affect:
因此,将 MHA 改为 GQA 会影响:
maximum context you can fit,
可以容纳的最大上下文长度,
maximum concurrent sequences,
最大并发序列数,
number of GPUs required,
所需的 GPU 数量,
and ultimately cost per generated token.
以及最终每生成一个 token 的成本。
Imagine two serving configurations with identical model weights.
假设两个服务配置使用相同的模型权重。
Configuration A uses MHA:
配置 A 使用 MHA:
32 KV heads
Configuration B uses GQA:
配置 B 使用 GQA:
8 KV heads
At the same context length, Configuration B needs roughly one quarter of the KV-cache storage.
在相同的上下文长度下,配置 B 需要约四分之一的 KV 缓存存储空间。
That can create room for more concurrent requests.
这可以为更多并发请求腾出空间。
More concurrent requests can improve batch utilization.
更多并发请求可以提高批处理利用率。
Higher utilization can improve the economics of the GPU.
更高的利用率可以改善 GPU 的经济效益。
A model architecture choice has therefore propagated all the way into infrastructure cost.
因此,模型架构的选择一路传导到了基础设施成本。
This is also why Shazeer's 2019 paper is interesting historically. The paper framed MQA around the operational reality of incremental decoding: the model repeatedly loads K/V state, and memory bandwidth becomes a limiting resource.
这也是 Shazeer 2019 年论文在历史上值得关注的原因。该论文围绕增量解码的运营现实来构建 MQA:模型重复加载 K/V 状态,而内存带宽成为限制资源。
The original Transformer demonstrated how attention could replace recurrence and make sequence modeling dramatically more parallel during training.
原始的 Transformer 展示了注意力如何替代循环,并在训练期间使序列建模显著更加并行。
The subsequent work on MQA and GQA shows another stage of the story: once these models entered large-scale inference, the physical movement of model state became an architectural concern.
随后关于 MQA 和 GQA 的工作展示了故事的另一个阶段:一旦这些模型进入大规模推理,模型状态的物理移动就成为了架构层面的考量。
So when you encounter an LLM architecture diagram saying:
所以当你遇到一个 LLM 架构图写着:
32 attention heads, 8 KV heads
你可以将其读作一个系统决策:
The designers decided that four query heads can economically share one representation of the past.
设计者决定四个查询头可以经济地共享一个关于过去的表示。
That single line in a model card tells you something about the model's memory behavior, inference characteristics, and architectural trade-offs.
模型卡片上的这一行告诉你关于该模型内存行为、推理特性和架构权衡的信息。
The progression from MHA to MQA to GQA is a beautiful example of how modern ML systems evolve.
从 MHA 到 MQA 再到 GQA 的演进是现代 ML 系统如何演化的一个绝佳例子。
MHA: give every head its own K/V representation.
MHA:给每个头自己的 K/V 表示。
MQA: share K/V across all query heads and dramatically reduce inference memory traffic.
MQA:在所有查询头之间共享 K/V,并大幅减少推理内存流量。
GQA: share K/V selectively and preserve more representational independence.
GQA:有选择地共享 K/V,同时保留更多表示独立性。
The attention equation remains essentially the same.
注意力方程本质上保持不变。
The architectural decision concerns who gets to own the keys and values.
架构决策涉及谁拥有 keys 和 values。
Once you see that, the three mechanisms become much easier to reason about:
一旦你看到这一点,三种机制就变得更容易理解:
MHA -> maximum independence
MQA -> maximum sharing
GQA -> controlled sharing
MHA → 最大独立性
MQA → 最大共享
GQA → 受控共享
The fascinating question for LLM engineers is:
对 LLM 工程师而言,一个引人深思的问题是:
How much representational independence are you willing to buy when every byte of KV cache has to be stored, moved, and paid for?
当每一个字节的 KV 缓存都必须被存储、移动和付费时,你愿意为多少表示独立性买单?
And perhaps the more practical question is:
也许更实际的问题是:
When you choose an LLM for production, how often do you look at its KV-head configuration?
当你为生产环境选择 LLM 时,你多久看一次它的 KV-head 配置?
AI agents write code fast. They also silently remove logic, change behavior, and introduce bugs -- without telling you. You often find out in production.
AI 智能体写代码很快。它们也会悄无声息地删除逻辑、改变行为、引入 bug——而不告诉你。你往往在生产环境中才发现。
git-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.
git-lrc 解决了这个问题。它挂接到 git commit,在每个 diff 合入之前进行审查。60 秒配置完成。完全免费。
Free, Micro AI Code Reviews That Run on Git Commit
免费、极简 AI 代码审查,提交时运行
| 🇩🇪 Dansk | 🇪🇸 Español | 🇮🇷 Farsi | 🇫🇮 Suomi | 🇯🇵 日本語 | 🇳🇴 Norsk | 🇵🇹 Português | 🇷🇺 Русский | 🇦🇱 Shqip | 🇨🇳 中文 | 🇮🇳 हिन्दी |
Free, Micro AI Code Reviews That Run on Commit
免费、极简 AI 代码审查,提交时运行

GenAI today is a race car without brakes. It accelerates fast -- you describe something, and large blocks of code appear instantly. But AI agents silently break things: they remove logic, relax constraints, introduce expensive cloud calls, leak credentials, and change behavior -- without telling you. You often find out in production.
今天的 GenAI 像一辆没有刹车的高速赛车。它加速很快——你描述一个东西,大块代码就瞬间出现。但 AI 智能体悄无声息地破坏东西:它们删除逻辑、松弛约束、引入昂贵的云调用、泄露凭证、改变行为——而不告诉你。你往往在生产环境中才发现。
git-lrc is your braking system. It hooks into git commit and runs an AI review on every diff before it lands. 60-second setup. Completely free.
git-lrc 就是你的刹车系统。它挂接到 git commit,在每个 diff 合入之前运行 AI 审查。60 秒配置完成。完全免费。
In short, git-lrc helps Prevent Outages, Breaches, and Technical Debt Before They Happen
简而言之,git-lrc 帮助在事故、漏洞和技术债务发生之前预防它们
At a glance: 10 risk categories · 100+ failure patterns tracked · every commit…
一览:10 个风险类别 · 跟踪 100+ 失败模式 · 每个 commit…
For further actions, you may consider blocking this person and/or reporting abuse
如需进一步行动,你可以考虑屏蔽此人或举报滥用