跳转至正文

肉眼可见的 KV 缓存收益:从 vLLM 中的前缀缓存到 llm-d 的分布式调度

·阅读时长 21 分钟
Maroon Ayoub
IBM 研究科学家与架构师
Danny Harnik
IBM 高级技术参谋
Tyler Smith
Red Hat 技术参谋
Kellen Swain
Google 软件工程师
Xining Wang
Xining Wang
阿里云高级技术专家
Hang Yin
Hang Yin
阿里云高级研发工程师
Kay Yan
DaoCloud 首席软件工程师

llm-d 项目提供了一系列“明径”——用于在生产环境中部署大语言模型的、经过测试和基准评估的解决方案。我们的第一条路径,智能推理调度,通过平衡集群负载和前缀缓存(prefix-cache)亲和性,为 AI 感知路由建立了基准。该路径的默认配置对后者使用“近似”方法,根据请求流量预测缓存局部性。

本博客阐述了一条更先进且强大的路径:精确前缀缓存感知调度

我们深入探讨了该特性的下一代技术,它超越了预测,赋予调度器直接内省分布式 vLLM 缓存的能力。这种精确性是最大化缓存命中率的关键,能在分布式部署中实现更高水平的性能并最大化成本效益。

博客核心要点
  • KV 缓存命中率直接影响底线:已缓存 token 与未缓存 token 之间存在 10 倍的成本差异,缓存效率不仅是性能优化,更是根本性的成本和性能驱动力
  • 并非理论:对话式 AI 和 Agent 工作流等真实生产工作负载,会自然产生这种适合该方案的高前缀模式
  • vLLM 的前缀缓存在分布式部署中会失效:标准负载均衡器会将相关请求分散到不同 Pod,破坏缓存局部性并强制进行昂贵的重复计算
  • 精确前缀缓存感知调度带来数量级提升:我们的基准测试显示,在相同硬件上,响应速度提升了 57 倍,且吞吐量翻倍

生产级 AI 中最重要的指标

在生产级 LLM 推理中,我们会追踪数十个指标——延迟、吞吐量、GPU 利用率和成本等等。但有一个指标脱颖而出。正如构建生产级 AI 智能体的工程师们所指出的:

KV-cache 命中率是生产阶段 AI 智能体唯一最重要的指标。它直接影响延迟和成本。

这不仅是一个学术主张;它对利润有着直接且巨大的影响。以 Anthropic 的 Claude Sonnet 等尖端模型的定价模型为例。处理已在缓存中的 Token 的成本比未缓存的 Token 低 10 倍(每百万 Token 0.30 美元 vs 3.00 美元)。在 OpenAI 的 API 定价页面也可以看到同样的模式。高缓存命中率不仅能让你的应用更快,还能使其运营成本从根本上降低。这就是 KV-cache 的力量。

在单实例环境中,vLLM 等引擎利用自动前缀缓存(Automatic Prefix Caching)来减少冗余工作,重用先前的计算以实现更快、更高效的性能。然而,一旦你扩展到分布式的多副本环境,这些精心调优的优化可能会失效。

这篇博客将探讨这一挑战:vLLM 前缀缓存的收益如何在朴素的分布式系统中流失,以及 llm-d 的精确前缀缓存感知调度如何恢复并增强这些收益。为了充分理解这一点,我们首先需要了解是什么让 vLLM 在单实例中表现如此出色。让我们深入了解。

走进 vLLM:在单实例中精通缓存

专家提示

已经了解 vLLM 如何使用 KV-cache 和前缀缓存来优化推理?欢迎直接跳到横向扩展的挑战

每个 Transformer 模型的核心是自注意力机制——模型通过计算每对 Token 之间的注意力分数来理解上下文。这种全对比较随输入长度呈二次方增长,使得初始的 Prefill(预填充)计算成为生成过程中最昂贵的部分。

