系统学习 AI 学习路径:从 GPU 运行时到推理、微调与 RAG 评估

版本信息最后核对:2026-10-25

nccl-hang

NCCL 集合通信卡死:区分初始化、网络、拓扑、驱动与配置问题的排查路径。

现象

分布式训练或推理在 init_process_group 阶段停住,或在某个 step 后再无进展;日志不再滚动,GPU 利用率可能是 0,也可能有个别 rank 仍在空转。多数框架最终会抛出超时或通信错误:

Watchdog caught collective operation timeout: WorkNCCL(...) ran for 600000 milliseconds before timing out.
NCCL error: unhandled system error
ncclInternalError: Internal check failed
Remote process exited or there was a network error

容器里常见的表现是 Pod 一直 Running、不重启,GPU 显存被占着,Job 永远不完成;也可能某个 rank 先退出,其余 rank 在集合通信处等到超时。还有一种容易被误判为“卡死”的情况:任务没有死,只是某个 rank 特别慢,整体吞吐被拖到接近停滞。

排障的关键不是先改 NCCL 环境变量,而是先回答两个问题:卡在初始化还是会合之后的集合通信;是所有 rank 都卡,还是只缺某一个 rank。答案不同,排查路径完全不同。

快速判断

先看最小面上的一组信息:

nvidia-smi
nvidia-smi topo -m
nvidia-smi nvlink -s
systemctl status nvidia-fabricmanager
journalctl -k --since '30 min ago' | grep -i -E 'NVRM|Xid|mlx|ib'
ip -br addr
ibstat

第一条命令先确认 GPU 是否都在、有没有进程异常占卡;nvidia-smi topo -m 看 GPU 与网卡的连接关系;ibstat 看 IB 端口是否 ACTIVE、速率是否正常。内核日志里如果同时出现 Xid,应先按 GPU 硬件问题处理,而不是继续调 NCCL。

再回答四个问题:

  1. 卡在初始化还是训练中?初始化卡住,优先查 MASTER_ADDR、端口、主机名解析、防火墙和 rendezvous;训练中卡住,优先查网络抖动、慢节点、GPU 故障和 rank 提前退出。
  2. 是否所有 rank 都卡?只有部分 rank 卡,通常是这些 rank 没收到数据、已经崩溃,或根本没进入同一个集合操作。
  3. NCCL 走了哪条链路?NCCL_DEBUG=INFO 里看到 NET/IB 还是 NET/Socket,决定了问题在 RDMA 路径还是 TCP 回退路径。
  4. 是“慢”还是“死”?看 loss、吞吐和 GPU 利用率是否还有微小变化;完全静止才更像死锁或链路中断。
线索 更可能的方向
卡在 init_process_group 会合、主机名、端口、防火墙
训练若干 step 后卡住,各 rank 利用率不均 慢节点、数据加载、straggler
所有 rank 同时卡住,IB 端口异常 网络硬件、交换机、链路
单卡报 Xid 后其余 rank 超时 GPU 硬件或驱动
只有容器内复现 设备挂载、共享内存、权限
换一台机器正常,原机器多机才复现 拓扑、网卡选择、配置漂移

常见原因

网络与交换

IB/RoCE 链路 down、光模块或线缆故障、交换机端口错误、MTU 不一致、防火墙阻断会合端口或数据端口、RoCE 的 GID index 配错、子网管理器异常,都会让 NCCL 在建立连接或传输时挂起。NCCL_SOCKET_IFNAME 选到管理网或 Docker 网桥,也是多机环境的常见事故。

网卡与 GPU 跨 NUMA、PCIe P2P 被 IOMMU 或虚拟化限制、NVLink 链路错误、Fabric Manager 未运行,都会让通信性能骤降甚至卡住。rank 放置不合理时,少数链路被打满,其他链路空闲,看起来像整体卡死。

版本与驱动

NCCL 与驱动、CUDA 版本不兼容,OFED/rdma-core 与内核不匹配,容器内 NCCL 与宿主机驱动不一致,或者集群里混用了不同版本的节点,都可能在建立连接或首次通信时报错。升级驱动后忘记同步 Fabric Manager 和容器工具链,也是典型来源。

配置与启动

world size 与 rank 数不一致、MASTER_ADDR/MASTER_PORT 错误或端口被占用、各节点主机名解析结果不同、环境变量只在一部分节点生效,都会导致会合失败。容器内 /dev/shm 太小、memlock 受限、缺少 IPC_LOCK,会影响共享内存和 RDMA 注册。

应用逻辑与资源

部分 rank 因异常提前退出、条件分支让某些 rank 不进入同一个 collective、输入长度严重不均、数据加载 CPU 瓶颈、进程被 OOM Killer 杀死,都会表现为其他 rank 无限等待。这类问题在 NCCL 日志里往往只能看到“某个 rank 没来”,根因在应用或系统层。

排查步骤

第一步:判断卡在初始化还是集合通信

查看各 rank 最后一行日志和 Python 调用栈。能复现时,用 py-spy dump --pid <PID> 抓取卡住进程的栈,确认停在 rendezvous、连接建立还是某个 all_reduce。初始化阶段卡住与会合配置有关,集合通信阶段卡住与数据路径和 rank 状态有关。

