拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Mooncake 鲲鹏 Kunpeng UB 传输层(Unified Bus Transport)构建与使用指南

Mooncake 鲲鹏 Kunpeng UB 传输层(Unified Bus Transport)构建与使用指南
  • 人工智能
  • 大模型
  • 模型推理服务
  • 后端

【免费下载链接】Mooncake

Mooncake is the serving platform for Kimi, a leading LLM service provided by Moonshot AI.

项目地址:https://gitcode.com/gh_mirrors/mo/Mooncake
点击查看免费下载

导读

本文面向希望在鲲鹏 950(Kunpeng 950)平台上为 Mooncake 启用 UB(Unified Bus,统一总线)传输能力的开发者,完整介绍基于 URMA(Unified Remote Memory Access)与 OBMM(Ownership Based Memory Management)两种 UB 协议实现的 Kunpeng UB Transport:从新增依赖、CMake 构建开关、注册验证,到单节点/多设备基准测试与源码级原理剖析。读完本文,你将能够独立在 openEuler 24.03(LTS-SP3)上编译出带ub协议支持的 Mooncake,并在真实或 Mock URMA 设备上运行传输引擎基准测试与单元测试。

一、背景:UB 协议与 URMA / OBMM

Kunpeng UB Transport 的源码位于mooncake-transfer-engine/src/transport/kunpeng_transport(源码目录实际命名为kunpeng_transport),内部包含针对 UB 协议的 Transport 对接代码与实现逻辑,相关实现细节可对照 ub_transport.cpp 与 ub_transport.h。

UB(Unified Bus,统一总线)是与 RDMA、CXL、NVLink 和 TCP 处于同一抽象层的传输协议,属于可在应用层灵活选择的一类传输方案。目前 UB 协议有两个开源实现:

  • URMA(Unified Remote Memory Access,统一远程内存访问):UB 协议为上层应用提供的统一编程抽象与核心语义层。它基于 UB 协议低延迟、高带宽的底层特性,为远程共享内存的访问与操作提供统一的 API 和语义接口。URMA 的开源项目为 openEuler 社区的 UMDK。
  • OBMM(Ownership Based Memory Management):面向超节点环境的内核内存管理系统,支持跨节点的物理内存共享。系统通过内核模块(obmm.ko)和用户态库(libobmm.so)提供高效的远程内存访问能力。OBMM 的开源项目为 openEuler 社区的 obmm。

在 Mooncake 的代码中,这两种端点类型被定义为枚举UB_ENDPOINT_TYPE { URMA_ENDPOINT = 0, OBMM_ENDPOINT = 1 }(见 ub_transport.h),UbTransport构造函数默认采用URMA_ENDPOINT。

二、新增依赖与前置条件

Kunpeng UbTransport 在 Mooncake 本身依赖的基础上,新增了部分 URMA 和 OBMM 相关依赖,要点如下:

依赖类别要求
硬件平台支持原生 UB 互联架构的鲲鹏 950 CPU
OS 版本openEuler 24.03(LTS-SP3)
URMA 依赖UMDK:yum install umdk-urma-devel,或从 UMDK 源码构建安装
协议优势URMA 提供类似 RDMA 的内存语义,并针对鲲鹏芯片片上互联进行了专门优化

URMA 的 UMDK 安装方式有两种等价路径:

# 方式一:yum 直接安装开发包 yum install umdk-urma-devel # 方式二:从源码构建 git clone https://atomgit.com/openeuler/umdk.git cd umdk mkdir build && cd build cmake .. make -j$(nproc) sudo make install

构建 Mooncake 本体所需的常规编译依赖(CMake、glog、jsoncpp、numa、gtest、pybind11 等)与此前一致。另外,仓库通过 FindUrma.cmake 自动探测系统是否已安装 UMDK:优先在/usr/include、/usr/local/include及其子路径下查找urma_api.h,并在/usr/lib、/usr/lib64等路径下查找liburma.so;若系统未安装,则会通过 FetchContent 拉取 UMDK 源码(仅提供头文件),此时真实的 UB 后端在运行期不可用,测试环境会注入自己的适配层。

