HIXL C++ 样例实战指南:KvCache 分离部署传输与 D2D/D2H 单边通信
2026/9/18 8:15:49 网站建设 项目流程

HIXL C++ 样例实战指南:KvCache 分离部署传输与 D2D/D2H 单边通信

【免费下载链接】hixlHIXL(Huawei Xfer Library)是一个灵活、高效的昇腾单边通信库,面向集群场景提供简单、可靠、高效的点对点数据传输能力。项目地址: https://gitcode.com/cann/hixl

导读

本文围绕 CANN HIXL 开源仓库 examples/cpp 下的 C++ 样例展开,系统讲解两类典型场景的落地方法:一类是基于 LLM-DataDist 接口实现的KvCache 分离部署(disaggregated serving)传输(pull / push cache 与 blocks、角色切换),另一类是基于 HIXL 原生接口实现的Device-to-Device(D2D)、Device-to-Host(D2H)单边通信(含单进程、多进程与 FabricMem 模式)。阅读本文后,你将掌握每个样例的源码结构、命令行参数、编译方式、运行前提与协议选择策略,并理解其背后的Initialize / RegisterKvCache / TransferSync / RegisterMem等核心调用链,可直接在昇腾 A2 / A3 / A5(Ascend 950PR/950DT)集群环境中复现与二次开发。

样例整体介绍与目录结构

本目录的样例通过 LLM-DataDist、HIXL 接口实现分离部署场景下 KvCache 传输功能。其中 LLM-DataDist 系列用于 Prompt/Decoder 分离部署时缓存与 KV block 的传输,HIXL 系列用于展示单边通信的多种协议与运行形态。

examples/cpp/ ├── prompt_pull_cache_and_blocks.cpp // pull cache 和 pull blocks 的 prompt 侧实现 ├── decoder_pull_cache_and_blocks.cpp // pull cache 和 pull blocks 的 decoder 侧实现 ├── prompt_push_cache_and_blocks.cpp // push cache 和 push blocks 的 prompt 侧实现 ├── decoder_push_cache_and_blocks.cpp // push cache 和 push blocks 的 decoder 侧实现 ├── prompt_switch_roles.cpp // switch_roles 的 prompt 侧实现 ├── decoder_switch_roles.cpp // switch_roles 的 decoder 侧实现 ├── hixl_example_d2rd.cpp // HIXL D2rD 单进程场景样例 ├── hixl_example_d2rh.cpp // HIXL D2rH 单进程场景样例 ├── hixl_example_d2rd_multiproc.cpp // HIXL D2rD 多进程场景样例 ├── fabric_mem_d2d.cpp // HIXL fabric-mem 模式下的 d2d 场景样例 └── CMakeLists.txt // 编译脚本

从编译脚本 examples/cpp/CMakeLists.txt 可以看到目标名称与源文件同名,其中前 6 个 LLM-DataDist 样例链接llm_datadist库,而hixl_example_d2rdhixl_example_d2rhhixl_example_d2rd_multiprocfabric_mem_d2d以及仓库另附的hixl_example_quickstart链接cann_hixl库,二者均依赖acl_rtascend_hal

环境与配置前提

A5 环境的 RDMA 链路说明

下面个别用例支持在 A5 环境使用 RDMA 链路执行,且需要在双机上执行,会在对应用例中特别说明。在 A5 环境中未手动配置local_comm_res时默认使用 UB 协议;如果需要使用 RDMA 链路,需要手动配置local_comm_res,配置方法参考 HIXL-interface.md 中 Initialize 的 options(Ascend 950PR/Ascend 950DT)说明。可通过以下操作获取 host 网卡的 IP 信息:

# 查询 RoCE 设备和网口的对应关系,查看状态为 Up 的网口名 ibdev2netdev # 根据网口名找出对应的 IP 信息 ifconfig

从接口文档对OPTION_LOCAL_COMM_RES的描述可以确认,A5(950PR/950DT)上配置local_comm_resversion"1.3"时使用 HixlCS 能力建链(推荐,需要 HDK 大于等于 25.5.0 且 toolkit 大于等于 9.1.0),无链路上限限制;而version"1.0"/"1.2"的 ranktable 格式则走集合通信通信域方式建链,建议单卡建链数量不超过 512。生产环境建议通过 scripts/tools/hixl_tool 工具辅助生成真实环境的 localcommres 信息,切勿直接拷贝样例值。

软件包与驱动

