Skip to content

NVSwitch Fabric Manager 服务运维:配置、启动顺序与 SXid 故障处置 ​

一句话:在没有 NVSwitch 的机器上,GPU 之间的 NVLink 是"点对点直连";一旦上了 NVSwitch,GPU 之间能不能互相看见、带宽能不能跑满,就不再由驱动单独决定,而是由一个叫 Fabric Manager 的常驻进程在启动时把整块 switch 配成一张共享 fabric——它没起来,8 张卡在拓扑上就是 8 座孤岛。

一、Fabric Manager 到底在做什么 ​

NVSwitch 把一台服务器里所有 GPU 连成一张全互联网络:任意两张卡之间都能通过 switch 通信,而不必依赖 GPU 之间的直连链路。但这张网络不是插上就能用——它需要被初始化、被路由、被监控。核心软件栈由两部分组成:

  • NVSwitch 内核驱动:响应 FM 的请求,做底层的硬件管理;
  • Fabric Manager(FM):一个特权用户态进程,负责把 NVSwitch 配置成所有 GPU 共享的单一内存 fabric、下发路由、与 GPU 驱动协同完成初始化,并监控 NVLink / NVSwitch 的错误。

官方文档对它的定位是"NVSwitch 管理的核心软件栈",同时提供带内与带外两种监控手段来上报 NVSwitch 与 GPU 的错误和状态。这个定位决定了三件运维事实:

  1. FM 是服务,不是工具。它得常驻、开机自启、有日志、有状态文件;
  2. 它有严格的启动前提。GPU 与 NVSwitch 必须先绑定到 nvidia.ko,FM 才能接管;
  3. 它一旦退出,CUDA 作业的语义会立刻变化。默认配置下 FM 退出会中止正在跑的 CUDA 作业(ABORT_CUDA_JOBS_ON_FM_EXIT=1)。

二、四代平台:先确认你在哪一代上干活 ​

不同代际的 NVSwitch 平台,组件构成和运维动作差别很大。这不是背景知识,而是决定"该改哪个配置项、该看哪个日志"的前提:

平台NVSwitch 数量与代际关键差异
HGX-2 / V1006 个第一代 NVSwitch,16 GPU 分布在双基板双基板通过 Trunk 端口互联
HGX A1006 个第二代 NVSwitchTrunk 故障有专门的高可用降级模式
HGX H1004 个第三代 NVSwitch不支持双基板互联;NVLink 由 ALI 在硬件层训练
HGX B200 / B300 / B1002 个第四代 NVSwitchNVSwitch 不再作为 PCIe 设备出现,改走 ConnectX-7 的 Bridge 呈现

第四代是一次架构断点,带来三个连锁变化:

  • 新增 NVLSM。第四代引入 NVLink Subnet Manager(源自 InfiniBand 的子网管理器),专门负责 NVSwitch 的路由表与 PKEY;FM 负责 GPU 侧路由与分区 API,两者通过 IPC 协作,socket 默认在 /var/run/nvidia-fabricmanager/fm_sm_ipc.socket;
  • 日志分家。FM 的日志在 /var/log/fabricmanager.log,NVLSM 的日志默认落到 /var/log/opensm.log(log_flags 0x3,即 ERROR + INFO);
  • 包与内核要求变化。第四代改用 nvidia-open-<branch> 加 nvlink5-<branch>(RHEL 侧是 nvidia-driver-<branch>-open 与 nvlink-<branch>),并要求内核不低于 5.17,另外需要 libibumad3、infiniband-diags。

三、服务面:命令、单元、包 ​

FM 以标准 systemd 服务运行,这套命令是运维日常:

bash
systemctl status nvidia-fabricmanager
systemctl start nvidia-fabricmanager
systemctl stop nvidia-fabricmanager
systemctl enable nvidia-fabricmanager
journalctl -u nvidia-fabricmanager --since "30 min ago"

单元文件在 /lib/systemd/system/nvidia-fabricmanager.service,它并不直接拉起 nv-fabricmanager,而是调用 /usr/bin/nv-fabricmanager-start.sh——这个脚本按平台决定拉起 FM、NVLSM,还是两者都拉。所以"服务 active"里去判断"到底哪几个进程在跑",别只看 systemctl 的状态色。

二进制本身是 nv-fabricmanager,可用参数不多但都用得上:

参数用途
-c / --config指定非默认配置文件
-r / --restart多租户场景下的 resiliency 重启流程(等价 FABRIC_MODE_RESTART=1)
-d / --database单机 HGX/DGX 不要用,官方明确不适用

安装方式按发行版分三类:

bash
# Ubuntu / Debian
apt-get install cuda-drivers-fabricmanager-<branch>
# RHEL 系
dnf module install nvidia-driver:<branch>/fm
# SUSE
zypper install cuda-drivers-fabricmanager-<branch>

最低驱动版本随代际递增:HGX-2/A100 是 450.xx,H100 是 525.xx,B200/B300/B100 是 570.xx。DGX 系列随机预装并已自启,HGX 系列要自己装、自己 enable、自己 start——这一条是"新机器插上卡却跑不出 P2P"的最常见原因。

包结构也值得知道:nvidia-fabricmanager-<version> 是核心包,含 FM 服务进程、服务单元文件和拓扑文件,裸金属只装它就够;nvidia-fabricmanager-devel-<version> 是 SDK 与库,做 Shared NVSwitch 或 vGPU 多租户时才需要。

四、fabricmanager.cfg:真正要调的只有几项 ​

默认配置在 /usr/share/nvidia/nvswitch/fabricmanager.cfg。改完必须重启服务才生效——配置文件是在服务启动时读取的。

配置项默认值说明
LOG_FILE_NAME/var/log/fabricmanager.log日志路径,最长 255 字符
LOG_LEVEL40 关闭,1 CRITICAL,2 ERROR,3 WARNING,4 INFO 及以上
LOG_APPEND_TO_LOG1每次启动追加而非覆盖
LOG_FILE_MAX_SIZE1024单位 MB,达到上限后停止写日志(不是滚动)
LOG_MAX_ROTATE_COUNT3非 0 才滚动,总日志量约为 MAX_SIZE × (COUNT + 1)
LOG_USE_SYSLOG0置 1 则改投 syslog
FABRIC_MODE00 裸金属/全透传,1 Shared NVSwitch 多租户,2 vGPU 多租户
FABRIC_MODE_RESTART0置 1 走多租户 resiliency 重启序列
FM_CMD_BIND_INTERFACE127.0.0.1FM SDK/API 监听接口(多租户用)
FM_CMD_PORT_NUMBER6666FM SDK/API 的 TCP 端口(多租户用)
STARTING_TCP_PORT16000FM 内部通信/IPC 起始端口
STATE_FILE_NAME/tmp/fabricmanager.state多租户 resiliency 的状态文件
DAEMONIZE1以后台守护方式运行
ABORT_CUDA_JOBS_ON_FM_EXIT1FM 退出时中止 CUDA 作业

三条实践结论:

  1. LOG_FILE_MAX_SIZE 的行为要看清:达到上限后 FM 是"跳过后续日志",不是自动滚动。如果 LOG_MAX_ROTATE_COUNT 被设成 0,一个 1 GB 的日志写满之后你会在最需要证据的时刻失去日志。官方建议就是保持 INFO 级别、保留滚动;
  2. STATE_FILE_NAME 落在 /tmp。重启后 /tmp 被清掉,多租户的 resiliency 状态就断了。生产上应把它挪到持久目录;
  3. ABORT_CUDA_JOBS_ON_FM_EXIT 只对 H100 之前有效。官方注明该行为在 H100 及以后不再适用,且只在裸金属/全透传模式下有意义。

第四代平台还有一项要配对改:FM_SM_IPC_INTERFACE(默认的 unix socket 路径),以及 NVLSM 侧 plugin_options grpc_mgr --grpc_server_address 必须指向同一个路径。改了一边没改另一边,两个进程握不上手,fabric 起不来。

五、初始化语义:三种"起不来"的形态 ​

FM 的启动不是"进程在就算成功",判断标准要落到 fabric 状态上。

5.1 版本不兼容直接 abort ​

FM 启动时会校验内核驱动栈的版本。不兼容时它不会降级运行,而是直接中止。所以"服务起不来"的第一现场永远是:

bash
journalctl -u nvidia-fabricmanager -n 100 --no-pager
grep -i "version\|abort" /var/log/fabricmanager.log | tail

驱动分支(-<branch>)与 FM 包分支必须一致,这是安装阶段就该配平的事。