三、构建与编译

3.1 前置条件

  • openEuler 24.03(LTS-SP3)操作系统;
  • 已安装 UMDK:yum install umdk-urma-devel,或已从源码构建安装(满足urma_api.h头文件与liburma.so库可用即可)。

3.2 CMake 配置与编译

# 克隆 Mooncake 仓库并初始化子模块 git clone https://github.com/kvcache-ai/Mooncake.git cd Mooncake git submodule update --init --recursive # 启用 UB 传输层进行配置 mkdir build && cd build cmake .. -DUSE_UB=ON \ -DURMA_INCLUDE_DIR=/usr/include \ -DURMA_LIBRARY=/usr/lib64/liburma.so \ -DCMAKE_BUILD_TYPE=RelWithDebInfo # 编译 make -j$(nproc)

编译选项说明:

  • -DUSE_UB=ON:总开关。在 src/transport/CMakeLists.txt 中,只有USE_UB为 ON 时才会把kunpeng_transport子目录编入并链接ub_transport对象库;
  • -DURMA_INCLUDE_DIR:URMA 头文件目录,默认探测值为/usr/include;
  • -DURMA_LIBRARY:liburma.so的完整路径。该值会被 kunpeng_transport/CMakeLists.txt 读取:若找到真实库,则编译ub_transport时链接真实 URMA 库;若未找到,则编译时加入urma/mock_urma.cpp(Mock 实现),用于无真实硬件环境下的测试,CMake 会打印Not Found liburma.so building ub_transport with Mock URMA library警告。

3.3 验证 UB 传输层注册

# 检查 UB 传输层是否已注册 ./mooncake_server --list-transports # 预期输出: rdma, tcp, nvlink, ub

UbTransport::getName()返回字符串"ub"(见 ub_transport.h),因此它会在传输层列表中以上述名字呈现。

3.4 Python 侧验证(可选)

构建完 Python 绑定后,也可以用 TransferEngine 直接初始化ub协议:

from mooncake.engine import TransferEngine te = TransferEngine() result = te.initialize('127.0.0.1', 'P2PHANDSHAKE', 'ub', '') print(f'Initialize result: {result}') # 预期为 0

初始化成功后日志应包含类似内容:

URMA module init success found 1 devices. device_name : urma0 EID : 01:02:03:04:05:06:07:08:09:0a:0b:0c:0d:0e:0f:10

四、源码视角:UbTransport 的组成与工作流程

4.1 类层次与核心组件

UB 传输层的源码设计围绕三个层次展开(对应 urma_endpoint.h 中的类定义):

组件职责
UbTransport传输层主类,负责管理 URMA 资源与端点、内存注册、提交传输、查询状态
UbContext(子类UrmaContext)每个设备一个上下文,负责设备打开、上下文/JFC/JFR 等资源创建与销毁、内存区注册、事件轮询
UbEndPoint(子类UrmaEndpoint)每个远端连接一个端点,负责 jetty(URMA 通信队列)创建、握手建连、实际的数据收发

从源码结构看,URMA 侧的实体对象对应关系为:

  • urma_context:URMA 设备上下文句柄;
  • urma_jfce(Jetty Factory for Completion Events):完成事件队列,UrmaContext::construct中按num_jfce_per_ctx创建;
  • urma_jfc(Jetty Factory for Completion,发送完成队列):num_jfc_per_ctx个,每个深度为max_jfc_e(默认 4096);
  • urma_jfr(接收队列):num_jfc_per_ctx个,深度 2048,传输模式URMA_TM_RC;
  • urma_jetty:通信 jetty,每个端点按num_jetty_per_ep(默认 1)创建,采用 Reliable Connection(RC)模式。

4.2 安装(install)流程

