☰
LLM应用开发必修课:彻底搞透 Attention 机制与工程优化
2026/9/30 11:45:35 网站建设 项目流程

如果说 Transformer 是 LLM 的骨架,那么 Attention 就是它的“信息路由系统”。

LLM 每生成一个 Token,本质上都在回答一个问题:当前这个 Token,应该从上下文中的哪些位置获取多少信息?

从最初的 MHA,到 MQA、GQA,再到 FlashAttention、PagedAttention,Attention 的演进史其实也是一部非常典型的工程优化史:

在模型质量、显存占用、内存带宽、计算吞吐和上下文长度之间寻找平衡。

对 LLM 应用开发者来说,理解 Attention 的意义并不只是为了面试。RAG 为什么会“看不见”某段文档?为什么 Context Window 越长,显存涨得越快?为什么 vLLM 能同时服务几百个请求?为什么同样是 32K 上下文,不同模型的显存需求可以差很多?

这些问题,最终都绕不开 Attention。


1. 引言:Attention 的本质——一场高维空间的“信息路由”

很多教程讲 Attention,第一句话通常是:

Query、Key、Value,分别是查询、键和值。

这句话没错,但对于工程开发者来说,它几乎没有解释力。

我们换一个场景。

1.1 把 Attention 想象成图书馆检索

假设你走进一个巨大的图书馆。

你现在手里有一个问题:

“Transformer 中为什么需要位置编码?”

这个问题就是你的Query(Q)。

图书馆里有成千上万本书,每本书都有自己的索引标签:

“位置编码”
“Transformer”
“Attention”
“RNN”
“CNN”……

这些索引标签就是Key(K)。

而真正的书籍内容,就是Value(V)。

于是整个检索过程变成:

当前问题 │ ▼ Query(Q) │ ┌────────┼────────┐ ▼ ▼ ▼ Key 1 Key 2 Key 3 │ │ │ 相似度 相似度 相似度 │ │ │ └────────┼────────┘ ▼ Attention 权重分配 │ ┌────────┼────────┐ ▼ ▼ ▼ Value 1 Value 2 Value 3 │ │ │ └────────┼────────┘ ▼ 加权信息融合

Q 决定“我现在想找什么”,K 决定“每条信息是什么”,V 决定“真正取回来什么内容”。

所以:

  • Q:当前 Token 的信息需求

  • K:上下文中每个 Token 的可匹配索引

  • V:上下文中真正被读取的信息

  • Attention:计算当前 Token 应该从哪些 Token 获取信息

这就是 Attention 最重要的物理直觉:

Attention 不是简单地“看上下文”,而是在上下文中动态选择信息。


1.2 为什么需要 Q、K、V 三套表示?

最经典的 Scaled Dot-Product Attention:

Attention(Q,K,V)=softmax(QKTdk)VAttention(Q,K,V) = softmax \left( \frac{QK^T}{\sqrt{d_k}} \right)V

可以拆成三个步骤。

第一步:Q 和 K 做匹配

S=QKTdkS = \frac{QK^T}{\sqrt{d_k}}

得到的是:

“当前 Token 和上下文中每个 Token 有多相关?”


第二步:Softmax 转成权重

A=softmax(S)A = softmax(S)

于是:

Token A 0.05 Token B 0.10 Token C 0.70 Token D 0.15

变成了一组概率式权重。

人话就是:

“这次查询,我主要关注 Token C。”


第三步:对 V 加权求和

Output=AVOutput = AV

最终得到的是:

融合上下文后的新表示。

因此 Attention 真正完成的是:

根据当前上下文需求,对已有信息进行动态路由和融合。


1.3 Attention 在 LLM 中到底干什么?

以一句话:

“小明把书放到桌子上,因为它太重了。”

当模型处理“它”时,需要判断“它”更可能指向:

  • 小明?

  • 书?

  • 桌子?

模型并不是通过某条硬编码规则解决这个问题,而是通过多层 Attention,让当前 Token 与上下文中的相关 Token 建立不同强度的信息连接。

因此可以把 Transformer 理解成:

一个不断进行上下文信息交换的高维信息路由网络。

这也是为什么 Attention 对 LLM 如此重要。

但问题来了:

如果上下文只有 100 个 Token,这套机制非常舒服;如果上下文变成 100K、1M Token 呢?

工程问题马上出现。


2. 架构演进:从 MHA 到 GQA,一场显存与速度的妥协

Attention 第一个巨大的工程问题不是算力,而是:

KV Cache 太大。

理解这个问题之前,需要先理解 MHA、MQA 和 GQA。


2.1 MHA:每个 Query Head 都有自己的 K/V Head

经典 Multi-Head Attention:

Multi-Head Attention(MHA)会把隐藏层拆成多个 Attention Head。

例如:

num_attention_heads = 32

那么通常意味着:

Q Head:32 K Head:32 V Head:32

结构可以理解为:

Q1 ─── K1 ─── V1 Q2 ─── K2 ─── V2 Q3 ─── K3 ─── V3 ... Q32 ── K32 ── V32

优点非常明显:

每个 Head 都拥有独立的 K/V 表示,表达能力强。

但缺点也非常明显:

推理阶段,每个请求都要缓存大量 K/V。

这就是 KV Cache。


2.2 为什么 KV Cache 会成为显存杀手?

假设:

Layers = 32 KV Heads = 32 Head Dim = 128 Context = 8192 dtype = FP16

单个 Token 的 K/V 数据量大约是:

2×L×HKV×d2 \times L \times H_{KV} \times d

其中:

  • 2:K + V

  • $L$:Layer 数

  • $H_{KV}$:KV Head 数量

  • $d$:Head Dimension

对于整个上下文:

MemoryKV∝2×L×HKV×N×dMemory_{KV} \propto 2 \times L \times H_{KV} \times N \times d

其中 $N$ 是序列长度。

关键点来了:KV Cache 与上下文长度 $N$ 成正比。

所以:

8K → 1 倍 16K → 2 倍 32K → 4 倍 64K → 8 倍 128K → 16 倍

这就是为什么:

长上下文推理首先遇到的往往不是模型参数显存,而是 KV Cache 显存。


2.3 MQA:让所有 Query Head 共享 K/V

于是研究人员想到:

Q Head 必须这么多吗?

K/V 能不能共享?

于是出现:

Multi-Query Attention(MQA)

结构

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询