ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

LLM应用开发必修课:彻底搞透 Attention 机制与工程优化

LLM应用开发必修课:彻底搞透 Attention 机制与工程优化 如果说 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)结构
返回列表