欢迎光临

NCCL 多机初始化卡住怎么查?网卡、端口与 rank 日志

多机 torchrun 启动卡住时,先在每个 rank 打印三个检查点:进入进程组初始化、初始化成功、第一次 all_reduce 完成。最早缺失的检查点决定下一步。先查 rank 是否都起来,再查 rendezvous 和 NCCL 网络;能完成小消息 collective 后,再做带宽测试。

Mellanox CX311A 硬件实拍资料照片
Mellanox CX311A 硬件实拍资料照片,Fastily 摄于 2024-02-20。本站生成缩放或裁切缩略图。 原始照片 · CC BY-SA 4.0

先找哪一层停止前进

最后看到的信号 优先检查 下一步
某台主机没有任何 rank 的入口输出 调度器、进程退出、节点参数、rendezvous 核对每台的 launcher stderr、节点数与控制地址
看到 enter init,没有 init OK Store、各 rank 的 GPU 绑定、NCCL Bootstrap/连接建立 按主机和 PID 对齐日志,核对选中的 IP 和 HCA
所有 rank 都初始化完成,但第一次 collective 卡住 首次操作的调用顺序、rank 是否漏调、设备与张量一致性、数据通路 跑固定大小的最小 probe,再逐步恢复训练代码

PyTorch 支持 device_id 的版本可以在 init_process_group 中提前建立 NCCL communicator。若旧脚本采用惰性初始化,网络错误也可能首次出现在 collective,此时仅看 init_process_group 已返回还不足以排除网络问题。

验证 rendezvous 地址,再查两侧实际走哪张网卡

下例使用 IPv4。把 PEER 替换为对端在任务网络里的实际 IP,在两台机器的训练容器或网络命名空间内分别执行。重点看 dev 和 src,以及对应设备在两端能否相互路由。

1
2
3
4
5
6
PEER=10.0.0.12
ip -br addr
ip -4 route get "$PEER"
getent ahostsv4 node-a
# rendezvous 服务监听期间,从对端探测
nc -vz -w 3 node-a 29500

TCP 探测只有在目标端口确实有监听时才有意义。Connection refused 时同时检查监听地址和服务状态,超时时检查路由、防火墙或安全组。29500 用于这个例子的 rendezvous;NCCL 还会使用进程间连接所需的其他端口。只放通 rendezvous 端口后,仍要核对节点间通路、实际端口及集群的放行规则。

让两台主机运行同一个最小 probe

下载并解压最小 NCCL 检测脚本 ZIP,把 tbr8-nccl-init-probe.py 放到两台主机的工作目录。脚本为每个 rank 绑定本地 GPU,主动初始化通信器,执行一次整数求和并验证结果。示例使用一节点一 GPU,共两个 rank,预期两个 rank 都报告 sum=3。适用支持 device_id 的 PyTorch 版本。

1
2
3
4
5
6
7
8
9
10
11
12
13
# 两端使用相同的可达 MASTER_ADDR 和 MASTER_PORT
export MASTER_ADDR=10.0.0.11 MASTER_PORT=29500
# 节点 A 为 0,节点 B 为 1
NODE_RANK=0
# 每台使用本机通往对端的网卡,名称可以不同
export NCCL_SOCKET_IFNAME='=ens5'
export NCCL_DEBUG=INFO NCCL_DEBUG_SUBSYS=INIT,NET,ENV
export NCCL_DEBUG_FILE='/tmp/nccl-%h-%p.log'

timeout --kill-after=10s 180s torchrun \
  --nnodes=2 --nproc-per-node=1 --node-rank="$NODE_RANK" \
  --master-addr="$MASTER_ADDR" --master-port="$MASTER_PORT" \
  tbr8-nccl-init-probe.py

=ens5 是精确匹配;省略等号时按前缀匹配。两台使用各自能到达对端的接口,IP 必须来自实际任务环境。调试日志中的 %h 和 %p 展开为主机名和 PID,便于区分进程。失败时先保留各 rank 的第一条错误及前后日志,再看后续超时。

从 Bootstrap 和 NET 日志判断该查哪条链路

  • 找不到 socket 接口:检查变量实际传到了 worker,接口名在容器内存在,且有合适地址。记录 Bootstrap 所用接口与地址,再对照 ip route get。
  • 能选到接口,连接仍超时:从两侧检查源 IP 到对端的路由、监听与节点间 TCP 放行范围。对照第一条网络错误,确认是哪台节点、哪个 rank、哪个方向。
  • Socket 基线成功、RDMA 路径失败:在隔离任务里短暂设 NCCL_IB_DISABLE=1,并从 NET/Socket 日志确认实际走的后端,测试后撤销。若仅 RDMA 失败,再查 HCA、端口状态、链路类型与容器设备映射。NCCL_IB_HCA 选择的是 RDMA 设备;NCCL_SOCKET_IFNAME 选择的是 IP 接口。
  • 小 probe 成功,业务训练卡住:恢复原来的后端,一次增加一种变量。先核对各 rank 的 collective 顺序、进程组成员和张量形状,再加入原有数据加载和训练逻辑。

实测:故意选错接口会出现什么日志

在 WSL2、RTX 2080 Ti、PyTorch 2.13.0+cu130、NCCL 2.29.7 上,用同一脚本做了单机单卡对照。精确匹配不存在的接口时,进程停在 enter init 之后,打印 Bootstrap : no socket interface found 并以状态 1 退出。改为精确匹配回环接口 =lo 后,初始化通过,all_reduce 返回 sum=1,状态为 0。

NCCL 错误接口与恢复测试终端输出
NCCL 错误接口与恢复测试终端输出。截取实际运行日志。
1
2
3
4
5
export NCCL_DEBUG=INFO NCCL_DEBUG_SUBSYS=INIT,NET,ENV
NCCL_SOCKET_IFNAME='=tbr8_no_iface' torchrun --standalone --nnodes=1 \
  --nproc-per-node=1 tbr8-nccl-init-probe.py
NCCL_SOCKET_IFNAME='=lo' torchrun --standalone --nnodes=1 \
  --nproc-per-node=1 tbr8-nccl-init-probe.py

这个实测验证了网卡筛选失败的日志与探针的检查点。两台主机的连通性、RDMA 通路和多 rank collective 仍需在目标集群验证。回环接口只用于这里的单机自检。

最小通信正常后,可用all_reduce_perf 带宽排障指南比较单机和多机基线。关于不同日志级别和训练中途挂起,见NCCL_DEBUG 日志排查。

参考资料:NVIDIA NCCL 网络排障、NCCL 环境变量、PyTorch Distributed。

【本站文章皆为原创,未经允许不得转载】:汤不热吧 » NCCL 多机初始化卡住怎么查?网卡、端口与 rank 日志
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址