Mooncake Ascend Transports
本文以 Mooncake main 在 2026-08-25 的提交 43365d45 为代码截面,并沿已合入 PR、关联 Issue、Mooncake 当前文档、CANN API 文档、HiXL 与 CANN SHMEM 开源代码交叉核验。为避免把不同强度的证据混在一起,正文使用以下标记:
- 事实:PR、Issue、文档或源码能够直接支持。
- 推断:由多个事实推出,但项目没有直接宣告。
- 判断:面向选型或未来演进的分析,依赖给定前提。
核心结论
先把容易混乱的名称拆开:
USE_ASCEND是第一代 HCCL 低层传输实现。它不是用AllReduce等集合通信搬 KV,而是复用 HCCL 内部的TransportMem、内存注册、建链和Read/Write能力,给 Transfer Engine 提供一边读写。Mooncake 当前文档已明确把它标为待废弃路径。USE_ASCEND_DIRECT是第二代 ADXL/HiXL 抽象。Mooncake 把内存注册、连接和同步/异步传输委托给adxl::AdxlEngine,由库选择 HCCS、RDMA 等链路。当前 Mooncake 文档推荐新部署使用这条路径。USE_UBSHMEM是 Fabric Memory 专用路径。它用 CANN VMM API 分离物理内存、虚拟地址和共享句柄,把对端 Fabric Memory 映射进本地虚拟地址空间,再通过 ACL 异步拷贝读写。它是对 Ascend Direct 的补充,而不是 HCCL 的第三种 engine。- 三者在构建上基本是替代关系。公共选项看起来可以分别打开,但 Ascend transport 子目录用
if / elseif / else选择一套源文件;运行时ascend也会在 Direct 与 HCCL 实现之间二选一,ubshmem才拥有独立协议名。不要把“独立 CMake 选项”误解为“同一进程可同时叠加三种后端”。 - 三者都不是当前源码意义上的 AIV 直驱。Mooncake 可见提交点分别在 Host worker 或 Host API:HCCL 路径调用
TransportMem::Write/Read,Direct 路径调用AdxlEngine::TransferSync/TransferAsync,UBShmem 路径调用aclrtMemcpyAsync。没有看到 AIV Kernel 在 Device 侧准备 WQE/SQE、敲 doorbell 并推进完成队列。
可以先用一张结论表定住坐标:
| 构建选项 | Mooncake 角色 | 主要抽象 | 可见提交者 | 当前定位 | 是否可据此称为 AIV 直驱 |
|---|---|---|---|---|---|
USE_ASCEND |
旧 Ascend transport | HCCL TransportMem RMA |
Host worker + ACL stream | 兼容旧环境,待废弃 | 否;至少没有直接证据 |
USE_ASCEND_DIRECT |
推荐的通用 Ascend transport | ADXL/HiXL 一边传输引擎 | Host 调用 AdxlEngine::Transfer* |
通用主路径 | 否;Direct 不等于 AIV Direct |
USE_UBSHMEM |
Fabric Memory 专用 transport | CANN VMM + Fabric/IPC handle + ACL copy | Host worker 调用 aclrtMemcpyAsync |
特化补充路径 | 否;是远端映射,不是 AIV 提交 |
关键时间线
这条时间线不是简单罗列版本,而是展示每次引入解决了上一阶段的什么问题。
| 时间 | 事件 | 直接变化 | 动机与意义 |
|---|---|---|---|
| 2025-06-16 至 07-01 | PR #502 合入 | 引入 USE_ASCEND、HCCL 相关依赖、内存注册、连接与 D2D 传输 |
先让 Transfer Engine 在 Ascend 上可用;复用 HCCL 的 HCCS/RoCE 能力,而不是从零实现传输栈 |
| 2025-07-12 至 07-18 | PR #619 合入 | 增加批量同步传输、Debian 支持与修复 | 早期路径进入性能与可部署性修整;PR 报告 128 KB 非连续块批传带宽较逐次 transferSync 提升超过 100% |
| 2025-08-06 | Issue #719 提出 | 要求原生高性能零拷贝 P2P,覆盖 Device RDMA、SDMA、Host RDMA 与 A2/A3 异构场景 | 说明项目需要的不只是“Ascend 可用”,而是一个更完整、稳定的直传产品抽象 |
| 2025-08-13 至 08-18 | PR #740 合入 | 引入 USE_ASCEND_DIRECT 与 Ascend Direct transport |
将链路选择、内存注册、同步/异步请求等交给 ADXL,减少 Mooncake 自己维护 HCCL 私有式传输拼装 |
| 2025-08 至 09 | PR #764、PR #856 | 适配 ADXL 错误码、CANN 版本并修复 TCP 端口问题 | Direct 从原型进入版本兼容和连接可靠性修复阶段 |
| 2025-10 至 11 | HiXL 开源;PR #1037、PR #1049 | Mooncake 曾引入 hixl transport 名称,随后改回对外名称 Ascend Direct |
表明底层产品从 ADXL 向 HiXL 演进,但 Mooncake 希望稳定用户面对的 transport 名称 |
| 2025-12-05 至 12-27 | PR #1170 合入 | Store 的 Ascend Direct 支持 Fabric Memory 模式与特殊 Host 分配 | Fabric Memory 先作为 Direct 的一种能力进入 Store,早于独立 UBShmem transport |
| 2025-12-31 | Issue #1312 提出 | 建议用 CANN VMM API 支持 Fabric Memory,作为 Ascend Direct 的 NVLink-like 补充 | 目标从“通用直传 API”进一步下沉到“远端内存可映射”的内存语义 |
| 2026-01-18 至 01-26 | PR #1399 合入 | 新增 USE_UBSHMEM、UBShmemTransport、VMM Fabric handle 与准确性测试 |
将 Fabric Memory 明确成独立协议和专用数据路径,并暴露独立构建开关 |
| 2026-02-09 至 02-14 | PR #1519 合入 | MC_USE_UBSHMEM_IPC=1、Fabric allocator 和 Python NPU pluggable allocator |
从 Fabric handle 扩展到同机跨进程 IPC,并解决上层框架如何获得可共享内存的问题 |
| 2026-03-02 | PR #1591 合入 | 8 个 worker、每请求 4 个 stream 的 stream pool;接入 Store 的 ubshmem 协议 |
修补单 stream/串行同步带来的并行度不足,并把独立 transport 变成 Store 可用能力 |
| 2026-07 至 08-05 | PR #3214 合入 | Fabric 内存从 100% 逐步回退到 50% 容量申请,1 GiB 对齐,优先 ADXL 分配能力 | Fabric Memory 的现实瓶颈不只在带宽,还包括大页粒度、连续容量、碎片和启动成功率 |
两个 Issue 的状态容易制造误读:#719 和 #1312 后来都因 stale 流程被标记为 not_planned 或关闭,但其核心能力分别已通过 #740 和 #1399 合入。Issue 的最终状态是项目管理状态,不是“功能从未实现”的证据。
三次演进的动机
先解决可用性
第一阶段的约束很现实:Mooncake Transfer Engine 已经有统一的内存注册、segment metadata、batch transfer 和状态轮询接口,但 Ascend 端缺少一个可以直接接上的公开后端。PR #502 选择复用 HCCL 的低层传输组件:
- 同 HCCS 域内可建立 IPC 类路径,跨 HCCS 域使用 RoCE 类路径。
- 注册本地内存并把可访问信息传播给远端。
- 把 Transfer Engine 的读写切片翻译为
TransportMem::Read/Write。 - 用 ACL stream 和同步接口管理执行顺序与完成状态。
事实:当前旧实现仍能在 hccl_transport.cpp 与 hccl_transport_mem_c.cpp 中看到:worker 创建 ACL stream,内存层初始化 HCCL dispatcher,根据拓扑创建 TransportMem,最终把请求落实到 Write/Read。
推断:它适合作为最快接通既有 HCCL 软硬件生态的桥梁,但 Mooncake 需要自己管理较多 HCCL 低层对象、版本差异和边界条件。随着支持范围扩大,这套实现的维护成本会高于使用专门的一边传输产品接口。
再解决通用抽象
Issue #719 期望同时覆盖 HBM/DDR、Device RDMA、SDMA、Host RDMA、同构和异构部署。这样的矩阵已经不适合由 Mooncake 针对每条链路分别拼装。
Ascend Direct 因此把接口收敛为:
1 | Initialize engine |
在当前 Mooncake 源码中,transfer_executor_base.cpp 创建 adxl::AdxlEngine,负责初始化、注册内存与连接;async_transfer_executor.cpp 组装 adxl::TransferOpDesc 并调用 TransferAsync。Mooncake 不再直接决定每一次 HCCS、RDMA 或中转 buffer 细节,而是消费 ADXL 的一边通信能力。
当前 HiXL 仓库把旧接口放在“待废弃 ADXL 接口”下,同时提供新的 HIXL API。这表示 ADXL 是可见 API 的旧名字,HiXL 是正在演进的产品与接口层。Mooncake 的构建选项仍叫 USE_ASCEND_DIRECT,源码仍使用 adxl::AdxlEngine,所以不能仅凭上游仓库名称就声称 Mooncake 已完成 HIXL 新 API 迁移。
最后解决内存语义
通用一边传输通常仍然遵循“注册本地与远端内存,提交一条包含两端地址的传输描述符”的模型。Fabric Memory 希望进一步提供类似统一内存窗口的体验:
1 | 远端物理内存 |
这就是 Issue #1312 所称的 “NVLink-like Transport”。这里的 “like” 更准确地说是 远端内存的可映射性和地址使用方式相似,并不自动承诺与 NVIDIA NVLink 相同的缓存一致性、拓扑、指令集、带宽或故障语义。
独立 UBShmem path 的实际价值包括:
- 数据路径更专用:不再为每次传输调用 Mooncake 中的 ADXL
Transfer*,而是先完成映射,再用 ACL runtime 对映射地址做异步 copy。 - 元数据更直接:传递的是 Fabric/IPC shareable handle、基址和长度,接收端导入后按 offset 重定位。
- Allocator 可配套:上层必须从一开始就分配可导出的物理内存,不能把普通
aclrtMalloc的任意 buffer 事后变成 Fabric Memory。 - 可独立优化并行度:PR #1591 用 worker 和 stream pool 改善大量 KV block 的批量传输。
推断:UBShmem 并不是为了证明 ADXL/HiXL 做不到 Fabric Memory。PR #1170 已证明 Direct 也有 Fabric 模式。它更像是把 Fabric Memory 从“通用引擎的一种内部能力”提取成 Mooncake 能显式选择、单独分配和单独调优的快路。
横向对比
架构差异
| 维度 | USE_ASCEND |
USE_ASCEND_DIRECT |
USE_UBSHMEM |
|---|---|---|---|
| 对外 protocol | ascend |
ascend |
ubshmem |
| Mooncake 类 | HcclTransport |
AscendDirectTransport |
UBShmemTransport |
| 建链抽象 | HCCL socket、dispatcher、TransportMem |
AdxlEngine::Connect |
元数据通道分发 handle;导入与映射远端物理内存 |
| 内存准备 | HCCL memory registration/export/grant | AdxlEngine::RegisterMem |
aclrtMallocPhysical、Reserve、Map、SetAccess、Export/Import |
| 单次提交 | TransportMem::Write/Read |
TransferSync/TransferAsync |
aclrtMemcpyAsync |
| 完成方式 | ACL stream 同步与 Mooncake slice 状态 | ADXL request/同步接口 | stream pool 同步后标记 slice 完成 |
| 链路选择 | Mooncake/HCCL 低层逻辑处理 IPC、RoCE 等 | ADXL/HiXL 根据能力与配置选择 HCCS/RDMA 等 | ACL/Fabric Memory runtime;公开 Mooncake 层不直接说明物理搬运 engine |
| Host 内存支持 | 取决于旧实现能力 | 文档明确覆盖 H2D、D2H、D2D | 核心目标是可导出/映射的 Device Fabric Memory,不是通用 Host RDMA |
| 跨机通用性 | 可用但维护负担较高 | 三者中最通用 | 依赖 Fabric Memory 可达域、芯片与 CANN/驱动能力 |
| 当前定位 | 文档提示废弃 | 推荐主路径 | 特化补充与实验/优化路径 |
Mooncake 的 common.cmake 同时声明三个开关,但 ascend_transport/CMakeLists.txt 使用条件分支选择 HCCL、异构 HCCL、UBShmem 或 Direct 源文件;multi_transport.cpp 再把运行时协议映射到具体类。
使用场景
可以按问题而不是按名字选后端:
- 新部署需要跨节点、Host/Device 多种方向和通用容错:优先 Ascend Direct,除非当前 CANN/驱动组合只验证过旧 HCCL path。
- 必须兼容已有旧版本环境:保留
USE_ASCEND,但应把迁移 Direct 纳入计划,因为 Mooncake 当前 Ascend Transport 文档 已明确提示废弃。 - A3 Fabric Memory 域内大量 KV block 搬运,能够控制 allocator 与进程模型:可以评估 UBShmem,并与 Direct Fabric mode 做同硬件 A/B,而不是只和非 Fabric Direct 对比。
- 目标是让算子 Kernel 自己发起细粒度通信:这三个开关都不是充分条件,应调研 CANN SHMEM/URMA 的 Device API 或 HCCL AIV 通信 engine,并重新设计 Transfer Engine 的 Device 侧队列与完成机制。
当前 Mooncake 构建文档 对 UBShmem 给出的环境门槛包括 CANN 9.0.0 及以上、Driver 26.0.0 及以上和 Lingqu 1.5 及以上。它不是仅打开一个 CMake 开关就能在任意 Ascend 机器上工作的通用共享内存。
概念坐标
这部分先用小白语言建立直觉,再用专业定义校正。
小白版
把两张 NPU 卡想成两个仓库:
- 一边通信:A 仓库发出“把这批货放到 B 的 3 号货架”,不要求 B 的管理员为这一次请求同步调用一个
recv。 - 零拷贝:货物尽量从注册的源货架直接运到目标货架,中间不再落到临时仓库倒一次。
- Direct transport:运输公司根据两地条件选择内部高速通道或跨园区道路,用户只提交起点、终点和长度。
- Fabric Memory:B 仓库把某些货架以安全凭证共享给 A;A 在自己的地址簿里给这些货架安排一个可用地址。
- AIV 直驱:A 仓库的现场工人不再每搬一小批货都去找办公室调度员,而是自己填写运输队能识别的工作单并按门铃提交。
这五件事可以组合,却不互相蕴含。货架能出现在本地地址簿里,不代表现场工人拥有提交运输任务的权限;运输不落临时仓库,也不代表 Host 没有参与下发。
专业版
| 概念 | 严格问题 | 不保证什么 | Mooncake 对应 |
|---|---|---|---|
| One-sided / RMA | 一次远端读写是否要求对端 CPU 同步参与匹配操作 | 不保证没有 Host 发起,不保证零拷贝 | HCCL TransportMem、ADXL、Fabric 映射都可表现为一边访问 |
| Zero-copy | 数据是否避免额外 bounce buffer 或 CPU staging copy | 不保证没有内存注册、描述符和控制面 | Direct 在满足注册与链路条件时可直传;小块或未注册内存可能走 buffer pool |
| Direct transfer | 已注册的源/目的内存是否通过 HCCS/RDMA/SDMA 等直接搬运 | 不保证提交者是 AIV | USE_ASCEND_DIRECT 的核心语义 |
| VMM | 物理内存、虚拟地址、映射、权限和共享 handle 是否可分别管理 | 不定义传输协议,也不定义完成同步 | USE_UBSHMEM 的内存基础 |
| Fabric Memory | 远端或共享物理内存是否能被导出、导入并映射到参与者地址空间 | 不自动提供缓存一致性或任意拓扑可达性 | Direct Fabric mode 与 UBShmem 都涉及 |
| AIV 直驱 | AIV Kernel 是否在 Device 侧准备并提交通信任务,绕开 Host/AICPU 高频中介 | 不代表 AIV 亲自搬字节,也不保证链路峰值更高 | 当前三条 Mooncake 路径均缺少这一证据 |
CANN VMM 双层解释
小白版:货架与地址簿
传统 aclrtMalloc 像是一次性拿到“货架 + 仓库地址”的组合。VMM 把这件事拆成多个可控制对象:
- 查询粒度:先问仓库一排货架最小要按多大单位租。
- 申请物理内存:
aclrtMallocPhysical真正租下一批货架,返回的不是普通指针,而是物理内存 handle。 - 预留虚拟地址:
aclrtReserveMemAddress在本进程地址簿里留出一段连续门牌号,此时门牌后面还没有货架。 - 建立映射:
aclrtMapMem把门牌号绑定到物理货架。 - 设置权限:指定哪些 Device 可以读写这段映射。
- 导出凭证:把物理内存 handle 转成可跨进程或跨 Fabric 传递的 shareable handle。
- 远端导入:另一进程拿到凭证后恢复物理内存 handle,在自己的地址簿里预留地址并映射。
两边的虚拟地址不必相同。因此,发送端告诉接收端的不应只是一枚裸指针,而应包含:共享 handle、原始基址、长度、设备与协议属性。接收端导入后根据偏移重定位:
$$
remote_mapped_addr = local_mapping_base + (requested_addr - exported_base)
$$
这个比喻在三个地方会失效:
- 映射不是普通 CPU 共享内存,不应假设硬件缓存自动一致。
- 地址可表达不等于任意节点都物理可达;拓扑、芯片、驱动和 Fabric 域仍有限制。
- copy API 返回或入队不等于数据已经完成;必须使用 stream/event/request 等完成机制建立生命周期边界。
专业版:对象与生命周期
CANN 官方 aclrtMallocPhysical 文档明确说明:接口申请 Device 物理内存并返回 handle,可与 Reserve/Map 配合获得连续虚拟地址,也可与 Export/Import 配合实现多进程物理内存共享。Mooncake UBShmem 在此基础上增加了远端 metadata、地址重定位、worker 与完成状态。
一段 Fabric Memory 的完整生命周期可写成:
1 | 查询 allocation granularity |
这条路径中至少有五类对象不能混为一谈:
| 对象 | 作用 | 生命周期错误的后果 |
|---|---|---|
| Physical handle | 代表一段实际 Device 物理内存 | 过早 release 会使所有映射失效 |
| Virtual address range | 当前进程的地址表达 | 不能跨进程直接复用裸地址;需要重定位 |
| Shareable handle | 把物理内存能力传给其他参与者 | 泄漏会扩大未授权访问面 |
| ACL stream/event | 建立 copy 顺序与完成边界 | 入队即标成功会造成上层复用或释放未完成 buffer |
| Mooncake segment metadata | 连接协议名、engine、handle、base 与 size | 过期或拓扑变化会导致错误导入、越界或不可达 |
PR #1399 的 review 恰好暴露了两个关键工程边界:
- 初版在
aclrtMemcpyAsync入队后过早markSuccess();review 后改为同步 stream 再标记完成。这说明 VMM 解决寻址,不能替代完成语义。 - 导出使用
ACL_RT_VMM_EXPORT_FLAG_DISABLE_PID_VALIDATION,review 指出它可能扩大 handle 的导入范围。这说明 可共享性越强,能力凭证的分发与隔离越重要。
PR #1519 增加 IPC mode,又进一步说明 Fabric 与 IPC 是 handle 类型和可达域的选择,不是单一的“共享内存开关”。PR #3214 则通过 100%、90% 逐级回退到 50% 的 best-effort 分配,说明大页对齐、连续容量和碎片会直接影响系统是否能启动。
映射关系
| 比喻 | 技术对象 | 对应 Mooncake 行为 |
|---|---|---|
| 物理货架 | aclrtDrvMemHandle 背后的 Device physical memory |
Fabric allocator 申请可导出的大页物理内存 |
| 本地门牌 | reserved virtual address | 每个进程分别保留地址,数值不要求相同 |
| 门牌绑定货架 | aclrtMapMem |
使本地 VA 指向导入的本地或远端物理内存 |
| 仓库通行证 | Fabric/IPC shareable handle | 经 Mooncake metadata 交给对端导入 |
| 访问名单 | aclrtMemSetAccess |
授予目标 Device 对映射区域的访问权限 |
| 搬运单 | aclrtMemcpyAsync 参数 |
指定 read/write 的本地地址、映射地址和长度 |
| 确认回执 | stream/event/request completion | 完成后才能让上层复用、释放或消费 KV block |
是否属于 AIV 直驱
判定标准
本仓库已有文章 AIV Direct Drive 对概念做过完整说明。这里把判据压缩成四个可检查问题:
- 是否存在运行在 AIV/Vector Core 上的 Device Kernel?
- 通信描述符、WQE 或 SQE 是否由该 Kernel 在 Device 侧准备?
- 是否由 AIV 执行 doorbell 或等价提交,而不是每次回到 Host/AICPU?
- 完成状态是否能在 Device 侧被观察并继续推进计算/通信流水?
满足 one-sided、zero-copy、VMM 或 Fabric Memory 都不能代替这四项。
真正的对照证据可以在 CANN SHMEM 开源代码中看到。以 2026-08-25 的 dca9886a 提交为截面,SDMA Device helper 明确写有 AIV direct STARS、准备 SQE 并 ring doorbell;UDMA Device helper 和 RDMA Device backend 则明确出现准备 WQE 与 ring doorbell。这类代码才是 AIV 直驱的强证据。
USE_ASCEND
结论:不能认定为 AIV 直驱,按 Mooncake 可见实现应归为 Host 驱动的 HCCL 低层 RMA。
调用链大致是:
1 | Mooncake Host worker |
HCCL 本身支持 AIV communication engine;例如 HCCL_OP_EXPANSION_MODE=AIV 可让特定通信算子在 AI Vector Core 展开。vLLM Ascend 的调优文档 也把 AIV engine 描述为 Vector Core 直接调度 RoCE、减少 AICPU 中介。但这不能反向证明 Mooncake 的 TransportMem::Write/Read 自动走 AIV:
- Mooncake 不是在此路径调用已声明 AIV expansion 的
AllReduce/AlltoAll等 collective。 - 当前源码未设置 AIV expansion mode,也未启动可见的 AIV 通信 Kernel。
TransportMem内部可能随闭源库版本选择不同执行机制,但“可能”不能作为架构归类证据。
因此更严谨的说法是:HCCL path 可能复用某些与 HCCL engine 共用的底层能力,但没有证据表明它是 AIV 发起的传输。
USE_ASCEND_DIRECT
结论:不是 Mooncake 接口层的 AIV 直驱;它是 Host 调用 ADXL/HiXL 的一边直传。
1 | Mooncake Host executor |
ADXL 的旧接口文档还明确指出,小于 256 KiB 或存在未注册内存时可能启用中转 buffer pool。这再次说明 Direct 是目标抽象,不保证每个请求在所有条件下都严格零中转。
对当前上游 HiXL 源码的旁证也要谨慎解释:2026-08-25 的 499e6c33 版本中,Fabric Memory engine 默认可启用 FabricMemAicpuTransferService,Host service 路径则调用 aclrtMemcpyAsync。这说明至少当前公开实现中存在 Host 与 AICPU 展开路径,不能把 HiXL/Fabric 自动等同于 AIV。由于 Mooncake 所链接的具体 CANN/ADXL 版本可能不同,这一证据只用来否定“必然 AIV”,不能宣称所有 ADXL 内部实现永远不可能增加 AIV backend。
USE_UBSHMEM
结论:当前明确不是 AIV 直驱。
ubshmem_transport.cpp 的关键动作是:导入/映射 Fabric 或 IPC handle,计算映射后的地址,Host worker 在若干 ACL stream 上调用 aclrtMemcpyAsync,最后同步 stream 并更新 slice 状态。
1 | Host metadata/import |
这里没有 CANN SHMEM Device API,没有 AIV Kernel,没有由 AIV 准备 WQE/SQE 和 ring doorbell 的代码。UBShmemTransport 这个名字也容易造成第二次误解:它使用的是 UB/Fabric Memory 语义,但当前 Mooncake 实现并不是对 CANN shmem Device 编程库的直接封装。
至于 aclrtMemcpyAsync 最终在某款芯片、某个 CANN 版本、某种映射类型下由 SDMA、HCCS 还是其他 runtime engine 完成,Mooncake 公开层没有给出足以覆盖所有组合的答案。可以确认提交者是 Host API,不能越过证据声称特定物理 engine。
最终判决
| 检查项 | HCCL path | Ascend Direct | UBShmem | 真正 AIV SHMEM/URMA 路径 |
|---|---|---|---|---|
| 一边远端访问 | 是 | 是 | 是 | 是 |
| 可实现零拷贝 | 条件满足时 | 条件满足时 | 映射后可避免传统中转 | 是 |
| VMM/Fabric 映射 | 不是核心 | 可选 Fabric mode | 是,核心机制 | 可以组合使用 |
| AIV Device Kernel 可见 | 否 | 否 | 否 | 是 |
| AIV 准备 WQE/SQE | 否 | 否 | 否 | 是 |
| AIV ring doorbell | 否 | 否 | 否 | 是 |
| AIV 直驱结论 | 否/无证据 | 否 | 否 | 是 |
性能证据
PR #1399 的带宽
PR #1399 使用 transfer-engine-bench、12 个 initiator thread、batch size 1 测 D2RD,作者给出的结果如下:
| Block size | Write GB/s | Read GB/s |
|---|---|---|
| 64 KiB | 7.76 | 8.34 |
| 128 KiB | 15.77 | 15.73 |
| 256 KiB | 31.86 | 30.27 |
| 512 KiB | 60.49 | 58.31 |
| 1 MiB | 108.83 | 108.57 |
| 2 MiB | 118.57 | 148.85 |
| 4 MiB | 131.45 | 158.17 |
| 8 MiB | 134.60 | 162.70 |
| 12 MiB | 135.69 | 164.20 |
应使用 PR 作者原表,而不是 bot summary 中的 “199.14 GB/s”;后者与原始表格不一致。这个结果能够支持“UBShmem 在大块下达到较高吞吐”,但不能独立证明它优于 Direct,因为 PR 没有给出同环境的三后端对照,硬件拓扑、CANN/驱动版本、预热和重复次数也不充分。
PR #1591 的延迟对比
PR #1591 在单机 16 NPU 的 Store 场景中比较非 Fabric Direct、Direct Fabric、原始 UBShmem 和 stream-pool UBShmem:
| Key 数量 | Direct | Direct Fabric | UBShmem | UBShmem stream pool |
|---|---|---|---|---|
| 32 | 62.78 ms | 21.29 ms | 28.49 ms | 21.10 ms |
| 64 | 123.90 ms | 40.86 ms | 56.04 ms | 41.66 ms |
| 128 | 262.77 ms | 78.27 ms | 115.94 ms | 80.22 ms |
| 256 | 518.35 ms | 156.23 ms | 234.38 ms | 164.27 ms |
| 512 | 1017.84 ms | 311.96 ms | 463.01 ms | 326.15 ms |
在 512 keys 点上,Direct Fabric 相对非 Fabric Direct 约为 3.26 倍,stream-pool UBShmem 约为 3.12 倍;Direct Fabric 只比 stream-pool UBShmem 快约 **4.35%**。32 keys 时 UBShmem stream pool 甚至略快于 Direct Fabric。
由此更合理的解释是:
- Fabric Memory 能力本身贡献了主要差距。非 Fabric Direct 与另外两条 Fabric path 的差距最大。
- 并行提交与同步结构是第二个关键因素。原始 UBShmem 到 stream pool 的提升说明单 stream/串行 worker 会浪费 Fabric 带宽。
- UBShmem 并没有显示出“因为是 AIV 直驱而额外领先”的形状。事实上它不是 AIV 直驱,优化后的曲线与 Direct Fabric 很接近。
- 这是单机单 workload 证据。跨节点、不同 block size、并发租户、不同芯片和 CANN 版本仍需重新测量。
纵横合并后的判断
纵向看,Mooncake 的路线是:
1 | 复用 HCCL 低层能力解决“能不能传” |
横向看,三条路径分别占据不同抽象层:
- HCCL path 更靠近通信库内部 transport 对象。
- Ascend Direct 更像通用一边传输产品 API。
- UBShmem 更靠近内存虚拟化、共享 handle 和 runtime copy。
- AIV 直驱则位于 Device 侧控制与提交层,和前三者不是同一条横轴。
这解释了为什么项目会出现看似重叠的选项:演进不是简单地把旧类重命名,而是在不同时间把责任从 Mooncake、HCCL、ADXL/HiXL、CANN runtime 和 Fabric allocator 之间重新划分。
后续演进
以下属于判断,不是项目已宣布的 roadmap。
Direct 迁移到 HIXL 新接口
判断:中期最自然的方向是保留 Ascend Direct 用户概念,但把 Mooncake 内部从待废弃的 adxl::AdxlEngine 迁到 HIXL 新 API。
- 成立前提:HIXL 新接口覆盖 Mooncake 所需的注册内存、异步 batch、错误码、连接恢复和 Fabric Memory。
- 领先信号:Mooncake 出现
hixl::Hixl头文件与对象、构建依赖不再使用 ADXL compatibility API、Direct 文档开始区分 HIXL 版本。 - 反向信号:上游长期维护 ADXL 兼容层,Mooncake 实测迁移收益不足或新接口缺少关键异步能力。
Fabric 能力向 Direct 收敛
判断:Direct Fabric 与 stream-pool UBShmem 的性能接近、allocator 逻辑又在 PR #3214 中趋于共享,因此 Fabric Memory 未来可能更像 Direct 的 capability,而不是长期维护完全平行的 transport。
- 成立前提:Direct 能暴露和 UBShmem 一样可控的 allocator、IPC/Fabric mode、stream 并行度和错误恢复。
- 领先信号:构建系统不再用独立源文件 flavor,运行时根据 topology/capability 自动选择 Fabric path,
ubshmemprotocol 被兼容映射到ascend。 - 反向信号:独立 VMM path 在部署体积、依赖、调优自由度或新硬件适配速度上持续明显优于通用 HIXL。
真正 AIV transport 以新后端出现
判断:如果 Mooncake 要服务算子内细粒度 KV/EP 通信,真正 AIV 直驱更可能以 CANN SHMEM/URMA/TENT/UB Device backend 或新的 Device queue 进入,而不是悄悄把现有三个开关中的某一个改名为 AIV。
- 成立前提:Transfer Engine 能把远端地址、队列、权限和完成状态安全地交给 Device Kernel,并支持 persistent kernel 或 kernel 内批量提交。
- 领先信号:源码出现
shmem_device_*、AIV kernel、WQE/SQE、doorbell、Device-side completion;基准重点转向小消息控制时延与通算重叠。 - 反向信号:Mooncake 的主工作负载继续是 Host 调度的大块 KV bulk copy,Host 提交成本相对链路时间很小,额外占用 AIV 反而挤压计算资源。
仍待确认
aclrtMemcpyAsync的物理执行 engine:在不同 Ascend 芯片、Fabric 映射类型和 CANN 版本下究竟使用 SDMA、HCCS 还是其他路径,需要对应版本的官方实现说明或 profiler trace,不能从函数名推断。- 三开关组合的正式支持矩阵:当前 CMake 表明它们基本互斥,但文档没有显式列出所有非法组合及配置时报错行为。
- #1399 基准环境:缺少完整芯片型号、拓扑、CANN/Driver/Lingqu、NUMA、预热、重复次数和误差条,峰值数字只适合作为开发者自测。
- Fabric handle 的多租户隔离:
DISABLE_PID_VALIDATION的使用边界、容器隔离和 handle 分发授权需要安全设计,不应只依赖 metadata 不泄漏。 - ADXL 到 HIXL 的迁移时间:上游已经把 ADXL 文档标为待废弃,但 Mooncake 尚未给出公开完成日期。
- A2/A3/950 的能力差异:VMM API 的存在不等于 Fabric Memory transport 在所有产品上等价可用,需把 API 支持、Fabric handle 支持、跨卡拓扑和性能分别验证。
- 失败恢复语义:远端进程退出、handle 失效、Fabric 映射断开或 stream 超时时,上层 Store 对 segment、replica 和正在消费的 KV block 如何原子回滚,仍需结合故障注入验证。
常见误解
- “用了 HCCL 就是集合通信。”HCCL path 在这里主要复用低层
TransportMem做一边读写,不是在为每个 KV block 调AllReduce。 - “Ascend Direct 就是 AIV Direct。”前者是传输产品/transport 名,后者是 Device 侧控制路径;Mooncake 当前 Direct 由 Host 调 ADXL。
- “VMM 映射后就是缓存一致的全局内存。”VMM 提供地址与物理内存映射,不自动提供 CPU 式缓存一致性、任意拓扑可达或完成顺序。
- “UBShmem 已经接入 CANN SHMEM Device API。”当前 Mooncake 类直接使用 CANN VMM 与 ACL copy,未出现 CANN SHMEM 的 AIV Device 调用链。
检查理解
以下问题不附答案,用于检查是否真正分清了五个维度:
- 一个 transport 同时满足 one-sided 和 zero-copy,但每次请求都由 Host 调用异步 API 提交,它是否属于 AIV 直驱?需要哪类新增证据才能改变结论?
- 为什么
aclrtMemImportFromShareableHandle成功后仍不能直接使用导出进程的原始虚拟地址?Mooncake metadata 至少需要保留哪些字段才能正确重定位? - 如果同一环境下 Direct Fabric 与 UBShmem stream pool 的延迟接近,但非 Fabric Direct 慢三倍,最应该优先验证的性能假设是什么?哪些指标能够把 Fabric 能力、并行度和提交者身份的贡献分开?
参考文献
- Mooncake PR #502:首个 Ascend HCCL transport
- Mooncake Issue #719:Ascend Direct 需求
- Mooncake PR #740:Ascend Direct 实现
- Mooncake PR #1170:Ascend Direct Fabric Memory
- Mooncake Issue #1312:CANN VMM 与 Fabric Memory 需求
- Mooncake PR #1399:UBShmem transport
- Mooncake PR #1519:UBShmem IPC allocator
- Mooncake PR #1591:stream pool 与 Store 接入
- Mooncake PR #3214:Fabric Memory best-effort allocation
- Mooncake Ascend Direct 文档
- CANN VMM:aclrtMallocPhysical
- HiXL:待废弃 ADXL 接口
- CANN SHMEM 开源仓库
- vLLM Ascend:AIV HCCL engine 调优说明