其结果是存储在 KV-cache(模型短期记忆)中的 Key (K)Value (V) 张量。在 Decode(解码)阶段生成后续 Token 时,模型只需从内存中调取这些现有的值,而无需重新计算。

vLLM 通过自动前缀缓存(Automatic Prefix Caching)更进一步:它能智能识别请求是否共享相同的 Token 序列前缀。它不再重新计算,而是通过基于哈希的块匹配(Block Matching)重用缓存中完全相同的内存页。这种重用已计算工作的原则驱动了 vLLM 的性能:

  • 首字延迟 (TTFT) 大幅下降,因为大部分耗时的预填充步骤被跳过了
  • 整体吞吐量增加,因为 GPU 被释放出来以服务更多请求

在一次简单测试中,将一个带有约 10,000 Token 提示词的请求第二次发送到 Qwen/Qwen3-32B 实例时,首字延迟从 4.3 秒降至仅 0.6 秒

实际用例中的前缀重用

vLLM 缓存的力量并非仅存在于理论中;它直接对应于最常见且最有价值的 LLM 工作负载结构。通过理解这一模式,我们可以清楚地看到在生产环境中提供服务时,哪些核心利益受到了挑战。

对话式 AI

在任何多轮对话中(从客服机器人到长文本助手),整个聊天历史和系统提示词构成了一个巨大的前缀。每个新的用户消息都是一个微小的后缀。有效的缓存意味着只有最新的轮次需要预填充,从而保持对话流畅且响应迅速,防止延迟随对话变长而增加。

Conversational AI prefix caching diagram

图 1:展示对话历史作为一个不断增长的缓存前缀的图表,只有新的用户查询需要预填充。

智能体(Agentic)工作流

AI 智能体代表了前缀占比极端的案例。这些系统在推理循环中运行,前缀包含智能体的目标、工具定义以及漫长的行动和观察历史。生产数据表明,这可能导致输入与输出的比例超过 100:1(来自 Manus 博客),使得前缀极其庞大。在每一步重用上下文使得智能体在计算上变得可行。

Agentic workflow prefix caching diagram

图 2:智能体循环示意图,显示巨大的静态上下文(工具、步骤历史)作为缓存前缀,新的观察/行动作为微小的后缀。

在每一轮中重用这些海量上下文,是复杂智能体在计算上可行且具有成本效益的关键。

那么 RAG 呢?

虽然检索增强生成(RAG)也依赖于长前缀(系统提示词 + 文档),但重用 KV 缓存更具挑战性。具体的文档及其顺序在不同查询之间经常发生变化,从而打破了简单的前缀模式。这需要更复杂的方法,我们将在本文末尾简要讨论。

横向扩展的挑战

当我们从单实例环境转移到分布式生产集群时会发生什么?曾经统一的 KV-cache 变得分散化(Disaggregated)。每个 vLLM Pod 在完全隔离的情况下管理自己的缓存。标准的负载均衡器盲目地使用与缓存无关的指标来平均分配流量,将相关请求分散到不同的 Pod 上,从而破坏了缓存的局部性。

让我们重新审视智能体工作流的例子,看看无管理、分散化的缓存带来的直接影响:

KV-cache miss scenario diagram

图 3:令人心碎的 KV-cache 缓存未命中场景。

这个单一的路由决策触发了一连串的失败:

  • 缓存未命中: Pod A 上的热缓存收益完全丢失
  • 重复工作: 最昂贵的计算被不必要地执行了两次
  • 延迟增加: 用户体验到显著更高的首字延迟 (TTFT)
  • 浪费 GPU 资源: 昂贵的硬件被占用去做重复的工作,而不是服务新请求,降低了整个系统的吞吐量

在处理成千上万个并发请求的生产环境中,这并非偶然事件;而是默认行为。结果就是系统明显变慢更加昂贵。这正是 llm-d 的精确前缀缓存感知调度旨在解决的核心问题。

llm-d:精确的前缀缓存感知调度

