Mooncake 集成 Sunrise Link Transport 实战指南:TENT 框架下的 GPU 直连传输后端
Mooncake 集成 Sunrise Link Transport 实战指南:TENT 框架下的 GPU 直连传输后端
导读
本文档面向需要在 Mooncake 分布式推理/缓存系统中启用曦望(Sunrise)GPU 直连互连硬件的开发者。Sunrise Link 被 Mooncake 以 SUNRISE_LINK 传输类型集成进 TENT 传输框架,本文将从传输流水线、依赖安装、CMake 编译、benchmark 运行验证、环境变量与配置调优到源码级实现原理,完整讲解如何在本仓库中构建、启用并验证该传输后端,读完即可上手在自有 Sunrise 硬件集群上跑通端到端传输。
Sunrise Link 是曦望(Sunrise)开发的 GPU 间高速直连互连技术。在 Mooncake 中,它作为 GPU 传输后端集成于 TENT(Transfer Engine with Notification Transport)传输框架,借助 Tang Runtime(tangrt)提供设备内存分配、指针属性查询、Peer Copy 与 IPC 句柄能力,并在 TENT 中以 SUNRISE_LINK 传输类型注册。运行时,当编译开启 USE_SUNRISE 且配置项 transports/sunrise_link/enable=true 时,TransferEngineImpl 会加载 Sunrise Link Transport(相关加载逻辑见 transport_loader.cpp)。
传输流水线
Sunrise Link Transport 的完整工作流程可分为以下五个阶段,与源码 sunrise_link_transport.cpp 中的实现一一对应:
-
初始化(Init):通过
dlopen动态加载libptml_shared.so与libtangrt_shared.so,并通过dlsym解析ptmlInit、ptmlPtlinkEnableAll、ptmlPtlinkPhytopoDetect、ptmlDeviceGetCount等符号,随后调用ptmlInit()初始化 PTML(Port Topology Management Layer)运行时。实现见initSunriseLink()(sunrise_link_transport.cpp)。 -
拓扑检测(Topology):调用
ptmlPtlinkPhytopoDetect逐设备发现芯片间物理端口,扫描每个端口的link_status,构建 C2C 映射(local_chipid, remote_chipid) → local_port,同时填充topology_map_(device_id → 活跃 peer 端口列表)。实现见detectTopology()(sunrise_link_transport.cpp)。 -
内存注册(Registration):
addMemoryBuffer()对 location 类型为cuda/npu的缓冲区调用tangIpcGetMemHandle生成 IPC 句柄,序列化后写入desc.shm_path供远程节点使用;CPU/通配符缓冲区则记录gpu_id = -1(sunrise_link_transport.cpp)。 -
传输执行(Execution):依据源/目标指针属性分派路径——
- 同设备:
tangMemcpy(DeviceToDevice); - 跨设备:优先
tangMemcpyPeer,失败后重试tangMemcpyPeer_v2,再回退到tangDeviceGetPeerPointer映射 + C2C memcpy(C2cMemcpyWithPeerMap); - 远程:通过
relocateRemoteAddress()调用tangIpcOpenMemHandle打开远端 IPC 句柄后进行 peer copy; - 主机 ↔ 设备:根据
tangMemoryType选择tangMemcpyDeviceToHost/tangMemcpyHostToDevice/tangMemcpyHostToHost方向(MemcpyKindForPointers)。
- 同设备:
-
异步路径(Async):当传输大小超过
async_memcpy_threshold时改用tangMemcpyAsync,使用按设备缓存的线程本地 stream(ThreadLocalTangStreamPool),并在getTransferStatus中通过tangStreamQuery/tangStreamSynchronize完成异步收尾。
值得注意的实现细节:源码注释明确指出 peer copy 不能使用进程级全局锁——若为所有
tangMemcpyPeer_v2加锁,会串行化所有并发设备拷贝,使多线程 C2C benchmark 比 PCCL(可并发执行大量设备拷贝)慢约 3 个数量级。因此实现只对tangSetDevice+ 非 peer 的tangMemcpy使用每设备互斥锁,peer 拷贝直接携带设备 ID 并发执行(sunrise_link_transport.cpp)。此外,指针属性查询同样刻意不加锁,避免多线程吞吐被全局锁卡死。
新增依赖
除 Mooncake 基础依赖外,Sunrise Link Transport 额外依赖 Tang Runtime(tangrt)与 PTML:
| 依赖项 | 说明 |
|---|---|
| 头文件路径 | /usr/local/tangrt/include |
| 库路径 | /usr/local/tangrt/lib/linux-x86_64(扁平布局下也可能为 /usr/local/tangrt/lib) |
| 共享库 | libtangrt_shared.so(运行时按默认安装路径加载) |
请确保 tangrt 与 ptml 相关运行库能被动态链接器找到(例如通过 LD_LIBRARY_PATH 或系统库搜索路径)。动态库路径的解析逻辑位于 TangRtSharedObjectPath():优先读取 MC_TANGRT_LIB_DIR 环境变量直接定位 .so 目录;否则按 MC_TANGRT_ROOT + MC_TANGRT_LIB_ARCH 拼出 <root>/lib/<arch>/<soname>,若该路径不存在则回退到 <root>/lib/<soname>(sunrise_link_transport.cpp)。
构建与编译
前置条件
- 已安装可用的 Tang Runtime(默认路径
/usr/local/tangrt),并保证include与lib目录就位; - 编译环境可访问 Mooncake 仓库及其基础依赖。
CMake 配置与编译
# 克隆 Mooncake 仓库
git clone https://github.com/kvcache-ai/Mooncake.git
cd Mooncake
# 启用 TENT + Sunrise Link
mkdir build && cd build
cmake .. -DUSE_TENT=ON -DUSE_SUNRISE=ON
# 编译
make -j$(nproc)
如果 Tang Runtime 安装在非默认路径,通过 MC_TANGRT_ROOT 指定:
cmake .. -DUSE_TENT=ON -DUSE_SUNRISE=ON -DMC_TANGRT_ROOT=/opt/tangrt
从 CMake 源码可以确认 USE_SUNRISE 的完整影响面(在 mooncake-transfer-engine 目录下):
- TENT 侧:
tent/src/CMakeLists.txt在USE_SUNRISE开启时向tent_interface注入USE_SUNRISE编译宏,并链接${MC_TANGRT_ROOT}/lib/linux-x86_64;tent/src/transport/sunrise_link/CMakeLists.txt编译tent_xport_sunrise_link静态库并链接${SUNRISE_LIBRARIES}; - 经典 TE 侧:
src/transport/CMakeLists.txt在USE_SUNRISE开启时引入src/transport/sunrise_link子目录并将sunrise_link_transport对象库并入transport目标; - Benchmark:
benchmark/CMakeLists.txt为tebench定义-DUSE_SUNRISE、引入 Tang 头文件与库路径,并在USE_SUNRISE时链接tangrt_shared、为 RPATH 追加${MC_TANGRT_ROOT}/lib。
USE_SUNRISE 还驱动了整个经典 TE benchmark 层的“CUDA 兼容接口”:benchmark/utils.h 在 USE_CUDA 未定义时包含 cuda_alike.h(gpu_vendor/sunrise.h),使 VRAM 分配、cudaMemset、指针属性判断等代码在 Sunrise 平台上以 Tang API 的封装形态运行(见 include/cuda_alike.h、include/sunrise_allocator.h)。
运行与测试
使用 transfer_engine_bench(经典 TE 后端)
transfer_engine_bench 支持 sunrise_link 协议,可用于基本连通性与性能验证(协议分发逻辑见 multi_transport.cpp)。
# 终端 1:目标端(Target)
./transfer_engine_bench \
--mode=target \
--protocol=sunrise_link \
--local_server_name=10.0.0.2 \
--metadata_server=P2PHANDSHAKE \
--gpu_id=0
# 终端 2:发起端(Initiator)
./transfer_engine_bench \
--mode=initiator \
--protocol=sunrise_link \
--metadata_server=P2PHANDSHAKE \
--segment_id=10.0.0.2:$PORT \
--gpu_id=0 \
--block_size=8388608 \
--batch_size=32
说明:当
metadata_server=P2PHANDSHAKE时,目标端实际监听端口可能为动态分配端口。请以目标端日志中打印的实际端口替换--segment_id中的$PORT。
transfer_engine_bench 的入口在 example/transfer_engine_bench.cpp,其中 use_vram、init_mem、gpu_id、block_size、batch_size 等 flag 在 USE_SUNRISE 编译路径下同样生效。
使用 tebench(TENT 后端)
角色由 --target_seg_name 决定:为空 → 目标端,否则 → 发起端。
# 终端 1:目标端
./tebench --backend=tent --metadata_type=p2p --xport_type=sunrise_link \
--seg_type=VRAM --local_gpu_id=0
# 终端 2:发起端
./tebench --backend=tent --metadata_type=p2p --xport_type=sunrise_link \
--seg_type=VRAM --target_seg_name=192.168.172.52:168 \
--local_gpu_id=1 --target_gpu_id=0
tebench 的 TENT 后端实现位于 benchmark/tent_backend.cpp:VRAM 段在 USE_SUNRISE 下使用 cudaSetDevice(Tang 封装)完成设备切换与分配,并提供按 GPU 的线程绑核(pinThread)逻辑,因为 Tang 指针查询对线程所属设备上下文敏感。经典 TE 后端则位于 benchmark/te_backend.cpp,其中 USE_SUNRISE 路径下会显式安装 Sunrise Link Transport,确保 IPC 句柄在 benchmark 发起传输之前就由已安装的传输后端生成。
单元测试
仓库为 Sunrise Link 提供了三层测试,全部仅在 USE_SUNRISE 开启时编译(tests/CMakeLists.txt、tent/tests/CMakeLists.txt):
- tent/tests/sunrise_link_transport_test.cpp:TENT 端 fork 双进程端到端用例,覆盖 server/client 双 GPU 的 Write/Read 路径,并在无 Sunrise GPU 或 GPU 数量不足时自动 skip;
- tests/sunrise_link_transport_unit_test.cpp:经典 TE 侧单元测试;
- tests/sunrise_link_transport_runtime_test.cpp:运行时集成测试。
环境变量
| 变量 | 描述 | 默认值 |
|---|---|---|
MC_TANGRT_ROOT |
Tang Runtime 根目录 | /usr/local/tangrt |
MC_TANGRT_LIB_DIR |
.so 目录路径,直接指定后优先于 MC_TANGRT_ROOT + 架构查找 |
(未设置) |
MC_TANGRT_LIB_ARCH |
<root>/lib/ 下的架构子目录 |
linux-x86_64 |
三者均作用于运行时 dlopen 的库定位(TangRtSharedObjectPath())。需要特别说明的是,MC_TANGRT_ROOT 同时是编译期变量(CMake 通过 -DMC_TANGRT_ROOT 指定),而 MC_TANGRT_LIB_DIR / MC_TANGRT_LIB_ARCH 是运行时环境变量,二者职责不同:前者决定头文件与链接目录,后者决定进程启动后从哪个路径加载共享库。
配置项说明(TENT)
Sunrise Link 支持通过配置文件调整行为。配置的读取入口有两处:install() 中读取 async_memcpy_threshold 并乘以 1024 换算为字节(sunrise_link_transport.cpp),startTransfer() 中读取 enable_port_striping(sunrise_link_transport.cpp),而 transports/sunrise_link/enable 由 TENT 传输加载器在装配传输列表时消费(transport_loader.cpp)。
| 选项 | 类型 | 描述 | 默认值 |
|---|---|---|---|
transports/sunrise_link/enable |
bool | 是否启用该传输 | true |
transports/sunrise_link/async_memcpy_threshold |
int | 触发异步 memcpy 的最小传输大小(MiB),设为 0 禁用异步路径 | 0 |
transports/sunrise_link/enable_port_striping |
bool | 为大型跨设备拷贝(>4 MiB)启用多端口条带化 | false |
关键配置项的底层行为
async_memcpy_threshold:仅在存在可用 stream(stream && threshold > 0 && len >= threshold)时才走异步路径。异步任务在getTransferStatus中通过tangStreamQuery判断是否tangSuccess(完成)或tangErrorNotReady(未就绪)来推进状态机。注意:跨设备 peer 拷贝路径始终走同步tangMemcpyPeer,异步仅作用于同设备与主机-设备路径。enable_port_striping:当启用且本端到对端存在多个活跃端口(ports_sd.size() > 1)、且传输长度 ≥ 4 MiB(kMultiPortThreshold = 4ull << 20)时,将一次拷贝按端口数均分(余数分摊到前rem个 lane),逐 lane 调用C2cMemcpyWithPeerMap并行条带化传输,任一路失败即整体回退到单端口 peer copy。
可根据业务负载与设备拓扑(端口数量、带宽、传输块大小分布)微调上述参数。
注意事项与实现要点
- 设备上下文(Device Context):Transport 内部统一管理
tangSetDevice,并在查询前后通过SavedTangDevice保存/恢复原设备;直接调用 Tang API 时,需在查询指针属性前手动设置正确设备。 - IPC 句柄生命周期:远端地址通过
relocateRemoteAddress()解析,tangIpcOpenMemHandle打开的句柄缓存在relocate_map_(带线程本地快照与RWSpinlock),在uninstall()中统一tangIpcCloseMemHandle释放并dlclose两个动态库。 - 并发 Peer Copy:每设备互斥锁保护上下文相关操作(
ScopedTangDeviceOps);跨设备拷贝按固定顺序(较低设备 ID 优先)获取源/目标锁,防止死锁;而 peer 拷贝本体不加全局锁以保障多线程吞吐。 - 映射主机指针规范化(Mapped Host Pointer Normalization):Sunrise S2 路径可能通过
tangHostAlloc分配映射 GPU 内存,NormalizeMappedHostPointer()通过tangHostGetDevicePointer取出对应的设备指针并更新属性,确保 peer copy 路径选择正确。 - 同设备 IPC 特判:当发起端与目标端使用同一 GPU ID(典型单卡 P2P bench 场景)时,指针实际是同一设备上下文内的 IPC 句柄,此时
tangMemcpyPeer不适用,源码会直接走tangSetDevice+tangMemcpy(DeviceToDevice)。 - 拓扑探测容错:单设备
ptmlPtlinkPhytopoDetect失败仅告警并跳过,不影响整体安装;C2C 映射按(local_chipid, remote_chipid)去重,端口列表在条带化前会排序去重。
扩展阅读
- 中文归档版本文档:docs/source/zh_archive/sunrise_link_transport.md
- TENT 支持的传输协议总览:docs/source/getting_started/supported-protocols.md
- TENT 指标与观测:docs/source/design/tent/metrics.md
- Sunrise 平台适配(含
SunrisePlatform与 allocator):tent/src/platform/sunrise/sunrise_allocator.cpp、tent/src/platform/sunrise/sunrise_probe.cpp - 经典 TE 协议分发入口:src/multi_transport.cpp