5.2 CUDA 抢跑:cudaErrorSystemNotReady ​

FM 还没完成初始化就提交 CUDA 作业,应用拿到的不是"卡忙"而是 cudaErrorSystemNotReady。这个错误的语义很明确:fabric 还没就绪。它不该被当作硬件故障排队报修,而是应该回到启动顺序上找原因。

5.3 H100 及以后:GPU 必须向 fabric 注册 ​

H100 起,NVLink 由 ALI 在硬件层训练,GPU 需要主动向 fabric 注册;注册失败的 GPU 会失去 P2P 能力。验收命令:

bash
nvidia-smi -q -i 0 | grep -i -A2 Fabric
# 期望看到 State: Completed
#          Status: Success

逐卡跑一遍,任何一张不是 Completed / Success,就先别谈性能基线——那张卡的 P2P 路径根本没建立。

六、重启的正确顺序(H100 及以后) ​

这是 FM 运维里唯一一个"顺序错了就会把作业打死"的动作。官方给出的顺序是:

bash
# 1. 停掉所有 CUDA 应用与 GPU 相关服务
#    (nvidia-persistenced 可以留着,DCGM 必须停)
systemctl stop nvidia-dcgm

# 2. 停 FM
systemctl stop nvidia-fabricmanager

# 3. GPU 复位
nvidia-smi -r

# 4. 起 FM,等 fabric 就绪
systemctl start nvidia-fabricmanager
nvidia-smi -q -i 0 | grep -i -A2 Fabric

# 5. 恢复被停掉的服务

# 6. 再跑 CUDA 作业

反过来做会怎样:先 nvidia-smi -r 再停 FM,复位过程中 FM 仍持有 fabric 状态,注册关系被打断;或者 FM 停了不等 fabric 就绪就拉起 CUDA,拿到一片 cudaErrorSystemNotReady。

还有一条来自官方文档的心态建议:FM 不需要频繁重启。它是个稳态服务,重启的合理触发点是驱动升级、配置变更、以及下面要讲的致命错误恢复,而不是"感觉不太对就重启一下"。

七、故障语义:GPU 报 Xid,NVSwitch 报 SXid ​

两套错误码必须分开看:

  • GPU 侧是 Xid,来自 NVIDIA 驱动的标准错误码体系;
  • NVSwitch 侧是 SXid,格式形如:
text
nvidia-nvswitch0: SXid (PCI:0000:0a:00.0): 12008, Fatal, Link 12

一行里包含四个关键信息:哪个 switch、PCI 地址、错误值、致命还是非致命、以及涉及的链路号。

7.1 非致命 SXid:只记账,不杀作业 ​

非致命 SXid 只做提示,不会中止正在运行的作业。它适合进监控告警、做趋势对比——比如同一条链路反复出非致命错误,就值得在下个维护窗口换件,而不是等到它变致命。

7.2 致命 SXid(GPU ↔ NVSwitch 端口):杀该卡上的作业 ​

当致命 SXid 出现在 GPU 与 NVSwitch 之间的端口上时,FM 会杀掉跑在那张 GPU 上的作业,并且可能连带产生 Xid 74 / Xid 45。恢复顺序:

bash
nvidia-smi -r          # 先复位
# 如果复位不解决问题 → 重启整机

7.3 致命 SXid(跨基板 Trunk 端口):杀掉全部 CUDA 作业 ​

这是最重的一档。当致命 SXid 出现在跨基板的 Trunk 端口时,FM 会杀掉机器上所有 CUDA 作业——因为 fabric 的部分路径已经不可信,继续跑只会得到静默的数据错误。官方给的恢复序列是:

bash
systemctl stop nvidia-fabricmanager        # 停 FM
# 停掉所有使用 GPU 的应用与服务
nvidia-smi -r                              # 注意:不要带 -i / -id
systemctl start nvidia-fabricmanager       # 起 FM
# 仍不恢复 → 重启 / 断电重上

nvidia-smi -r 不带 -i/-id 是有意的:Trunk 级故障不是单卡问题,只复位一张卡不会重建 fabric。

7.4 第四代平台:SXid 机制不再适用 ​

