跳到内容

MooncakeStoreConnector 使用指南

MooncakeStoreConnector 是一个使用 MooncakeDistributedStore 作为共享 KV cache 池的 KV cache 连接器。与在 prefiller 和 decoder 之间进行直接点对点 KV 传输的 MooncakeConnector 不同,MooncakeStoreConnector 支持将 KV cache 卸载到外部分布式存储,并支持:

  • CPU/磁盘卸载:通过 Mooncake 的传输引擎将缓存卸载到 CPU 内存或磁盘,从而扩展有效的 KV cache 容量。
  • 跨实例的前缀缓存(Prefix caching):基于哈希的去重机制允许多个 vLLM 实例通过存储池共享缓存的 KV block。
  • 单节点和多节点部署:既可以作为独立的 KV cache 扩展使用,也可以在分离式 prefill-decode 架构中使用。

先决条件

安装 Mooncake

通过 pip 安装 mooncake

uv pip install mooncake-transfer-engine

有关更多安装说明和从源码编译的信息,请参考 Mooncake 官方仓库

启动 Mooncake Master 服务器

Mooncake master 负责管理元数据并协调分布式存储。请在启动 vLLM 之前启动它:

mooncake_master --port 50051

默认端口

  • RPC: 50051

多个 vLLM 实例可以共享同一个 master 服务器。

配置 Mooncake

创建一个 JSON 配置文件(例如:mooncake_config.json

{
  "mode": "embedded",
  "metadata_server": "P2PHANDSHAKE",
  "master_server_address": "127.0.0.1:50051",
  "global_segment_size": "80GB",
  "local_buffer_size": "4GB",
  "protocol": "rdma",
  "device_name": "",
  "enable_offload": false
}
  • mode: 拓扑选择。"embedded"(默认值,PR-40900 基准)让每个 vLLM rank 在进程内向池中贡献 global_segment_size 大小的空间。"standalone-store" 使 ranks 变为纯请求者 —— 由外部 mooncake_client 进程拥有 CPU 池和(可选的)SSD 层。
  • protocol: 使用 "rdma" 以获得最佳性能。"tcp" 可作为备选方案。
  • global_segment_size: 贡献给分布式池的 CPU 内存(每个 GPU)。在 embedded 模式下必须 > 0,在 standalone-store 模式下必须为 0
  • local_buffer_size: 该节点自身操作的私有缓冲区(每个 GPU)。
  • enable_offload: 当为 true 时,vLLM 会分配一个 DirectIO 暂存缓冲区,以便大型 prefill 不会超过所有者的 SSD 写入预算。请在 mooncake_master 和外部 mooncake_client(如果有)上同时设置匹配的 --enable_offload=true 标志。

通过环境变量设置配置路径

export MOONCAKE_CONFIG_PATH=/path/to/mooncake_config.json

用法

单节点 KV Cache 卸载

使用 MooncakeStoreConnector 将 KV cache 卸载到 CPU 内存,扩展有效缓存大小。

MOONCAKE_CONFIG_PATH=mooncake_config.json \
vllm serve meta-llama/Llama-3.1-8B-Instruct \
    --kv-transfer-config '{"kv_connector":"MooncakeStoreConnector","kv_role":"kv_both"}'

分离式 Prefill-Decode (XpYd)

在分离式 prefill-decode 模式下,使用 MultiConnectorMooncakeConnector(点对点 KV 传输)与 MooncakeStoreConnector(共享 KV cache 池)结合使用。这既实现了 prefiller 和 decoder 之间的直接 P2P 传输,又实现了通过分布式存储的跨实例前缀缓存共享。Prefiller 节点:

MOONCAKE_CONFIG_PATH=mooncake_config.json \
VLLM_MOONCAKE_BOOTSTRAP_PORT=50052 \
vllm serve meta-llama/Llama-3.1-8B-Instruct \
    --port 8100 \
    --kv-transfer-config '{
        "kv_connector": "MultiConnector",
        "kv_role": "kv_producer",
        "kv_connector_extra_config": {
            "connectors": [
                {
                    "kv_connector": "MooncakeConnector",
                    "kv_role": "kv_producer"
                },
                {
                    "kv_connector": "MooncakeStoreConnector",
                    "kv_role": "kv_both"
                }
            ]
        }
    }'

Decoder 节点

MOONCAKE_CONFIG_PATH=mooncake_config.json \
VLLM_MOONCAKE_BOOTSTRAP_PORT=50053 \
vllm serve meta-llama/Llama-3.1-8B-Instruct \
    --port 8200 \
    --kv-transfer-config '{
        "kv_connector": "MultiConnector",
        "kv_role": "kv_consumer",
        "kv_connector_extra_config": {
            "connectors": [
                {
                    "kv_connector": "MooncakeConnector",
                    "kv_role": "kv_consumer"
                },
                {
                    "kv_connector": "MooncakeStoreConnector",
                    "kv_role": "kv_consumer"
                }
            ]
        }
    }'

代理 (Proxy)

