跳转至

Mooncake vLLM Ascend

导言

Mooncake 接入 vLLM 并不是把一个传输库直接塞进 attention:vLLM KVConnector 管请求和生命周期,Mooncake Transfer Engine 或 Store 管数据,vllm-ascend 再补上 NPU 地址、事件与后端适配。本文从固定 revision 的真实调用点穿刺这条链路,并专门核验一个容易混淆的问题:支持 Ascend、HCCL/RDMA 或名为 UBSHMEM 的 transport,是否等于使用 AIV Kernel 直驱?公开源码给出的答案是:不能等同,且当前没有找到 Mooncake KV 传输由 AIV Kernel 直驱的证据

结论与边界

本文固定四个源码版本:Mooncake 9bce06174d11378475e9580917ac88711e552caf、vLLM b2dd9ce73dce2ad09007d1db5c171454118981d7、vllm-ascend 37e382498c81fdbcfce8529ea1d53570e0d239a5、cann/shmem 382afa08efa801d7bca6c2645fd17e155111efcc。完整证据台账见仓库内的 Mooncake vLLM Ascend Sources.md

核心判断有四条:

  1. 职责分层:vLLM 决定何时查命中、分配 block、启动加载、等待完成以及失败后 fail/recompute;Mooncake TE 搬运已注册内存,Mooncake Store 提供对象化的存在性、put/get;vllm-ascend 注册 Ascend 专用 connector/backend。
  2. 依赖方向:vLLM/vllm-ascend connector 调用 Mooncake Python API;Mooncake 不反向依赖 vLLM 的 scheduler。Store 可以复用 TE,但 Store 与 P2P connector 不是同一个抽象。
  3. 异步口径:connector 对 scheduler 呈现异步命中和完成集合,但本文追到的 P2P 数据 primitive 是后台线程调用的同步 batch_transfer_sync_read/write。Mooncake TE 自身虽然另有 async API,不能据此宣称这些 connector 已使用 native async primitive。
  4. AIV 审计:Mooncake 的 Ascend Direct 是 ADXL;UBSHMEM 当前是 Host thread pool、ACL stream、aclrtMemcpyAsync 与 VMM/FabricMem/IPC 映射。固定源码未发现 Mooncake connector/transport 中的 __aicore__AscendC::HcclChannelAcquireaclshmem 或 AIV Kernel。

否定性结论的边界

“未发现 AIV Kernel”只针对上述固定 revision 的公开源码。ADXL、HCCL runtime 或 FabricMem 闭源库内部如何实现,不在本次证据范围内;本文不把“公开源码未发现”扩张成“任何二进制内部绝不使用 AIV”。

四层职责

Mooncake 接入 vLLM 和 vLLM Ascend 的连接器架构

自绘技术图:上半部区分 scheduler/worker、P2P PD connector、共享 KV Store connector 与 Mooncake Transfer Engine;下半部逐项审计 `USE_ASCEND_DIRECT`、`USE_UBSHMEM` 和 AIV device-kernel 证据。红色框表示固定公开源码中的未发现项,不代表闭源依赖内部不存在。

图 1 的源码锚点:vLLM factory.py L27-L75、L218-L227,base.py L124-L397;Mooncake README.md L87-L130、multi_transport.cpp L459-L509;vllm-ascend distributed/kv_transfer/__init__.py L21-L55。

vLLM KVConnector

KVTransferConfig 是入口,至少包含 kv_connectorkv_role、engine ID、IP/port、额外配置和加载失败策略。KVConnectorFactory 延迟导入 connector,并分别创建 scheduler 侧与 worker 侧对象。

scheduler 侧负责:

  • 查询外部可复用 token;异步查询未完成时可返回 None,请求暂缓调度;
  • 分配本地 KV blocks,更新 request 状态并构造 connector metadata;
  • request 结束时协调远端保存和 block 延迟释放;
  • 消费 finished/failed IDs,依据 kv_load_failure_policy 失败或重算。

worker 侧负责:

  • 注册 model runner 中 KV cache 的真实指针;
  • forward 前 bind metadata、启动加载并在需要时等待;
  • attention 后触发逐层或整请求保存;
  • 汇报异步完成、invalid block IDs,并清理本轮 metadata。

源码锚点:配置factoryscheduler 调用worker 调用

Mooncake TE 与 Store

