hccl-capture 是一个独立于 HCCL 源码的工作负载捕获与 Trace Bundle 生成工程。HCCL 以只读 Git submodule 固定版本,捕获代码、schema、适配层和导出器全部位于本仓库。
推荐使用 native_docker 或 native_local 后端。每次捕获显式选择 HCCL source variant;工程按“submodule commit + overlay + CANN header”指纹,在隔离目录构建同源的 host libhccl.so、libhccl_compat.so 和 ST AICPU 内核。两条后端共用相同 spec、Runner、Bundle 和分析逻辑,均不修改 third_party/hccl。
当前原生 Runner 已覆盖 AllToAll、AllGather、AllReduce、ReduceScatter、Broadcast、Reduce、Scatter、 AllGatherV、ReduceScatterV、AllToAllV/VC、相邻配对 Send/Recv 和 BatchSendRecv。逐算子的参数语义、 Device、Execution Engine、拓扑、算子、算法实现和 HCCL/CANN 版本的全景见 能力边界矩阵;逐算子的参数语义、实跑 algTag 与细节见 算子兼容矩阵。
每次运行只生成 5 个核心文件:
manifest.json:输入、算法选路、指标、校验、requested/observed topology、endpoint 和 channel 的统一元数据。tasks.jsonl:完整 Task DAG 节点,并内联逐 task 的 Jetty/channel/port 注解。edges.jsonl:stream 顺序、LocalPost/Wait、跨 rank Post/Wait 依赖。p2p_flows.csv:逐 P2P activity 保存 payload、all-of 前驱 activity、ready wave、 launch group 和SendRecvWrite/Read双向 rendezvous;它不再是缺少依赖的 rank-pair 汇总表。raw.log.gz:压缩原始执行日志。
旧的拆分 Bundle 仍可读取,并可用 hccl-capture compact <目录> --recursive 原地升级。
原生后端的依赖边来自 TaskNode.parents/children,不是 stdout 推断。旧的 docker_st 日志后端仍保留作兼容兜底,其中 queue 顺序精确、Post/Wait 匹配为 best-effort。
| Device | 同输入实跑结果 | 当前捕获状态 |
|---|---|---|
DEV_TYPE_950 |
当前 Runner 中 13 类 workload 均已实跑,可导出真实 task、依赖和 P2P channel | 可选 |
DEV_TYPE_910B |
回退 HcclAlltoAllInner,当前 ST stub 返回 not support |
页面可见但禁用 |
DEV_TYPE_910_93 |
回退 HcclAlltoAllInner,当前 ST stub 返回 not support |
页面可见但禁用 |
这张表是“当前 HCCL tag + 当前 native ST 捕获入口”的能力矩阵,不代表 910B/910_93
不支持其他集合通信或实机 HCCL。Device 会从 spec 一直传到 SimWorld::Init,并写入 Bundle 的
requested/runtime 校验字段;不支持的组合在 Web、HTTP 和 CLI 三层都会拒绝。
spec 可用 execution.engine,页面可用 Execution Engine 下拉框选择:
| Engine | 当前捕获结果 | 已验证拓扑 |
|---|---|---|
AI_CPU |
完整 Task DAG、P2P、ready/join 与 channel | 950 的单 Server、两级 stock、UBX |
HOST_DPU |
完整 Task DAG、P2P 与 channel;algTag 含 DPU_host |
950 的两级多 Server;2×2、2×4 和 2+3 非对称已实跑 |
AIV |
selection-only:真实 AIV algTag 与 engine code 可见,但 beta3 ST 不展开 AIV kernel,Task/P2P 为 0 | 950 的单 Server和两级 stock;UBX replay 不兼容 |
HostDPU 的底层仍设置 HCCL_OP_EXPANSION_MODE=AI_CPU,并额外设置
ENABLE_HOSTDPU_FOR_LLT=1;AIV 设置 HCCL_OP_EXPANSION_MODE=AIV。AIV 为穿过 beta3 ST 缺失资源桩,
Runner 会把 ST 链路协议适配为 UB_MEM,并提供 host-backed engine context/registered-memory loopback;
这些适配名称全部写进 manifest,不能作为真实硬件端口或时延证据。
Task ID 形如 r0-q2-p3:r 是 rankIdx,q 是该 rank 内的逻辑 task queue/stream
queIdx,p 是 task 在该 queue 中从 0 开始的 pos。它在一份 Bundle 内可稳定引用,但 queue
分配和位置会随算法改变,因此不能当作跨算法的语义 flow ID。
仓库还包含本地 HCCL Capture Studio:标准前端工程位于 frontend/,采用 React、TypeScript、Vite、
TanStack Query 和 Lucide;生产构建作为 Python package 的静态资源随 CANN 容器直接启动,运行时不依赖 Node。
页面可以配置算子、算法、拓扑和消息参数,异步执行捕获,
并查看可交互 Task DAG、单-rank 拓扑无关通信调度、P2P rank 流量矩阵、Jetty/channel/端口字段和全部原始产物。Web 层
只调用上述 bundle 接口,不修改 HCCL,也不维护第二套分析逻辑。
推荐让服务和劫持都运行在 CANN 容器内,宿主机只需要 Docker:
git clone --recurse-submodules https://github.com/ubsim-dev/hccl-capture.git
cd hccl-capture
tools/start_containerized_studio.sh
docker logs -f hccl-capture-studio仓库将 HCCL submodule 固定在官方 v9.1.0-beta.3 tag,并直接使用与之配套的公开 CANN beta.3
开发镜像,不覆盖镜像内的 libhccl.so。hccl-st-work 保存 variant/ST/runner 编译缓存;源码以只读方式挂载到
/project,宿主机 out/ 以读写方式挂载到 /out,因此删除容器不会删除捕获结果。空卷会在首次启动时
快速启动服务,并在第一次使用某个 variant 时构建;后续按指纹复用缓存。
默认 CANN tag 同时提供 linux/arm64 与 linux/amd64。启动脚本按宿主机架构选择镜像 manifest,并将
CANN 目录解析为 aarch64-linux 或 x86_64-linux;远程 Docker daemon 场景可通过
HCCL_CAPTURE_PLATFORM=linux/amd64(或 linux/arm64)覆盖。
启动脚本默认继承宿主机 shell 中的 HTTP_PROXY、HTTPS_PROXY、ALL_PROXY 和
NO_PROXY(同时写入大小写两套变量)。如果代理监听在宿主机的 127.0.0.1、localhost 或
::1,脚本会在容器内改写为 host.docker.internal,Linux Docker 也会自动添加
host-gateway 映射。可用 HCCL_CAPTURE_INHERIT_PROXY=0 禁用;镜像拉取仍由宿主机 Docker
daemon 完成,因此 Registry 代理需要在 Docker daemon / Docker Desktop 中配置。
重复执行启动脚本不会无条件删除容器。镜像、源码、端口、挂载路径和代理配置的指纹一致且健康检查
通过时会直接复用;配置变化时先保留旧容器,只有新容器通过 /api/health 后才提交替换,失败则自动
回滚。需要明确重建时设置 HCCL_CAPTURE_RECREATE=1。out/ bind mount 和 /work Docker volume
独立于容器生命周期,首次 variant 构建中断后再次执行会复用健康服务和已有构建缓存。
bootstrap.sh 是同一流程的一键封装:它创建 Python 虚拟环境、启动容器化服务,并默认预热原版
variant:
git clone --recurse-submodules https://github.com/ubsim-dev/hccl-capture.git
cd hccl-capture
tools/bootstrap.sh本机访问 http://127.0.0.1:8787/,远程访问 http://<服务器IP>:8787/,默认 API Key 为 1234。
两种启动方式都会把固定的 HCCL submodule 以只读方式挂载,
按 variant 指纹构建完整 host HCCL 与同源 ST;可重复执行。完整的前置条件、镜像替换、HCCL 升级和
故障排查见 从零启动指南。
已有兼容容器时,也可以手动安装:
git submodule update --init --recursive
python3 -m venv .venv
.venv/bin/python -m pip install -e .
tools/prepare_st_container.sh hccl-capture-studio当前示例默认使用 hccl-capture-studio。也可以显式预热某个 variant:
tools/prepare_st_container.sh hccl-capture-studio stock_beta3
tools/prepare_st_container.sh hccl-capture-studio ubx_pipelined_beta3该脚本创建指纹化源码副本并成对构建 host HCCL 与 ST,不修改 submodule 或镜像内 CANN 安装。
.venv/bin/hccl-capture run \
examples/alltoall-single-server.json \
-o out/alltoall-single-server
.venv/bin/hccl-capture run \
examples/allgather-single-server.json \
-o out/allgather-single-server
.venv/bin/hccl-capture run \
examples/allreduce-single-server.json \
-o out/allreduce-single-server检查 submodule 和接口兼容性:
python3 tools/check_compatibility.py运行单元测试:
PYTHONPATH=src python3 -m unittest discover -s tests -v修改 Web 前端时运行:
cd frontend
npm install
npm run dev # /api 自动代理到 127.0.0.1:8787
npm test
npm run build # 更新 Python package 内的生产静态资源启动或重建容器化服务:
tools/start_containerized_studio.sh浏览器在本机访问 http://127.0.0.1:8787,或从其他机器访问
http://<服务器IP>:8787。首次进入需要 API Key,技术穿刺阶段默认值为 1234。服务会直接加载
out/ 中已有的 Trace Bundle,新捕获保存到 out/web-runs/。也可以使用安装后的 CLI:
hccl-capture serve --host 127.0.0.1 --port 8787 --bundle-root out容器化启动默认发布到所有 IPv4 网卡。生产或共享环境应通过
HCCL_CAPTURE_API_KEY=<强密钥> 覆盖默认值,并配合服务器防火墙限制来源;仅需本机访问时设置
HCCL_CAPTURE_HOST_BIND=127.0.0.1。页面和 API 的结构、扩展方式见
Capture Studio 设计与接口。
不使用页面时,直接运行 .venv/bin/hccl-capture run <spec> -o <output>;不传 -o 时默认保存到
out/<run.name>/。需要异步调度时也可以直接调用 POST /api/runs 并轮询任务状态。完整 CLI、HTTP 示例
和文件保存规则见 无网页捕获接口。
如果代码已经位于安装好 CANN 的开发机或容器内,可先运行
tools/prepare_hccl_variant.sh stock_beta3,再使用 native_local backend;此时 CLI 不调用 Docker,
variant 仍负责生成隔离的 host HCCL 与同源 ST。
auto 使用 HCCL 自动选择:
{"algorithm": {"variant": "stock_beta3", "mode": "auto"}}CLI/core 仍允许用 configured 设置 HCCL 原生 HCCL_ALGO,用于兼容性诊断和版本回归;值使用
CANN 规定的完整语法:
{"algorithm": {"variant": "stock_beta3", "mode": "configured", "hccl_algo": "alltoall=level0:NA;level1:pairwise"}}在当前 HCCL v9.1.0-beta.3 + AllToAll/AllGather AICPU 路径中,两套 selector 虽然解析该环境变量,
却都没有消费 configAlgMap。AllToAll 系统遍历 15 组配置、AllGather 实跑 Ring/Pairwise 对照后,实际
algTag、Task DAG 和 P2P 都没有变化。因此 Web 页面禁用这个无效选项;真正替换算法应使用
algorithm.variant 构建并加载新的 HCCL template/selector。CLI 保留该输入,是为了验证未来版本是否
开始消费它,而不是承诺它会改变当前 AllToAll。
是否真正改变执行必须同时看 manifest.json.selection 和 Bundle 对比,不能把
requested_hccl_algo 当成实际算法。原生后端会捕获实际 algTag;selection_verified=true 表示实际
选择可观察,不表示请求一定生效。
比较两个运行:
PYTHONPATH=src python3 -m hccl_capture compare \
out/alltoall-auto out/alltoall-pairwise \
-o out/compare.json报告中的 requested_change_observed 只有在实际选路、HCCL 观察到的拓扑、Task DAG 或 P2P 流量
至少一项发生变化时才为 true。这样可以区分“输入拓扑没有传进去”和“拓扑传进去了,但算法回退后
执行图仍相同”。
原生 runner 通过主程序符号抢占记录 HcclRankGraphGetTopoInstsByLayer、
HcclRankGraphGetRanksByTopoInst、HcclRankGraphGetTopoType 和 endpoint 查询,不修改 HCCL。
当前 beta3 AllToAll 原生 ST 已验证单 Server 和单 SuperPod 内多 Server 两级拓扑:
PYTHONPATH=src python3 -m hccl_capture run \
examples/alltoall-single-server.json -o out/alltoall-single
PYTHONPATH=src python3 -m hccl_capture run \
examples/alltoall-2level.json -o out/alltoall-2levelexamples/alltoall-3level-pod.json 保留为负向能力探针。beta3 的 TopoMatch1D 会拒绝三层
topoLevelNum,ST 的 endpoint 模型也不支持 layer 2,因此多 SuperPod 输入会在执行前得到明确错误,
不会生成看似成功但不真实的 DAG。自定义非对称拓扑目前支持一个 SuperPod 内不同规模的 Server,
例如 3+5 Rank。
ubx_mesh1d_clos overlay 已支持板内 Mesh endpoint/link、跨板 CLOS endpoint/link、4 个对称
Jetty channel,以及 channel 到 P2P task 的关联:
PYTHONPATH=src python3 -m hccl_capture run \
examples/alltoall-ubx.json -o out/ubx-16pv9.1.0-beta.3 使用该版本自己的 TopoMatchUBX/TopoMatchUBX1d 和 CCU/AICPU UBX 模板,Runner
按源码能力识别这条旧版原生路径,并在 manifest.json/ubx_multijetty_provider 中记录
native_beta3_legacy_ubx。若未来切换到新版 HCCL,版本化能力探测会区分新版 CANN 原生实现与外部
兼容实现,不会把两套算法混为同一个 baseline。
优化版 variant 会把
algorithms/ubx_pipelined_beta3/files/ 中可直接阅读的算法源码
安装到独立的指纹化 HCCL checkout,再应用小型
integration.patch。它把后续版本的 UBX 分轮调度作为
真实 HCCL template 回移到 beta3,并让同源 selector 发出独立 tag
InsAlltoAllMesh1DUBXPipelined。上游 submodule 保持干净;manifest 保存 variant 指纹、源码 commit、
实际加载路径和 host/ST SHA-256。原版和优化版不会重绑定同一个 tag。
原生 AlltoAll 的 workload 只保存 dtype、send_count_per_peer 和诊断用途的可选 HCCL_ALGO。拓扑是独立的
显式层级树 SuperPod[] → Server[] → physical_device_ids[],Rank ID 按树的稳定遍历顺序生成,
rank_count、Server 数和每层规模都是派生值。输入结构可以表达任意层级,但当前 beta3 AllToAll
执行能力限制为一个 SuperPod、至多两级;同一 SuperPod 内支持 Server 规模不同的非对称布局。UBX 的
boards/Jetty 作为 rank_graph overlay 保存,不冒充物理 Server。
AllGather 已通过同一个原生 HcclAllGather 入口验证五条实际选路:单机 Mesh1D、两层小消息
NHR、两层大消息 ParallelMesh1DNHR、UBX 4P ConcurrentMesh1DNHR,以及 UBX 8P
ParallelMesh1DNHRMultiJetty。这些选路由拓扑、Rank 数和 payload 阈值自动决定,不由当前版本的
HCCL_ALGO 决定。
p2p_flows.csv 表示真正执行的物理 P2P task,而不是抽象的“源数据贡献矩阵”。在 Mesh1D 中每个 Rank
直接从所有其他 Rank 读取,因此 8P 恰好有 56 条有向 activity,并形成 28 个精确的 SendRecvRead
rendezvous。NHR/Parallel 路径包含转发和并行分支,同一份贡献数据可能经过中间 Rank;应使用
predecessor_activity_ids、ready_wave 和 task slice offset 还原执行依赖,不能把每一行都解释为源数据
所有者到最终接收者的直达流。
当前 beta3 ST 的单 Server stock AllGather 已实跑确认最多稳定到 8 Rank;9–14P 会在通道就绪阶段超时, 15P 以上还会触发 TopoMatch/运行时资源错误。页面和 CLI 在执行前统一门禁这一已知边界。两层 2×4 与 UBX 8P 正常,不受该“单 Server stock”门禁影响。大于 1 GiB 聚合数据才会触发的 Sequence/Z-axis 分支 超出当前 ST 200 MiB CCL 内存模型,暂不宣称已验证。
下面的命令使用临时 Bundle 遍历 Rank 边界、拓扑、payload、dtype、UBX 源码变体和全部可解析的
HCCL_ALGO,只保留一个聚合 JSON,避免产生大量调试目录:
PYTHONPATH=src python3 tools/run_alltoall_matrix.py \
--output out/regression/alltoall-matrix.json可用 --case hccl-algo-pairwise 只跑一个 case,或用 --resume 复用已有结果并补跑新增 case。
当前 beta3/DEV_TYPE_950/ST 基线为 49 个 case:41 个通过、8 个已解释的预期失败、0 个未知失败。
已知边界包括 stock Mesh1D 的 9/11/13/15/17 Rank channel-ready timeout、多 SuperPod 三级拓扑不支持,
以及非法 HCCL_ALGO 语法被拒绝。
对于 AICPU InsAlltoAllMesh1D*,阶段解码器严格复现 HCCL 的
CalcCommRankSetForOneLoop:每个 rank 同时覆盖最多 16 个远端,17 rank 仍是一轮,18 rank 起才是多轮。
多轮之间按复用 queue/lane 流水依赖,不被解释为全局 barrier。dag_level 是真实 DAG 的 ASAP
拓扑深度,algorithm_round 才是算法语义轮次,两者不能混用。
成功执行时,UBX 的实际分支由外部 DFX algTag 捕获,原始 Task DAG 完整导出。阶段解码器复现
GetBoardSendRecvMatrix 与 GetRankSendRecvMatrix:跨板使用 round-robin board pairing,每个 board pair
包含“每板 Rank 数”个 rank step;板内 fullmesh 标注为与 board round 0 重叠。跨 step 依赖只收缩
真实 DAG 中已经存在的路径,不添加推测边。
端口字段分两层:jetty_index/logical_plane 是 task 实际使用的逻辑平面;port_selector 是 endpoint
EID 中参与 HCCL 建链筛选的字节。当前 replay 的兼容值为 127,它不是物理 NIC/交换机端口号。
若要得到真实硬件端口,必须录制实机 rank graph endpoint/link 或联合设备 profiling;ST 不能凭空恢复。
这份 trace 是 HCCL ST 模型展开出的逻辑任务与依赖,不是网卡抓包,也没有真实硬件上的排队、拥塞和协议头开销。适合算法仿真、依赖分析和解析流量建模;若目标是拟合实机时延,还需要用真实 profiling 数据校准链路带宽、启动开销和资源竞争参数。详见 设计说明。
- 每次提交固定一个 HCCL submodule SHA。
- 每份 bundle 分别保存 submodule 和实际执行后端的 HCCL commit、dirty 文件、容器镜像及关键 CANN/ST 动态库 SHA-256,禁止把镜像 tag 相同误判为运行时完全一致。
- 更新 submodule 后先运行兼容性检查和 golden tests。
- 不允许直接修改
third_party/hccl;CI 应检查其git status --porcelain为空。
- 扩展 native workload adapter:AlltoAllV/VC、AllReduce、AllGather、ReduceScatter、Send/Recv。
- 批量矩阵运行与 golden baseline/CI 回归。
libhccl_capture.so:LD_PRELOAD 录制真实应用的 endpoint/link/workload,再离线重放。- 把实机 profiling 的物理 port、带宽和拥塞计数器与逻辑 Jetty trace 对齐。