LMCache 实用指南:vLLM 推理服务如何复用 KV Cache

一篇偏实战的 LMCache 使用指南:什么场景值得接入 KV Cache 复用,如何用 vLLM MP 模式跑通 LMCache,怎么测试缓存命中,以及上线前要关注的内存、chunk size、命中率和观测指标。

LMCache 解决的是一个很实际的问题:大模型推理里,很多请求前半段 prompt 是重复的,但服务端每次都重新 prefill,显卡时间就白白烧掉了。

如果你的业务里有长系统提示词、RAG 模板、多轮对话、Agent 工具说明、固定知识上下文,LMCache 就值得看一眼。它把临时的 KV Cache 从推理引擎里抽出来,放到可以复用、可观测、可扩展的缓存层里,减少重复 prefill,目标是降低 TTFT,也就是首 token 延迟。

项目地址:

1
https://github.com/LMCache/LMCache

官方文档:

1
https://docs.lmcache.ai/

先判断你需不需要 LMCache

不是所有本地推理服务都需要 LMCache。它更适合下面这些场景:

  • prompt 很长,而且多个请求共享一大段前缀。
  • RAG 每次会塞入相似的文档片段或固定模板。
  • 多轮对话里历史上下文很长,用户请求会持续复用前面的内容。
  • Agent 系统提示词、工具说明、策略文本很长。
  • 多个 vLLM 实例需要共享缓存,而不是每个进程各算各的。
  • 你关心 TTFT,不只是关心 decode 阶段的 tokens/s。

如果你的请求大多很短、互相没有相同前缀,或者瓶颈主要在生成阶段,LMCache 的收益就可能不明显。它省的是重复 prefill,不是魔法加速所有 token。

推荐先用 vLLM MP 模式

LMCache 和 vLLM 有两种常见接法:

  • MP 模式:LMCache 作为独立服务运行,vLLM 通过 LMCacheMPConnector 连接它。
  • In-process 模式:LMCache 嵌在 vLLM 进程里,适合快速实验。

实用角度看,建议先试 MP 模式。原因很简单:缓存服务独立,推理引擎重启时不一定要丢掉全部缓存,也更方便接管理接口、指标和多实例共享。

安装

官方 Quickstart 推荐用 Python 3.12 环境:

1
2
3
uv venv --python 3.12
source .venv/bin/activate
uv pip install lmcache vllm

如果不用 uv,也可以先用普通虚拟环境,再安装:

1
2
3
python -m venv .venv
source .venv/bin/activate
pip install lmcache vllm

生产环境建议固定版本,不要裸用最新版。尤其是 vLLM 和 LMCache 的 connector 版本要一起确认。

启动 LMCache 服务

先开一个终端启动 LMCache:

1
2
3
4
lmcache server \
  --l1-size-gb 20 \
  --eviction-policy LRU \
  --chunk-size 16

这里几个参数先这样理解:

  • --l1-size-gb 20:给本地一级缓存分配 20GB。
  • --eviction-policy LRU:缓存满了以后优先淘汰最久没用的数据。
  • --chunk-size 16:演示用的小块大小,方便短 prompt 也能看到命中日志。

官方也提醒,chunk-size 16 更适合 demo,生产环境一般用默认值,例如 256。块越小,命中更细,但管理开销也更高;块越大,开销小一些,但短前缀不一定命中得漂亮。

默认情况下,LMCache 的 ZMQ 端口是 5555,HTTP 管理和指标端口是 8080

启动 vLLM 并接入 LMCache

再开一个终端启动 vLLM:

1
2
3
4
vllm serve Qwen/Qwen3-8B \
  --port 8000 \
  --kv-transfer-config \
  '{"kv_connector":"LMCacheMPConnector", "kv_role":"kv_both"}'

如果你使用的是 vLLM 0.20.0 或更新版本,官方建议可以显式指定 LMCache 自带的 connector:

1
2
3
4
vllm serve Qwen/Qwen3-8B \
  --port 8000 \
  --kv-transfer-config \
  '{"kv_connector":"LMCacheMPConnector", "kv_connector_module_path":"lmcache.integration.vllm.lmcache_mp_connector", "kv_role":"kv_both"}'

这样做的好处是可以使用 LMCache 项目里更新的 server protocol 和修复,而不是只依赖 vLLM 内置版本。

用两次请求测试是否命中

测试缓存最简单的方法,是发送两个共享前缀的请求。

第一次:

1
2
3
4
5
6
7
8
curl http://localhost:8000/v1/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "Qwen/Qwen3-8B",
    "prompt": "Qwen3 is the latest generation of large language models in Qwen series, offering a comprehensive suite of dense and mixture-of-experts",
    "max_tokens": 100,
    "temperature": 0.7
  }'

第二次把前缀保留,只在后面加一点内容:

1
2
3
4
5
6
7
8
curl http://localhost:8000/v1/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "Qwen/Qwen3-8B",
    "prompt": "Qwen3 is the latest generation of large language models in Qwen series, offering a comprehensive suite of dense and mixture-of-experts (MoE) models",
    "max_tokens": 100,
    "temperature": 0.7
  }'