第二步:用最小复现缩小范围

先用 nccl-tests 把问题从业务代码里剥离出来:

# 单机 8 卡
./build/all_reduce_perf -b 8 -e 8G -f 2 -g 8

# 多机,每机 8 卡,一进程一卡
mpirun -np 16 --hostfile hosts \
  -x NCCL_DEBUG=INFO -x NCCL_SOCKET_IFNAME=<数据网卡> \
  ./build/all_reduce_perf -b 8 -e 8G -f 2 -g 1

单机正常、多机异常,重点查网络和跨机配置;只有特定 GPU 组合异常,重点查 NVLink、PCIe 和拓扑;nccl-tests 正常但业务卡住,重点查应用逻辑、rank 放置和超时设置。测试时固定消息大小和 GPU 数,便于和基线对比。

第三步:收集 NCCL 日志

在复现命令上临时打开调试:

export NCCL_DEBUG=INFO
export NCCL_DEBUG_SUBSYS=INIT,NET,COLL
export NCCL_DEBUG_FILE=/tmp/nccl.%h.%p.log

重点看:bootstrap 是否成功、选中了哪张网卡和哪个 HCA、ring/tree 拓扑是否包含所有 rank、连接在哪一步停住、最后完成的 collective 是什么。日志按主机和 PID 分开保存,才能对齐时间线。NCCL_DEBUG=INFO 日志量大且会影响性能,只用于复现,不要长期开在生产环境。

第四步:检查网络链路

ibstat
ibv_devinfo
ip -br addr
ip -s link show <dev>
ethtool -S <dev> | grep -i -E 'err|drop|discard'
ping -M do -s 8972 <对端IP>

确认 IB 端口状态、速率和 MTU;RoCE 场景还要确认 GID index、PFC/ECN 和交换机配置。ping -M do 用来验证端到端 MTU,避免大包被静默丢弃。若日志显示走了 NET/Socket,说明 RDMA 没生效,应检查 NCCL_SOCKET_IFNAME、NCCL_IB_HCA、/dev/infiniband 和容器权限。

nvidia-smi -q
nvidia-smi nvlink -e
nvidia-smi -q | grep -i -A5 fabric
dmesg -T | grep -i -E 'NVRM|Xid'

任何一张卡有 Xid、NVLink 错误计数持续增长、Fabric 状态异常,都可能导致集合通信挂起。此时应先修硬件或 Fabric,再回到 NCCL 排查。GPU Direct RDMA 是否生效,可以结合 nvidia-smi topo -m 看网卡与 GPU 是否在同一 PCIe/NUMA 分支。

第六步:检查容器与系统限制

df -h /dev/shm
ulimit -l
ls /dev/infiniband

容器默认 /dev/shm 往往只有 64MB,大模型训练容易在这里出问题;使用 RDMA 需要 IPC_LOCK 能力和足够的 memlock;容器还必须能看到 /dev/infiniband。Kubernetes 环境要确认 Pod 使用 host network 或正确的 CNI,避免 NCCL 选到错误的网络命名空间。

第七步:排查 slow rank 与应用逻辑

第八步:二分与隔离

每次只改一个变量:先在单机复现,再扩到多机;先禁用 IB 走 TCP,再恢复 RDMA;先固定网卡,再更换 rank 放置;最后替换节点、线缆或交换机端口。把每一步结果记录成对照表,避免在多变量同时变化时得出错误结论。

修复与验证

按根因分别处理:

验证分四步:

  1. 单机 nccl-tests 多次运行,busbw 与基线一致,无 #wrong。
  2. 多机 nccl-tests 覆盖实际使用的 GPU 数和网卡,连续运行不挂起。
  3. 真实任务完整跑完至少一个训练或推理周期,通信日志中没有超时和重连。
  4. 观察 IB 错误计数、GPU Xid、NCCL watchdog 告警,确认在验证窗口内没有增长。

只跑通一次不算通过,至少重复多次并覆盖原来的故障时段。

预防

相关命令

参考链接

读完自测

合上页面,先回答,再展开对照。

  1. 卡在 init_process_group 和卡在训练中的集合通信,排查方向有什么不同?
  2. NCCL_DEBUG=INFO 显示走了 NET/Socket,说明什么?应该检查哪些配置?
  3. 为什么 NCCL_IB_DISABLE=1 只能作为诊断手段,不能作为生产修复?
答案
  1. 初始化阶段卡住,优先查会合配置:MASTER_ADDR/MASTER_PORT、主机名解析、防火墙、rank 数和 rendezvous。训练中卡住,优先查网络抖动、慢节点、GPU 故障和某个 rank 提前退出。
  2. 说明 RDMA 没有生效,NCCL 回退到了 TCP。应检查 NCCL_SOCKET_IFNAME 是否指向数据网卡、NCCL_IB_HCA 是否正确、容器是否挂载 /dev/infiniband 并有 IPC_LOCK 权限。
  3. 禁用 IB 只是把问题范围缩小到“TCP 能通、RDMA 不通”,用来定位网络或配置问题。生产环境禁用 IB 会失去 RDMA 带宽,显著降低多机通信性能,也会掩盖真正的链路故障。
微信小程序码:扫码打开命令速查小程序

小程序版

微信扫码,随时查命令