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。
核心判断有四条:
- 职责分层:vLLM 决定何时查命中、分配 block、启动加载、等待完成以及失败后 fail/recompute;Mooncake TE 搬运已注册内存,Mooncake Store 提供对象化的存在性、put/get;vllm-ascend 注册 Ascend 专用 connector/backend。
- 依赖方向:vLLM/vllm-ascend connector 调用 Mooncake Python API;Mooncake 不反向依赖 vLLM 的 scheduler。Store 可以复用 TE,但 Store 与 P2P connector 不是同一个抽象。
- 异步口径:connector 对 scheduler 呈现异步命中和完成集合,但本文追到的 P2P 数据 primitive 是后台线程调用的同步
batch_transfer_sync_read/write。Mooncake TE 自身虽然另有 async API,不能据此宣称这些 connector 已使用 native async primitive。 - AIV 审计:Mooncake 的 Ascend Direct 是 ADXL;UBSHMEM 当前是 Host thread pool、ACL stream、
aclrtMemcpyAsync与 VMM/FabricMem/IPC 映射。固定源码未发现 Mooncake connector/transport 中的__aicore__、AscendC::、HcclChannelAcquire、aclshmem或 AIV Kernel。
否定性结论的边界
“未发现 AIV Kernel”只针对上述固定 revision 的公开源码。ADXL、HCCL runtime 或 FabricMem 闭源库内部如何实现,不在本次证据范围内;本文不把“公开源码未发现”扩张成“任何二进制内部绝不使用 AIV”。
四层职责¶
图 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_connector、kv_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。
源码锚点:配置、factory、scheduler 调用、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 API、Store binding、vLLM 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、后台队列和完成状态。
协议与生命周期¶
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
这里的 register 与 allocate 不是一回事:前者把一段长期存在的 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 transfer、register 与完成、逐层 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.cmake、sync executor、async 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_DEVICE、AscendC:: 与 “AIV direct UDMA/STARS” |
该仓存在明确设备侧 AIV 实现 | Mooncake 自动继承该实现 |
精确检索在 Mooncake 全仓与 vllm-ascend KV-transfer 子树未命中 __aicore__、AscendC::、HcclChannelAcquire、aclshmem 或独立 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 的证据。
接入步骤¶
以下步骤是固定源码与官方教程的最小交集,不替代目标集群的兼容性测试。
- 固定组合:记录 vLLM、vllm-ascend、Mooncake、CANN/HCCL 的版本。vLLM 固定源码要求
mooncake-transfer-engine >= 0.3.12;vllm-ascend 多机教程仍示例 Mooncake v0.3.9,二者不能直接当成完整兼容矩阵。 - 构建 Ascend transport:官方单机 PD 教程使用
cmake .. -DUSE_ASCEND_DIRECT=ON。在本文固定 Mooncake 源码中,这个开关的语义是 ADXL engine。 - 配置网络与设备:P/D 两端明确 NPU 可见设备、HCCL/GLOO/TP 网卡、可达 IP 和互不冲突的控制/TE 端口。
- 选择 connector:整请求 P2P 选
MooncakeConnectorV1;逐层流水选MooncakeLayerwiseConnector;对象化共享/复用选AscendStoreConnector。不要把三者的 completion 与失败语义混用。 - 设置 role 与拓扑:prefill 使用
kv_producer,decode 使用kv_consumer;prefill/decode的 DP/TP 配置必须与真实部署一致。 - Store 单独配置:设置
MOONCAKE_CONFIG_PATH,backend protocol 为ascend;确认 metadata 服务、buffer 注册和 FabricMem/非 FabricMem 分支。 - 先验证再压测:至少覆盖全命中、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 调用与端到端调用链为止。