执行所有样例前,需要确保已经安装驱动和固件;执行 Python 样例前还需要安装 ops 包。构建编译需要 Toolkit 开发套件包,安装方式可参考 源码构建,包括 Docker 部署与手动安装两种场景(A5 容器还需要额外挂载/dev/ummu/dev/uburma设备与driver/topo目录)。

程序编译

参考 源码构建 中的编译执行章节,利用bash build.sh --examples进行编译:

# 若源码未改动或修改不涉及 src/ops 下的代码,建议添加 --host 参数 bash build.sh --examples bash build.sh --host --examples

编译结束后,在build/examples/cpp目录下生成多个可执行文件,其名称与上表源文件名一一对应。编译依赖的第三方开源软件(googletest、json、makeself、pybind11、cann-cmake)会在编译时自动下载,离线环境可通过--cann_3rd_lib_path={your_3rd_party_path}指定已上传的依赖包目录。

LLM-DataDist 样例:分离部署 KvCache 传输

通用运行说明

  • 所有样例需要成对运行,prompt 侧和 decoder 侧执行间隔时间不要过长。样例中 decoder 侧设置WAIT_PROMPT_TIME为 5s,prompt 侧设置WAIT_TIME为 10s,用户可根据实际情况自行修改这两个变量的值以保证用例成功运行。
  • 下面所有样例以 prompt 和 decoder 运行在相同机器上为前提编写,将local_ipremote_ip设为相同。

以 prompt_pull_cache_and_blocks.cpp 为例,源码中定义kPromptListenPort = 26000kPromptControlPort = 26002kPromptClusterId = 0kNumTensors = 4、tensor shape 为{8, 16}DT_INT32类型),并接受device_idlocal_ip、可选transfer_backend、可选local_comm_res共 2~4 个参数。

配置环境变量

若运行环境上安装的是 “Ascend-cann-toolkit” 包,环境变量设置如下(${HOME}/Ascend请替换为相关软件包的实际安装路径):

source ${HOME}/Ascend/cann/set_env.sh

若运行环境上安装的是 “CANN-XXX.run” 包,环境变量设置如下:

source ${HOME}/Ascend/latest/bin/setenv.bash

(1)pull_cache_and_blocks:decoder 向 prompt 拉取

此样例介绍 decoder 向 prompt 进行 pull cache 和 pull blocks 的流程,其中 link 和 pull 的方向与角色无关,可以根据需求更改。默认走 adxl 传输后端;可选参数transfer_backendhixl可切换为 hixl cs 后端。A5 环境上只支持使用 hixl cs 后端,默认走 UB 协议,可手动配置local_comm_res走 RDMA 链路。

  • 执行 prompt 侧,参数为device_idlocal_ip、可选transfer_backendlocal_comm_res,其中device_id为 prompt 要使用的 device_id,local_ip为 prompt 所在 host 的 IP:

    ./prompt_pull_cache_and_blocks 0 10.10.170.1 hixl
  • 执行 decoder 侧,参数为device_idlocal_ipremote_ip、可选transfer_backendlocal_comm_res,其中device_id为 decoder 要使用的 device_id,local_ip为 decoder 所在 host 的 IP,remote_ip为 prompt 所在 host 的 IP:

    ./decoder_pull_cache_and_blocks 2 10.170.10.1 10.170.10.1 hixl

从源码看,prompt 侧流程为:Initialize(写入OPTION_DEVICE_IDOPTION_LISTEN_IP_INFO与可选的OPTION_TRANSFER_BACKEND/OPTION_LOCAL_COMM_RES)→aclrtMalloc分配 4 个 tensor buffer 并初始化 →RegisterKvCache(cache_desc, tensor_addrs, {}, cache_id)注册 KvCache → 通过 26002 端口等待 decoder 完成 unlink 的通知(WaitUnlinkDone,超时 60s)→UnregisterKvCache释放。decoder 侧则解析remote_ip建链、执行 pull,再通知 prompt 侧可以释放。

(2)push_cache_and_blocks:prompt 向 decoder 推送

此样例介绍 prompt 向 decoder 进行 push cache 和 push blocks 的流程,其中 link 和 push 的方向与角色无关,可以根据需求更改。默认走 HCCL 传输后端;可选参数transfer_backendhixl可切换为 hixl 后端。在 A5 环境上使用 hixl 时默认走 UB 协议,可手动配置local_comm_res走 RDMA 链路。

  • 执行 prompt 侧,参数为device_idlocal_ipremote_ip、可选transfer_backendlocal_comm_res,其中device_id为 prompt 要使用的 device_id,local_ip为 prompt 所在 host 的 IP,remote_ip为 decoder 所在 host 的 IP:

    ./prompt_push_cache_and_blocks 0 10.10.10.1 10.10.10.1 hixl
  • 执行 decoder 侧,参数为device_idlocal_ip、可选transfer_backendlocal_comm_res,其中device_id为 decoder 要使用的 device_id,local_ip为 decoder 所在 host 的 IP:

    ./decoder_push_cache_and_blocks 4 10.10.10.1 hixl