Mooncake TE 面向已注册内存区域提供传输:注册/注销内存,allocate/submit/poll/free batch,以及同步/异步 Python binding。Mooncake Store 面向键与对象提供 batch_is_exist、批量 put/get,并可复用 TE 作为数据面。

这一区分决定了两个 connector:

  • MooncakeConnector/MooncakeConnectorV1 是 P2P 路径,metadata 描述远端 endpoint、block 与地址,数据直接在 KV cache 间搬运;
  • MooncakeStoreConnector/AscendStoreConnector 是 Store 路径,scheduler 先查 key,worker 再从 Store 取到本地 buffer 或把本地 KV 写成对象。

源码锚点:TE APIStore bindingvLLM Store worker

vllm-ascend backend

vllm-ascend 沿用 vLLM 的 protocol,而不是另造 scheduler。插件启动时向同一个 factory 注册:

  • MooncakeConnectorV1:Ascend 非 layerwise P2P;
  • MooncakeLayerwiseConnector:prefill 按层 push;
  • AscendStoreConnector:可选择 layerwise 的 Store facade;旧名 MooncakeConnectorStoreV1 映射到同一实现;
  • MooncakeHybridConnector:组合场景入口。

全局 MooncakeTransferEngine 直接导入 Mooncake,并用 protocol="ascend" 初始化。NPU KV cache 指针经该全局 TE 注册;connector 再管理 NPU event、buffer、后台队列和完成状态。

源码锚点:插件注册全局 TE

协议与生命周期

classDiagram
    class KVTransferConfig {
      kv_connector
      kv_role
      kv_load_failure_policy
    }
    class KVConnectorFactory {
      register_connector()
      create_connector()
    }
    class SchedulerConnector {
      get_num_new_matched_tokens()
      update_state_after_alloc()
      build_connector_meta()
      request_finished()
    }
    class WorkerConnector {
      register_kv_caches()
      start_load_kv()
      wait_for_layer_load()
      save_kv_layer()
      get_finished()
    }
    class MooncakeTE {
      register_memory()
      batch_transfer_sync_read()
      batch_transfer_sync_write()
    }
    class MooncakeStore {
      batch_is_exist()
      batch_get_into_multi_buffers()
      batch_put_from_multi_buffers()
    }
    KVTransferConfig --> KVConnectorFactory
    KVConnectorFactory --> SchedulerConnector
    KVConnectorFactory --> WorkerConnector
    WorkerConnector --> MooncakeTE
    WorkerConnector --> MooncakeStore
    MooncakeStore --> MooncakeTE : optional/shared data plane

图 2 的源码锚点:vLLM base.py L124-L397;上游 mooncake_connector.py L357-L569;vllm-ascend mooncake_connector.py L1567-L2146;Ascend Store ascend_store_connector.py L76-L268。

一次 request 的最小状态机可写成:

lookup external KV
  -> allocate local blocks
  -> build request/block/endpoint metadata
  -> bind worker metadata
  -> register cache once when model runner exposes pointers
  -> start load before forward
  -> wait at attention boundary when required
  -> optionally save after attention / request
  -> collect finished or invalid block IDs
  -> free, fail, or recompute

这里的 registerallocate 不是一回事:前者把一段长期存在的 KV cache 内存交给 TE/backend,后者是 scheduler 为某个请求分配逻辑/物理 blocks。metadata 则把请求 token、block IDs、远端 endpoint 与传输状态连接起来。

三条数据路径

非 layerwise P2P

上游 vLLM 的 Mooncake connector 使用后台控制通道协调两端,并在发送线程调用 batch_transfer_sync_write。vllm-ascend 的非 layerwise connector 则由 decode 接收线程调用 batch_transfer_sync_read。二者都可向 scheduler 呈现非阻塞状态,但底层调用点是同步 batch primitive。

sequenceDiagram
    participant DS as Decode Scheduler
    participant DW as Decode Worker
    participant PS as Prefill/Peer
    participant TE as Mooncake TE
    DS->>DS: external lookup / allocate blocks
    DS->>DW: request + block + endpoint metadata
    DW->>DW: start_load_kv()
    DW->>PS: control request / exchange metadata
    alt upstream vLLM Mooncake
        PS->>TE: batch_transfer_sync_write(dst KV)
    else vllm-ascend non-layerwise
        DW->>TE: batch_transfer_sync_read(src KV)
    end
    TE-->>DW: success / failed blocks
    DW-->>DS: finished IDs / invalid block IDs
    DS->>DS: continue, fail, or recompute