需要一个分离式代理来在 prefiller 和 decoder 节点之间路由请求。代理分配 do_remote_prefill=True / do_remote_decode=True 以协调通过 MooncakeConnector 的 P2P 传输。有关代理设置的详细信息,请参考 MooncakeConnector 使用指南

磁盘卸载

磁盘卸载通常运行在 standalone-store 模式下:一个外部 mooncake_client 进程拥有 CPU 池和 SSD 层,每个 vLLM rank 都是纯请求者。这避免了 SSD 池在每个 rank 上的重复,并将 DirectIO 预算跟踪保持在单个进程中。

端到端磁盘卸载需要对齐以下三项:

  1. mooncake_master 启动时带有 --enable_offload=true
  2. mooncake_client(所有者)启动时带有 --enable_offload=true 以及通过 MOONCAKE_OFFLOAD_FILE_STORAGE_PATH 指定的 SSD 路径。
  3. vLLM 侧 在 JSON 配置文件中设置 "enable_offload": true(这是由连接器读取的,不是环境变量)。

vLLM 侧的 mooncake_config.json 示例

{
  "mode": "standalone-store",
  "metadata_server": "P2PHANDSHAKE",
  "master_server_address": "127.0.0.1:50051",
  "global_segment_size": 0,
  "local_buffer_size": "4GB",
  "protocol": "rdma",
  "device_name": "mlx5_0",
  "enable_offload": true
}

通过以下方式将此 rank 引导至本地所有者分段:

export MOONCAKE_PREFERRED_SEGMENT=127.0.0.1:50053

所有者的 SSD 目录、磁盘逐出策略和 DirectIO 暂存缓冲区大小在 mooncake_client 端通过标准 Mooncake 环境变量(MOONCAKE_OFFLOAD_FILE_STORAGE_PATHMOONCAKE_BUCKET_EVICTION_POLICYMOONCAKE_USE_URINGMOONCAKE_OFFLOAD_LOCAL_BUFFER_SIZE_BYTESMOONCAKE_OFFLOAD_TOTAL_SIZE_LIMIT_BYTES 等)进行控制。这些独立于 vLLM 的 JSON 配置。

环境变量

可变 描述 默认值
MOONCAKE_CONFIG_PATH Mooncake JSON 配置文件路径 (必填)
VLLM_MOONCAKE_BOOTSTRAP_PORT MooncakeConnector P2P 传输的引导端口(仅限分离模式) 8998
MOONCAKE_PREFERRED_SEGMENT 将此 rank 的副本固定到特定的所有者分段 (host:port);用于 standalone-store 模式
MOONCAKE_REQUESTER_LOCAL_HOSTNAME 覆盖 vLLM rank 作为请求者在 Mooncake 注册时使用的主机名。默认为该 rank 解析后的 IP。
VLLM_MOONCAKE_STORE_TIER_LOG 当设为 1 时,记录每批次的层级摘要(内存 vs 磁盘命中情况)以供观测 已禁用
VLLM_MOONCAKE_DISK_STAGING_USABLE_RATIO 请求者在单次 batch_get_into_multi_buffers 调用中将填充的所有者 DirectIO 暂存缓冲区的比例。较低的值 → 更保守的预拆分,更多的往返次数。 0.9

KV 传输配置

KV 角色选项

  • kv_producer:用于将 KV caches 存储到池中的实例。
  • kv_consumer:用于从池中加载 KV caches 的实例。
  • kv_both:实例既存储又加载 KV caches。适用于单节点 CPU 卸载或 prefiller 实例。

kv_connector_extra_config

  • load_async (bool): 启用异步加载以获得更好的计算-I/O 重叠。默认值:true
  • lookup_async (bool): 在后台线程上运行外部前缀缓存查找,使其永远不会阻塞调度步骤。请求将被挂起,直到正在进行的查找完成,然后在稍后的步骤中恢复。默认值:false
  • enable_cross_layers_blocks (bool): 启用跨层 block 打包以减少存储操作。默认值:false
  • lookup_rpc_port (int): ZMQ 查找 RPC 套接字的自定义端口。默认值:0
  • cache_prefix (str): 在每个存储键前添加的命名空间。允许不同的部署共享一个 Mooncake master 而不互相干扰 —— 配置了不同前缀的实例永远看不到彼此缓存的 block,即使对于完全相同的 prompt 也是如此。所有应该共享前缀缓存的实例必须使用相同的值。默认值:""(无前缀;键与未加前缀的格式按字节一致)。

注意事项

跨进程的可重现 Block Hash

MooncakeStoreConnector 依赖于共享分布式存储的所有 vLLM 进程之间一致的 block hash。由于 Python 默认在每个进程中随机化其 hash 种子,相同的 prompt 在不同进程中可能会产生不同的 block hash —— 从而阻止跨进程的前缀缓存命中。

在共享存储的所有实例(DP ranks、独立的 prefiller/decoder 节点以及任何其他指向同一 Mooncake 存储的 vLLM 进程)上设置固定的 PYTHONHASHSEED

PYTHONHASHSEED=0 vllm serve ...