我们刚刚看到,横向扩展 vLLM 集群会自然地使 KV-cache 分散化,形成一个导致昂贵缓存未命中的分布式内存池。解决方案就是桥接这种分散性。为了恢复前缀缓存的收益,调度器需要一种新的“视野”:洞察分布式缓存的实时状态。

这正是 llm-d 所提供的。它创建了集群 KV-cache 的全局视图,使其能够将分散的内存视为一个单一、可管理的池,并进行精确的请求路由。

工作原理:通过 KVEvents 实现全局缓存视图

全局缓存视图建立在来自每个 vLLM Pod 的连续 KVEvents 流之上,这些事件由开源的 llm-d-kv-cache 库高效处理。

KVEvents 提供了集群中所有物理缓存变化的实时反馈,每当缓存块被创建或淘汰时都会触发。然后,这个流被 llm-d-kv-cache 库的组件摄取并组织:

  1. kvevents.Pool:该组件消费高吞吐量的事件流。在消化这些事件时,它会持续更新底层的 KV-Block 索引,该索引维护着块哈希与其所在 Pod 和内存介质(GPU/CPU)的实时映射。
  2. kvcache.Index:这是调度器使用的高层索引。它利用底层的 KV-Block 索引将 Token 的逻辑序列(即前缀)映射到持有它们的 Pod。这直接回答了这样一个问题:“该请求的前缀有多少比例存在于可访问的 Pod 上?”

这种两层架构提供了一个持续更新、可扩展的集群缓存状态视图,这是实现智能缓存感知路由的关键。

llm-d architecture diagram

图 4:简化的架构图。(1) - (3) 展示读取路径,而 (A) - (B) 展示写入管线。

开销如何? 该全局索引的内存开销微乎其微——参见 附录 A.3 的扩展性分析,显示数据与元数据的比例为 1,000,000:1

高可用性支持

此设计天然支持双活或主备部署,通过配置可实现全量视图复制或分片。

精确前缀缓存打分器 (Precise Prefix-Cache Scorer)

有了准确、实时的全局缓存视图,调度器现在可以进行智能路由。负责此项工作的组件是精确前缀缓存打分器。它位于调度器内部,利用 kvcache.Index 为每个进入的请求执行一项简单但至关重要的任务:

  1. 它查询 kvcache.Index 以确定该前缀的百分之多少已在每个活动的 vLLM Pod 上可用。
  2. 它为每个 Pod 输出一个“缓存亲和性分数”,直接代表可以节省的计算工作量。

该打分器提供了一个强有力的粘性信号,调度请求以最大化缓存命中的概率。然而,仅依靠粘性可能会产生新问题,例如将大量请求发送到已经过载的 Pod,而其他 Pod 却处于闲置状态。

因此,最终的路由决策不仅基于此分数。正如我们之前关于智能推理调度“明径”的文章中所详述的,KV-cache 亲和性分数会与分布式负载感知分数相结合,从而做出平衡的决策。

性能结果

为了验证这一方法,我们在一个包含 8 个 vLLM Pod(共 16 张 H100 GPU)的集群上基准测试了四种调度策略。我们使用了一个真实的 B2B 工作负载:模拟 150 个企业客户,每个客户拥有 6,000 Token 的上下文,每个客户有 5 个并发用户3-60 QPS 的持续负载下提交 1,200 Token 的查询

该工作负载产生的 KV-cache 总需求为集群容量的 73%,这是任何单个 Pod 所能处理容量的 6 倍,迫使系统在整个集群中分布前缀——这正是智能调度变得至关重要的时刻。

基准测试详情

有关完整的基准测试方法和工作负载详情,请参阅 附录 A.1附录 A.2

对比的四种策略:

  • random-scheduling:朴素调度器,作为对照组。
  • load-scheduling:仅感知负载得分的调度器:vLLM 队列 + kv-cache 利用率。
  • approximate-scheduling:智能推理调度路径中的默认配置,在负载感知调度的基础上扩展了 近似前缀缓存打分器
    • 此插件基于路由历史构建近似局部性索引。
  • precise-scheduling:本文描述的高级“明径”方案。

