Mooncake 集成方式:Python 绑定、SGLang、vLLM 和 LMCache

梳理 pybind11、张量与对象 API,以及 SGLang、vLLM 和 LMCache 接入 Mooncake 时各自负责的部分。

Code walkthroughsMooncake and HiCache internalsLLM servingKV cacheMooncakeSGLang

Mooncake 的 README 和文档会频繁提到 SGLang、vLLM、LMCache、预填充与解码分离、KV 缓存池。读这些材料时,一个容易踩的坑是把“系统愿景”和“当前仓库里的代码边界”混在一起。

边界可以先拆成三层:

  • Mooncake 仓库直接提供 Transfer Engine、Mooncake Store、Python 绑定、测试和集成文档。
  • 上层框架负责请求调度、模型执行、预填充与解码工作进程的组织,以及何时复用或传输 KV 缓存。
  • 文档里的 SGLang、vLLM 和 LMCache 集成说明,是 Mooncake 能力接入上层框架的入口,但不代表所有适配逻辑都在 Mooncake 仓库里。

layer view

Mooncake 接入上层框架时,入口和职责边界要分开看

Python 绑定暴露 C++ 能力;推理框架决定何时调用;Store 和 Transfer Engine 只提供对象语义与数据传输能力。

推理服务框架

请求调度和缓存策略

SGLangvLLMLMCache调度器成本模型

Python 集成层

把框架对象转换为 Mooncake 调用

pybind11张量 API对象 APIMooncakeStore 后端

Mooncake Store

对象、元数据和副本可见性

对象键切片副本租约Segment

Transfer Engine

注册内存和搬运字节

SegmentHandleBatchTransferRDMA / TCP / 设备路径

本文作为系列附录,只回答一个问题:Mooncake 到底接在上层框架的哪里。

Python 绑定不是另一套 Store

Mooncake 的 Python API 很重要,因为上层推理框架通常不会直接调用 C++ Store Client 或 Transfer Engine API。但 Python 层并不是另一套独立实现。

它主要通过 pybind11 把 C++ 能力暴露出去:

text
Python 应用或框架
  -> mooncake.store / mooncake.engine
  -> pybind11 包装层
  -> C++ Store Client / Transfer Engine
  -> Master 与数据传输链路

Store 绑定中的 MooncakeDistributedStore 暴露初始化、挂载 Segment、读写、张量 API 和复制或移动任务等方法。Transfer Engine 绑定则暴露初始化、Segment 和同步或异步传输等能力。

所以阅读 Python 接口时,不要停留在 wheel 包表面。关键是追踪它最终调用哪个 C++ 方法:是 Store 的对象接口,还是 Transfer Engine 的传输接口。

张量 API 只是上层包装,底层仍是对象和切片

Mooncake 支持张量读写,这很容易让人以为底层就是“张量存储”。但从 Store 的角度看,张量只是上层对象的一种表达方式。

底层仍然是键、元数据、组成部分、切片、副本和 Segment。张量接口需要处理数据类型、形状、载荷范围等信息,但这些最终会被组织成 Store 可以处理的对象组成部分。

这也是零元素张量等细节会出现在 Python 绑定中的原因。空张量没有载荷,但元数据仍要表达形状和数据类型,读取时再恢复成 torch.empty(shape, dtype)。这个问题不属于 Transfer Engine;它属于 Python 张量包装层怎样把上层对象语义映射到 Store 对象。

这个例子能说明 Mooncake 集成层的定位:它不只负责语言绑定,还要把框架中的对象模型转换为 Store/Transfer Engine 可以处理的接口参数。

SGLang 有两条 Mooncake 路径

SGLang 里至少有两类 Mooncake 相关路径。

第一类是预填充与解码分离。两个阶段由不同工作进程承担后,KV 缓存需要跨节点传递。这条路径更靠近 Mooncake Transfer Engine,因为核心问题是把一段 KV 从一个工作进程搬到另一个工作进程。

第二类是 HiCache 的 L3 存储后端。它通过 HiCacheStorage 接入 MooncakeStore,把前缀 KV 页写入 Mooncake Store,再为后续请求预取回主机内存池。

从边界上看,SGLang 仍然负责模型执行和请求调度。Mooncake 提供的是把 KV Cache 从一个节点搬到另一个节点的传输能力,以及在一些路径下和 Store/缓存体系配合的基础设施。

