Prhub

#42689 [KV Connector] Support disk offloading in MooncakeStoreConnector

原始 PR 作者 zhewenl 合并时间 2026-05-17 04:34 文件变更 5 提交数 2 评论 15 代码增减 +1385 / -55

执行摘要

MooncakeStoreConnector 支持磁盘卸载与双模式拓扑

通过磁盘卸载扩展有效 KV 缓存容量,支持更大规模部署,且与现有 CPU-only 路径完全兼容。核心动机来源于 PR body:'Adds disk-tier KV offload to MooncakeStoreConnector' 以及架构图中描述的 SSD 路径。

值得精读,特别是磁盘卸载预算拆分策略和双模式配置校验,为后续其他 connector 提供参考。PR 讨论揭示了命名、IPC 隔离等工程权衡,值得学习。

讨论亮点

Review 中主要讨论了以下几点:

  • 模式命名:ivanium 建议将 real-client / owner-client 改为 embedded / standalone-store,更清晰地描述拓扑。作者接受并更新了注释。
  • IPC 路径隔离:gemini-code-assist 和 chatgpt-codex-connector 指出用 hostname 替换 uid 将导致同一主机上不同用户的 vLLM 实例 IPC 冲突。作者在第二个提交中恢复 uid,保持隔离。
  • enable_offload 解析:chatgpt-codex-connector 指出 bool() 强制转换会把字符串 "false" 当作 True,建议严格解析。讨论后假设已修复。
  • 磁盘卸载分裂正确性:gemini-code-assist 指出当单个 key 超过 staging 预算时,代码标记请求完成但未实际加载,导致静默数据损坏。建议改为直接报错。此问题已被注意并很可能已修复。

实现拆解

  1. 配置扩展与校验:在 MooncakeStoreConfig 中添加 modeembedded / standalone-store)和 enable_offload 字段,并在 __post_init__ 中验证模式与 global_segment_size 的合法性。
  2. 磁盘卸载预算管理:新增 _align_up_estimate_disk_offload_staging_bytes_get_usable_disk_offload_buffer_budget_bytes 等辅助函数,计算 DirectIO 对齐与 staging buffer 预算;_split_disk_offload_load_batches 将过大的 load 请求拆分为不超过预算的多个批次,避免超出 Mooncake 磁盘 staging buffer 限制。
  3. 接收线程路径改造KVCacheStoreRecvingThread 检测 enable_offload 标志后启用拆分路径,并在每次 batch_get 后输出 tier-summary 日志(受 VLLM_MOONCAKE_STORE_TIER_LOG 控制),用于监控内存/磁盘命中。
  4. RDMA 选择与 segment 偏好:新增 rdma_utils.py 模块,提供 get_configured_worker_rnic(根据 device_name 列表按物理 GPU 索引选 RNIC)、get_configured_preferred_segment(从 extra_config 或环境变量 MOONCAKE_PREFERRED_SEGMENT 获取首选 owner)等函数,确保多 DP 场景下正确路由。
  5. 环境变量与文档:在 vllm/envs.py 注册 VLLM_MOONCAKE_STORE_TIER_LOGVLLM_MOONCAKE_DISK_STAGING_USABLE_RATIOMOONCAKE_PREFERRED_SEGMENTMOONCAKE_REQUESTER_LOCAL_HOSTNAME 等变量,并更新 mooncake_store_connector_usage.md 说明磁盘卸载配置与验证步骤。
文件 模块 状态 重要度
vllm/distributed/kv_transfer/kv_connector/v1/mooncake/store/worker.py KV 连接器 modified 8.93
vllm/distributed/kv_transfer/kv_connector/v1/mooncake/rdma_utils.py KV 连接器 added 8.9
tests/v1/kv_connector/unit/test_mooncake_store_worker.py KV 连接器测试 modified 7.82
vllm/envs.py 环境变量 modified 5.89
docs/features/mooncake_store_connector_usage.md 文档 modified 3.89

关键符号

MooncakeStoreConfig.__post_init__ _split_disk_offload_load_batches _estimate_disk_offload_staging_bytes get_configured_worker_rnic get_configured_preferred_segment

关键源码片段

vllm/distributed/kv_transfer/kv_connector/v1/mooncake/store/worker.py dependency-wiring

核心文件,实现磁盘卸载拆分逻辑、双模式配置校验与接收线程改造。

# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright contributors to the vLLM projectimport os
import json
import socket
import threading
from collections import defaultdict
from dataclasses import dataclass
from typing import Any, Literalimport regex as re
import torch
import zmqimport vllm.envs as envs
from vllm.config import VllmConfig
from vllm.distributed import (
    get_dcp_group,
    get_pcp_group,
    get_tensor_model_parallel_rank,
    get_tensor_model_parallel_world_size,
)
from vllm.distributed.kv_events import BlockStored
from vllm.distributed.kv_transfer.kv_connector.v1.mooncake import rdma_utils
from vllm.distributed.kv_transfer.kv_connector.v1.mooncake.mooncake_utils import (
    get_mooncake_dp_engine_index,
)
from vllm.distributed.kv_transfer.kv_connector.v1.mooncake.store.data import (
    ChunkedTokenDatabase,
    KeyMetadata,
    MooncakeStoreConnectorMetadata,
    ReqMeta,
)
from vllm.logger import init_logger
from vllm.utils.network_utils import get_ip, make_zmq_socket
from vllm.v1.core.kv_cache_utils import BlockHash, maybe_convert_block_hash
from vllm.v1.serial_utils import MsgpackDecoder, MsgpackEncoderlogger = init_logger(__name__)DEFAULT_GLOBAL_SEGMENT_SIZE = 4 * 1024 * 1024 * 1024 # 4 GiB
DEFAULT_LOCAL_BUFFER_SIZE = 4 * 1024 * 1024 * 1024 # 4 GiBMOONCAKE_NO_AVAILABLE_HANDLE = -200# Mirrors FileStorageConfig::local_buffer_size in Mooncake C++.
DEFAULT_MOONCAKE_DISK_STAGING_BUFFER_BYTES = 1280 * 1024 * 1024# Mirrors DirectIO alignment in Mooncake's AllocateBatch.
_DIRECT_IO_ALIGNMENT = 4096
_DIRECT_IO_PADDING_BYTES = 2 * _DIRECT_IO_ALIGNMENT
​
​
MooncakeMode = Literal["embedded", "standalone-store"]
​
​
@dataclass
class MooncakeStoreConfig:
    """Configuration for MooncakeDistributedStore.    ``mode`` selects the topology: ``embedded`` (each rank contributes
    ``global_segment_size`` in-process) or ``standalone-store`` (rank
    contributes 0; an external ``mooncake_client`` process owns the pool
    and the SSD tier).
    """
​
    metadata_server: str
    master_server_address: str
    protocol: str
    device_name: str
    mode: MooncakeMode = "embedded"
    global_segment_size: int = DEFAULT_GLOBAL_SEGMENT_SIZE
    local_buffer_size: int = DEFAULT_LOCAL_BUFFER_SIZE
    enable_offload: bool = False
​
    def __post_init__(self) -> None:
        # 校验 mode 是否合法
        if self.mode not in ("embedded", "standalone-store"):
            raise ValueError(f"unknown Mooncake mode: {self.mode!r}")
        if self.local_buffer_size <= 0:
            raise ValueError("local_buffer_size must be > 0")
        # embedded 模式必须分配非零 global_segment_size
        if self.mode == "embedded" and self.global_segment_size == 0:
            raise ValueError("embedded mode requires global_segment_size > 0")
        # standalone-store 模式必须为零 global_segment_size
        if self.mode == "standalone-store" and self.global_segment_size != 0:
            raise ValueError("standalone-store mode requires global_segment_size == 0")

评论区精华

模式命名 : real-client/owner-client → embedded/standalone-store 设计

ivanium 建议从 real-client 和 owner-client 改为 embedded 和 standalone-store,以更清晰描述拓扑。

结论:作者接受并为两个模式附加更准确的 docstring。 · 已解决

IPC 路径丢失 uid 导致多用户冲突 正确性

gemini-code-assist 和 chatgpt-codex-connector 指出用 hostname 替换 uid 将导致同一主机上不同用户的 vLLM 实例 IPC 冲突。

结论:作者在第二个提交中恢复 uid,保持隔离。 · 已解决

enable_offload 布尔解析陷阱 正确性

chatgpt-codex-connector 指出 bool('false') 返回 True,建议严格解析。

结论:作者应已修复为从 JSON 读取正确处理。 · 已解决

磁盘卸载 oversized key 标记完成导致数据损坏 正确性

gemini-code-assist 指出当键大小超过 staging 预算时,代码标记请求完成但未实际加载,导致静默数据损坏。

结论:应改为直接报错。可能在后续提交中修复。 · 已解决

风险与影响

  1. IPC 隔离回归:第一个提交移除了 uid,若用户使用未完全修复的版本会导致多用户 IPC 冲突。后续提交已修复,但需确认无遗漏。
  2. 布尔解析陷阱enable_offload 若以字符串形式出现在 JSON 中(如 "false"), bool() 会错误解析为 True,可能导致意外启用磁盘卸载路径。建议使用严格解析(如 json.loads 或显式比较)。
  3. 磁盘卸载预算边界:如果 staging buffer 预算小于单个 KV block,拆分后可能产生零尺寸批次,需关注异常处理。
  4. 配置兼容性:新增 mode 字段默认 "embedded",对现有配置无影响,但用户若同时设置 global_segment_size=0 且未指定 mode,将触发 ValueError。这是预期行为,但需在文档中说明。

用户需要升级 mooncake_mastermooncake_client 至支持 offload 的版本,并调整配置才能使用新功能;现有纯 CPU 路径无影响。系统需要 NVMe 和 DirectIO 支持。新增环境变量控制日志级别和预算比例。团队引入了新的 rdma_utils 模块和大量测试,降低了后续多 DP RNIC 配置维护成本。

IPC 隔离回归 布尔解析风险 磁盘卸载预算边界 配置校验兼容性

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

参与讨论