因此,该基准测试考验了调度器高效管理分散化 KV-cache 的能力。在生产环境中,如果总缓存需求超过集群容量,自动扩缩容系统将负责启动更多副本以维持 SLO。在这里,我们专注于最大化现有硬件的性能

结果:性能的飞跃

下表总结了各关键性能指标的差异。

实验输出 Toks/sTTFT p90 (s)TTFT 均值 (s)vLLM 等待队列 (均值)
precise-scheduling8730.00.5420.2980.1
approximate-scheduling6944.431.08313.3168.1
load-scheduling4428.794.86546.98728.9
random-scheduling4428.792.55145.28127.3

首字延迟 (TTFT)

对面向用户的延迟影响最为显著。precise-scheduling 提供的 P90 TTFT 仅为 0.542 秒。相比之下,近似调度器耗时超过 31 秒,而对缓存盲目的调度器耗时则超过 90 秒

  • precise-schedulingapproximate-scheduling 快 57 倍。
  • precise-schedulingrandom-scheduling 快超过 170 倍。

这就是交互式体验与在大规模下功能上不可用系统之间的区别。

系统总吞吐量

这种延迟效率直接转化为更高的系统容量。precise-scheduling 实现了 8,730 输出 Token/秒 的总吞吐量。这代表着:

  • 相较于 approximate-scheduling 基准提升了 25%
  • 相较于对缓存盲目的配置,吞吐量提升了 1 倍以上

这允许你在完全相同的硬件上处理明显更多的流量,只需通过消除缓存未命中的浪费即可实现。

Performance benchmark charts

图 5:在逐渐升高的 QPS 速率下测量的 TTFT、TPoT 和吞吐量的三面板图。

上图清晰地展示了这些优势。随着请求率增加,蓝线(precise-scheduling)始终保持最低的平均 TTFT 并实现了最高的总吞吐量。

原因剖析:从节省的工作到系统吞吐量

基准测试中看到的显著性能提升是系统效率的直接结果,这种差异在 Grafana 实时指标中清晰可见。

以下图表是在基准测试运行期间捕获的。调度器显示顺序为:precise-scheduling(左)、approximate-scheduling(中)和 random-scheduling(右)。

1. 有效缓存吞吐量:量化节省的工作

首先,我们测量有效缓存吞吐量——每秒直接从缓存中提供的提示词 Token 数量。该指标量化了 GPU 避免的计算工作。高数值意味着系统持续节省了大量昂贵的预填充计算。

Effective cache throughput metrics

图 6:基准测试期间,集群中通过 KV-cache 节省的总计算工作量。

图表清晰地显示,precise-scheduling 通过有效命中前缀,维持了巨大且稳定的节省工作吞吐量。中间我们可以看到 approximate-scheduling 效率不错但较低,而右侧的 random-scheduling 几乎没有节省任何工作。

2. 系统状态:效率带来的结果

这些节省的工作直接转化为系统健康。通过避免预填充瓶颈,GPU 可以专注于高效解码。我们可以通过比较“等待 (Waiting)”请求(排队中)和“运行 (Running)”请求(解码中)的数量来观察这一点。

vLLM waiting requests metrics
图 7:基准测试期间 vLLM 中的等待请求数量。

vLLM running requests metrics
图 8:基准测试期间 vLLM 中的运行(解码中)请求数量。

左侧的 precise-scheduling 曲线图显示系统非常稳定。通过有效利用分散的 KV-cache,它保持了极小的等待队列,并最大化了主动运行请求的数量。相比之下,其他调度器显然已不堪重负;它们不断增长的等待队列阻塞了系统,阻碍了工作的有效完成。