UbTransport::install()(见 ub_transport.cpp)是传输层初始化的入口,依次完成:

  1. 保存元数据(TransferMetadata)与本地拓扑(Topology)引用;
  2. initializeUbResources():调用init()初始化 URMA 模块(urma_init),从拓扑中获取 HCA 设备列表;若拓扑为空则回退到mock_urma_device用于测试;逐个设备构建UrmaContext并调用doConstruct,失败的设备会被disableDevice禁用;若无任何可用设备则返回ERR_DEVICE_NOT_FOUND;
  3. allocateLocalSegmentID():以"ub"为协议名创建本地 SegmentDesc 并登记每个设备的名称与 EID;
  4. startHandshakeDaemon():启动握手守护进程,注册onSetupConnections回调,用于被动接收远端建连请求;
  5. updateLocalSegmentDesc():把本地段描述发布到元数据服务。

4.3 内存注册与数据通路

  • 注册:registerLocalMemory()对每个 context 调用registerMemoryRegion()与buildLocalBufferDesc()。URMA 实现(urma_endpoint.cpp)通过urma_register_seg注册内存段,访问权限为URMA_ACCESS_READ | URMA_ACCESS_WRITE | URMA_ACCESS_ATOMIC,Token 策略为URMA_TOKEN_NONE;注册长度受max_seg_size(默认0x10000000000,即 1 TiB)约束。当注册名称为kWildcardLocation("*")时,会自动通过getMemoryLocation探测内存位置并写入 BufferDesc;
  • 提交:submitTransfer()把批量请求挂到 BatchDesc 上,submitTransferTask()按slice_size将请求切分为 Slice,为每个 Slice 选择设备(selectDevice,按 buffer 地址范围与拓扑亲和性选择),最终经submitPostSend下发到对应 context 的 worker 池;
  • 完成:worker 通过urma_poll_jfc轮询发送完成队列(JFC),成功的 Slice 调用markSuccess(),失败(含URMA_CR_WR_FLUSH_ERR)的 Slice 交回上层做重试或失败处理(urma_endpoint.cpp)。

五、运行与测试

5.1 单节点基准测试

利用mooncake-transfer-engine/example下的transfer_engine_bench(其命令行参数定义见 transfer_engine_bench.cpp):

# 终端 1:目标端(Target) ./transfer_engine_bench \ --mode=target \ --protocol=ub \ --device_name=urma0 \ --local_server_name=127.0.0.1 \ --metadata_server=P2PHANDSHAKE # 终端 2:发起端(Initiator) ./transfer_engine_bench \ --mode=initiator \ --protocol=ub \ --device_name=urma0 \ --metadata_server=P2PHANDSHAKE \ --segment_size=8388608 \ --batch_size=1 \ --segment_id=127.0.0.1:$PORT

参数含义:

  • --mode:运行模式,initiator或target(发起端负责读写远端段,目标端被动等待);
  • --protocol=ub:选择 UB 传输协议。bench 程序中--protocol=ub分支会先通过拓扑discover({FLAGS_device_name})发现设备,再以空参安装ub传输层(见 transfer_engine_bench.cpp);
  • --device_name=urma0:指定 URMA 设备名;urma0,urma1,...逗号分隔即可启用多设备;
  • --metadata_server=P2PHANDSHAKE:元数据服务地址;P2PHANDSHAKE表示点对点握手模式(无需 etcd),也可使用etcd://...、redis://...等格式;
  • --segment_size=8388608:发起端申请的段大小(8 MiB);
  • --batch_size:每批传输任务数;
  • --segment_id=127.0.0.1:$PORT:目标段标识,$PORT需替换为目标端实际监听端口。

5.2 多设备基准测试

自动发现多个 URMA 设备:

./transfer_engine_bench \ --protocol=ub \ --device_name=urma0,urma1,urma2,urma3

多个设备名逗号分隔后,会生成对应的 CPU/NIC 拓扑 JSON(包含多个 device 的亲和矩阵),使传输引擎能够按拓扑选择最优设备。

5.3 单元测试

UB 传输层单测位于 ub_transport_test.cpp,构建后运行:

./build/mooncake-transfer-engine/tests/ub_transport_test

测试套件包含两个核心用例:

测试描述
MultiWrite多次(10 轮)写入操作,每次 4 MB 数据,校验提交与完成状态机
MultipleRead多次读写操作并做数据完整性校验

也可用 CTest 一次性运行全部单测:

cd build && ctest --output-on-failure

单测相关的环境变量:

export MC_METADATA_SERVER=P2PHANDSHAKE # 默认值 export MC_LOCAL_SERVER_NAME=127.0.0.1:12345 # 默认值

需要注意的是,单测在没有真实 URMA 硬件时会走 Mock 路径:URMA_LIBRARY未找到时 CMake 会编译urma/mock_urma.cpp(见 kunpeng_transport/CMakeLists.txt),且拓扑为空时initializeUbResources会回退到mock_urma_device,保证无硬件环境也能验证传输层逻辑。

六、UB 相关配置参数

UB 传输层在 config.h 中定义了一组专属调优参数:

参数默认值说明
num_jfc_per_ctx2每个 context 的发送完成队列(JFC)数量
num_jfce_per_ctx2每个 context 的完成事件队列(JFCE)数量
eid_index0设备 EID 索引(多 EID 设备时选择使用哪个 EID)
max_seg_size0x10000000000单个内存段注册的最大长度(1 TiB)
max_jfc_e4096JFC 队列深度(URMA 侧当前使用该默认值)
num_jetty_per_ep1每个端点的 jetty(通信队列)数量

其中num_jfc_per_ctx与num_jfce_per_ctx可通过环境变量MC_NUM_CQ_PER_CTX同时覆盖(见 config.cpp);eid_index在 urma_endpoint.cpp 的openDevice中决定从设备 EID 列表中选择哪个 EID 创建 context,若该 EID 对应的 GID 为空,日志会提示 "GID is NULL, please check your EID index"。另外,updateUrmaGlobalConfig会根据设备实际能力自动下调max_ep_per_ctx与num_jfc_per_ctx,避免超出硬件容量(urma_endpoint.h)。

七、常见问题排查

现象排查方法
UbTransport: No URMA devices found确认 URMA 已正确安装且设备可见:ls /usr/lib64/liburma.so、检查头文件urma_api.h是否存在,用urma_admin -l查看设备列表
URMA module init failed确认 URMA 内核模块已加载:sudo modprobe urma,用sudo lsmod \| grep urma检查模块状态,用urma_admin -l查看设备状态
Device urma0 port not active确认 UB 端口已配置并激活:urma_admin -p urma0
cannot find -lurma确认liburma.so已安装且在库路径中:export LD_LIBRARY_PATH=/usr/lib64:$LD_LIBRARY_PATH

结语

Kunpeng UB Transport 为 Mooncake 在鲲鹏 950 CPU 平台上提供了一套与 RDMA 同层、针对片上互联优化的高速传输方案:URMA 语义层负责远程内存访问的统一抽象,OBMM 面向超节点内存共享场景,二者都以UbTransport这一统一接口接入 Mooncake 传输引擎。通过本文的构建开关、验证命令、基准测试与源码级剖析,开发者可以快速在 openEuler 24.03 + 鲲鹏 950 环境中启用ub协议,并借助 Mock URMA 在无硬件环境下先行验证传输层逻辑;后续可依据MC_NUM_CQ_PER_CTX等参数与设备能力进行调优,以适配大规模参数传输与分布式训练等场景。

  • 人工智能
  • 大模型
  • 模型推理服务
  • 后端

【免费下载链接】Mooncake

Mooncake is the serving platform for Kimi, a leading LLM service provided by Moonshot AI.

项目地址:https://gitcode.com/gh_mirrors/mo/Mooncake
点击查看免费下载

相关推荐

上一篇:5分钟精通SSHFS-Win:Windows远程文件挂载终极实战指南
下一篇:Tiled编辑器完全指南:从零开始制作专业级游戏地图

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

返回列表