图 3 的源码锚点:上游 vLLM mooncake_connector.py L1598-L1627、L1752-L1876;vllm-ascend kv_p2p/mooncake_connector.py L960-L1017、L2586-L2611、L3537-L3625。

layerwise P2P

layerwise 模式把传输与 prefill 计算流水化。每层 KV 写入完成后记录 NPU event,后台线程等待可用 buffer/事件并调用 batch_transfer_sync_write,decode 侧按层消费。这减少了“等全部层完成才传”的尾部等待,但增加了 buffer 复用、层序、错误收敛和两端并行拓扑一致性的约束。

源码锚点:layerwise transferregister 与完成逐层 save

Store

flowchart LR
    Q[request tokens / cache key] --> LS[Store scheduler lookup]
    LS -->|batch_is_exist| MS[Mooncake Store]
    LS -->|hit + metadata| AW[GPU/NPU Store worker]
    AW -->|register cache/buffer| MEM[local KV memory]
    MS -->|batch_get_into_multi_buffers| MEM
    MEM -->|batch_put_from_multi_buffers| MS
    MS -.复用.-> TE[Mooncake TE]
    AW -->|finished / invalid blocks| SCH[vLLM scheduler]
    LS -->|exception| MISS[treat as cache miss]

Store lookup 异常按 miss 处理,避免把未确认对象当成命中;get 的部分失败可转成 invalid block IDs;put 多为 best-effort,失败通常记录日志并结束 Store job,而不是让前台生成永久等待。Ascend backend 同样以 block 状态返回 get 结果,并要求 Mooncake 配置使用 protocol=ascend

源码锚点:vLLM Store worker L900-L1322、L1884-L1987;vllm-ascend pool_scheduler.py L439-L545、L801-L873,pool_worker.py L708-L960、L2026-L2055,mooncake_backend.py L62-L266。

Ascend transport 与 AIV 审计

Mooncake 的构建开关已经给出第一层边界:

# 语义摘录;完整定义见固定源码
USE_ASCEND         # HCCL engine
USE_ASCEND_DIRECT  # ADXL engine
USE_UBSHMEM        # 独立 ubshmem transport

USE_ASCEND_DIRECT 路径的 sync/async executor 都在 Host C++ 构造 adxl::TransferOpDesc:同步调用 TransferSync,异步调用 TransferAsync 后再以 GetTransferStatus 收敛。源码锚点:common.cmakesync executorasync executor

USE_UBSHMEM 不能按名字自动归类为 cann/shmem AIV。固定实现的真实调用链是:

Host queue/thread pool
  -> ACL stream
  -> aclrtMemcpyAsync
  -> stream synchronize
  -> markSuccess / retry/error

remote visibility
  -> IPC export/open,或 FabricMem/VMM share handle
  -> address remap/relocation

源码锚点:UBSHMEM worker远端映射

全局检索结果应读成下面这张判定表:

观察 能证明什么 不能证明什么
Mooncake 有 HCCL/RDMA transport 可走对应 Host/runtime 数据通路 connector 内含 AIV device Kernel
vllm-ascend 用 protocol=ascend Ascend backend 已接入 Mooncake TE 底层一定是 AIV 直驱
多机教程设置 HCCL_OP_EXPANSION_MODE=AIV HCCL 运行环境选择了相关 expansion mode Mooncake connector 调用了自有 AIV Kernel
Mooncake 有 USE_UBSHMEM 存在名为 UBSHMEM 的 transport 使用 cann/shmem 的 aclshmem 设备 API
cann/shmem 出现 ACLSHMEM_DEVICEAscendC:: 与 “AIV direct UDMA/STARS” 该仓存在明确设备侧 AIV 实现 Mooncake 自动继承该实现

精确检索在 Mooncake 全仓与 vllm-ascend KV-transfer 子树未命中 __aicore__AscendC::HcclChannelAcquireaclshmem 或独立 AIV Kernel。与之相对,cann/shmem 382afa08...shmemi_device_cc_kernel.cpp L18-L40、shmem_device_mo.hpp L16-L36、shmemi_device_sdma.h L281-L306、shmemi_device_udma.h L263-L298 明确出现设备函数和 AIV direct 标记。

不要用名称代替调用证据

USE_UBSHMEM ≠ cann/shmem aclshmem device API ≠ AIV Kernel direct drive。同样,HCCL_OP_EXPANSION_MODE=AIV 是运行环境证据,不是 Mooncake KV connector 源码调用 AIV Kernel 的证据。