这种不稳定性是由“缓存抖动(Cache Thrashing)”引起的。对缓存盲目的调度器不断在不同 Pod 之间重复创建和淘汰相同的前缀,将 GPU 周期浪费在冗余的预填充上。precise-scheduling 完全避免了这一点。它精确感知前缀位置,只要负载允许就始终路由请求以命中缓存,从而减少工作量,几乎消除排队,使系统保持健康。

基于会话的调度 (Session-Based Scheduling)

基于会话的调度为个人用户提供了亲和性,但忽略了跨用户的场景。在我们对 150 个企业客户(每个都有 6,000 Token 的系统提示词)的基准测试中,会话调度会创建 750 个独立的会话,但会漏掉客户组内跨用户的缓存重用,导致大部分计算工作无法被优化。精确的前缀缓存感知调度保证了整个系统的最大化重用

业界采用

基准测试中展示的巨大性能改进正在推动现实世界的采用。

例如,阿里云正将此精确路由策略集成到其 阿里云容器服务 Kubernetes 版 (ACK) 带有推理扩展的网关 (GIE) 中。为了进一步增强 QwenDeepSeek 等模型的生产部署,他们正在开发分布式 Token 化服务以支持配套功能,并计划将这些工作贡献回 llm-d 社区。其端到端能力已在客户模拟环境中得到验证。

同样的潜力促使 DaoCloud 增强其 d.run 模型即服务 (MaaS) 平台,以加速 DeepSeek 及其他先进模型的推理,通过 KubernetesvLLMllm-d 采用了带有 P/D 分离和先进 KV-cache 架构的分布式推理。扬凯(Kay Yan)强调:“智能 KV-cache 管理能够实现更具适应性且更具成本效益的推理架构”。

下一步:扩展缓存感知范式

精确的前缀感知调度是向前迈出的一大步,但这只是更广泛的、以缓存为中心的推理愿景的一部分。llm-d 项目正在迅速发展,未来有几个令人兴奋的方向:

  • 增强型 CPU 卸载 (CPU Offloading): 针对更大规模的 KV-cache 池,我们正在深化与 vLLM 原生的 CPU 卸载集成。这将允许构建海量的缓存池,在 GPU 显存和更便宜的 CPU 内存之间进行智能分层,并由调度器做出感知延迟的决策。
  • 针对 RAG 的 KV-Cache 融合: 如前所述,RAG 工作负载面临独特挑战,因为检索到的文档顺序可能不同,从而打破了简单的前缀模式。下一个前沿领域是位置无关的 KV 融合,这项技术能够使多样的 RAG 查询实现灵活且强大的缓存重用。这将与大规模存储卸载同步推出。

结论

llm-d 的历程反映了我们思考 LLM 推理方式的重大转变——推理不再是一组无状态的函数调用,而是一个动态的、有状态的编排问题。基准测试数据很明确:前缀缓存感知调度不仅是一项优化,更是生产性能和成本效率的关键。

通过从 AI 盲目路由转向精确的 KV-cache 感知策略,我们能够在相同的硬件上实现延迟和吞吐量数量级的提升。精确前缀缓存感知的“明径”方案提供了一个经过测试和基准验证的解决方案,让你的分布式部署效率显著提高。

选择正确的策略

最佳调度器取决于工作负载的复杂性。以下是支持策略的层级,每一级都解决了前一级的局限性。

  • 1. 随机/轮询调度 (Random/Round-Robin):这种简单方法适用于对称工作负载,即所有请求的计算成本相似且缓存重用极少的情况。

  • 2. 负载感知调度 (Load-Aware):处理非对称工作负载的必要步骤。通过基于 Pod 的服务能力路由请求,防止过载并提高资源利用率。

  • 3. 近似前缀缓存调度 (Approximate Prefix-Cache):为具有上下文重用模式的工作负载引入缓存感知。

    • 局限性: 在大规模或动态工作负载下,估算可能变得不可靠,导致路由并非最优——正如我们在基准测试中所见。
  • 4. 精确前缀缓存感知调度 (Precise Prefix-Cache Aware):在具有严格 SLO 的生产环境中,这是应对动态、大规模工作负载最有效的策略,此时最大化缓存命中率是主要的性能驱动力。