B200/B300 上这套 SXid 上报机制已经不再适用,错误观测改为由 DCGM 通过 NVSDM 读取端口与 ASIC 计数器。这意味着运维栈要跟着换:靠 dmesg 抓 SXid 的老办法在新平台上抓不到东西,得把 NVSwitch/端口级遥测接进 DCGM 侧。

八、高可用降级模式:A100 世代的遗产 ​

FM 有三个降级开关,用来决定"链路坏了是退出还是降级运行":

配置项作用取值语义
ACCESS_LINK_FAILURE_MODEGPU ↔ NVSwitch 接入链路故障0 = 把故障 GPU 移出 fabric(保留非 P2P 用途)或退出 FM;1 = 降级继续
TRUNK_LINK_FAILURE_MODE跨基板 Trunk 链路故障同上
NVSWITCH_FAILURE_MODE整颗 NVSwitch 故障1 = 禁用该 switch 及其对端,带宽降到 5/6

这三个开关只在 A100 世代有效,H100 及以后被忽略。所以从 A100 集群迁到 H100 集群时,那些为了"尽量不停机"调过的降级参数会静默失效——不是配置丢了,是新平台不再走这条路径。这一点在迁移评审里必须写进变更单。

九、MIG 互操作与权限边界 ​

开 MIG 会禁用(或不使用)GPU 的 NVLink,随之失去 P2P。代际差异在这件事上很明显:

  • H100 及以后:MIG 期间 NVLink 保持 active;
  • A100:关闭 MIG 之后,要靠 FM 在运行才能恢复 P2P。

所以 A100 上"关掉 MIG 但 P2P 还是不通",先看 FM 是不是活的,而不是先怀疑卡。

9.2 非 root 运行 FM ​

FM 支持非 root 运行,但要显式授权这些路径与设备:

text
目录:/var/run/nvidia-fabricmanager、/var/log/、/usr/share/nvidia/nvswitch
proc:/proc/driver/nvidia-nvlink/capabilities/fabric-mgmt
设备:/dev/nvidia-nvlink、/dev/nvidia-nvswitchctl、
      /dev/nvidia-nvswitchX、/dev/nvidiactl、/dev/nvidiaX

第四代(B200 等)还要加上 /dev/infiniband/umadX、/dev/infiniband/issmX,以及对 /sys/class/infiniband/mlx5_X/device/vpd 的读权限。麻烦之处在于:驱动重载或重启后,/proc 下的条目会重建,权限随之丢失。所以这些授权必须做成 udev 规则自动化,否则每次升级驱动都要人工补一遍。

另外一条边界:在 ConnectX 端口上使用 infiniband 工具是不受支持的,别拿 ibstat 那套去诊断 NVSwitch 侧的问题。

上线验收清单 ​

  1. systemctl is-enabled nvidia-fabricmanager 与 is-active 双绿,HGX 机器确认是自己 enable 过的;
  2. nvidia-smi -q -i N | grep -A2 Fabric 逐卡 Completed / Success;
  3. FABRIC_MODE 与业务形态匹配(裸金属/透传=0,多租户=1/2),改过就重启过;
  4. 第四代平台核对 FM_SM_IPC_INTERFACE 与 NVLSM grpc_server_address 指向同一路径;
  5. LOG_LEVEL=4、LOG_MAX_ROTATE_COUNT 非 0,日志能在满盘前滚动;
  6. STATE_FILE_NAME 已从 /tmp 挪到持久目录(多租户场景);
  7. 驱动升级后跑一遍 restart 顺序脚本,并确认 udev 规则把非 root 权限补回来了;
  8. 监控侧已接 SXid(三代及以前)或 DCGM 的 NVSwitch 端口计数器(四代)。

收口三句 ​

  • FM 不是可选的监控组件,是 fabric 的初始化者:它没起来,卡再多也只是点对点;cudaErrorSystemNotReady 要往启动顺序里查,不要当硬件故障;
  • 重启有唯一正确顺序:停 CUDA 与 GPU 服务 → 停 FM → nvidia-smi -r → 起 FM → 恢复服务,顺序错了就是把作业打死;
  • SXid 的致命级别决定爆炸半径:端口级只影响单卡作业,Trunk 级会让 FM 杀掉全部 CUDA 作业,第四代则完全换了观测通道(DCGM + NVSDM)。

延伸阅读 ​

AI-HPC 智算超算专家 · Contact: openaihpc@gmail.com