(3)switch_roles:prompt 与 decoder 角色切换

此样例介绍 prompt 和 decoder 进行角色切换,并结合 pull 以及 push 使用流程。两端的参数均为device_idlocal_ipremote_ip三个必选参数。

  • 执行 prompt 侧,device_id为 prompt 要使用的 device_id,local_ip为 prompt 所在 host 的 IP,remote_ip为 decoder 所在 host 的 IP:

    ./prompt_switch_roles 0 10.10.170.1 10.170.10.1
  • 执行 decoder 侧,device_id为 decoder 要使用的 device_id,local_ip为 decoder 所在 host 的 IP,remote_ip为 prompt 所在 host 的 IP:

    ./decoder_switch_roles 2 10.170.10.1 10.170.10.1

参数与后端选型小结

样例默认传输后端可选后端参数(按顺序)
pull_cache_and_blocksadxlhixl(A5 仅支持 hixl cs 后端)prompt:device_id local_ip [transfer_backend] [local_comm_res];decoder:device_id local_ip remote_ip [transfer_backend] [local_comm_res]
push_cache_and_blocksHCCLhixlprompt:device_id local_ip remote_ip [transfer_backend] [local_comm_res];decoder:device_id local_ip [transfer_backend] [local_comm_res]
switch_roles--两侧均为device_id local_ip remote_ip

transfer_backend仅支持hixl取值,传其他值会在 Initialize 中直接报错并退出。local_comm_res为可选的本地通信资源 JSON 字符串,在 A5 上用于切换 RDMA 链路。

HIXL 样例:D2rD / D2rH 单边通信

运行形态说明

  • 单进程用例(hixl_example_d2rdhixl_example_d2rh)在一个进程内启动两个 engine,无需分开终端,在大于等于 CANN-9.1.0 版本支持。
  • 多进程用例(hixl_example_d2rd_multiproc)需要分别在两个终端启动 server 和 client,server 先启动,无 CANN 版本要求。
  • fabric_mem_d2d需要成对运行,两个终端分别启动。

HIXL 样例进程参数说明

参数适用样例必选/可选默认值说明
--protocol=<type>[,...]hixl_example_d2rd、hixl_example_d2rh、hixl_example_d2rd_multiproc必选-通信协议,支持逗号分隔多协议。hixl_example_d2rd 支持roce:deviceuboe:deviceub_rtp:deviceub_ctp:device;hixl_example_d2rh 支持roce:deviceuboe:deviceub_rtp:deviceub_ctpub_ctp:deviceub_ctp:host;hixl_example_d2rd_multiproc 支持hccs:deviceroce:deviceuboe:deviceub_rtp:deviceub_ctp:device。协议硬件依赖如下:hccs:deviceroce:device仅支持 Atlas A2 训练系列产品/Atlas A2 推理系列产品、Atlas A3 训练系列产品/Atlas A3 推理系列产品;uboe:deviceub_rtp:deviceub_ctpub_ctp:deviceub_ctp:host仅支持 Ascend 950PR/Ascend 950DT。协议定义详见 HIXL 接口 中comm_resource_config.protocol_desc的 option 说明。
--device=<id>--device=id1,id2hixl_example_d2rd、hixl_example_d2rh、hixl_example_d2rd_multiproc可选hixl_example_d2rd、hixl_example_d2rh 默认 0,2;hixl_example_d2rd_multiproc 默认 client=0、server=2hixl_example_d2rd、hixl_example_d2rh 使用--device=id1,id2指定两个 engine 分别绑定的 device;hixl_example_d2rd_multiproc 使用--device=<id>指定当前进程绑定的 device。
--version=0\|1hixl_example_d2rd、hixl_example_d2rh、hixl_example_d2rd_multiproc可选1配置为 0 时,表示使用 HCCL 集合通信通信域方式构筑的单边通信能力,仅支持 Atlas A2 训练系列产品/Atlas A2 推理系列产品、Atlas A3 训练系列产品/Atlas A3 推理系列产品;配置为 1 时,表示 HIXL 调用 HIXL CS 接口实现的单边通信能力,解耦通信域,推荐使用,支持 Atlas A2 训练系列产品/Atlas A2 推理系列产品、Atlas A3 训练系列产品/Atlas A3 推理系列产品、Ascend 950PR/Ascend 950DT。
--role=client\|serverhixl_example_d2rd_multiproc必选-指定当前进程为 client 或 server。
--local-engine=<ip:port>hixl_example_d2rd_multiproc可选client=127.0.0.1:16000、server=127.0.0.1:16001指定当前进程的 engine 地址。
--remote-engine=<ip:port>hixl_example_d2rd_multiproc可选client=127.0.0.1:16001、server=127.0.0.1:16000指定对端进程的 engine 地址。

