1. 问题现场与背景还原
8张B200跑NCCL all-reduce,进程挂起,日志停在NVLS初始化阶段,这是我在一个GPU集群交付现场遇到的真实故障。当时客户催得紧,8卡机器跑单机通信测试直接卡死,nvidia-smi看GPU利用率全是0,但进程状态是R状态,CPU占用也不高,典型的"假死"——不是算不动,是通信层根本没建起来。
先把现场信息摆出来。机器是8×B200 SXM,通过NVSwitch做全互联,驱动版本570系列,CUDA 12.8,NCCL用的是2.24。跑一个最简单的all_reduce_perf,-b 8 -e 128M -f 2 -g 8,结果卡在初始化,NCCL_DEBUG=INFO打出来的日志最后几行反复出现NVLS相关的报错,大意是NVLS multicast无法建立,然后就是长时间无输出,最后超时退出。
这个问题的核心关键词是Fabric Manager版本不一致,导致NVLS建不起来。NVLS是NVLink SHARP的缩写,简单说就是利用NVSwitch做网内归约,把all-reduce的累加操作下沉到交换机里做,减少GPU之间的数据搬运。B200这一代NVSwitch能力很强,NVLS用好了能省不少带宽,但前提是Fabric Manager得把NVSwitch管起来,而且版本得和驱动、NCCL对得上。
我先把结论说在前面:这次卡死的根因是Fabric Manager的版本比驱动版本低了一个大版本,导致NVSwitch的NVLS能力没有被正确激活,NCCL探测到NVLS不可用后没有优雅回退,而是卡在了初始化握手上。下面我把整个排查过程、原理拆解、修复步骤和避坑经验完整写出来,给遇到类似问题的同行一个可复现的参考。
2. Fabric Manager与NVLS的关系拆解
2.1 Fabric Manager到底管什么
很多人装完驱动就以为NVSwitch自动就工作了,其实不是。NVSwitch是一颗独立的交换芯片,它需要有一个管理进程来配置路由、监控链路状态、管理NVLink域。这个管理进程就是Fabric Manager,简称FM。
在HGX和DGX这类多GPU全互联的机器上,FM是必须常驻的。它做的事情包括:初始化NVSwitch、建立GPU到NVSwitch的拓扑映射、管理NVLink的错误恢复、以及最关键的——激活NVLS(NVLink SHARP)能力。如果FM没跑起来,或者跑起来了但版本不对,NVSwitch就只是一堆"哑交换机",GPU之间还能通过NVLink通信,但NVLS这种高级特性就用不了。
你可以把FM理解成NVSwitch的"操作系统"。没有它,硬件在,但功能不全。
2.2 NVLS为什么依赖FM
NVLS的全称是NVLink SHARP,SHARP是Scalable Hierarchical Aggregation and Reduction Protocol的缩写,最早在InfiniBand交换机上用来做网内归约。NVLS把这个思路搬到了NVLink域内,让NVSwitch在数据转发的同时做累加、求最大值等操作。
要启用NVLS,需要满足几个条件:
- NVSwitch固件支持SHARP
- Fabric Manager正确配置了NVLS资源
- 驱动版本与FM版本匹配
- NCCL编译时启用了NVLS支持,且运行时探测到可用
其中FM版本与驱动版本匹配是最容易被忽略的一条。NVIDIA的驱动包和FM包是分开发布的,驱动版本570.xx对应的FM版本也应该是570.xx系列。如果FM还是旧的565或者更早,就会出现"驱动认识NVSwitch,但FM不认识NVLS"的尴尬局面。
2.3 版本不一致时会发生什么
版本不一致的表现不一定是直接报错。我这次遇到的情况是:FM能启动,systemctl status nvidia-fabricmanager显示active,NVSwitch也能被nvidia-smi -q看到,但NVLS的capability字段是disabled。NCCL在初始化时会去查询NVLS是否可用,查询结果是"不可用",然后它尝试回退到普通NVLink通信,但回退路径上有一个握手超时,导致进程卡死。
这里有个细节值得注意:NCCL的日志级别要开到INFO才能看到NVLS探测的细节,默认的WARN级别只会看到最后的超时。所以排查这类问题,第一件事就是把NCCL_DEBUG=INFO加上,必要时上NCCL_DEBUG_SUBSYS=INIT,NET,GRAPH。
3. 排查过程与关键证据链
3.1 第一步:确认GPU和NVSwitch的可见性
先跑nvidia-smi,8张B200都能看到,温度、功耗正常。再跑nvidia-smi -q | grep -i nvswitch,能看到NVSwitch设备,说明硬件层面没问题。
然后检查FM服务状态:
systemctl status nvidia-fabricmanager输出显示active (running),但注意看启动时间,比驱动加载时间晚了将近2分钟。这个延迟本身不一定是问题,但结合后面的日志看,FM启动过程中有重试。
3.2 第二步:对比版本号
这是最关键的一步。分别查驱动版本和FM版本:
cat /proc/driver/nvidia/version输出类似:NVRM version: NVIDIA UNIX x86_64 Kernel Module 570.86.10
再查FM版本:
dpkg -l | grep fabricmanager或者如果是tar包安装的:
/usr/bin/nv-fabricmanager --version我这次查出来FM是565.57.01,驱动是570.86.10。差了一个大版本。这就是问题所在。
3.3 第三步:看FM日志里的NVLS初始化
FM的日志在/var/log/fabricmanager.log。翻到启动阶段,能看到类似这样的记录:
[INFO] NVLS: SHARP not supported by current firmware/config [WARN] NVLS multicast group creation failed这两行就是铁证。FM自己都说了NVLS建不起来,NCCL那边自然拿不到可用的NVLS资源。
3.4 第四步:确认NCCL的探测行为
把NCCL日志打开,重新跑测试:
NCCL_DEBUG=INFO NCCL_DEBUG_SUBSYS=INIT,NET ./all_reduce_perf -b 8 -e 128M -f 2 -g 8日志里会看到:
NCCL INFO NVLS multicast support: 0 NCCL INFO NVLS: disabled NCCL INFO Setting affinity for GPU 0 to ...然后就是长时间的沉默,最后超时。这里NCCL的行为是:探测到NVLS不可用,尝试走普通路径,但在某些版本组合下,普通路径的初始化也会因为FM状态异常而卡住。
4. 修复步骤与验证方法
4.1 升级Fabric Manager到匹配版本
修复的核心动作就一个:把FM升级到和驱动同一个版本系列。
如果是apt管理的:
apt-get update apt-get install nvidia-fabricmanager-570注意包名里的版本号要和驱动对应。如果是tar包安装的,去NVIDIA官方下载对应版本的FM包,解压后替换/usr/bin/nv-fabricmanager和相关库文件。
升级前先停服务:
systemctl stop nvidia-fabricmanager升级完再启动:
systemctl start nvidia-fabricmanager systemctl enable nvidia-fabricmanager4.2 验证NVLS是否激活
升级后,先看FM日志:
grep -i nvls /var/log/fabricmanager.log应该能看到NVLS: SHARP supported或者类似的成功信息。
再跑NCCL测试,日志里应该出现:
NCCL INFO NVLS multicast support: 1 NCCL INFO NVLS: enabled这时候all-reduce应该能正常跑完,带宽也能达到预期。
4.3 版本匹配对照表
为了方便大家查,我整理了一个B200常见驱动与FM的版本对照:
| 驱动版本 | FM版本 | NVLS支持 | 备注 |
|---|---|---|---|
| 570.86.10 | 570.86.10 | 是 | 推荐组合 |
| 570.86.10 | 565.57.01 | 否 | 本次故障组合 |
| 565.57.01 | 565.57.01 | 是 | 旧版稳定组合 |
| 550.54.14 | 550.54.14 | 部分 | 需确认固件 |
注意:FM版本不能高于驱动版本,也不能低太多。差一个小版本通常没事,差一个大版本基本会出问题。
5. 常见问题与避坑经验
5.1 为什么FM版本会不一致
最常见的原因是驱动升级了但FM没跟着升。很多运维同学用apt upgrade升级了nvidia-driver-570,但FM包名是独立的,没有被自动带上。还有一种情况是用了CUDA toolkit自带的驱动,和系统里的FM版本对不上。
我的建议是:驱动和FM永远一起升,一起降。在部署脚本里把两个版本号写成变量,绑定在一起。
5.2 NVLS建不起来还有哪些原因
除了版本不一致,还有几个常见原因:
- NVSwitch固件太旧:B200的NVSwitch固件需要一定版本才支持SHARP,固件升级要用
nvidia-fabricmanager自带的工具或者厂商提供的固件包。 - FM配置里禁用了NVLS:检查
/etc/nvidia/fabricmanager.cfg,看有没有NVLS_ENABLED=0之类的配置。 - NCCL编译时没开NVLS:如果是自己编译的NCCL,确认
NVCC_GENCODE和NVLS相关宏打开了。 - 拓扑不是全互联:如果机器不是8卡全互联,NVLS可能本来就不支持。
5.3 排查顺序建议
遇到多卡通信卡死,我一般按这个顺序查:
nvidia-smi确认GPU和NVSwitch可见systemctl status nvidia-fabricmanager确认FM在跑- 对比驱动和FM版本号
- 看FM日志里的NVLS记录
- 开NCCL DEBUG看探测结果
- 检查拓扑和固件
这个顺序从硬件到软件,从底层到上层,能最快定位问题。
5.4 一个容易忽略的细节
FM启动是有顺序要求的。它必须在驱动加载之后启动,而且要在NCCL使用NVLink之前就绪。如果FM启动太慢,NCCL可能已经探测完了,结果就是NVLS不可用。所以systemctl里FM的依赖关系要配好,确保它在驱动之后、应用之前启动。
我在现场还遇到过一次FM启动后崩溃重启的情况,日志里是NVSwitch固件握手失败,最后发现是固件版本和FM不匹配。所以固件、驱动、FM这三者的版本要一起看。
6. 实操心得与后续建议
这次故障从发现到修复花了大概两个小时,其中大部分时间花在确认版本号和看日志上。真正修复就是升级FM一个动作。但如果没有前面的排查,直接瞎试,可能一天都搞不定。
我个人的经验是:多卡通信问题,先看FM,再看NCCL。FM是NVLink域的管理者,它出问题,上层怎么调都没用。而FM的问题里,版本不一致占了很大比例。
另外,B200这一代NVLS的收益很明显,但前提是配置正确。如果NVLS建不起来,NCCL会回退到普通NVLink,带宽会下降,延迟会上升。对于大模型训练这种通信密集的场景,性能损失可能到20%以上。所以NVLS不是可选项,是必选项。
最后分享一个小技巧:在部署新机器时,写一个检查脚本,把驱动版本、FM版本、NVSwitch固件版本、NCCL版本都打出来,和已知good combination对比。这样能在跑训练之前就发现问题,而不是等到卡死了再查。这个脚本我放在下面,可以直接抄:
#!/bin/bash echo "=== Driver ===" cat /proc/driver/nvidia/version | head -1 echo "=== Fabric Manager ===" nv-fabricmanager --version 2>/dev/null || dpkg -l | grep fabricmanager echo "=== NVSwitch ===" nvidia-smi -q | grep -A2 "NVSwitch" | head -10 echo "=== NCCL ===" python3 -c "import torch; print(torch.cuda.nccl.version())" 2>/dev/null || echo "NCCL version not found via torch" echo "=== NVLS Status ===" grep -i nvls /var/log/fabricmanager.log | tail -5这个脚本跑一遍,基本能判断出NVLS能不能用。如果FM日志里没有NVLS supported的字样,那就得先解决FM的问题,别急着跑训练。