如何通过KV Cache加速大模型的推理吞吐率
本期播客
如何通过KV Cache加速大模型的推理吞吐率
如何通过KV Cache加速模型的推理吞吐率?
对LLM来说kv cache是单独的服务 还是 内置的能力?
一、如何通过KV Cache加速模型的推理吞吐率
KV Cache(Key-Value Cache)是大语言模型(LLM)推理加速中最核心的技术之一,尤其在 自回归生成(auto-regressive generation) 场景下(如问答、对话、代码生成)能显著提升吞吐率(throughput)和降低延迟(latency)。
下面从原理、实现、优化策略三个层面,通俗易懂地解释 如何通过 KV Cache 加速推理吞吐率。
一、KV Cache 是什么?为什么需要它?
🧠 背景:Transformer 的自注意力机制
在 Transformer 解码器中,每生成一个 token,都要计算它与所有已生成 token的注意力(Attention):
Q(Query):当前 token 的查询向量 K, V(Key, Value):所有历史 token 的键和值
❌ 问题:重复计算
如果不缓存,每次生成新 token 时,都要重新计算所有历史 token 的 K 和 V,时间复杂度为:
第 1 步:计算 1 个 K/V 第 2 步:计算 2 个 K/V ... 第 n 步:计算 n 个 K/V
总计算量:O(n²)
✅ 解决方案:KV Cache
首次计算每个 token 的 K 和 V 后,将其缓存起来 后续生成新 token 时,直接复用缓存的 K/V,只计算当前 token 的 Q
💡 效果:每步计算量从 O(n) → O(1),总计算量从 O(n²) → O(n)
二、KV Cache 如何提升吞吐率(Throughput)?
吞吐率 = 每秒生成的 token 数(tokens/s)
KV Cache 通过以下方式提升吞吐:
| 减少重复计算 | |
| 降低显存带宽压力 | |
| 支持批处理(Batching) |
📊 实测:在 Llama-3-8B 上,启用 KV Cache 可使吞吐率提升 3~5 倍
三、KV Cache 的实现细节(以 Hugging Face / vLLM 为例)
1. 缓存结构
每个 layer 都有自己的 KV Cache,形状为:
[batch_size, num_heads, seq_len, head_dim]
seq_len动态增长(从 1 到 max_length)通常用 PagedAttention(vLLM) 或 动态张量拼接 实现
2. 代码示意(伪代码)
# 首次输入 prompt
prompt = "Hello, how are you?"
input_ids = tokenizer(prompt).input_ids # [1, 5]
# 第一次 forward:计算所有 token 的 K/V,并缓存
logits, kv_cache = model(input_ids, use_cache=True)
# 生成第一个 token
next_token = sample(logits)
output_ids = [next_token]
# 后续 step:只输入新 token,复用 kv_cache
for i in range(max_new_tokens):
logits, kv_cache = model(
input_ids=next_token.unsqueeze(0), # [1, 1]
past_key_values=kv_cache, # 复用历史 K/V
use_cache=True
)
next_token = sample(logits)
output_ids.append(next_token)
四、高级优化:让 KV Cache 更高效
✅ 1. PagedAttention(vLLM)
将 KV Cache 分页存储(类似操作系统虚拟内存) 避免内存碎片,支持动态批处理(continuous batching) 吞吐率提升 2~4 倍(相比 Hugging Face Transformers)
✅ 2. 量化 KV Cache
将 K/V 从 FP16 量化为 INT8 或 FP8 显存占用减少 **50%**,适合长上下文(32K+ tokens) 工具:SGLang、TensorRT-LLM
✅ 3. 共享 KV Cache(多轮对话)
在对话系统中,历史对话的 KV Cache 可复用 新 query 只需计算增量部分,避免重复 encode 历史
✅ 4. 窗口注意力(Sliding Window)
只缓存最近 N 个 token 的 K/V(如 Mistral 的 4K window) 显存占用恒定,适合超长文本
五、KV Cache 的代价与权衡
💡 经验法则:
8B 模型 + 4K 上下文 ≈ 额外占用 2~4GB 显存(FP16) 70B 模型 + 32K 上下文 ≈ 额外占用 40GB+ 显存
六、总结:如何最大化利用 KV Cache 提升吞吐?
**务必启用 use_cache=True**(Hugging Face 默认开启)使用 vLLM / SGLang / TensorRT-LLM 等高性能推理引擎(内置 PagedAttention) 对长上下文场景,考虑量化 KV Cache 或滑动窗口 在服务端启用动态批处理(continuous batching),让多个请求共享 GPU 计算
🌟 最终效果:在 A100 上,Llama-3-8B 的吞吐率可从 50 tokens/s 提升至 300+ tokens/s
如果你有具体模型(如 Qwen、Llama)、硬件(如 Mac M3、A100)或框架(Ollama、vLLM)的需求,我可以给出针对性优化建议!
二、对LLM来说kv cache是单独的服务 还是 内置的能力?
对大语言模型(LLM)来说,KV Cache(Key-Value Cache)不是单独的服务,而是推理引擎(inference engine)内置的核心能力,属于推理过程中的内存管理优化技术。
✅ 详细解释:
1. KV Cache 是什么?
在 Transformer 解码器中,每生成一个 token,都需要计算它与所有已生成 token的注意力(Attention)。 KV Cache 就是把每个已生成 token 对应的 Key(K)和 Value(V)向量缓存起来,避免重复计算。 后续生成新 token 时,只需计算当前 token 的 Query(Q),然后与缓存的 K/V 做 Attention。
📌 本质:用内存换计算,大幅减少重复计算,提升推理速度。
2. 它是“内置能力”而非“独立服务”
| 集成在推理引擎中 | |
| 自动启用 | use_cache=True),用户无需手动实现 |
| 生命周期绑定推理过程 | |
| 不对外暴露 API |
🔧 举例:
# Hugging Face 默认启用 KV Cache
outputs = model.generate(input_ids, use_cache=True) # ← 内置支持
3. 什么时候会“像服务”一样管理 KV Cache?
虽然 KV Cache 本身不是服务,但在高并发推理系统中,它的管理会变得复杂,可能需要类似服务的调度逻辑:
| 多用户对话系统 | |
| PagedAttention(vLLM) | |
| 长上下文推理 |
✅ 但即便如此,KV Cache 仍是推理引擎的一部分,不是独立部署的微服务。
4. 对比:KV Cache vs 独立缓存服务(如 Redis)
💡 有些系统会用 Redis 缓存完整对话历史,但不会缓存 KV Cache,因为后者是模型私有、格式固定、生命周期短的中间状态。
✅ 总结
KV Cache 是 LLM 推理引擎的内置优化能力,不是独立服务。
它由推理框架自动管理,用于加速自回归生成,属于“看不见但离不开”的底层技术。
只有在构建高性能推理服务器(如 vLLM、TGI)时,才会对 KV Cache 做精细化调度(分页、共享、压缩等),但依然属于推理服务内部模块,而非外部依赖服务。