---
title: "共享 KV 缓存把 LLM 推理延迟降低 14x"
canonical: https://wavect.io/zh/blog/shared-kv-cache-llm-inference-latency/
language: zh
description: "LMCache 的共享 KV 缓存如何在同样的 GPU 和内存下，把 Qwen3-235B 的平均 TTFT 从 3.98s 降到 0.29s，以及如何判断它对你的推理有没有帮助。"
image: "https://wavect.io/img/blog/headers/header_shared-kv-cache-llm-inference-latency.png"
---

[**返回**](/zh/blog/overview/)

[![Kevin Riedl](/img/team/kevin.webp)](/zh/team/kevin-riedl/)

[Kevin Riedl](/zh/team/kevin-riedl/) https://linkedin.com/in/wsdt

9 分钟 阅读 · 2026年7月23日

[**下一篇**](/zh/blog/self-hosting-llms-eu-cost/)

# 一个共享 KV 缓存如何在不新增 GPU 的情况下把 LLM 推理延迟降低 14x

要点速览

为了快速服务一个大模型，你会每块 GPU 跑一个进程，而默认情况下这些数据并行的 rank 里每一个都保有一份私有 KV 缓存。所以当一段对话的后续一轮落在不同的 rank 上时，即使另一个 rank 已经计算过，模型仍会重新 prefill 整段历史：那个状态就在 同一台服务器上，却在错误的进程里。LMCache 的 Multi-Process 模式把缓存从各个 进程中移出，放进一个所有进程都能读取的共享主机侧层。在一台 8x H100 服务器上跑 Qwen3-235B 时，这把平均 time-to-first-token 从 3.98s 降到 0.29s（约 14x），并把 解码速度提高到三倍，而模型、硬件和 400GB 的总缓存都不变。这个教训比一个库更大： 很多推理延迟其实是你的系统在重新计算它已经持有的答案，只因为缓存是按进程拆分而 不是按节点共享的而被丢弃。它带来的回报与你的请求重叠程度成正比：对聊天、智能体 和长的共享提示词很大，对独特的一次性提示词很小。在购买更快的硬件之前，先测量复用 度并给节省下来的 GPU 小时定价。

**一句话总结：**一个名为 LMCache 的开源 KV 缓存层，在一个大型混合专家（MoE）模型上把平均 time-to-first-token 降低了大约 14x，而且它没有用上更快的 GPU、更小的模型或更多的内存。唯一改变的是缓存所在的位置。原本各自囤积私有缓存的八个服务进程，变成了八个共享同一份缓存的进程。

这就是全部要点，而它的意义超出了这一个库。大多数推理优化被包装成购买更快的硬件。你付出的很多延迟，其实是你自己的系统在重新计算一个它已经拥有的答案，只是那份缓存归属于错误的进程。本文解释了改变了什么、这些数字能证明和不能证明什么，以及如何判断同样的架构是否会对你自己的 [LLM](/zh/glossary/llm/) 服务有帮助。

## 昂贵的默认做法：每个 rank 都囤积自己的缓存

当一个模型服务一段对话时，它不会在每一轮都重新读一遍整个历史。它会存储自己已经见过的 token 的中间注意力状态。这份存储就是 KV 缓存（key-value cache），而复用它正是聊天第二轮比第一轮快得多的原因。重新计算它的过程叫做 prefill（预填充），而 prefill 正是回答一个长提示词中昂贵的那部分。

陷阱在这里。在该基准测试的拓扑中，vLLM 使用了八个数据并行 rank，并启用了自动专家并行：注意力层在各块 GPU 上复制，Mixture-of-Experts 层则被分片。每个 rank 都在独立进程中运行，并保有自己的私有 KV 缓存。这些缓存之间不通信。

LMCache 自己的基准测试把这个代价说得很具体。Qwen3-235B-A22B 跑在八块 H100 GPU 上。每个 rank 分到 50 GB 的 CPU 内存用于 KV 缓存卸载，因此这台服务器总共持有 400 GB。纸面上这是一份很大的缓存。但实际上它是八个各自隔离的 50 GB 缓存，而不是一份共享的 400 GB 缓存。

现在设想一段真实的多轮对话。第一轮被路由到 rank 3，它计算并缓存了上下文。同一段对话的第二轮被路由到了 rank 6。rank 6 看不到 rank 3 缓存的内容。它所需要的那个确切状态就躺在同一台物理服务器的主机内存里，但它归属于另一个进程，因此模型只能做它唯一能做的事：从头开始把整段对话重新 prefill 一遍。这段计算你已经付过一次费。每一轮落在不同 rank 上时，你都要再付一次。

## LMCache 改变了什么：用一份缓存代替八份