接入步骤

以下步骤是固定源码与官方教程的最小交集,不替代目标集群的兼容性测试。

  1. 固定组合:记录 vLLM、vllm-ascend、Mooncake、CANN/HCCL 的版本。vLLM 固定源码要求 mooncake-transfer-engine >= 0.3.12;vllm-ascend 多机教程仍示例 Mooncake v0.3.9,二者不能直接当成完整兼容矩阵。
  2. 构建 Ascend transport:官方单机 PD 教程使用 cmake .. -DUSE_ASCEND_DIRECT=ON。在本文固定 Mooncake 源码中,这个开关的语义是 ADXL engine
  3. 配置网络与设备:P/D 两端明确 NPU 可见设备、HCCL/GLOO/TP 网卡、可达 IP 和互不冲突的控制/TE 端口。
  4. 选择 connector:整请求 P2P 选 MooncakeConnectorV1;逐层流水选 MooncakeLayerwiseConnector;对象化共享/复用选 AscendStoreConnector。不要把三者的 completion 与失败语义混用。
  5. 设置 role 与拓扑:prefill 使用 kv_producer,decode 使用 kv_consumerprefill/decode 的 DP/TP 配置必须与真实部署一致。
  6. Store 单独配置:设置 MOONCAKE_CONFIG_PATH,backend protocol 为 ascend;确认 metadata 服务、buffer 注册和 FabricMem/非 FabricMem 分支。
  7. 先验证再压测:至少覆盖全命中、miss、partial failure、P/D 断连、端口冲突、传输超时以及 fail/recompute 策略,确认请求不会永久等待或误用部分 KV。

最小 P/D 配置骨架来自固定 vllm-ascend 单机教程:

{
  "kv_connector": "MooncakeConnectorV1",
  "kv_role": "kv_producer",
  "kv_port": "30000",
  "kv_connector_extra_config": {
    "prefill": {"dp_size": 1, "tp_size": 1},
    "decode": {"dp_size": 1, "tp_size": 1}
  }
}

decode 端把 kv_role 改为 kv_consumer,并使用自己的监听端口。源码/文档锚点:vllm-ascend pd_disaggregation_mooncake_single_node.md L122-L220。实际部署仍需按模型、并行度和网卡修改,不能照抄示例端口与 shape。

性能数字的可用范围

Mooncake 固定仓库中可完整复核的一组 vLLM V1 PD benchmark 条件为:16 × NVIDIA H800 81 GB、每节点 8 卡、8 × ConnectX-7 RoCE、Qwen3-8B、P/D 各 TP=8、vLLM 0.11.2.dev358、MooncakeConnector;50 个 prompt,输入随机 128–32768 tokens、输出 128、并发 1。

在 32768-token、4.50 GB KV 样本上,文档报告 31.65 ms、142.25 GB/s,为 200 GB/s 理论带宽的 71.1%,传输占 TTFT 4.2%。这里的 baseline 是理论网络带宽和 TTFT 占比,不是另一 connector 的同条件端到端对照。

源码锚点:Mooncake docs/source/performance/vllm/vllm-v1-pd-performance.md L13-L50、L54-L76、L87-L103。

不得外推到 Ascend

这组数字只属于 NVIDIA H800 + ConnectX-7 + 指定软件/workload。固定 vllm-ascend revision 没有同时给出硬件、模型/shape、版本、baseline 与测量口径的 Mooncake Ascend 数值 benchmark,因此本文不报告、也不推导 Ascend 吞吐或 TTFT。

总结

Mooncake-vLLM-Ascend 的正确心智模型不是“一个 AIV 传输算子”,而是四层协作:vLLM protocol 管生命周期,connector 管 metadata 与状态,Mooncake TE/Store 管数据,vllm-ascend 管 NPU 适配。真实源码还揭示了三个工程边界:register 不等于 request block allocation;框架异步不等于底层调用 native async API;Ascend/HCCL/RDMA/UBSHMEM 名称不等于 AIV Kernel 直驱。

在固定 revision 上可以肯定 Mooncake 已有 Ascend 数据通路,也可以肯定 vllm-ascend 已把这些通路接入 vLLM connector 生命周期;但没有公开源码证据表明当前 Mooncake KV connector/transport 由 AIV Kernel 直接驱动。这条否定性边界应保留到出现可定位的 device kernel、注册/launch 调用与端到端调用链为止。

评论