几点源码级补充说明:

  • 在 hixl_example_d2rd.cpp 的ParseArgs中,--protocol缺失会被判定为错误;version=0模式仅接受roce:device单一协议。version=0 的 legacy 流程(ConfigLegacyOptions)会写入OPTION_LOCAL_COMM_RES={"version": "1.2"}OPTION_GLOBAL_RESOURCE_CONFIG={"comm_resource_config.listen_port": port}OPTION_BUFFER_POOL="0:0",并针对 roce 设置HCCL_INTRA_ROCE_ENABLE=1;而 version=1 的 v2 流程(ConfigV2Options)则写入OPTION_GLOBAL_RESOURCE_CONFIG={"comm_resource_config.protocol_desc": [...]},通过comm_resource_config.protocol_desc配置协议数组。
  • 关于protocol_desc,接口文档说明支持"ub_ctp"/"roce:device"/"hccs:device"/"ub_ctp:device"/"ub_ctp:host"/"uboe:device"/"ub_rtp:device"/"roce:host"。A5 上未配置该字段或仅配置ub_ctp:device时自动生成 Device UB 资源(Host 内存通过 UBMEM 映射到 Device 地址后使用 Device UB 链路传输);同时配置ub_ctp:deviceub_ctp:host时生成 Device+Host UB 资源并使用纯 URMA 路径,与单独配置ub_ctp等价。
  • 环境变量配置与 LLM-DataDist 样例相同,按 Toolkit 包或 run 包二选一执行source命令即可。

(1)hixl_example_d2rd:D2RD 单进程场景

单进程一个线程内启动两个 engine,分别绑定不同 device,由 engine A 发起 WRITE 传输到 engine B 的 device buffer。传输缓冲区 8 MiB,被切分为 512 个 16 KiB 的 block,逐个构造TransferOpDesc后通过TransferSync一次提交,最后将 engine B 的 device buffer 拷回 Host 校验是否为填充值0xAA(对应 Transfer/Verify)。

运行示例:

# 使用 roce:device 协议 ./hixl_example_d2rd --protocol=roce:device # 指定 device ./hixl_example_d2rd --protocol=roce:device --device=0,2 # 使用 version 0 模式(仅支持 roce:device) ./hixl_example_d2rd --protocol=roce:device --version=0

(2)hixl_example_d2rh:D2RH 单进程场景

单进程一个线程内启动两个 engine,分别绑定不同 device,双方各自发起 WRITE 传输到对方的 host buffer。该样例支持纯 URMA 的ub_ctp协议及其等价写法ub_ctp:device,ub_ctp:host

运行示例:

# 使用 roce:device 协议 ./hixl_example_d2rh --protocol=roce:device # 使用 UB CTP 纯 URMA 协议 ./hixl_example_d2rh --protocol=ub_ctp # 原有 Device+Host 写法同样使用纯 URMA 协议 ./hixl_example_d2rh --protocol=ub_ctp:device,ub_ctp:host # 使用 version 0 模式 ./hixl_example_d2rh --protocol=roce:device --version=0

(3)hixl_example_d2rd_multiproc:D2RD 多进程场景

两个独立进程分别启动 engine,通过 socket 交换 buffer 地址后,由 client 发起 READ 传输并本地校验。从 hixl_example_d2rd_multiproc.cpp 可以看到,server 在local_engine端口号 +1000 的偏移端口上监听,接受 client 连接后将本地 device buffer 地址发送出去;client 通过 socket 获取远端地址后执行TransferSync(READ),再校验数据是否为填充值0xAA。该样例支持hccs:device,是唯一覆盖 HCCS 协议的多进程样例,且 version=0 模式支持roce:devicehccs:device

运行示例(注意 server 先启动):