参与 llm-d

llm-d 项目的蓬勃发展离不开社区的贡献,有多种方式可以参与:

  • 查看 llm-d 社区快速入门指南 → 从这里开始,了解更多关于参与 llm-d 项目的信息。
  • 加入我们的 Slack → 获取邀请 并与维护者和贡献者联系。
  • 浏览代码 → 访问我们的 GitHub 组织 并寻找你感兴趣的 Issue。
  • 参加会议 → 所有会议均公开开放!将我们的 公共日历 添加到你的日程并加入讨论。

附录

A.1: 基准测试设置详情

  • 模型Qwen/Qwen-32B
  • 硬件:包含 8 个 vLLM Pod 的集群,每个 Pod 运行在 2 张 NVIDIA H100 GPU 上(共 16 张)。
    • 每个实例持有 307,328 Token 的 KV-cache。
  • 对比的调度器:
    • random-scheduling:朴素调度器,作为对照组。
    • load-scheduling:仅感知负载得分的调度器:vLLM 队列 + kv-cache 利用率。
    • approximate-scheduling:基准智能调度器,在负载调度基础上扩展了近似前缀缓存打分器。
    • precise-scheduling:本文描述的高级“明径”方案。

A.2: 工作负载详情 - 真实 B2B SaaS 场景

该基准测试旨在模拟高价值、多租户的 B2B 应用在沉重、持续负载下的表现。想象一个为大量企业客户提供专业 AI 助手的平台。

  • 150 个不同的企业客户(群体)同时使用该平台。
  • 每个客户都有一个独特且庞大的上下文,包含 6,000 Token。这可以被视为他们公司的内部知识库或一套详细的指令,构成了极具价值的共享前缀
  • 对于每个客户,有 5 名员工同时与助手交互,每人提交各自独特的问题,每个问题 1,200 Token
  • 系统承受着持续的泊松分布请求压力,从 3 QPS 攀升至极具挑战性的 60 QPS,以模拟业务高峰时段。

对于此工作负载,在理想状态下,为所有活跃客户缓存共享前缀需要集群总 KV-cache 容量的 约 73%。这几乎是任何单个 Pod 独立容量(约 12.5%)的 6 倍。这使得单个副本无法处理负载,并迫使调度器在整个集群中智能地分布前缀。

因此,该基准测试考验了调度器高效管理分散化 KV-cache 的能力。在现实场景中,如果总缓存需求超过集群容量,自动扩缩容系统将负责启动更多副本以维持 SLO。在这里,我们专注于最大化现有硬件的性能——在这种情况下,对缓存盲目的配置会产生巨大的排队和高延迟。

实验工具和具体细节已记录在 llm-d-kv-cache 基准测试报告中。

A.3: 索引规模分析

这种全局记账的开销在于存储 KV 块哈希,而非巨大的 KV 张量本身。让我们以这个 vLLM 例子为例:在 8xH200 上以 FP8 运行 DeepSeek-R1

对于运行在 8 张 NVIDIA H200 GPU 上的 DeepSeek R1 模型(FP8),专门用于 KV-cache 池的显存共 45.7 GB * 8 = 365 GB,这由数千个独立的内存块组成。每个代表 128 Token 的块消耗约 8.6 MB 显存。然而,在全局索引中追踪这些块所需的元数据仅为一个 64 位哈希,即 8 字节。如果效率高,维护数据结构的额外开销微不足道。

这意味着管理整个 365 GB 的缓存池,调度器索引仅需约 339 KB 的内存——数据与元数据的比例超过了 1,000,000:1。索引的内存占用比它所追踪的 GPU 显存小好几个数量级,使其成为一种极度高效、低开销的解决方案。