KV Cache 与推理加速:为什么首 Token 慢、后面越来越快
一、背景
用本地 llama.cpp、vLLM 或在线 API 续写长文 时,你会发现:第一个字(token)往往最慢,后面一串出来得更快。训练时我们关心 整体算力,推理时更关心 延迟和吞吐——其中一个大头就是 注意力里对历史 token 的重复计算。
KV Cache 做的事很朴素:前面已经算过的 Key/Value 向量存起来,生成新 token 时只算 最新那一列,不再从头把整个序列重算一遍。搞懂它,你才能理解:为什么上下文越长越吃显存、为什么 批推理 要调 max_batch、以及它和 量化(尤其 K/V 量化)是什么关系。
二、核心概念和核心原理(详细解答+通俗解释)
(一)核心概念(先通俗,再详细)
1. 自回归生成——一次吐一个 token通俗解释:生成第 (t) 个词时,模型能看见 前 (t-1) 个词(加自己刚预测的)。详细解答:朴素实现下,第 (t) 步要对长度 (t) 的序列做注意力,每步都算一遍前面所有位置,复杂度随长度平方增长,浪费极大。
2. KV Cache——把历史位置的 K、V 张量缓存通俗解释:第 (i) 个位置的 K、V 算完就不变(在没有 KV量化动态刷新 等特殊策略时),下次直接 拼上新的 K、V 做注意力。详细解答:缓存按 层 × 头 × 序列位置 × 维度 占显存;上下文越长,Cache 线性膨胀,这是长上下文模型的 显存杀手 之一。
3. 首 Token 延迟(TTFT)与逐 Token 延迟通俗解释:Prefill 阶段要把用户整段 prompt(可能很长)先算一遍并填满 Cache,所以慢;Decode 阶段每步只算1 个新 token,相对快。详细解答:优化 Prefill 用 算子融合、并行、FlashAttention 等;优化 Decode 用 批处理、投机解码(draft model) 等。
(二)核心原理(通俗拆解,一步一步讲清楚)
第一步:注意力需要 Q、K、V通俗解释:每个位置用 Q 去点乘所有 K 得权重,再乘 V 求和。详细解答:已生成位置的 K、V 不随后面新词改变(标准 Transformer 解码器里),故可缓存。
第二步:显存公式直觉通俗解释:层数 × 隐藏维度 × 序列长度 × batch × 精度字节数 量级;FP16 比 FP32 省一半。详细解答:GQA/MQA 减少 K/V 头数,是 砍 Cache 的主流架构手段。
第三步:与量化的交界通俗解释:有人对 K/V 也做 INT8/INT4,进一步省显存,可能轻微掉点长文质量。详细解答:和 lianghua(权重量化) 不同,KV量化针对 推理态激活/缓存;选型看框架支持。
三、补充进阶知识点(易懂不晦涩,适配新手进阶)
1. FlashAttention通俗解释:分块计算注意力,减少 HBM 读写,Prefill/训练都受益。简单补充:现在主流推理栈常默认开。
**2. 投机解码(Speculative Decoding)**通俗解释:小模型 草稿 多个 token,大模型 并行验证,加速 decode。简单补充:需要 草稿模型 与主模型兼容。
3. 和之前知识点的关联****上下文窗口 拉长直接撑大 KV Cache;Tokenizer 决定同样文本多少 token →影响 Cache长度;量化 权重与 KV 量化 是不同维度优化。
四、文章知识总结
- 背景:推理贵在对同一前缀反复注意力;KV Cache 是 标配优化。
- 核心概念:缓存历史 K/V;Prefill vs Decode 两阶段延迟不同。
- 核心原理:Cache 随层数、长度、batch、精度涨;GQA/MQA 减负。
- 进阶:FlashAttention、投机解码;KV 量化是进阶选项。
- 核心逻辑:长上下文不仅费算力,更费显存——大头常在 KV。
总结:读 Transformer 结构时加上 KV Cache 这一层,才算 inference 视角 学懂了;和量化、长窗口文章连起来,就是部署工程师的日常语言。