# 使用 roce 协议 ./hixl_example_d2rd_multiproc --role=server --protocol=roce:device ./hixl_example_d2rd_multiproc --role=client --protocol=roce:device # 使用 hccs 协议 ./hixl_example_d2rd_multiproc --role=server --protocol=hccs:device ./hixl_example_d2rd_multiproc --role=client --protocol=hccs:device # 使用 version 0 模式 ./hixl_example_d2rd_multiproc --role=server --protocol=roce:device --version=0 ./hixl_example_d2rd_multiproc --role=client --protocol=roce:device --version=0

fabric_mem_d2d:FabricMem 模式 D2D 场景

版本与硬件前提

  • FabricMem 仅支持 Atlas A3 训练系列产品/Atlas A3 推理系列产品,最低支持 HDK 25.5。
  • HDK 25.5 不支持aclrtMemRetainAllocationHandle。在该版本上,FabricMem 场景的 Host 内存必须使用 ADXL 提供的MallocMem/FreeMem进行申请和释放。
  • HDK 26.0 及以上版本可以直接使用 ACL 接口管理 FabricMem 场景的 Host 内存。
  • 当前fabric_mem_d2d样例在AllocateBuffer中直接使用 ACL VMM 接口aclrtReserveMemAddressaclrtMallocPhysicalaclrtMapMem分配内存,随后以MEM_DEVICE注册,未通过 ADXL 的AdxlEngine::MallocMem分配。该注册路径需要aclrtMemRetainAllocationHandle,因此样例要求 HDK 26.0 及以上版本,不兼容 HDK 25.5。样例中的aclrtMallocHost/aclrtFreeHost仅用于初始化和校验 buffer,并非 FabricMem Host 内存注册。

从 fabric_mem_d2d.cpp 源码可以看到,Initialize阶段向 options 写入OPTION_ENABLE_USE_FABRIC_MEM = "1"以开启 FabricMem 能力,随后通过ConnectTransferSync(WRITE)完成跨 engine 的显存到显存写入,两端以文件(<ip:port>命名的本地文件)方式交换对方 buffer 地址,具备 60s 等待超时。传输大小为 2 MiB,写 1 MiB。

运行方法

两个终端成对运行,参数为device_id、local engine 和 remote engine,其中device_id为当前 engine 要使用的 device_id:

  • 终端一(server1):

    ./fabric_mem_d2d 0 127.0.0.1:16000 127.0.0.1:16001
  • 终端二(server2):

    ./fabric_mem_d2d 1 127.0.0.1:16001 127.0.0.1:16000

常见问题与排查建议

  • 成对运行与超时:LLM-DataDist 样例的 prompt/decoder 必须成对启动且间隔不宜过长,若超时可增大源码中的WAIT_PROMPT_TIME(decoder 侧,默认 5s)与WAIT_TIME(prompt 侧,默认 10s)。
  • A5 默认协议与 RDMA 切换:A5 上未手动配置local_comm_res时默认走 UB 协议;需要 RDMA 时须手动配置local_comm_res(推荐version: "1.3"),并先用ibdev2netdevifconfig确认 RoCE 网口与 IP。可参考 scripts/tools/hixl_tool/readme.md 使用工具生成 localcommres 信息。
  • 协议与硬件不匹配hccs:deviceroce:device仅支持 A2/A3 系列产品,uboe:deviceub_rtp:deviceub_ctp*仅支持 Ascend 950PR/950DT,选型时务必与protocol_desc的硬件依赖对齐。
  • version 模式限制:version=0(HCCL 通信域方式)仅支持roce:device(d2rd/d2rh)或roce:device/hccs:device(multiproc),且仅支持 A2/A3 系列产品;新项目建议使用默认的 version=1(HIXL CS 方式)。
  • FabricMem 版本兼容:当前fabric_mem_d2d样例基于aclrtMemRetainAllocationHandle的注册路径,要求 HDK 26.0 及以上;HDK 25.5 上应改用 ADXLMallocMem/FreeMem管理 Host 内存。

如需继续深入学习,可结合 HIXL C++ 接口文档(重点看 Initialize 的 options 与comm_resource_config.protocol_desc字段说明)以及 LLM-DataDist 接口文档 理解各 option 的完整语义;也可参考 examples/README.md 了解 Python 侧样例与其余示例。

【免费下载链接】hixlHIXL(Huawei Xfer Library)是一个灵活、高效的昇腾单边通信库,面向集群场景提供简单、可靠、高效的点对点数据传输能力。项目地址: https://gitcode.com/cann/hixl

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询