PostgreSQL码农集散地

如何通过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 通过以下方式提升吞吐:

优化点
说明
减少重复计算
避免重复计算历史 K/V,节省 50%~80% 的 Attention 计算
降低显存带宽压力
虽然 KV Cache 占用显存,但避免了频繁从显存读取原始 token embeddings
支持批处理(Batching)
多个请求可共享计算资源,KV Cache 使每个请求的增量计算更轻量

📊 实测:在 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 的代价与权衡

优点
缺点
⚡ 推理速度大幅提升
💾 显存占用增加(与 seq_len 成正比)
📈 支持高吞吐批处理
🚫 不适用于非自回归任务(如分类)
🔁 支持流式输出
🧩 长上下文(>32K)可能爆显存

💡 经验法则:

  • 8B 模型 + 4K 上下文 ≈ 额外占用 2~4GB 显存(FP16)
  • 70B 模型 + 32K 上下文 ≈ 额外占用 40GB+ 显存

六、总结:如何最大化利用 KV Cache 提升吞吐?

  1. **务必启用 use_cache=True**(Hugging Face 默认开启)
  2. 使用 vLLM / SGLang / TensorRT-LLM 等高性能推理引擎(内置 PagedAttention)
  3. 对长上下文场景,考虑量化 KV Cache 或滑动窗口
  4. 在服务端启用动态批处理(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. 它是“内置能力”而非“独立服务”

特性
说明
集成在推理引擎中
如 Hugging Face Transformers、vLLM、llama.cpp、TensorRT-LLM、Ollama 等都内置了 KV Cache 管理逻辑
自动启用
大多数框架默认开启(如 use_cache=True),用户无需手动实现
生命周期绑定推理过程
KV Cache 随对话/生成任务创建,任务结束即释放,不跨请求持久化(除非显式实现对话记忆)
不对外暴露 API
它是底层优化机制,用户通常只感知到“更快的生成速度”,看不到 KV Cache 本身

🔧 举例:

# Hugging Face 默认启用 KV Cache
outputs = model.generate(input_ids, use_cache=True)  # ← 内置支持

3. 什么时候会“像服务”一样管理 KV Cache?

虽然 KV Cache 本身不是服务,但在高并发推理系统中,它的管理会变得复杂,可能需要类似服务的调度逻辑:

场景
说明
多用户对话系统
每个用户的对话历史需要独立的 KV Cache,系统需管理成千上万个缓存实例
PagedAttention(vLLM)
将 KV Cache 分页存储(类似虚拟内存),由调度器动态分配/回收内存页
长上下文推理
KV Cache 可能占用几十 GB 内存,需内存池、换入换出(swap)等机制

✅ 但即便如此,KV Cache 仍是推理引擎的一部分,不是独立部署的微服务。


4. 对比:KV Cache vs 独立缓存服务(如 Redis)

项目
KV Cache
Redis / Memcached
目的
加速单次 LLM 推理
跨请求共享数据
数据内容
模型中间激活(K/V 向量)
用户定义的键值对(如对话历史、token)
生命周期
单次生成任务内
可持久化、跨会话
是否可关闭
可(但性能暴跌)
可选组件

💡 有些系统会用 Redis 缓存完整对话历史,但不会缓存 KV Cache,因为后者是模型私有、格式固定、生命周期短的中间状态。


✅ 总结

KV Cache 是 LLM 推理引擎的内置优化能力,不是独立服务。
它由推理框架自动管理,用于加速自回归生成,属于“看不见但离不开”的底层技术。

只有在构建高性能推理服务器(如 vLLM、TGI)时,才会对 KV Cache 做精细化调度(分页、共享、压缩等),但依然属于推理服务内部模块,而非外部依赖服务。