<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>LLM推理 on KnightLi的博客</title>
        <link>https://knightli.com/tags/llm%E6%8E%A8%E7%90%86/</link>
        <description>Recent content in LLM推理 on KnightLi的博客</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>zh-cn</language>
        <lastBuildDate>Thu, 25 Jun 2026 09:14:41 +0800</lastBuildDate><atom:link href="https://knightli.com/tags/llm%E6%8E%A8%E7%90%86/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>LMCache 实用指南：vLLM 推理服务如何复用 KV Cache</title>
        <link>https://knightli.com/2026/06/25/lmcache-vllm-kv-cache-guide/</link>
        <pubDate>Thu, 25 Jun 2026 09:14:41 +0800</pubDate>
        
        <guid>https://knightli.com/2026/06/25/lmcache-vllm-kv-cache-guide/</guid>
        <description>&lt;p&gt;LMCache 解决的是一个很实际的问题：大模型推理里，很多请求前半段 prompt 是重复的，但服务端每次都重新 prefill，显卡时间就白白烧掉了。&lt;/p&gt;
&lt;p&gt;如果你的业务里有长系统提示词、RAG 模板、多轮对话、Agent 工具说明、固定知识上下文，LMCache 就值得看一眼。它把临时的 KV Cache 从推理引擎里抽出来，放到可以复用、可观测、可扩展的缓存层里，减少重复 prefill，目标是降低 TTFT，也就是首 token 延迟。&lt;/p&gt;
&lt;p&gt;项目地址：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;https://github.com/LMCache/LMCache
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;官方文档：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;https://docs.lmcache.ai/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;先判断你需不需要-lmcache&#34;&gt;先判断你需不需要 LMCache
&lt;/h2&gt;&lt;p&gt;不是所有本地推理服务都需要 LMCache。它更适合下面这些场景：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;prompt 很长，而且多个请求共享一大段前缀。&lt;/li&gt;
&lt;li&gt;RAG 每次会塞入相似的文档片段或固定模板。&lt;/li&gt;
&lt;li&gt;多轮对话里历史上下文很长，用户请求会持续复用前面的内容。&lt;/li&gt;
&lt;li&gt;Agent 系统提示词、工具说明、策略文本很长。&lt;/li&gt;
&lt;li&gt;多个 vLLM 实例需要共享缓存，而不是每个进程各算各的。&lt;/li&gt;
&lt;li&gt;你关心 TTFT，不只是关心 decode 阶段的 tokens/s。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你的请求大多很短、互相没有相同前缀，或者瓶颈主要在生成阶段，LMCache 的收益就可能不明显。它省的是重复 prefill，不是魔法加速所有 token。&lt;/p&gt;
&lt;h2 id=&#34;推荐先用-vllm-mp-模式&#34;&gt;推荐先用 vLLM MP 模式
&lt;/h2&gt;&lt;p&gt;LMCache 和 vLLM 有两种常见接法：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MP 模式：LMCache 作为独立服务运行，vLLM 通过 &lt;code&gt;LMCacheMPConnector&lt;/code&gt; 连接它。&lt;/li&gt;
&lt;li&gt;In-process 模式：LMCache 嵌在 vLLM 进程里，适合快速实验。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;实用角度看，建议先试 MP 模式。原因很简单：缓存服务独立，推理引擎重启时不一定要丢掉全部缓存，也更方便接管理接口、指标和多实例共享。&lt;/p&gt;
&lt;h2 id=&#34;安装&#34;&gt;安装
&lt;/h2&gt;&lt;p&gt;官方 Quickstart 推荐用 Python 3.12 环境：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;uv venv --python 3.12
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;source&lt;/span&gt; .venv/bin/activate
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;uv pip install lmcache vllm
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果不用 &lt;code&gt;uv&lt;/code&gt;，也可以先用普通虚拟环境，再安装：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;python -m venv .venv
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;source&lt;/span&gt; .venv/bin/activate
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pip install lmcache vllm
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;生产环境建议固定版本，不要裸用最新版。尤其是 vLLM 和 LMCache 的 connector 版本要一起确认。&lt;/p&gt;
&lt;h2 id=&#34;启动-lmcache-服务&#34;&gt;启动 LMCache 服务
&lt;/h2&gt;&lt;p&gt;先开一个终端启动 LMCache：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;lmcache server &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  --l1-size-gb &lt;span class=&#34;m&#34;&gt;20&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  --eviction-policy LRU &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  --chunk-size &lt;span class=&#34;m&#34;&gt;16&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这里几个参数先这样理解：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--l1-size-gb 20&lt;/code&gt;：给本地一级缓存分配 20GB。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--eviction-policy LRU&lt;/code&gt;：缓存满了以后优先淘汰最久没用的数据。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--chunk-size 16&lt;/code&gt;：演示用的小块大小，方便短 prompt 也能看到命中日志。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;官方也提醒，&lt;code&gt;chunk-size 16&lt;/code&gt; 更适合 demo，生产环境一般用默认值，例如 256。块越小，命中更细，但管理开销也更高；块越大，开销小一些，但短前缀不一定命中得漂亮。&lt;/p&gt;
&lt;p&gt;默认情况下，LMCache 的 ZMQ 端口是 &lt;code&gt;5555&lt;/code&gt;，HTTP 管理和指标端口是 &lt;code&gt;8080&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id=&#34;启动-vllm-并接入-lmcache&#34;&gt;启动 vLLM 并接入 LMCache
&lt;/h2&gt;&lt;p&gt;再开一个终端启动 vLLM：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;vllm serve Qwen/Qwen3-8B &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  --port &lt;span class=&#34;m&#34;&gt;8000&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  --kv-transfer-config &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s1&#34;&gt;&amp;#39;{&amp;#34;kv_connector&amp;#34;:&amp;#34;LMCacheMPConnector&amp;#34;, &amp;#34;kv_role&amp;#34;:&amp;#34;kv_both&amp;#34;}&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果你使用的是 vLLM 0.20.0 或更新版本，官方建议可以显式指定 LMCache 自带的 connector：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;vllm serve Qwen/Qwen3-8B &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  --port &lt;span class=&#34;m&#34;&gt;8000&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  --kv-transfer-config &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s1&#34;&gt;&amp;#39;{&amp;#34;kv_connector&amp;#34;:&amp;#34;LMCacheMPConnector&amp;#34;, &amp;#34;kv_connector_module_path&amp;#34;:&amp;#34;lmcache.integration.vllm.lmcache_mp_connector&amp;#34;, &amp;#34;kv_role&amp;#34;:&amp;#34;kv_both&amp;#34;}&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这样做的好处是可以使用 LMCache 项目里更新的 server protocol 和修复，而不是只依赖 vLLM 内置版本。&lt;/p&gt;
&lt;h2 id=&#34;用两次请求测试是否命中&#34;&gt;用两次请求测试是否命中
&lt;/h2&gt;&lt;p&gt;测试缓存最简单的方法，是发送两个共享前缀的请求。&lt;/p&gt;
&lt;p&gt;第一次：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;curl http://localhost:8000/v1/completions &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -H &lt;span class=&#34;s2&#34;&gt;&amp;#34;Content-Type: application/json&amp;#34;&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -d &lt;span class=&#34;s1&#34;&gt;&amp;#39;{
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;    &amp;#34;model&amp;#34;: &amp;#34;Qwen/Qwen3-8B&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;    &amp;#34;prompt&amp;#34;: &amp;#34;Qwen3 is the latest generation of large language models in Qwen series, offering a comprehensive suite of dense and mixture-of-experts&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;    &amp;#34;max_tokens&amp;#34;: 100,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;    &amp;#34;temperature&amp;#34;: 0.7
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;  }&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;第二次把前缀保留，只在后面加一点内容：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;curl http://localhost:8000/v1/completions &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -H &lt;span class=&#34;s2&#34;&gt;&amp;#34;Content-Type: application/json&amp;#34;&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -d &lt;span class=&#34;s1&#34;&gt;&amp;#39;{
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;    &amp;#34;model&amp;#34;: &amp;#34;Qwen/Qwen3-8B&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;    &amp;#34;prompt&amp;#34;: &amp;#34;Qwen3 is the latest generation of large language models in Qwen series, offering a comprehensive suite of dense and mixture-of-experts (MoE) models&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;    &amp;#34;max_tokens&amp;#34;: 100,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;    &amp;#34;temperature&amp;#34;: 0.7
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;  }&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果 LMCache 正常工作，第一次请求会看到类似 &lt;code&gt;Stored ... tokens&lt;/code&gt; 的日志；第二次请求会看到 &lt;code&gt;Retrieved ... tokens&lt;/code&gt;，说明共享前缀从缓存里取出来了。&lt;/p&gt;
&lt;h2 id=&#34;读懂命中日志&#34;&gt;读懂命中日志
&lt;/h2&gt;&lt;p&gt;不要只看“有没有 Retrieved”。更要关注这几个点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;命中了多少 tokens。&lt;/li&gt;
&lt;li&gt;从哪里取回缓存，例如 CPU RAM、本地磁盘、远端存储。&lt;/li&gt;
&lt;li&gt;取回耗时是否比重新 prefill 更划算。&lt;/li&gt;
&lt;li&gt;是否只命中了很短的一段，导致实际收益有限。&lt;/li&gt;
&lt;li&gt;是否因为 chunk 对齐问题，明明前缀相似却没有完整命中。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;举个例子，如果 prompt 有 5000 tokens，命中 4000 tokens，TTFT 下降明显，这就是好场景。如果 prompt 只有 200 tokens，命中 32 tokens，业务体感可能没什么变化。&lt;/p&gt;
&lt;h2 id=&#34;哪些业务最容易吃到收益&#34;&gt;哪些业务最容易吃到收益
&lt;/h2&gt;&lt;h3 id=&#34;1-长系统提示词&#34;&gt;1. 长系统提示词
&lt;/h3&gt;&lt;p&gt;很多企业内部助手会塞一大段角色设定、规则、工具说明、输出格式要求。只要这段内容在多次请求里一致，就很适合缓存。&lt;/p&gt;
&lt;h3 id=&#34;2-rag-固定模板&#34;&gt;2. RAG 固定模板
&lt;/h3&gt;&lt;p&gt;RAG 不只是文档片段，通常还有固定提示模板、引用规则、回答约束。如果检索结果重复度高，或者用户围绕同一批资料连续提问，LMCache 会更有价值。&lt;/p&gt;
&lt;h3 id=&#34;3-agent-工具说明&#34;&gt;3. Agent 工具说明
&lt;/h3&gt;&lt;p&gt;Agent 经常把工具列表、调用规则、错误处理策略放进上下文。这些内容很长，而且跨请求重复度高，是典型可复用前缀。&lt;/p&gt;
&lt;h3 id=&#34;4-多实例推理服务&#34;&gt;4. 多实例推理服务
&lt;/h3&gt;&lt;p&gt;单个 vLLM 进程有自己的前缀缓存，但多实例扩容后，缓存容易被切碎。LMCache 独立出来后，可以让多个服务实例共享一层缓存。&lt;/p&gt;
&lt;h2 id=&#34;不建议一开始就追求复杂后端&#34;&gt;不建议一开始就追求复杂后端
&lt;/h2&gt;&lt;p&gt;LMCache 支持多种后端，例如 CPU RAM、本地磁盘、Redis/Valkey、S3 兼容对象存储、Mooncake、InfiniStore、NIXL 等。&lt;/p&gt;
&lt;p&gt;但第一次接入时，不建议直接上分布式存储。先用本地 CPU RAM 跑通链路，看命中率和 TTFT 是否真的改善。确认收益以后，再考虑：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;缓存要不要跨机器共享。&lt;/li&gt;
&lt;li&gt;是否需要持久化。&lt;/li&gt;
&lt;li&gt;网络传输成本会不会抵消缓存收益。&lt;/li&gt;
&lt;li&gt;缓存淘汰策略是否符合业务访问模式。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;缓存层越复杂，排查成本越高。先证明“业务 prompt 真的可复用”，再扩大架构。&lt;/p&gt;
&lt;h2 id=&#34;in-process-模式适合快速试验&#34;&gt;In-process 模式适合快速试验
&lt;/h2&gt;&lt;p&gt;如果只是想本机试一下，也可以用 In-process 模式：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;LMCACHE_CHUNK_SIZE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;8&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;vllm serve Qwen/Qwen3-8B &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  --port &lt;span class=&#34;m&#34;&gt;8000&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  --kv-transfer-config &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s1&#34;&gt;&amp;#39;{&amp;#34;kv_connector&amp;#34;:&amp;#34;LMCacheConnectorV1&amp;#34;, &amp;#34;kv_role&amp;#34;:&amp;#34;kv_both&amp;#34;}&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这种方式简单，但缓存跟着 vLLM 进程走。进程重启、崩溃、扩容时，独立性不如 MP 模式。它适合验证概念，不太适合作为长期生产结构的默认选择。&lt;/p&gt;
&lt;h2 id=&#34;上线前的检查清单&#34;&gt;上线前的检查清单
&lt;/h2&gt;&lt;p&gt;接入 LMCache 前，建议先做一轮小压测：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;对比开启和关闭 LMCache 的 TTFT。&lt;/li&gt;
&lt;li&gt;单独记录 prefill 延迟，而不是只看总耗时。&lt;/li&gt;
&lt;li&gt;统计 prefix cache hit tokens 和 hit ratio。&lt;/li&gt;
&lt;li&gt;观察 LMCache 进程内存是否稳定。&lt;/li&gt;
&lt;li&gt;测试 vLLM 重启后缓存是否还能按预期复用。&lt;/li&gt;
&lt;li&gt;检查高并发下 ZMQ、HTTP 指标和日志是否正常。&lt;/li&gt;
&lt;li&gt;用真实业务 prompt 测，不要只用 demo prompt。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果真实业务里的 prompt 重复度很低，压测结果会诚实地告诉你：这东西暂时不该上。&lt;/p&gt;
&lt;h2 id=&#34;常见坑&#34;&gt;常见坑
&lt;/h2&gt;&lt;h3 id=&#34;1-把-lmcache-当成普通结果缓存&#34;&gt;1. 把 LMCache 当成普通结果缓存
&lt;/h3&gt;&lt;p&gt;LMCache 缓的是 KV Cache，不是最终回答。它减少的是模型重新处理前缀的成本，不会保证两次输出一样。&lt;/p&gt;
&lt;h3 id=&#34;2-只看-tokenss&#34;&gt;2. 只看 tokens/s
&lt;/h3&gt;&lt;p&gt;LMCache 更直接影响 TTFT 和 prefill 成本。decode 阶段 tokens/s 可能不会明显变化。&lt;/p&gt;
&lt;h3 id=&#34;3-chunk-size-乱调&#34;&gt;3. chunk-size 乱调
&lt;/h3&gt;&lt;p&gt;demo 里用小 chunk 是为了方便观察命中。生产里要结合 prompt 长度、重复模式、内存和吞吐测试来调，不要照抄演示参数。&lt;/p&gt;
&lt;h3 id=&#34;4-版本没对齐&#34;&gt;4. 版本没对齐
&lt;/h3&gt;&lt;p&gt;vLLM、LMCache、connector 之间有兼容关系。升级前先看文档和 release note，别在生产环境临时拉最新版。&lt;/p&gt;
&lt;h3 id=&#34;5-没有观测指标&#34;&gt;5. 没有观测指标
&lt;/h3&gt;&lt;p&gt;缓存系统没有指标就像盲开。至少要看命中率、命中 tokens、读写耗时、缓存容量、淘汰次数和错误日志。&lt;/p&gt;
&lt;h2 id=&#34;总结&#34;&gt;总结
&lt;/h2&gt;&lt;p&gt;LMCache 适合“长 prompt 重复出现”的 LLM 推理服务。它不是让模型生成更快的万能按钮，而是把重复 prefill 变成可复用的 KV Cache。&lt;/p&gt;
&lt;p&gt;如果你已经在用 vLLM，最推荐的入门路线是：先用 MP 模式本机跑通，再用两条共享前缀的请求确认命中，然后拿真实业务流量对比 TTFT。只有真实命中率足够高，LMCache 才值得进入生产架构。&lt;/p&gt;
</description>
        </item>
        
    </channel>
</rss>