如果 LMCache 正常工作,第一次请求会看到类似 Stored ... tokens 的日志;第二次请求会看到 Retrieved ... tokens,说明共享前缀从缓存里取出来了。

读懂命中日志

不要只看“有没有 Retrieved”。更要关注这几个点:

  • 命中了多少 tokens。
  • 从哪里取回缓存,例如 CPU RAM、本地磁盘、远端存储。
  • 取回耗时是否比重新 prefill 更划算。
  • 是否只命中了很短的一段,导致实际收益有限。
  • 是否因为 chunk 对齐问题,明明前缀相似却没有完整命中。

举个例子,如果 prompt 有 5000 tokens,命中 4000 tokens,TTFT 下降明显,这就是好场景。如果 prompt 只有 200 tokens,命中 32 tokens,业务体感可能没什么变化。

哪些业务最容易吃到收益

1. 长系统提示词

很多企业内部助手会塞一大段角色设定、规则、工具说明、输出格式要求。只要这段内容在多次请求里一致,就很适合缓存。

2. RAG 固定模板

RAG 不只是文档片段,通常还有固定提示模板、引用规则、回答约束。如果检索结果重复度高,或者用户围绕同一批资料连续提问,LMCache 会更有价值。

3. Agent 工具说明

Agent 经常把工具列表、调用规则、错误处理策略放进上下文。这些内容很长,而且跨请求重复度高,是典型可复用前缀。

4. 多实例推理服务

单个 vLLM 进程有自己的前缀缓存,但多实例扩容后,缓存容易被切碎。LMCache 独立出来后,可以让多个服务实例共享一层缓存。

不建议一开始就追求复杂后端

LMCache 支持多种后端,例如 CPU RAM、本地磁盘、Redis/Valkey、S3 兼容对象存储、Mooncake、InfiniStore、NIXL 等。

但第一次接入时,不建议直接上分布式存储。先用本地 CPU RAM 跑通链路,看命中率和 TTFT 是否真的改善。确认收益以后,再考虑:

  • 缓存要不要跨机器共享。
  • 是否需要持久化。
  • 网络传输成本会不会抵消缓存收益。
  • 缓存淘汰策略是否符合业务访问模式。

缓存层越复杂,排查成本越高。先证明“业务 prompt 真的可复用”,再扩大架构。

In-process 模式适合快速试验

如果只是想本机试一下,也可以用 In-process 模式:

1
2
3
4
5
LMCACHE_CHUNK_SIZE=8 \
vllm serve Qwen/Qwen3-8B \
  --port 8000 \
  --kv-transfer-config \
  '{"kv_connector":"LMCacheConnectorV1", "kv_role":"kv_both"}'

这种方式简单,但缓存跟着 vLLM 进程走。进程重启、崩溃、扩容时,独立性不如 MP 模式。它适合验证概念,不太适合作为长期生产结构的默认选择。

上线前的检查清单

接入 LMCache 前,建议先做一轮小压测:

  • 对比开启和关闭 LMCache 的 TTFT。
  • 单独记录 prefill 延迟,而不是只看总耗时。
  • 统计 prefix cache hit tokens 和 hit ratio。
  • 观察 LMCache 进程内存是否稳定。
  • 测试 vLLM 重启后缓存是否还能按预期复用。
  • 检查高并发下 ZMQ、HTTP 指标和日志是否正常。
  • 用真实业务 prompt 测,不要只用 demo prompt。

如果真实业务里的 prompt 重复度很低,压测结果会诚实地告诉你:这东西暂时不该上。

常见坑

1. 把 LMCache 当成普通结果缓存

LMCache 缓的是 KV Cache,不是最终回答。它减少的是模型重新处理前缀的成本,不会保证两次输出一样。

2. 只看 tokens/s

LMCache 更直接影响 TTFT 和 prefill 成本。decode 阶段 tokens/s 可能不会明显变化。

3. chunk-size 乱调

demo 里用小 chunk 是为了方便观察命中。生产里要结合 prompt 长度、重复模式、内存和吞吐测试来调,不要照抄演示参数。

4. 版本没对齐

vLLM、LMCache、connector 之间有兼容关系。升级前先看文档和 release note,别在生产环境临时拉最新版。

5. 没有观测指标

缓存系统没有指标就像盲开。至少要看命中率、命中 tokens、读写耗时、缓存容量、淘汰次数和错误日志。

总结

LMCache 适合“长 prompt 重复出现”的 LLM 推理服务。它不是让模型生成更快的万能按钮,而是把重复 prefill 变成可复用的 KV Cache。

如果你已经在用 vLLM,最推荐的入门路线是:先用 MP 模式本机跑通,再用两条共享前缀的请求确认命中,然后拿真实业务流量对比 TTFT。只有真实命中率足够高,LMCache 才值得进入生产架构。

记录并分享
使用 Hugo 构建
主题 StackJimmy 设计