[LMCache](https://github.com/LMCache/LMCache) 是一个开源的、采用 Apache-2.0 许可的 KV 缓存层，面向 [vLLM](https://github.com/vllm-project/vllm) 和 SGLang 这类推理引擎。它的职责是把 KV 缓存从稀缺的 GPU 内存中移出，放进一个由 CPU 内存、本地磁盘和远程存储构成的分层体系中，并让缓存能够跨请求、跨会话、跨引擎实例被复用。

产生 14x 这个数字的改变是架构层面的，而不是算法层面的。在传统的进程内设置里，每个服务进程内部都嵌入了一个独立的缓存库，这正是缓存彼此隔离的原因。LMCache 的 Multi-Process 模式（多进程模式）把缓存从各个进程中抽离出来，作为一个独立的服务来运行。节点上的每个服务进程都向它注册，并从同一个主机侧的池中读取。

于是同样的 400 GB 不再是八个被隔开的桶，而成为一个共享的层。当第二轮落在 rank 6 上时，rank 6 向共享缓存发起询问，找到 rank 3 已经计算好的状态，从而跳过 prefill。模型、硬件和总的缓存容量全都完全一样。只不过那份计算不再被丢弃。

## 基准测试数字

这些数字来自 LMCache 发布的、在 Qwen3-235B-A22B-Instruct-2507-FP8 上的多轮对话基准测试，运行环境为八块 NVIDIA H100 80GB GPU、vLLM 0.18.1 和 LMCache 0.4.3-dev。它们比较的是传统的进程内卸载与 Multi-Process 模式。这些是作者报告的结果，基于单一硬件和工作负载；请把它们当作一个有力的方向性信号，而不是对你自己流量的保证。

| 指标 | 进程内（隔离缓存） | Multi-Process（共享缓存） | 变化 |
| --- | --- | --- | --- |
| 平均 time-to-first-token | 3.98 s | 0.29 s | 约快 14x |
| P99 time-to-first-token | 13.55 s | 1.30 s | 约快 10x |
| 平均解码速度 | 9.81 tokens/s | 37.47 tokens/s | 约快 3.8x |
| P99 解码速度 | 34.27 tokens/s | 45.14 tokens/s | 约快 1.3x |

要看形状，而不只是看标题数字。收益最大的地方，正是隔离缓存伤害最深的地方：那些原本需要重新 prefill 一段长历史的冷启动轮次。平均 TTFT 从约四秒降到不到三分之一秒，是一个感觉迟钝的聊天和一个感觉即时的聊天之间的差别。对一个产品来说，P99 的改善甚至更重要，因为长尾才是你最慢的那批用户实际体验到的东西。

## 为什么即便你从不碰 LMCache 这件事也很重要

重点不是你应该去装某一个特定的库。重点是浪费藏在哪里。服务器已经做完了这份工作。它有内存来保留结果。它把结果丢掉了，只因为那份缓存是按进程划分的，而不是按节点共享的。

这种模式在自托管推理里到处都是：已经付过费的计算，只因为系统是怎样拼装起来的（而不是它有多少硬件）而被丢弃。在有人批准一笔更大的 GPU 采购之前，更便宜的问题是：现有的这些机器是不是在重新计算它们已经持有的答案。购买容量是解决一个问题的昂贵办法，而复用往往能免费解决这个问题。我们在关于 [降低 LLM token 成本](/zh/blog/reduce-llm-token-costs-2026/) 的指南里对开销提出了同样的论点，也在 [本地模型对比 API 的盈亏平衡分析](/zh/blog/local-models-vs-apis-break-even-eu-2026/) 里对硬件提出了同样的论点。

如果复用优化已经做完，而且一个模型长期承担稳定、低延迟负载，下一步才是专用硬件。我们的 [Taalas HC1 硬编码 LLM ASIC 评测](/zh/blog/taalas-hc1-llm-asic-review/) 解释了每秒 17,000 token 真正证明了什么，以及用模型灵活性换速度前必须验证哪些问题。

## 共享 KV 缓存在哪里有帮助，在哪里没有

缓存复用带来的回报，与你的请求之间重叠程度成正比。它是一个杠杆，而不是一条定律，所以在期待 14x 之前，请对你自己的流量诚实一点。

| 工作负载 | 共享缓存帮助有多大 | 为什么 |
| --- | --- | --- |
| 多轮聊天和智能体 | 大 | 每一个后续轮次都会重新发送同一段不断增长的历史；复用跳过了重复的 prefill，这正是基准测试的场景。 |
| 长的共享系统提示词或 RAG 上下文 | 大 | 一个在许多请求间重复的大而固定的前缀，只需 prefill 一次并复用，而不是每个请求、每个 rank 各 prefill 一次。 |
| 大量简短、独特、一次性的提示词 | 小 | 请求之间几乎没有重叠，意味着可复用的缓存很少；收益会缩小到接近运行缓存层的成本。 |
| 单进程、单 GPU 服务 | 此改变带来的收益为无 | 没有多个独立的 rank 需要统一；进程内的前缀缓存已经覆盖了你的情况。 |

共享一份缓存也并非免费。一个独立的缓存服务会增加一条进程间协调路径、一个需要运维和监控的活动部件，以及一次在未命中时会带来少量延迟的查找。当请求之间几乎不重叠时，这份开销可能超过节省下来的 prefill。对于对话式和长上下文服务，这个架构是一个有力的默认选择，而不是普适升级。

## 这真的能削减你的推理账单吗？

更快并不等于更便宜。一次延迟上的胜利，只有在它从账单上抹去了某项开销，或让你能用同一台机器服务更多流量时，才会变成一次成本上的胜利。用你实际运行的东西来给这个改变定价：

`每月收益 = 不再花在重复 prefill 上的 GPU 小时 + 每块现有 GPU 更高的吞吐 + 推迟的硬件采购 - 缓存服务的开销与运维时间`

被复用的 prefill 释放了 GPU 时间，而释放出来的 GPU 时间，要么意味着一个更小的集群，要么意味着在当前集群上服务更多流量。干净利落的胜利在于跨过一个阈值：一个你现在无需新增节点就能满足的延迟目标、一个同样的 GPU 现在能维持的并发水平，或者一次你可以推迟的既定硬件升级。如果你的请求很少重叠，诚实的答案是：节省很小，你的精力花在别处会更好。要看这件事所汇入的完整的自建对比租用全景，请通读 [在欧盟自托管 LLM 到底要花多少钱](/zh/blog/self-hosting-llms-eu-cost/) 。

## 在你重连服务架构之前的一次简短评估

1. **测量你的复用度。** 在动架构之前，记录请求共享前缀或延续同一段对话的频率有多高。重叠就是这份奖赏的全部大小；如果它很低，到此为止。
2. **为长尾建立基线，而不只是均值。** 在你真实的流量上记录 P50 和 P99 的 TTFT 与解码速度。基准测试最大的收益出现在长尾上，而长尾才是用户感受到的东西。
3. **确认拓扑是否匹配。** 这 14x 来自把一个节点上多个数据并行的 rank 统一起来。如果你今天是每块 GPU 一个进程，那你就有它所修复的这种碎片化；如果你跑的是单个进程，那你没有。
4. **在影子流量或一部分流量上试点。** 把一份副本或一部分流量路由到共享缓存的设置中，并在相同的硬件和工作负载上与基线作比较。
5. **给它定价，而不只是计时。** 把测得的延迟和吞吐变化换算成 GPU 小时、节点数量或推迟的采购，再减去运行缓存服务的成本。

## 在采用它之前要问的问题

- 我们的请求中，实际上有多大比例共享一个前缀或延续一段已有的对话？
- 我们是否在每个节点上运行多个数据并行的 rank，以至于隔离缓存对我们来说才算得上是个问题？
- 在生产流量上（而非基准测试上），我们当前的 P50 和 P99 的 TTFT 与解码数字是多少？
- 那个独立的缓存服务，在未命中时的延迟上、在运维面上、以及在故障模式上，各让我们付出什么代价？
- 延迟收益是否会转化为更少的 GPU、更高的吞吐或一次推迟的采购，又能转化多少？
- 这个缓存层的成熟度、许可证和维护状态如何，以及在必要时我们能否运维或 fork 它？

## 来源与结论边界

这个架构、400 GB 的碎片化示例以及所有基准测试数字，均来自 LMCache 的文章 ["LMCache's New Architecture Boosts MoE Inference Performance by 10x"](https://blog.lmcache.ai/en/2026/04/03/lmcaches-new-architecture-boosts-moe-inference-performance-by-10x/) ，以及该项目的 [GitHub 仓库](https://github.com/LMCache/LMCache) 和 [文档](https://docs.lmcache.ai/) 。所报告的延迟和吞吐数字归属于其作者及其测试系统，即一台 8x H100 服务器，运行 vLLM 0.18.1 和 LMCache 0.4.3-dev，跑 Qwen3-235B-A22B；Wavect 没有复现它们。事实核对于 2026 年 7 月 23 日。

## 常见问题

### 什么是 LLM 推理中的 KV 缓存？

KV 缓存（key-value cache）存储模型为它已经处理过的 token 计算出的中间注意力状态。复用它意味着模型不必在每一步都重新计算整个提示词，这正是一段对话的后续轮次比第一轮快得多的原因。重新计算那个状态的过程叫做 prefill。

### 为什么共享 KV 缓存能让推理快 14x？

在传统的设置里，每个数据并行的 rank 都保有一份私有缓存，因此当后续一轮被路由到不同的 rank 时，即使另一个 rank 已经计算过，模型仍会重新 prefill 整段对话。共享缓存让任何 rank 都能复用那份工作，在 LMCache 的基准测试中，把平均 time-to-first-token 从 3.98 s 降到了 0.29 s，而模型、硬件和总缓存容量都不变。

### 什么是 LMCache？

LMCache 是一个开源的、采用 Apache-2.0 许可的 KV 缓存层，面向 vLLM 和 SGLang 这类推理引擎。它把 KV 缓存从 GPU 内存移到一个由 CPU 内存、磁盘和远程存储构成的分层体系中，并让缓存能够跨请求、跨会话、跨引擎实例被复用。它的 Multi-Process 模式就是本文结果背后的共享缓存架构。

### 共享 KV 缓存会加速我的工作负载吗？

它的帮助与你的请求之间重叠程度成正比。多轮聊天、智能体，以及长的共享系统提示词或 RAG 上下文受益最多。大量简短、独特、一次性的提示词受益很少，而单进程、单 GPU 服务从这个具体的改变中什么也得不到，因为没有多个独立的 rank 需要统一。在期待较大收益之前，先测量你的前缀复用度。

### 更快的推理是否自动意味着更便宜的推理？

不。一次延迟上的胜利，只有在它抹去了你原本要付的 GPU 小时、让同样的 GPU 服务更多流量，或推迟一次硬件采购，并在减去运行缓存服务的开销之后，才会变成一次成本上的胜利。用你真实的账单来给这个改变定价，而不要假设速度就等于节省。

## 最终思考

这个结果里被引用最多的一句话，是推理在不新增任何 GPU 的情况下快了 14x。更有用的一句话是为什么：系统本来就已经在做这份工作，也已经有内存来保留它，然后却把结果丢掉了，只因为那份缓存是按进程拆分的，而不是按节点共享的。这是一个披着硬件问题外衣的架构问题。

在你批准更快的 GPU 之前，先测量你的服务栈重新计算它已经持有的答案的频率有多高。共享 KV 缓存对对话式和长上下文的工作负载是一个有力的默认选择，对独特的简短提示词则是一个弱选择，而无论哪种情况都值得为它定价。标题是那 14x。真正的教训是：复用你已经付过费的那份计算。

## 你可能也喜欢..

[**跨多台计算机的分布式 LLM 推理** 当一台机器装不下一个模型时，如何把它铺开到多台机器上，以及这在延迟上要付出什么代价。](/zh/blog/mesh-llm-distributed-inference-multiple-computers/) [**把 RAG 向量内存降低 16x** 另一个复用你已有内存的胜利：无需训练的量化在不换更大机器的情况下把检索语料库缩小 16x。](/zh/blog/rag-vector-memory-quantization/)

模型与基础设施

## 继续浏览此集群

[从核心文章开始**在欧盟自托管 LLM：开放权重模型何时才真正划算**](/zh/blog/self-hosting-llms-eu-cost/)

- [Claude 会给文本加水印吗？2026 API 实战解读](/zh/blog/claude-text-watermark-api-2026/)
- [OpenKB 评测：知识编译器 vs RAG](/zh/blog/openkb-review-vs-rag/)
- [Unsloth Desktop 评测：私有本地 AI 工作站？](/zh/blog/unsloth-desktop-local-ai-workstation-review/)
- [NeMo Switchyard 0.2：无需训练的智能体模型路由？](/zh/blog/nemo-switchyard-model-router/)
- [Firecrawl AnyDoc 评测：14 种格式转 Markdown](/zh/blog/firecrawl-anydoc-review/)

只收重要内容

## 关注与你相关的内容

每当我们发布新文章，你会收到一封简短邮件。你可以关注整个博客，也可以只选感兴趣的主题。

[**返回**](/zh/blog/overview/)

[![Kevin Riedl](/img/team/kevin.webp)](/zh/team/kevin-riedl/)

[Kevin Riedl](/zh/team/kevin-riedl/) https://linkedin.com/in/wsdt

9 分钟 阅读 · 2026年7月23日

[**下一篇**](/zh/blog/self-hosting-llms-eu-cost/)

邮件订阅新文章 ×

×

通过邮件获取新文章

我们发布时给你一封简短邮件。免费，不做跟踪。

## Structured Data

```json
{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@id": "https://wavect.io/#organization",
      "@type": [
        "Organization",
        "ProfessionalService",
        "LocalBusiness"
      ],
      "employee": [
        {
          "@id": "https://wavect.io/team/kevin-riedl/#person",
          "@type": "Person",
          "jobTitle": "Managing Director",
          "name": "Kevin Riedl",
          "url": "https://wavect.io/team/kevin-riedl/",
          "worksFor": {
            "@id": "https://wavect.io/#organization",
            "@type": [
              "Organization",
              "ProfessionalService",
              "LocalBusiness"
            ]
          }
        },
        {
          "@id": "https://wavect.io/team/christof-jori/#person",
          "@type": "Person",
          "jobTitle": "Managing Director",
          "name": "Christof Jori",
          "url": "https://wavect.io/team/christof-jori/",
          "worksFor": {
            "@id": "https://wavect.io/#organization",
            "@type": [
              "Organization",
              "ProfessionalService",
              "LocalBusiness"
            ]
          }
        }
      ],
      "founder": [
        {
          "@id": "https://wavect.io/team/kevin-riedl/#person",
          "@type": "Person",
          "jobTitle": "Managing Director",
          "name": "Kevin Riedl",
          "url": "https://wavect.io/team/kevin-riedl/",
          "worksFor": {
            "@id": "https://wavect.io/#organization",
            "@type": [
              "Organization",
              "ProfessionalService",
              "LocalBusiness"
            ]
          }
        },
        {
          "@id": "https://wavect.io/team/christof-jori/#person",
          "@type": "Person",
          "jobTitle": "Managing Director",
          "name": "Christof Jori",
          "url": "https://wavect.io/team/christof-jori/",
          "worksFor": {
            "@id": "https://wavect.io/#organization",
            "@type": [
              "Organization",
              "ProfessionalService",
              "LocalBusiness"
            ]
          }
        }
      ],
      "legalRepresentative": [
        {
          "@id": "https://wavect.io/team/kevin-riedl/#person",
          "@type": "Person",
          "jobTitle": "Managing Director",
          "name": "Kevin Riedl",
          "url": "https://wavect.io/team/kevin-riedl/",
          "worksFor": {
            "@id": "https://wavect.io/#organization",
            "@type": [
              "Organization",
              "ProfessionalService",
              "LocalBusiness"
            ]
          }
        },
        {
          "@id": "https://wavect.io/team/christof-jori/#person",
          "@type": "Person",
          "jobTitle": "Managing Director",
          "name": "Christof Jori",
          "url": "https://wavect.io/team/christof-jori/",
          "worksFor": {
            "@id": "https://wavect.io/#organization",
            "@type": [
              "Organization",
              "ProfessionalService",
              "LocalBusiness"
            ]
          }
        }
      ],
      "name": "Wavect GmbH",
      "subjectOf": {
        "@id": "https://wavect.io/verified-claims.json#dataset",
        "@type": "Dataset",
        "creator": {
          "@id": "https://wavect.io/#organization",
          "@type": [
            "Organization",
            "ProfessionalService",
            "LocalBusiness"
          ]
        },
        "description": "A machine-readable registry of quantitative and qualitative claims published by Wavect, with review dates, localized page appearances and public third-party citations where available.",
        "inLanguage": "en",
        "isAccessibleForFree": true,
        "license": "https://creativecommons.org/licenses/by/4.0/",
        "name": "Wavect verified publication claims",
        "url": "https://wavect.io/verified-claims.json"
      },
      "url": "https://wavect.io/"
    },
    {
      "@id": "https://wavect.io/team/kevin-riedl/#person",
      "@type": "Person",
      "jobTitle": "Managing Director",
      "name": "Kevin Riedl",
      "sameAs": [
        "https://www.wikidata.org/wiki/Q139796365",
        "https://www.linkedin.com/in/wsdt",
        "https://github.com/wsdt"
      ],
      "url": "https://wavect.io/team/kevin-riedl/",
      "worksFor": {
        "@id": "https://wavect.io/#organization",
        "@type": [
          "Organization",
          "ProfessionalService",
          "LocalBusiness"
        ]
      }
    },
    {
      "@id": "https://wavect.io/team/christof-jori/#person",
      "@type": "Person",
      "jobTitle": "Managing Director",
      "name": "Christof Jori",
      "sameAs": [
        "https://www.wikidata.org/wiki/Q139796367",
        "https://www.linkedin.com/in/jocr77/",
        "https://github.com/jo-chris"
      ],
      "url": "https://wavect.io/team/christof-jori/",
      "worksFor": {
        "@id": "https://wavect.io/#organization",
        "@type": [
          "Organization",
          "ProfessionalService",
          "LocalBusiness"
        ]
      }
    },
    {
      "@id": "https://wavect.io/#website",
      "@type": "WebSite",
      "inLanguage": [
        "en",
        "de",
        "es",
        "zh"
      ],
      "name": "Wavect",
      "potentialAction": {
        "@type": "SearchAction",
        "query-input": "required name=search_term_string",
        "target": {
          "@type": "EntryPoint",
          "urlTemplate": "https://wavect.io/search/?q={search_term_string}"
        }
      },
      "publisher": {
        "@id": "https://wavect.io/#organization",
        "@type": [
          "Organization",
          "ProfessionalService",
          "LocalBusiness"
        ]
      },
      "url": "https://wavect.io/"
    },
    {
      "@id": "https://wavect.io/zh/blog/shared-kv-cache-llm-inference-latency/#webpage",
      "@type": "WebPage",
      "dateModified": "2026-07-23",
      "inLanguage": "zh",
      "isPartOf": {
        "@id": "https://wavect.io/#website",
        "@type": "WebSite"
      },
      "lastReviewed": "2026-07-23",
      "url": "https://wavect.io/zh/blog/shared-kv-cache-llm-inference-latency/"
    }
  ]
}
```

```json
{
  "@context": "https://schema.org",
  "@type": "BlogPosting",
  "abstract": "为了快速服务一个大模型，你会每块 GPU 跑一个进程，而默认情况下这些数据并行的 rank 里每一个都保有一份私有 KV 缓存。所以当一段对话的后续一轮落在不同的 rank 上时，即使另一个 rank 已经计算过，模型仍会重新 prefill 整段历史：那个状态就在 同一台服务器上，却在错误的进程里。LMCache 的 Multi-Process 模式把缓存从各个 进程中移出，放进一个所有进程都能读取的共享主机侧层。在一台 8x H100 服务器上跑 Qwen3-235B 时，这把平均 time-to-first-token 从 3.98s 降到 0.29s（约 14x），并把 解码速度提高到三倍，而模型、硬件和 400GB 的总缓存都不变。这个教训比一个库更大： 很多推理延迟其实是你的系统在重新计算它已经持有的答案，只因为缓存是按进程拆分而 不是按节点共享的而被丢弃。它带来的回报与你的请求重叠程度成正比：对聊天、智能体 和长的共享提示词很大，对独特的一次性提示词很小。在购买更快的硬件之前，先测量复用 度并给节省下来的 GPU 小时定价。",
  "articleBody": " 博客概览/AI 与智能体/模型与基础设施 一个共享 KV 缓存如何在不新增 GPU 的情况下把 LLM 推理延迟降低 14x 要点速览 为了快速服务一个大模型，你会每块 GPU 跑一个进程，而默认情况下这些数据并行的 rank 里每一个都保有一份私有 KV 缓存。所以当一段对话的后续一轮落在不同的 rank 上时，即使另一个 rank 已经计算过，模型仍会重新 prefill 整段历史：那个状态就在 同一台服务器上，却在错误的进程里。LMCache 的 Multi-Process 模式把缓存从各个 进程中移出，放进一个所有进程都能读取的共享主机侧层。在一台 8x H100 服务器上跑 Qwen3-235B 时，这把平均 time-to-first-token 从 3.98s 降到 0.29s（约 14x），并把 解码速度提高到三倍，而模型、硬件和 400GB 的总缓存都不变。这个教训比一个库更大： 很多推理延迟其实是你的系统在重新计算它已经持有的答案，只因为缓存是按进程拆分而 不是按节点共享的而被丢弃。它带来的回报与你的请求重叠程度成正比：对聊天、智能体 和长的共享提示词很大，对独特的一次性提示词很小。在购买更快的硬件之前，先测量复用 度并给节省下来的 GPU 小时定价。 一句话总结：一个名为 LMCache 的开源 KV 缓存层，在一个大型混合专家（MoE）模型上把平均 time-to-first-token 降低了大约 14x，而且它没有用上更快的 GPU、更小的模型或更多的内存。唯一改变的是缓存所在的位置。原本各自囤积私有缓存的八个服务进程，变成了八个共享同一份缓存的进程。 这就是全部要点，而它的意义超出了这一个库。大多数推理优化被包装成购买更快的硬件。你付出的很多延迟，其实是你自己的系统在重新计算一个它已经拥有的答案，只是那份缓存归属于错误的进程。本文解释了改变了什么、这些数字能证明和不能证明什么，以及如何判断同样的架构是否会对你自己的 LLM 服务有帮助。 昂贵的默认做法：每个 rank 都囤积自己的缓存 当一个模型服务一段对话时，它不会在每一轮都重新读一遍整个历史。它会存储自己已经见过的 token 的中间注意力状态。这份存储就是 KV 缓存（key-value cache），而复用它正是聊天第二轮比第一轮快得多的原因。重新计算它的过程叫做 prefill（预填充），而 prefill 正是回答一个长提示词中昂贵的那部分。 陷阱在这里。在该基准测试的拓扑中，vLLM 使用了八个数据并行 rank，并启用了自动专家并行：注意力层在各块 GPU 上复制，Mixture-of-Experts 层则被分片。每个 rank 都在独立进程中运行，并保有自己的私有 KV 缓存。这些缓存之间不通信。 LMCache 自己的基准测试把这个代价说得很具体。Qwen3-235B-A22B 跑在八块 H100 GPU 上。每个 rank 分到 50 GB 的 CPU 内存用于 KV 缓存卸载，因此这台服务器总共持有 400 GB。纸面上这是一份很大的缓存。但实际上它是八个各自隔离的 50 GB 缓存，而不是一份共享的 400 GB 缓存。 现在设想一段真实的多轮对话。第一轮被路由到 rank 3，它计算并缓存了上下文。同一段对话的第二轮被路由到了 rank 6。rank 6 看不到 rank 3 缓存的内容。它所需要的那个确切状态就躺在同一台物理服务器的主机内存里，但它归属于另一个进程，因此模型只能做它唯一能做的事：从头开始把整段对话重新 prefill 一遍。这段计算你已经付过一次费。每一轮落在不同 rank 上时，你都要再付一次。 LMCache 改变了什么：用一份缓存代替八份 LMCache 是一个开源的、采用 Apache-2.0 许可的 KV 缓存层，面向 vLLM 和 SGLang 这类推理引擎。它的职责是把 KV 缓存从稀缺的 GPU 内存中移出，放进一个由 CPU 内存、本地磁盘和远程存储构成的分层体系中，并让缓存能够跨请求、跨会话、跨引擎实例被复用。 产生 14x 这个数字的改变是架构层面的，而不是算法层面的。在传统的进程内设置里，每个服务进程内部都嵌入了一个独立的缓存库，这正是缓存彼此隔离的原因。LMCache 的 Multi-Process 模式（多进程模式）把缓存从各个进程中抽离出来，作为一个独立的服务来运行。节点上的每个服务进程都向它注册，并从同一个主机侧的池中读取。 于是同样的 400 GB 不再是八个被隔开的桶，而成为一个共享的层。当第二轮落在 rank 6 上时，rank 6 向共享缓存发起询问，找到 rank 3 已经计算好的状态，从而跳过 prefill。模型、硬件和总的缓存容量全都完全一样。只不过那份计算不再被丢弃。 基准测试数字 这些数字来自 LMCache 发布的、在 Qwen3-235B-A22B-Instruct-2507-FP8 上的多轮对话基准测试，运行环境为八块 NVIDIA H100 80GB GPU、vLLM 0.18.1 和 LMCache 0.4.3-dev。它们比较的是传统的进程内卸载与 Multi-Process 模式。这些是作者报告的结果，基于单一硬件和工作负载；请把它们当作一个有力的方向性信号，而不是对你自己流量的保证。 LMCache 进程内卸载对比 Multi-Process 共享缓存，来自 LMCache 发布的基准测试，核对于 2026 年 7 月 23 日 指标进程内（隔离缓存）Multi-Process（共享缓存）变化 平均 time-to-first-token3.98 s0.29 s约快 14x P99 time-to-first-token13.55 s1.30 s约快 10x 平均解码速度9.81 tokens/s37.47 tokens/s约快 3.8x P99 解码速度34.27 tokens/s45.14 tokens/s约快 1.3x 要看形状，而不只是看标题数字。收益最大的地方，正是隔离缓存伤害最深的地方：那些原本需要重新 prefill 一段长历史的冷启动轮次。平均 TTFT 从约四秒降到不到三分之一秒，是一个感觉迟钝的聊天和一个感觉即时的聊天之间的差别。对一个产品来说，P99 的改善甚至更重要，因为长尾才是你最慢的那批用户实际体验到的东西。 为什么即便你从不碰 LMCache 这件事也很重要 重点不是你应该去装某一个特定的库。重点是浪费藏在哪里。服务器已经做完了这份工作。它有内存来保留结果。它把结果丢掉了，只因为那份缓存是按进程划分的，而不是按节点共享的。 这种模式在自托管推理里到处都是：已经付过费的计算，只因为系统是怎样拼装起来的（而不是它有多少硬件）而被丢弃。在有人批准一笔更大的 GPU 采购之前，更便宜的问题是：现有的这些机器是不是在重新计算它们已经持有的答案。购买容量是解决一个问题的昂贵办法，而复用往往能免费解决这个问题。我们在关于 降低 LLM token 成本 的指南里对开销提出了同样的论点，也在 本地模型对比 API 的盈亏平衡分析 里对硬件提出了同样的论点。 如果复用优化已经做完，而且一个模型长期承担稳定、低延迟负载，下一步才是专用硬件。我们的 Taalas HC1 硬编码 LLM ASIC 评测解释了每秒 17,000 token 真正证明了什么，以及用模型灵活性换速度前必须验证哪些问题。 共享 KV 缓存在哪里有帮助，在哪里没有 缓存复用带来的回报，与你的请求之间重叠程度成正比。它是一个杠杆，而不是一条定律，所以在期待 14x 之前，请对你自己的流量诚实一点。 工作负载共享缓存帮助有多大为什么 多轮聊天和智能体大每一个后续轮次都会重新发送同一段不断增长的历史；复用跳过了重复的 prefill，这正是基准测试的场景。 长的共享系统提示词或 RAG 上下文大一个在许多请求间重复的大而固定的前缀，只需 prefill 一次并复用，而不是每个请求、每个 rank 各 prefill 一次。 大量简短、独特、一次性的提示词小请求之间几乎没有重叠，意味着可复用的缓存很少；收益会缩小到接近运行缓存层的成本。 单进程、单 GPU 服务此改变带来的收益为无没有多个独立的 rank 需要统一；进程内的前缀缓存已经覆盖了你的情况。 共享一份缓存也并非免费。一个独立的缓存服务会增加一条进程间协调路径、一个需要运维和监控的活动部件，以及一次在未命中时会带来少量延迟的查找。当请求之间几乎不重叠时，这份开销可能超过节省下来的 prefill。对于对话式和长上下文服务，这个架构是一个有力的默认选择，而不是普适升级。 这真的能削减你的推理账单吗？ 更快并不等于更便宜。一次延迟上的胜利，只有在它从账单上抹去了某项开销，或让你能用同一台机器服务更多流量时，才会变成一次成本上的胜利。用你实际运行的东西来给这个改变定价： 每月收益 = 不再花在重复 prefill 上的 GPU 小时 + 每块现有 GPU 更高的吞吐 + 推迟的硬件采购 - 缓存服务的开销与运维时间 被复用的 prefill 释放了 GPU 时间，而释放出来的 GPU 时间，要么意味着一个更小的集群，要么意味着在当前集群上服务更多流量。干净利落的胜利在于跨过一个阈值：一个你现在无需新增节点就能满足的延迟目标、一个同样的 GPU 现在能维持的并发水平，或者一次你可以推迟的既定硬件升级。如果你的请求很少重叠，诚实的答案是：节省很小，你的精力花在别处会更好。要看这件事所汇入的完整的自建对比租用全景，请通读 在欧盟自托管 LLM 到底要花多少钱。 在你重连服务架构之前的一次简短评估 测量你的复用度。在动架构之前，记录请求共享前缀或延续同一段对话的频率有多高。重叠就是这份奖赏的全部大小；如果它很低，到此为止。 为长尾建立基线，而不只是均值。在你真实的流量上记录 P50 和 P99 的 TTFT 与解码速度。基准测试最大的收益出现在长尾上，而长尾才是用户感受到的东西。 确认拓扑是否匹配。这 14x 来自把一个节点上多个数据并行的 rank 统一起来。如果你今天是每块 GPU 一个进程，那你就有它所修复的这种碎片化；如果你跑的是单个进程，那你没有。 在影子流量或一部分流量上试点。把一份副本或一部分流量路由到共享缓存的设置中，并在相同的硬件和工作负载上与基线作比较。 给它定价，而不只是计时。把测得的延迟和吞吐变化换算成 GPU 小时、节点数量或推迟的采购，再减去运行缓存服务的成本。 在采用它之前要问的问题 我们的请求中，实际上有多大比例共享一个前缀或延续一段已有的对话？ 我们是否在每个节点上运行多个数据并行的 rank，以至于隔离缓存对我们来说才算得上是个问题？ 在生产流量上（而非基准测试上），我们当前的 P50 和 P99 的 TTFT 与解码数字是多少？ 那个独立的缓存服务，在未命中时的延迟上、在运维面上、以及在故障模式上，各让我们付出什么代价？ 延迟收益是否会转化为更少的 GPU、更高的吞吐或一次推迟的采购，又能转化多少？ 这个缓存层的成熟度、许可证和维护状态如何，以及在必要时我们能否运维或 fork 它？ 来源与结论边界 这个架构、400 GB 的碎片化示例以及所有基准测试数字，均来自 LMCache 的文章 \"LMCache's New Architecture Boosts MoE Inference Performance by 10x\"，以及该项目的 GitHub 仓库 和 文档。所报告的延迟和吞吐数字归属于其作者及其测试系统，即一台 8x H100 服务器，运行 vLLM 0.18.1 和 LMCache 0.4.3-dev，跑 Qwen3-235B-A22B；Wavect 没有复现它们。事实核对于 2026 年 7 月 23 日。 常见问题 什么是 LLM 推理中的 KV 缓存？ KV 缓存（key-value cache）存储模型为它已经处理过的 token 计算出的",
  "articleSection": "Engineering",
  "author": {
    "@id": "https://wavect.io/team/kevin-riedl/#person",
    "@type": "Person",
    "name": "Kevin Riedl",
    "sameAs": [
      "https://www.wikidata.org/wiki/Q139796365",
      "https://www.linkedin.com/in/wsdt",
      "https://github.com/wsdt"
    ],
    "url": "https://wavect.io/team/kevin-riedl/"
  },
  "dateModified": "2026-07-23",
  "datePublished": "2026-07-23",
  "description": "为了快速服务一个大模型，你会每块 GPU 跑一个进程，而默认情况下这些数据并行的 rank 里每一个都保有一份私有 KV 缓存。所以当一段对话的后续一轮落在不同的 rank 上时，即使另一个 rank 已经计算过，模型仍会重新 prefill 整段历史：那个状态就在 同一台服务器上，却在错误的进程里。LMCache 的 Multi-Process 模式把缓存从各个 进程中移出，放进一个所有进程都能读取的共享主机侧层。在一台 8x H100 服务器上跑 Qwen3-235B 时，这把平均 time-to-first-token 从 3.98s 降到 0.29s（约 14x），并把 解码速度提高到三倍，而模型、硬件和 400GB 的总缓存都不变。这个教训比一个库更大： 很多推理延迟其实是你的系统在重新计算它已经持有的答案，只因为缓存是按进程拆分而 不是按节点共享的而被丢弃。它带来的回报与你的请求重叠程度成正比：对聊天、智能体 和长的共享提示词很大，对独特的一次性提示词很小。在购买更快的硬件之前，先测量复用 度并给节省下来的 GPU 小时定价。",
  "headline": "共享 KV 缓存在不新增 GPU 的情况下把 LLM 推理延迟降低 14x",
  "image": "https://wavect.io/img/blog/headers/header_shared-kv-cache-llm-inference-latency.svg",
  "inLanguage": "zh",
  "mainEntityOfPage": {
    "@id": "https://wavect.io/zh/blog/shared-kv-cache-llm-inference-latency/",
    "@type": "WebPage"
  },
  "publisher": {
    "@id": "https://wavect.io/#organization",
    "@type": [
      "Organization",
      "ProfessionalService",
      "LocalBusiness"
    ]
  },
  "url": "https://wavect.io/zh/blog/shared-kv-cache-llm-inference-latency/",
  "wordCount": 533
}
```

```json
{
  "@context": "https://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": [
    {
      "@type": "ListItem",
      "item": "https://wavect.io/zh/",
      "name": "首页",
      "position": 1
    },
    {
      "@type": "ListItem",
      "item": "https://wavect.io/zh/blog/overview/",
      "name": "博客概览",
      "position": 2
    },
    {
      "@type": "ListItem",
      "item": "https://wavect.io/zh/blog/topics/ai-agents/",
      "name": "AI 与智能体",
      "position": 3
    },
    {
      "@type": "ListItem",
      "item": "https://wavect.io/zh/blog/clusters/models-infrastructure/",
      "name": "模型与基础设施",
      "position": 4
    },
    {
      "@type": "ListItem",
      "item": "https://wavect.io/zh/blog/shared-kv-cache-llm-inference-latency/",
      "name": "共享 KV 缓存把 LLM 推理延迟降低 14x | ",
      "position": 5
    }
  ]
}
```

```json
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {
      "@type": "Question",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "KV 缓存（key-value cache）存储模型为它已经处理过的 token 计算出的中间注意力状态。复用它意味着模型不必在每一步都重新计算整个提示词，这正是一段对话的后续轮次比第一轮快得多的原因。重新计算那个状态的过程叫做 prefill。"
      },
      "name": "什么是 LLM 推理中的 KV 缓存？"
    },
    {
      "@type": "Question",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "在传统的设置里，每个数据并行的 rank 都保有一份私有缓存，因此当后续一轮被路由到不同的 rank 时，即使另一个 rank 已经计算过，模型仍会重新 prefill 整段对话。共享缓存让任何 rank 都能复用那份工作，在 LMCache 的基准测试中，把平均 time-to-first-token 从 3.98 s 降到了 0.29 s，而模型、硬件和总缓存容量都不变。"
      },
      "name": "为什么共享 KV 缓存能让推理快 14x？"
    },
    {
      "@type": "Question",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "LMCache 是一个开源的、采用 Apache-2.0 许可的 KV 缓存层，面向 vLLM 和 SGLang 这类推理引擎。它把 KV 缓存从 GPU 内存移到一个由 CPU 内存、磁盘和远程存储构成的分层体系中，并让缓存能够跨请求、跨会话、跨引擎实例被复用。它的 Multi-Process 模式就是本文结果背后的共享缓存架构。"
      },
      "name": "什么是 LMCache？"
    },
    {
      "@type": "Question",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "它的帮助与你的请求之间重叠程度成正比。多轮聊天、智能体，以及长的共享系统提示词或 RAG 上下文受益最多。大量简短、独特、一次性的提示词受益很少，而单进程、单 GPU 服务从这个具体的改变中什么也得不到，因为没有多个独立的 rank 需要统一。在期待较大收益之前，先测量你的前缀复用度。"
      },
      "name": "共享 KV 缓存会加速我的工作负载吗？"
    },
    {
      "@type": "Question",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "不。一次延迟上的胜利，只有在它抹去了你原本要付的 GPU 小时、让同样的 GPU 服务更多流量，或推迟一次硬件采购，并在减去运行缓存服务的开销之后，才会变成一次成本上的胜利。用你真实的账单来给这个改变定价，而不要假设速度就等于节省。"
      },
      "name": "更快的推理是否自动意味着更便宜的推理？"
    }
  ]
}
```