这意味着一个重要判断:不要期待在 Mooncake 仓库中看到完整的 SGLang 调度器。Mooncake 的能力需要由 SGLang 推理引擎和调度逻辑调用,但“什么时候值得等待远端 KV 缓存,什么时候回退到重新计算,怎样在预填充和解码之间分配请求”等问题属于上层推理系统。

Mooncake 提供的是这类决策可以依赖的数据面能力。

object mapping

同样叫 Mooncake 集成,落点可能完全不同

SGLang PD 更靠近 Transfer Engine;HiCache 后端更靠近 Store;vLLM/LMCache 通常从缓存后端或对象存储的角度接入。

Mooncake 集成

同一个底层项目,接入点取决于上层系统要解决什么问题

SGLang PD

工作进程之间的 KV 传输

预填充工作进程解码工作进程共享 Transfer EngineKV 传输

SGLang HiCache L3

前缀页写入远端缓存

HiCacheStorage主机 KV 池batch_get_intobatch_put_from

vLLM / LMCache

缓存后端 / 对象存储

KV 对象命名远端缓存后端Store 客户端Transfer Engine

对 LMCache / vLLM 来说,Mooncake Store 更像缓存后端

LMCache 和 vLLM 的语境稍有不同。LMCache 本身就是围绕 KV 缓存复用构建的一层系统,Mooncake Store 可以作为后端基础之一:把 KV 缓存对象放进分布式对象缓存,再通过 Store 和 Transfer Engine 跨节点访问。

vLLM 相关文档中也会看到 MooncakeStore 与 Redis 等方案的性能对比。这类基准测试有参考价值,但要注意结论范围:具体数字依赖模型、硬件、PD 比例、网络和负载。更重要的不是“Mooncake 在所有情况下都更快”,而是它为 KV 缓存的存储和搬运提供了一条专门面向推理服务的系统路径。

从接口边界看:

text
vLLM / LMCache
  -> 缓存后端 / 对象存储抽象
  -> Mooncake Store
  -> Transfer Engine

这和 SGLang 直接强调 Transfer Engine 的 PD 传输路径不同,但底层问题仍然是 KV Cache 的命名、存储、查询和移动。

上层集成的核心是成本模型

Mooncake 把能力提供出来以后,上层框架还要回答一个更难的问题:什么时候该用它?

远端 KV 缓存不是免费资源。它可能节省预填充计算,但也会引入网络传输、元数据查询、等待和缓存命中的不确定性。对推理服务来说,关键不是“能不能传”,而是:

  • 远端 KV Cache 多大。
  • 传回来要多久。
  • 重新计算要多久。
  • 当前请求的尾延迟预算是多少。
  • 解码工作进程等待这段 KV 是否会影响其他请求。
  • 缓存本地性是否能纳入调度策略。

这些问题不完全属于 Mooncake 仓库本身,但 Mooncake 的 Store 和 Transfer Engine 是回答这些问题的基础设施。没有稳定的数据传输能力和对象语义,上层调度器也就无法可靠地评估 KV 缓存复用。

边界比入口更重要

Mooncake 接在上层框架的位置,不是一个单点 API,而是一组边界。

Python 绑定把 C++ Store 和 Transfer Engine 暴露给 Python;张量和对象包装层把上层对象转换为 Store 可处理的组成部分与切片;SGLang 更关注预填充和解码分离场景下的 KV 传输;LMCache/vLLM 更容易从缓存后端和对象存储的角度接入。

真正要避免的是把这些边界混成一句“Mooncake 支持某某框架”。支持只是入口。技术上更重要的是:上层框架在什么时机调用 Mooncake,调用的是 Store 语义还是 Transfer Engine 数据面,以及这次 KV Cache 复用在成本模型上是否真的划算。

框架集成不是单一能力

Mooncake 的价值不在于提供一个“万能 KV 缓存 API”,而是把几件底层能力做清楚:Python 可以调用 C++ Store 和 Transfer Engine;Store 能表达对象、副本和租约;Transfer Engine 能通过多种传输方式搬运远端内存。上层框架再把这些能力接进自己的运行时、调度器和缓存策略。

因此,阅读集成代码时不要只找入口函数名。更重要的是判断这次调用解决哪类问题:是在 PD 工作进程之间搬运 KV,是读写 HiCache L3 缓存页,还是通过 LMCache/vLLM 后端存取数据。落点不同,需要关注的代码路径、性能瓶颈和正确性边界也不同。

成本模型也必须留在上层。Mooncake 可以让远端 KV 变得可用,却不能替 SGLang 或 vLLM 决定当前请求是否值得等待远端命中。这个判断需要结合预填充成本、传输成本、队列状态和尾延迟预算。