F3 多卡与分布式:脚本从单卡到多卡要改什么
编制:观澜|日期:2026-10-06|级别:T2 标准级 层级:F 层 · 场景实战(F 层第 3 课;前接 F1 模型迁移) 素材来源:昇腾官方 CANN 文档(《HCCL 集合通信库》《HCCL 性能测试工具》)+ ModelZoo《执行训练》 + TorchNPU《torch_npu_run》《RANK_TABLE_FILE》 + 昇腾官方故障案例库 本课定位:F1 解决的是「一份脚本怎么从 GPU 搬到 NPU」,落脚在单卡。 这一课解决的是「一张卡不够用,8 卡、16 卡、多机怎么弄」——还是脚本层面,不改架构。 ⚠️ 本课不讲服务化部署的多卡调度(PD 分离、混部)——那是 D4 的内容,不重复。
第一段 章前定位
F1 做完,一份脚本能在一张卡上跑起来了。接下来几乎所有真实任务都会立刻撞到同一堵墙:
一张卡太慢,或者模型根本装不下一张卡。
这时候要做的事有个统一的名字——多卡(分布式)。它要解决的不是「怎么装」,也不是「怎么迁」,而是:
让 N 个进程同时算同一件事,并且把每一步的结果对齐。
这一课要讲清三件事:
- 单卡脚本改哪几处,才能变成多卡脚本(官方《执行训练》给了明确的四个必改点);
- 卡与卡之间靠什么"说话" —— 答案是 HCCL(华为集合通信库),你把
backend指成它就行; - 为什么"多卡跑起来没报错"不等于"多卡跑对了" —— 以及怎么用官方工具
hccl_test把"通信真的通"这件事单独验一遍。
本课不教什么(先说清,免得越界):
| 不教的内容 | 去哪一课 |
|---|---|
| 服务化部署里的多卡调度、PD 分离、混部 | D4(已发) |
| 多卡跑完结果和参考平台对不上(精度) | F2 精度调试 |
| 多卡训练慢在哪里、怎么调 | F4 性能调优 |
| 多卡推理服务的拉起 | D2 / D3(已发) |
一句话定位:F1 是"把脚本搬到昇腾",F3 是"把脚本从 1 张卡扩展到 N 张卡"。 两件事都在脚本层面,都不碰服务化。
第二段 学习目标
学完这一课,你应该能:
- ✅ 说出多卡场景里绕不开的三个词:rank、通信域、
backend="hccl"—— 并说清它们各自是什么 - ✅ 把一份单卡脚本改成单机多卡脚本(官方给的四个必改点,一处不漏)
- ✅ 用
torchrun拉起单机多卡,用torch_npu_run拉起集群(官方推荐) - ✅ 用官方工具
hccl_test单独验证「卡与卡之间真的能通信」——这是"多卡跑起来了"和"多卡跑对了"之间的那道闸 - ✅ 按网络层 → 建链层 → 脚本层的顺序定位多卡故障,不再对着一个卡死的进程干等
第三段 全景:多卡到底在改什么
3.1 先给一张图(单卡 → 多卡 → 底下那层)
┌────────────────────────────────────────────────────┐
│ 单卡:1 进程 → 1 张卡,没有"通信"这回事 │
│ (F1 迁完的样子) │
└────────────────────────────────────────────────────┘
↓ 多卡 = 加 4 样东西(见第四段)
┌────────────────────────────────────────────────────┐
│ 多卡:N 个进程 → 各占 1 张卡(rank 0..N-1) │
│ init_process_group(backend="hccl") ← 关键行 │
└────────────────────────────────────────────────────┘
↓ 这一行背后,是通信库在干活
┌────────────────────────────────────────────────────┐
│ HCCL —— 华为集合通信库(CANN 核心组件) │
│ rank / 通信域 / 通信算子 / 通信算法 │
│ AllReduce、Broadcast、AllGather ... │
└────────────────────────────────────────────────────┘
这张图要读出来的三件事:
- 多卡的"多",是进程级的多 —— 一个 device 对应一个训练进程(官方约束,第五段会给原文);
- 进程之间要"对齐",靠的是
backend指定的那套通信方案,在昇腾上就是 HCCL; - HCCL 是 CANN 的核心组件,也就是说它在 B1 装 CANN 的时候就已经到位了,多卡不需要再装别的东西。
3.2 五个词(官方《相关概念》原文口径)
| 词 | 官方定义(原文) | 一句话理解 |
|---|---|---|
| AI Server | 又称计算节点,通常是 8 卡或 16 卡的昇腾 NPU 设备组成的服务器形态的统称 | 一台机器 |
| AI 集群 | 多个 AI Server 通过交换设备互联后用于分布式训练或推理的系统 | 一堆机器 |
| 通信成员 | 通常称为 rank,是参与通信的最小逻辑实体,每个 rank 都会分配一个唯一标识 | 一个进程的编号 |
| 通信域 | 一组通信成员的组合,描述通信范围。一个计算任务可以创建多个通信域,通信成员也可以加入多个通信域 | "这一组人一起对表" |
| 通信算子 | 在通信域内完成通信任务的算子,集合通信指所有成员一起参与的通信操作,如 Broadcast、AllReduce 等 | 一次"集体对表"的动作 |
⭐ 官方在《相关概念》里还给了一个很有用的补充: 「若 AI Server 间通过灵衢总线交换设备进行连接,组成的组网称之为超节点组网」。 —— 这就是 A3 课里提到的"超节点",它是"多机"的一种紧耦合形态,链路带宽和普通以太组网不一样,后面排障时会用到。
3.3 HCCL 是什么(官方《HCCL 简介》原文)
集合通信库 HCCL(Huawei Collective Communication Library)是基于昇腾硬件的高性能集合通信库, 为计算集群提供高性能、高可靠的通信方案。
官方列出的六项核心功能(原文):
- 提供单机、多机环境中的高性能集合通信和点对点通信;
- 支持 AllReduce、Broadcast、AllGather、ReduceScatter、AlltoAll、Send、Receive 等集合通信原语;
- 支持 Ring、Mesh、Recursive Halving-Doubling(RHD) 等通信算法;
- 支持 HCCS、RoCE、PCIe、UB(Unified Bus) 等高速通信链路;
- 支持单算子和图模式两种执行模式;
- 支持通信算子的自定义开发。
软件架构(官方原文):HCCL 包含两个部分 ——
- HCCL 集合通信库:包含内置通信算子和扩展通信算子,提供对外的通信算子接口;
- HCOMM 通信基础库:把通信能力划分为控制面(拓扑信息查询与通信资源管理)与数据面(数据搬运和计算)两部分。
3.4 ⭐ 最关键的一条:为什么"改 backend 那一行"就够了
很多人第一次看多卡教程会疑惑:HCCL 是个库,为什么我只改一行 backend="hccl" 就能多卡了?
官方《主流框架集成》给了答案(原文):
针对 PyTorch 和 MindSpore 框架,HCCL 的调用已集成到 TorchNPU 和 MindSpore 框架代码中, 开发者指定使用 HCCL 作为分布式后端,直接使用框架原生通信 API,即可实现分布式能力。
把它翻译成人话:
你要写的 :torch.distributed.init_process_group(backend="hccl", ...)
框架(TorchNPU):收到 → 转成 HCCL 的 C 接口调用 → 下发到加速引擎
HCCL :真正去搬数据、做 AllReduce
所以多卡脚本的改动量很小 —— 改的不是"用哪个库",而是"告诉框架走哪条后端"。 这也是为什么本课的重点是改哪几行 + 怎么验,而不是学一套新 API。
⚠️ 官方同时提醒:HCCL 在系统中的工作方式取决于 AI 框架的编程执行形态—— 单算子模式、图模式(Ascend IR)、图捕获模式(aclgraph) 三种形态下,HCCL 的调用路径不一样。 这一点在 C3(框架适配原理)里讲过原理,排障时会用到:同一个通信报错,图模式和单算子模式的排查方向不同。
3.5 ⭐ 一条从 F1 带过来的高频坑(多卡场景里最容易踩)
F1 讲自动迁移时给过这条,它在多卡场景里会被反复踩到,所以在本课再说一遍(官方《自动迁移》原文口径):
若原脚本中使用的 backend 为
nccl,在init_process_group初始化进程组后, backend 会被自动迁移工具替换为hccl。 如果后续代码逻辑包含 backend 是否为 nccl 的判断,例如assert backend in ['gloo', 'nccl']、if backend == 'nccl', 请手动将字符串nccl改写为hccl。
为什么它在多卡场景里"更"容易踩:因为这段判断代码只有走到多卡分支才会执行。
单卡跑得好好的,一上多卡就报断言失败 —— 上面那行 assert 就是元凶。
⭐ 一句话记住:自动迁移能改"接口调用",改不了"写在字符串里的平台名"。 多卡前,先在脚本里搜一遍
nccl和gloo,把该改的字符串改掉。
3.6 本课与前后的关系
F1 模型迁移(GPU → NPU,单卡) ← 上一课
│
▼
F3 多卡与分布式(1 卡 → N 卡) ← 本课:改脚本、起多卡、验通信
│
├─→ F2 精度调试(多卡跑对了,但结果不对)
└─→ F4 性能调优(多卡跑对了,但慢)
│
D4 PD 分离与混部(服务化侧的多卡调度) ← 另一条路,不在本课
第四段 【如果我来做】—— 从「单卡跑通」到「多卡跑对」
这一节是本课的核心。 前三段讲的是"多卡是什么、底下有哪几样东西",这一节讲的是: 如果现在把这件事交给我,我从哪里开始、按什么顺序做、每一步凭什么判断。
4.0 先亮结论:我会按这个顺序做
为什么顺序不能反:多卡最容易犯的错是上来就改脚本——
- 网络根本不通,你却在改
world_size,改一天也跑不起来(多卡的错有一大半在网络层,不在脚本里); - 单卡还没跑通就上多卡,一报错分不清是"多卡引入的"还是"脚本本来就有"(F1 那条铁律在多卡里同样成立)。
我会按这个顺序做(顺序 = 我"手伸进去"的顺序):
① 先确认单卡能跑:多卡是在单卡脚本上长的,单卡不跑通、多卡无从谈起 ② 摸底(下命令查事实):这台机器有几张卡、卡与卡网络通不通 —— 这两件不查清,后面全是盲改 ③ 定规模:官方约束集合通信仅支持 1/2/4/8P 粒度 —— 先用单机 8 卡,别一上来就多机 ④ 改脚本(四个必改点):
world_size/local_rank→device→init_process_group(backend="hccl")→DDP+DistributedSampler⑤ 起单机多卡并立刻验:torchrun拉起,看 rank0 的迭代日志,比对 loss 是否和单卡对得上 ⑥ 验通信(单独验一遍):用官方hccl_test把"通信真的通"和"脚本写对了"分开验 —— 混在一起查不出问题 ⑦ 上多机(单机跑对之后):先配 device IP + 查网络健康,再torchrun多机 /torch_npu_run⑧ 诚实:官方没给的地方(具体 rank table JSON 字段、通用性能数字)明说"这里要自己查",不编
下面把中间的每一步展开。
4.1 第 ① 步:先确认单卡能跑(不碰任何多卡的东西)
目的:拿到一份「能跑通的单卡基准」。多卡之后如果 loss 不对,这份基准是唯一能证明"不是我改坏的"的东西。
我会先做这件事:把 F1 迁好的脚本,在一张卡上完整跑一遍(哪怕只跑 1 个 step),
然后记下两样东西:
- 迭代日志里第一个 step 的 loss(多卡后要拿它对);
- 脚本里有没有
nccl/gloo的字符串判断(3.5 那条坑,这时候先搜出来)。
为什么先做这一步:多卡引入了两层新变量(进程数和通信), 如果单卡基准没有,之后一报错你要同时怀疑三件事 —— 排查成本直接翻三倍。
4.2 第 ② 步:摸底 —— 查两张"不可返工"的底牌
摸底是"下命令查事实",不是"凭感觉改脚本"。 我会查两件事:
| 查什么 | 怎么查 | 查到什么算合格 | 不合格去哪 |
|---|---|---|---|
| 有几张卡 | torch.npu.device_count() |
输出 ≥ 2(单机多卡的前提) | 回 A0(系统认不认卡) |
| 卡与卡通不通 | hccn_tool -i <ID> -ip -g + -net_health -g |
device IP 有值、net health 为 Success | 本课第七段 |
⭐ 为什么"几张卡"要单独查:官方约束里有一条 —— 一个 device 对应执行一个训练进程,当前不支持多进程在同一个 device 上进行训练。 也就是说 卡数 = 进程数。不知道卡数,你连
nproc_per_node该填几都不知道。⭐ 为什么多机前必须查网络:官方案例库把多机失败的第一条原因直接写成 「多机节点的 NPU device ip 不能互相 ping 通」。这不是脚本问题,先查网络再动脚本。
4.3 第 ③ 步:定规模(别默认上多机)
官方对参与集合通信的 NPU 数目有明确约束,先按它定规模:
| 产品 | 单 Server 场景 | Server 集群场景 |
|---|---|---|
| Atlas 训练系列产品 | 只能为 1/2/4/8,且 0-3 卡和 4-7 卡各为一个组网 | 只能为 1*n、2*n、4*n、8*n(n 为 Server 数,上限 512) |
| Atlas A2 / A3 训练系列产品 | 对参与集合通信的 AI 处理器数量无限制 | (1\~8)*n(n 为 Server 数,上限 1152) |
并且官方另有一条更粗的约束:集合通信仅支持 1/2/4/8P 粒度的分配。
⭐ 我的做法:先在单机 8 卡上跑通,再考虑多机。 理由:单机多卡不涉及 device IP 配置、交换机、防火墙这一整套集群配置, 把"脚本改对了吗"和"网络通不通"这两件事分开验证 —— 这是多卡里最省时间的一条纪律。
4.4 第 ④ 步:改脚本(官方给的四个必改点)
这是本课的"体力活",官方《执行训练》给的单机单卡 → 单机多卡四个必改点,一处都不能漏(代码在第五段逐条给):
| # | 改什么 | 官方原文给的写法 |
|---|---|---|
| 1 | 从环境变量取进程信息 | world_size = int(os.environ["WORLD_SIZE"]) / local_rank = int(os.environ["LOCAL_RANK"]) |
| 2 | 用 local_rank 自动取 device 号 | device = torch.device(f'npu:{local_rank}') |
| 3 | 初始化进程组,通信方式设为 HCCL | torch.distributed.init_process_group(backend="hccl", rank=local_rank, world_size=world_size) |
| 4 | 开启 DDP + 分布式采样 | DistributedDataParallel(model, device_ids=[local_rank], output_device=local_rank) + DistributedSampler 赋给 DataLoader 的 sampler |
⭐ 第 4 点里最容易漏的是
DistributedSampler:忘了它,8 张卡会把同一份数据各算 8 遍 ✗—— 训练能跑完、日志也正常,但等于批量只有 1/8。这类"不报错但不对"的错,比报错难查得多。
4.5 第 ⑤ 步:起单机多卡,并立刻验
每改一处,立刻跑一次,不攒着一起跑(F1 的原则,多卡里同样成立)。
验收口径(对应第六段):
- rank0 的迭代日志开始打印 ✓
- 第一个 step 的 loss 与单卡基准在同一量级(不是"相等",多卡有梯度聚合,数值会有差异)✓
- 不是"进程起来了、没报错"就算过 ✗
4.6 第 ⑥ 步:把通信单独验一遍(本课独有的一步)
这一步最容易省,但省了最吃亏。
多卡启动失败有两大类原因,现象都是"卡住/报错":
A 类:脚本写错了(world_size 没填、sampler 忘了、backend 字符串还是 nccl)
B 类:通信根本不通(网卡选错、端口被占、防火墙拦住、device IP 不通)
如果只用"跑训练脚本"这一个动作去验,A 和 B 的现象混在一起,你无从下手。
所以我会单独跑一次官方工具 hccl_test —— 它不跑模型,只做集合通信本身:
- 通 → 问题在脚本(A 类),去查四个必改点;
- 不通 → 问题在网络/建链(B 类),去查网卡、端口、防火墙。
⭐ 这就是本课和第 ⑦ 步的价值:把"通信"和"脚本"分成两个可独立验证的东西。 官方专门提供了
hccl_test这个工具来测「HCCL 集合通信的功能正确性以及性能」,就是为这件事准备的。
4.7 第 ⑦ 步:上多机(单机跑对之后才做)
多机 = 单机多卡 + 一套集群配置。官方《执行训练》给的多机顺序是:
① 组网(交换机 / 光口直连)
② 配 device IP(hccn_tool -i N -ip -s address ...)
③ 配网络检测对象 IP(hccn_tool -i N -netdetect -s address ...)
④ 查网络健康(hccn_tool -i N -net_health -g)→ 必须 Success
⑤ 关防火墙
⑥ 确认交换机状态(hccn_tool -i N -lldp -g)
⑦ 调内核参数(somaxconn / tcp_max_syn_backlog)
⑧ 拉起多机训练(torchrun 多机 / torch_npu_run)
⭐ 我的判断点:第 ④ 步 net_health 是整条链的闸门。
它不 Success,后面一步都别做 —— 那是在浪费计费时间。
4.8 第 ⑧ 步:出证据 + 诚实
出证据:留下一份能给别人看的东西 —— 多卡启动命令、rank0 日志、hccl_test 的输出表。
诚实:下面这些官方没给出,我会明写"需现场确认",不编:
- rank table 文件的具体 JSON 字段结构 —— 官方只给了用途与约束(JSON 格式、不能是软链接、要有读权限),并指向《HCCL 集合通信库》的"集群信息配置"章节,本课不复述字段;
- 多卡训练的性能数字 —— 官方文档里没有给出通用加速比,本课不给任何数字。
第五段 从单卡脚本到多卡脚本:改什么 + 怎么起(命令详解)
本段是"怎么动手"。先改脚本(四段代码),再查网络(三条命令),最后启动(三条命令), 需要时再上
hccl_test(两条命令)。 ⚠️ 下面每条命令后紧跟的五项 —— 含义 / 拆解 / 用法 / 期望 / 不过会怎样 —— 请当成"现场照着敲"的清单。
A · 摸底的命令
命令 python3 -c "import torch, torch_npu; print(torch.npu.device_count())"
含义:查这台机器上昇腾卡的数量 —— 多卡脚本里
world_size/nproc_per_node的依据 拆解:python3 -c "..."(直接执行一段 Python,不建文件)+import torch, torch_npu(加载 PyTorch 与昇腾插件,见 C1)+torch.npu.device_count()(返回可用 NPU 个数,官方《执行训练》示例里就用它取devices_per_node)+No module named 'torch_npu'就先sourceCANN 环境变量(回 B1) 期望:打印一个整数,如8—— 这个数就是单机的最大进程数上限 不过会怎样:报No module named→ 环境没 source / TorchNPU 没装(回 C1);输出0→ 卡没被识别,先回 A0 查npu-smi info
命令 hccn_tool -i 0 -ip -g
含义:查 0 号 NPU 的 device IP —— 这是多机场景能不能"互相找到"的第一步 拆解:
hccn_tool(A3 讲过的集群网络管理工具,单卡用不上,多卡/超节点运维要用)+-i 0(设备 ID)+-ip(操作对象:IP)+-g(get,查询;-s才是 set) 用法:单机多机都建议查一遍;多机时写成for i in {0..7}; do hccn_tool -i $i -ip -g; done一次看 8 张卡 期望:打印ipaddr:...和netmask:...两行(官方原文:返回上述打印则表示已经连通) 不过会怎样:报命令不存在 → 驱动/hccn_tool 不在 PATH(回 A1/A3);IP 为空 → 还没配 device IP(多机必须先配)
命令 for i in {0..7}; do hccn_tool -i $i -net_health -g; done
含义:查每张卡所在网口的网络健康状态 —— 多机拉起前的整条链闸门 拆解:
for i in {0..7}(循环 8 张卡)+-net_health(网络健康检测对象)+-g(查询) 用法:在多机的每一台上执行,两边都要看 期望:每张卡回显net health status: Success(官方状态码表:0即 Success) 不过会怎样:回显1/2/3/4等非 0 值 → 官方状态码对应 Socket fail / Receive timeout / Unreachable / Time exceeded,属网络层故障;此步不 Success,不要去起训练
B · 起多卡训练的命令
命令 torchrun --nnodes=1 --nproc_per_node=8 --master_addr localhost --master_port 12345 train_8p_torchrun.py
含义:单机 8 卡启动(官方《执行训练》"单机多卡示例"给的原命令) 拆解:
torchrun(PyTorch 官方启动器)+--nnodes=1(节点数 1)+--nproc_per_node=8(每节点进程数 = 卡数)+--master_addr localhost(本机)+--master_port 12345(通信端口,要挑一个空闲的)+ 最后的train_8p_torchrun.py(你的训练脚本) 用法:--nproc_per_node填4.2 查出来的卡数;--master_port冲突就换一个 期望:8 个进程起来,rank0 开始打印迭代日志(脚本里的if local_rank_idx == 0: print(...)生效) 不过会怎样:卡在 init → 见第七段;报Address already in use→ 端口被占(官方案例ptacase_0043同源问题,改端口或按 4.6 预留端口)
命令 torchrun --nnodes 2 --node_rank 0 --nproc_per_node 8 --master_addr xxxx --master_port 12345 train_16p_torchrun.py
含义:双机 16 卡启动 —— 在主节点执行的那一条(官方《执行训练》"多机多卡示例"原文) 拆解:
--nnodes 2(2 个节点)+--node_rank 0(本机是第 0 号节点)+--nproc_per_node 8(每机 8 卡)+--master_addr xxxx(主节点 IP)+--master_port 12345用法:官方要求依次在每个节点执行;从节点把--node_rank改成1、其余不变:torchrun --nnodes 2 --node_rank 1 --nproc_per_node 8 --master_addr xxxx --master_port 12345 train_16p_torchrun.py期望:两个节点各起 8 个进程,全局 16 个 rank 参与同一次训练(脚本里用RANK取全局序号) 不过会怎样:从节点不起来 → 先回头查 4.7 的 ④net_health、⑤防火墙;报连接超时 → 官方案例topic_0000001589975097(防火墙可能拦了集合通信端口)
命令 torch_npu_run --rdzv_backend=parallel --master_addr=$MASTER_IP_ADDR --master_port=$MASTER_PORT --nnodes=1 --nproc_per_node=8 ddp_test.py
含义:用
torch_npu_run(官方:torchrun 在大集群场景的改进版,提升集群建链性能)拉起 —— 官方在《执行训练》里标注"集群场景推荐" 拆解:torch_npu_run(torchrun的昇腾增强版)+--rdzv_backend=parallel(建链后端)+--nnodes=1 --nproc_per_node=8(同 torchrun 语义)+ddp_test.py(训练脚本,示例名,换成你自己的) 用法:先用export MASTER_IP_ADDR=<node_rank0 的 IP>、export MASTER_PORT=<一个空闲 tcp 端口>(官方样例写法); 多机时两端都加--node_rank 0/1;再想提速就加--enable_tiered_parallel_tcpstore=true(官方:推荐在大规模集群场景下使用) 期望:训练拉起;节点多时建链时间不再随进程数线性增长(官方说明:分层建链把时间复杂度从 O(n) 降到 O(√n)) 不过会怎样:报命令不存在 → TorchNPU 版本不含该特性(官方属 TorchNPU 26.1.X);报建链失败 → 回torchrun先用小规模验证,再排查集群
C · 预留 HCCL 端口(官方 CAUTION,多卡必做一次)
命令 sysctl -w net.ipv4.ip_local_reserved_ports=60000-60015
含义:给 HCCL 预留 60000-60015 这 16 个端口(官方原文:分布式训练场景下,HCCL 会使用 Host 服务器的部分端口进行集群信息收集,需要操作系统预留该部分端口) 拆解:
sysctl -w(write,临时写内核参数)+net.ipv4.ip_local_reserved_ports=(保留给系统自用的本地端口区间)+60000-60015(HCCL 建议使用的 16 个端口) 用法:临时生效就敲这一条;要永久生效 →vim /etc/sysctl.conf,末尾加net.ipv4.ip_local_reserved_ports=60000-60015,再sysctl -p; 官方注明:物理机在物理机配,容器场景在容器里配 期望:命令回显写入的值,ip_local_reserved_ports变为60000-60015不过会怎样:不配 → 端口被别的组件占用时,官方案例ptacase_0043的报错会出现在你的日志里:Failed to bind the IP port. ... The IP address and port have been bound already.
D · 单独验通信:hccl_test(官方工具,多卡必备)
命令 cd ${INSTALL_DIR}/tools/hccl_test && make MPI_HOME=/usr/local/mpich
含义:进入官方 HCCL 性能测试工具的源码目录并编译它 拆解:
${INSTALL_DIR}(CANN 安装路径,root 默认/usr/local/Ascend/cann,见 B1)+tools/hccl_test(工具源码所在,官方原文路径)+make+MPI_HOME=/usr/local/mpich(告诉 make 用哪个 MPI,官方给的编译参数) 用法:先装 MPI(官方依赖)—— A2 训练系列要求 MPICH 3.2.1 或 Open MPI 4.1.5;装完再编译 期望:编译产出bin/下的可执行文件(如all_reduce_test) 不过会怎样:报找不到 MPI 头文件 →MPI_HOME路径不对;报缺 CANN 依赖 → 官方注明编译运行依赖 Toolkit 与 ops 包(回 B1/B2)
命令 mpirun -f hostfile -n 16 ./bin/all_reduce_test -p 8 -b 8K -e 64M -f 2 -d fp32 -o sum
含义:跑 AllReduce 集合通信测试 —— 在单机 8 卡上验证"卡与卡之间真的能通信" 拆解:
mpirun(MPI 启动器)+-f hostfile(节点列表文件;单机场景可不配)+-n 16(参与通信的 NPU 总数)+./bin/all_reduce_test(测试命令)+-p 8(本机参与测试的 NPU 个数)+-b 8K -e 64M(测试数据量从 8K 到 64M)+-f 2(数据量按 2 倍递增)+-d fp32(数据类型)+-o sum(归约操作) 用法:单机 8 卡可简化为mpirun -n 8 ./bin/all_reduce_test -b 8K -e 64M -f 2 -d fp32 -o sum -p 8; 执行前建议ulimit -n 65535(官方:防止资源耗尽导致工具运行失败) 期望:打印一张表,每行是data_size / avg_time(us) / alg_bandwidth(GB/s) / check_result,check_result全是success—— 这就是"通信通了"的证据 不过会怎样:出现非success或进程卡住 → 问题在通信层不在脚本(去第七段查网卡/端口/防火墙); 报数据量不足 → 官方提示建议HCCL_BUFFSIZE取值大于测试数据量
E · 起多卡前先钉死的两个环境变量
命令 export HCCL_SOCKET_IFNAME==eth0,enp0
含义:指定 HCCL 用哪块网卡做通信 —— 多机场景最常见的"选错网卡"就靠它治 拆解:
export(设置环境变量)+HCCL_SOCKET_IFNAME(官方:HCCL 初始化时 Host 侧使用的网卡名)+=(精确匹配,只使用 eth0 或 enp0)+^=(排除)+ 逗号分隔可写多个 用法:四种规格选其一 —— 精确匹配=eth0,enp0/精确排除^=eth0,enp0/模糊匹配eth,enp/模糊排除^eth,enp; 官方 CAUTION:若各节点网卡名不同(node1 是 eth1、node2 是 eth2),建议用模糊匹配 期望:HCCL 用你指定的网卡完成建链,日志里不再出现"找不到可用网卡"类报错 不过会怎样:不指定且机器多网口 → 可能选到错误网卡导致建链超时;报错文本可对照官方案例ptacase_0041(多网口下的通信失败)
命令 export HCCL_CONNECT_TIMEOUT=600
含义:调大集合通信的建链超时时间 —— 官方默认 120s,卡数多时不够用 拆解:
HCCL_CONNECT_TIMEOUT(官方:集合通信场景中设备间 socket 建链超时等待时间,默认 120s)+ 值单位是秒 用法:官方给的换算 —— 3K 卡建议 240s,5K 卡建议 600s;用RANK_TABLE_FILE场景下还可参考官方案例ptacase_0042期望:大规模集群下次建链不再因超时失败 不过会怎样:不调且卡数多 → 官方原话:默认值 120 秒无法满足建链需求,会报建链超时;日志见第七段
第六段 怎么算"多卡跑通了":判据与验收
本课最重要的一张表。 多卡的坑全在"不报错但不等于跑对"上。 只测「进程起来了没」是不够的,要分层各验一次。
6.1 五级判据(从下往上,下一级不过就别查上面)
| 级 | 判据 | 怎么验 | 不过说明问题在 |
|---|---|---|---|
| ① 卡数对 | torch.npu.device_count() ≥ 2 且等于你填的 nproc_per_node |
4.2 那条命令 | L0 / A 层 |
| ② 通信通 | hccn_tool -i N -net_health -g 全部 Success |
4.7 步骤 ④ | 网络层(本课第七段) |
| ③ 建链成 | 多卡启动后没有建链超时,rank 能起来 | torchrun 或 torch_npu_run |
建链层(端口/网卡/超时) |
| ④ 通信算子对 | hccl_test 的 check_result 全 success |
4.6 那条命令 | HCCL 侧(CANN/驱动) |
| ⑤ 训练对 | rank0 迭代日志在打印,且首个 step 的 loss 与单卡基准同量级 | 看日志 | 脚本层(四个必改点) |
⭐ 这张表就是本课的差异化所在:市面上讲多卡的内容基本只到 ③(能起来就行), 但真正在现场卡住的,是 ③ 和 ④ 分不开——现象都是"卡住", 一个是网络、一个是脚本,不分开验就无从下手。第 ②④ 级是本课专门补上的。
6.2 官方给的正向判据(《执行训练》相关约束,抄原文)
| 项 | 官方口径 |
|---|---|
| 进程与卡 | 一个 device 对应执行一个训练进程,当前不支持多进程在同一个 device 上进行训练 |
| 并行模式 | 数据并行模式中不同 device 上执行的计算图相同 |
| 粒度 | 集合通信仅支持 1/2/4/8P 粒度的分配 |
| 数据类型(AllReduce / reduce_scatter) | Atlas 训练系列:仅 int8 / int32 / float16 / float32;A2 / A3:再加 bfloat16 |
| 日志位置 | 多机场景 host 日志统一保存在 ~/ascend/log 路径下,可在该路径查看每个 host 的 device 日志 |
⭐ "计算图相同"这条很容易被忽略,但它解释了一类最诡异的故障: 官方案例
tensorflow_faq_0014记录的就是——多 Device 上执行的模型不同导致进程卡死, 现象是某些卡上的 graph 数量和其他卡不一样。数据并行不是"各算各的",是"算同一张图、各算一部分数据"。
6.3 一段不该有的"隐性验收":数据被算了几遍
官方没给这条判据,但它是"不报错但不对"的典型(本课归纳,非官方表述):
改了 DDP、忘了 DistributedSampler → 8 张卡各算完整数据集 → 等于 batch 只有 1/8
现象:训练正常跑完、loss 正常、日志正常 —— 但收敛慢、结果系统性偏移
怎么发现:把一个 epoch 的 step 数 × batch_size × 卡数,和数据集大小对一下。 对不上就是采样出了问题,不是精度问题。
第七段 出问题怎么查
排障原则:多卡的问题,九成能归到三层里的某一层 —— 先定层,再查细节。
7.1 三层定位(先看什么,再看什么)
多卡起不来 / 卡住 / 报错
│
├─ 第 1 层:网络层(最外层,先查)
│ ├─ device IP 有没有配、配得对不对 → hccn_tool -i N -ip -g
│ ├─ 卡到卡的链路健康吗 → hccn_tool -i N -net_health -g
│ └─ 防火墙是不是把端口拦了 → 查端口开放(官方案例 topic_0000001589975097)
│ ★ 这一层不过,后面都别查
│
├─ 第 2 层:建链层
│ ├─ 端口预留了吗(60000-60015) → ptacase_0043
│ ├─ 网卡选对了吗 → export HCCL_SOCKET_IFNAME=...
│ ├─ 超时够不够(默认 120s) → export HCCL_CONNECT_TIMEOUT=...
│ └─ RANK_TABLE_FILE 场景专属 → ptacase_0042
│
└─ 第 3 层:脚本层(最后查)
├─ backend 是不是 hccl?字符串判断改了没? → 3.5
├─ world_size / local_rank 取得对不对
├─ DDP 包了吗?DistributedSampler 赋给 sampler 了吗?
└─ --gpu 这类"单卡卡号参数"删了吗(F1 讲过)
7.2 按现象查(现场是拿着现象来找的)
| 你看到的现象 | 大概在哪一层 | 先查什么 |
|---|---|---|
| 进程起来就卡死,无报错 | 建链层 | 端口预留(60000-60015)、HCCL_CONNECT_TIMEOUT、HCCL_SOCKET_IFNAME |
报 Failed to bind the IP port ...already been bound |
建链层 | 端口被占:sysctl -w net.ipv4.ip_local_reserved_ports=60000-60015(ptacase_0043) |
报 connect() timed out |
网络层 | 防火墙拦了集合通信端口(topic_0000001589975097) |
报 RuntimeError: The Inner Error ...(含通信算子名) |
建链层 | 是否配了 RANK_TABLE_FILE:增大约 30s 的 HCCL_CONNECT_TIMEOUT(ptacase_0042) |
报 Gloo connectFullMesh failed |
网络层 | 多网口:export GLOO_SOCKET_IFNAME=<网口名>(ptacase_0041) |
assert backend in ['gloo','nccl'] 断言失败 |
脚本层 | 自动迁移没改字符串:手工把 nccl 改成 hccl(3.5) |
| 多机某节点起不来 / 通信失败 | 网络层 | device IP 能否互 ping、TLS 配置是否一致(topic_0000001953463657) |
| 健康检查 timeout | 网络层 | 网关 IP 与侦测 IP 是否配成一样(topic_0000002230003537) |
| 跑完了但 loss 不对 | 脚本层 | DistributedSampler 漏了(6.3);梯度聚合的数值差异是否在合理范围 |
7.3 ⭐ 一个最省时间的判断法
多卡失败时,先问一句:
"把卡数改成 1,还失败吗?"
→ 不失败了:问题和多卡有关(通信 / 进程 / 采样)
→ 还失败 :问题在脚本本身,和多卡无关(回 F1 的验收口径)
再问一句:
"hccl_test 通过吗?"
→ 通过 :大概率是脚本层(A 类)
→ 不通过:通信层(B 类),别再改脚本了
两句问话,把"网络"、"脚本"、"本来就有"三种可能一次分开 —— 这是本课最实用的一件工具,比记任何报错都管用。
第八段 常见报错清单
下表报错全部来自昇腾官方故障案例库,案例编号可直接在
https://www.hiascend.com/document/caselibrary打开核对。 检索技巧(E1 讲过,这里再用一次):按报错里的稳定特征词检索(错误码、端口号、函数名), 不要按"多卡"这种大词检索。
| 报错原文(特征词) | 官方收录 | 查看量 | 大概属于 | 先查什么 |
|---|---|---|---|---|
Failed to bind the IP port. Reason: The IP address and port have been bound already.(伴随 ERR02200 DIST call hccl api failed、port[60007]) |
ptacase_0043 |
2093 | 建链层 | HCCL 用 60000~60015 端口,被别的组件占了:sysctl -w net.ipv4.ip_local_reserved_ports=60000-60015 |
RuntimeError: The Inner Error ...(且打印的 operator name 是具体通信算子) |
ptacase_0042 |
791 | 建链层 | 配置了 RANK_TABLE_FILE 的场景专属:ranktable 建链没有 socket 协商,直接建链 → 在 HCCL_CONNECT_TIMEOUT 原值上加 30 秒(如 export HCCL_CONNECT_TIMEOUT=150) |
RuntimeError: Gloo connectFullMesh failed with [...] no error |
ptacase_0041 |
1653 | 网络层 | 多网口导致:export GLOO_SOCKET_IFNAME=<网口名>;ifconfig 找与机器 IP 相同的网口;bond4 超过 60 个时换 GE 网口 |
RuntimeError:connect() timed out. |
topic_0000001589975097 |
1071 | 网络层 | 系统防火墙阻截了 HCCL 集合通信端口:排查端口开放情况并放行 |
| 「HCCL 集群通信失败」(无更具体特征) | topic_0000001953463657 |
4525 | 网络层 | 三条依次查:①多机 device IP 能否互 ping(hccn_tool -i 0 -ping -g address <对端 rank0 IP>,回显含 0.00% packet loss 才算通);②多机 NPU 的 TLS 配置是否相同(hccn_tool -i $i -tls -g \| grep switch);③其他查《集合通信接口参考》FAQ |
| 「NPU 卡健康检查返回错误,提示 timeout」 | topic_0000002230003537 |
5515 | 网络层 | 侦测 IP 和网关 IP 没配成一样:hccn_tool -i N -netdetect -g 看侦测 IP、-gateway -g 看网关,改成同一网关地址 |
| 「多 Device 上执行模型不同导致应用程序出错」(进程卡死,各卡 graph id 数量不一致) | tensorflow_faq_0014 |
607 | 脚本层 | 数据并行要求不同 device 上执行的计算图相同:搜日志关键字 The model has been compiled on the Ascend AI processor, current graph id is,比对各卡 graph 是否一致 |
host not found. |
topic_0000001538748902 |
1087 | 网络层 | 主机名解析:查 /etc/hosts 是否配了节点名(hccl_test 安装文档里要求把"IP地址 主机名"写进去) |
⚠️ 本课不给的报错:官方文档里没有一份"多卡通用报错总表" —— 上面这些是从案例库里按现象检索出来的。 遇到表里没有的报错,做法是回到 7.1 那张三层图:先定层,再按特征词去案例库检索,不要瞎猜。
第九段 小结与下一课
这一课要带走的三句话:
- 多卡改的是"进程数 + 一行 backend",不是学一套新 API —— 官方:PyTorch/MindSpore 的 HCCL 调用已集成进 TorchNPU/MindSpore 框架代码,你只需指定 HCCL 作为分布式后端。
- 四个必改点一个都不能漏:
world_size/local_rank→device→init_process_group(backend="hccl")→DDP+DistributedSampler。 最容易漏的是DistributedSampler(漏了不报错,但数据被算多遍)。 - "跑起来没报错"不等于"多卡跑对了" —— 要用五级判据分层验:
卡数 → 网络 → 建链 → 通信算子(
hccl_test) → 训练 loss。
多卡的判断顺序(串联本课):
先确认单卡能跑(F1 的铁律)
├─ 查卡数(torch.npu.device_count())
├─ 改脚本四个必改点(含把字符串 nccl → hccl)
├─ 单机 8 卡起(torchrun)—— 先别上多机
│ └─ 通信单独验一遍(hccl_test)→ 分开"脚本错"和"通信不通"
└─ 单机跑对后 → 上多机
└─ 顺序:配 device IP → net_health → 关防火墙 → lldp → 内核参数 → torchrun/torch_npu_run
下一课预告(F2 / F4 任选其一,取决于你手上是"跑不对"还是"跑得慢"):
- 结果和参考平台对不上 → F2 精度调试:多卡跑通了,但数值不对;
- 能跑但不快 → F4 性能调优:Profiling 采集与分析,看通信到底占了多少时间。
⚠️ 一条容易混的边界:本课讲的都是训练/脚本层面的多卡。 服务化部署里的多卡调度(PD 分离、混部、调度器)是另一条路,见 D4,不要拿本课的命令去套服务化场景。
自测题(能答上就算学会):
- 单卡脚本改多卡,官方给的四个必改点是什么?哪一个漏了不报错但会把数据算多遍?
- 为什么"改
backend="hccl"这一行"就能多卡?HCCL 是谁在替你做? hccl_test是干什么的?它和"跑训练脚本"验的是不是同一件事?- 多卡进程卡死、无报错,你先查哪一层、先敲哪条命令?
- 官方说 HCCL 建议用哪个端口段?不预留会看到哪条报错(给案例编号)?
附录 A · 本课引用的官方出处
| 内容 | 来源文档 |
|---|---|
| HCCL 定义、六项核心功能、软件架构(HCCL 集合通信库 + HCOMM 通信基础库)、支持产品 | 《HCCL 集合通信库 · HCCL 简介》(CANN 9.2.0-beta.2) |
| AI Server / AI 集群 / 超节点组网 / 通信成员(rank)/ 通信域 / 通信算子 / 通信算法;术语缩略语表 | 《HCCL 集合通信库 · 相关概念》 |
| 三种编程执行形态(单算子 / 图模式 Ascend IR / 图捕获 aclgraph);PyTorch 与 MindSpore 的 HCCL 调用已集成进 TorchNPU/MindSpore 框架代码,指定 HCCL 后端即可用框架原生通信 API | 《HCCL 集合通信库 · 主流框架集成》 |
| 集合通信不支持昇腾虚拟化实例场景;单卡多进程并发数量建议;A2 集群 (1~8)*n、Atlas 训练系列 1/2/4/8 与 0-3/4-7 组网 | 《HCCL 集合通信库 · 系统约束与限制》 |
hccl_test 用途(测集合通信功能正确性与性能)、依赖(Toolkit + ops)、源码路径 ${INSTALL_DIR}/tools/hccl_test、算法带宽定义 |
《HCCL 性能测试工具 · 工具介绍》 |
MPI 依赖与版本(A2:MPICH 3.2.1 或 Open MPI 4.1.5)、make MPI_HOME=...、/etc/hosts 配置、SSH 互信 |
《HCCL 性能测试工具 · 工具安装与编译》 |
关防火墙 / somaxconn / tcp_max_syn_backlog / ulimit -n 65535;HCCL_SOCKET_FAMILY、HCCL_SOCKET_IFNAME(4 种匹配规格与 CAUTION)、HCCL_CONNECT_TIMEOUT(默认 120s、3K→240s、5K→600s)、HCCL_BUFFSIZE、HCCL_TEST_USE_DEVS、HCCL_TEST_PROFILING;hostfile 格式;mpirun 命令格式与示例;结果表字段 |
《HCCL 性能测试工具 · 工具执行》 |
支持的测试命令列表(all_reduce_test 等 11 个)、-p/-b/-e/-i/-f/-o/-r/-d 参数含义与默认值 |
《HCCL 性能测试工具 · 参数说明》 |
单机单卡 / 单机多卡 / 多机多卡三种场景的模型脚本改动与启动方式;四个必改点;5 种拉起方式与"torch_npu_run 集群场景推荐";60000-60015 端口预留 CAUTION;device IP 配置与网段规则;-netdetect/-net_health/-lldp 命令与状态码;~/ascend/log;torchrun 单机 8 卡与双机 16 卡命令;"一个 device 一个进程"、"计算图相同"、数据类型与 1/2/4/8P、2 卡改写方法 |
ModelZoo《传统模型训练 · PyTorch · 执行训练》 |
torch_npu_run 是 torchrun 的大集群改进版(epoll 多线程 TCP server、分层建链 enable_tiered_parallel_tcpstore、建链复杂度 O(n)→O(√n))、参数与单机/双机样例 |
《TorchNPU · torch_npu_run》(26.1.X) |
RANK_TABLE_FILE 用途与约束(JSON 格式、不能为软链接、需读权限);配置场景下 RuntimeError: The Inner Error ... → 增大 HCCL_CONNECT_TIMEOUT |
《TorchNPU · 环境变量参考 · RANK_TABLE_FILE》 |
| 本课 3.5 的 backend 字符串坑 | ModelZoo《模型迁移 · 自动迁移》(F1 已引用) |
| 8 条报错案例(编号见第八段) | 昇腾官方故障案例库 https://www.hiascend.com/document/caselibrary |
本课未做的事(数据纪律,避免越界):
- 未给出 rank table 文件的具体 JSON 字段结构 —— 官方只给了用途与使用约束(须为 JSON 格式、路径不能是软链接、需有读取权限), 并指向《HCCL 集合通信库》的"集群信息配置"章节;本课不复述字段,需现场按该章节配置。
- 未给任何多卡性能数字(加速比、通信耗时占比等)—— 官方文档中未给出,故不编造。
性能数据要用
hccl_test自己测(本课第五段 D 组命令),分析走 F4。 - 未给"多卡通用报错总表" —— 官方没有这样一份表; 第八段是从案例库按现象检索出来的 8 条,其余报错按 7.1 三层法定位。
- 6.3 的"数据被算多遍"判据是本课归纳,非官方表述 —— 官方给的是"数据并行模式中不同 device 上执行的计算图相同"这条约束。
- 未展开 PD 分离 / 混部的多卡调度 —— 属 D4,本课按边界不重复。
附录 B · 命令与代码逐条详解
B.1 单卡脚本 → 单机多卡的四个必改点(官方《执行训练》原文代码)
必改点 1:从环境变量取 world_size 与 local_rank
world_size = int(os.environ["WORLD_SIZE"])
local_rank = int(os.environ["LOCAL_RANK"])
必改点 2:用 local_rank 自动取 device 号
device = torch.device(f'npu:{local_rank}')
必改点 3:初始化进程组,通信方式设为 HCCL
torch.distributed.init_process_group(backend="hccl", rank=local_rank, world_size=world_size)
必改点 4:开启 DDP 模式 + 分布式采样
model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[local_rank], output_device=local_rank)
train_sampler = torch.utils.data.distributed.DistributedSampler(train_data)
train_dataloader = DataLoader(dataset=train_data, batch_size=batch_size, sampler=train_sampler)
以上四段逐字来自官方《执行训练》"单机多卡场景 · 模型脚本配置",未改写。
B.2 多机多卡相对单机多卡的增量(官方原文)
| 项 | 单机多卡 | 多机多卡(增量) |
|---|---|---|
| 取 rank | local_rank = int(os.environ["LOCAL_RANK"]) |
还要取 全局序号:global_rank_idx = int(os.environ["RANK"]) |
init_process_group 的 rank |
rank=local_rank |
rank=(args.node_rank)*(args.nproc_per_node) + local_rank |
DistributedSampler |
num_replicas=devices_per_node |
num_replicas=world_size(全局数) |
| 启动参数 | --nnodes=1 |
还要加 --node_rank,并保证各节点 --master_addr 指向同一主节点 |
官方多机多卡模型脚本示例里
world_size / RANK / LOCAL_RANK三个都取,dist.init_process_group("hccl", rank=global_rank_idx, world_size=world_size, timeout=timedelta(minutes=30))。
B.3 启动器参数对照
| 参数 | torchrun | torch_npu_run |
|---|---|---|
| 节点数 | --nnodes=1 |
--nnodes=1 |
| 每节点进程数 | --nproc_per_node=8 |
--nproc_per_node=8 |
| 本节点序号 | --node_rank 0 |
--node_rank 0 |
| 主节点地址 / 端口 | --master_addr / --master_port |
--master_addr / --master_port |
| 建链后端 | — | --rdzv_backend=parallel |
| 分层建链(大集群提速) | — | --enable_tiered_parallel_tcpstore=true(默认 false) |
| 官方定位 | 通用启动器 | torchrun 的大集群改进版,集群场景推荐 |
B.4 hccl_test 关键参数(官方《参数说明》)
| 参数 | 含义 | 默认值 |
|---|---|---|
./bin/<executable_file> |
测试命令(all_reduce_test、broadcast_test、all_gather_test 等 11 个) |
必选 |
-p / --npus |
单节点参与训练的 NPU 个数 | 当前节点 NPU 总数 |
-b / --minbytes |
测试数据量起始值 | 64M(单位 K/M/G) |
-e / --maxbytes |
测试数据量结束值 | 64M |
-i / --stepbytes |
数据增量步长方式(默认开启) | (e−b)/10 |
-f / --stepfactor |
数据增量乘法因子方式 | — |
-o / --op |
Reduce 类操作的运算类型(sum/prod/max/min) | sum |
-r / --root |
broadcast_test/reduce_test/scatter_test 的根节点 Device ID |
0 |
-d / --datatype |
数据类型 | fp32 |
MPI 侧参数:-f <hostfile>(节点列表,单机可省)、-n <number>(参与通信的 NPU 总数 = 节点数 × 每节点卡数,必选)。
结果表五列:data_size(Bytes) / avg_time(us) / alg_bandwidth(GB/s) / check_result。
判据就用最后一列:
check_result全为success= 通信通了。
B.5 多机 device IP 配置(官方命令格式)
hccn_tool -i 0 -ip -s address 10.***.***.2 netmask 255.255.255.0
| 部分 | 含义 |
|---|---|
-i 0 |
设备 ID(0~7) |
-ip |
操作对象:IP 地址 |
-s address <IP> netmask <掩码> |
set:设置 device IP 与掩码(-g 是查询) |
-netdetect -s address <IP> |
设置网络检测对象 IP(官方:通常配成与 NPU 网口 IP 同网段的网关地址) |
-net_health -g |
查网络健康状态(0=Success,1=Socket fail,2=Receive timeout,3=Unreachable,4=Time exceeded,5=Fault,6=Init,7=Thread error,8=Detect ip set) |
-lldp -g |
查链路层邻居信息(返回值不为空则正常) |
网段规则(官方):Atlas 训练系列——第 0/4、1/5、2/6、3/7 号 device 需处于同一网段,第 0/1/2/3 号在不同网段、第 4/5/6/7 号在不同网段; A2 / A3——多台节点的 NPU 在同一网段即可;每个 IP 都不能冲突。
B.6 多卡前值得钉死的环境变量(官方《工具执行》口径)
| 变量 | 作用 | 官方给的取值建议 |
|---|---|---|
HCCL_SOCKET_FAMILY |
通信网卡使用的 IP 协议版本 | AF_INET(IPv4)/ AF_INET6(IPv6) |
HCCL_SOCKET_IFNAME |
Host 侧通信网卡名 | =eth0,enp0(精确)/^=…(精确排除)/eth,enp(模糊)/^eth,enp(模糊排除) |
HCCL_CONNECT_TIMEOUT |
socket 建链超时(秒) | 默认 120;3K 卡→240,5K 卡→600 |
HCCL_BUFFSIZE |
NPU 间共享缓冲区(MB) | 每个通信域默认占用 200MB;测试大通信量时取值应大于测试数据量 |
HCCL_IF_BASE_PORT |
指定 Host 网卡起始端口 | 预留以该端口起始的 16 个端口 |
RANK_TABLE_FILE |
rank table 文件路径(用于建链) | 默认未配置;配了就不走默认协商建链 |
⚠️
RANK_TABLE_FILE的一个官方提醒:配置该变量的场景下,分布式训练若出现RuntimeError: The Inner Error ...,建议增大HCCL_CONNECT_TIMEOUT—— 因为 rank table 建链方式下没有 socket 协商阶段(官方案例ptacase_0042)。