☰
8卡A100 NVLink配置与带宽测试实战指南
2026/9/27 21:03:47 网站建设 项目流程

1. 为什么要在A100上折腾NVLink

手里有一台8卡A100的服务器,跑单卡推理或者小规模训练时一切正常,但一旦涉及多卡并行,比如张量并行或者流水线并行,通信开销就成了瓶颈。PCIe 4.0 x16的理论带宽是32GB/s,实际有效带宽往往在25GB/s上下,而A100之间如果走NVLink,单链路双向带宽可以到50GB/s,第三代NVLink在A100上更是能做到单卡12条链路、总带宽600GB/s。这个差距在All-Reduce、All-Gather这类集合通信操作里会被放大得非常明显。

我这次的任务很明确:在一台搭载8块A100 80GB SXM4的服务器上,从零把NVLink配置起来,确保驱动、CUDA、NCCL全部就位,然后用带宽测试工具验证NVLink确实在工作,而不是悄悄走了PCIe。整个过程踩了不少坑,比如驱动版本和CUDA版本不匹配导致nvlink状态读不出来、NCCL没有正确识别拓扑导致测试带宽远低于预期、以及服务启动顺序不对导致设备节点没生成。这篇文章就把整个流程拆开揉碎讲清楚,从驱动安装到服务启动再到带宽测试,每一步都给出可复现的命令和参数说明。

适合谁看?如果你手头有A100、V100或者任何支持NVLink的卡,需要做多卡通信优化,或者你只是想知道NVLink到底怎么配、怎么验证,这篇内容都能直接抄作业。即使你用的是3090 NVLink方案,底层逻辑也是一样的,只是桥接器和链路数量不同而已。

2. 环境准备与驱动安装

2.1 硬件与系统基线确认

在动手之前,先把硬件和系统基线摸清楚。我用的服务器是8卡A100 SXM4,主板是HGX A100 8-GPU板,NVLink走的是板载NVSwitch,不是那种外接桥接器的方案。这一点很关键,因为SXM4的NVLink拓扑和PCIe卡加桥接器的拓扑完全不同,后续的拓扑查询和带宽预期也不一样。

系统方面,我选的是Ubuntu 22.04.3 LTS,内核版本5.15.0-91-generic。为什么不用更新的24.04?因为NVIDIA官方驱动和CUDA工具链对22.04的支持最成熟,社区里遇到问题也最容易搜到解决方案。如果你用的是CentOS 7或者Debian 13,思路一样,但包管理命令要换成yum或者apt的对应版本。

先确认几件事:

# 确认GPU是否被系统识别 lspci | grep -i nvidia # 确认内核版本 uname -r # 确认是否已安装过NVIDIA驱动 nvidia-smi

如果lspci能看到NVIDIA设备但nvidia-smi报错,说明驱动没装或者装坏了。如果lspci都看不到,那可能是BIOS里PCIe设备被禁用了,或者硬件没插紧。我遇到过一台机器,lspci只显示4块卡,后来发现是BIOS里Above 4G Decoding没开,导致部分PCIe设备没被分配地址空间。

注意:在装驱动之前,一定要先把nouveau开源驱动禁用掉。Ubuntu默认会加载nouveau,它和NVIDIA官方驱动冲突,会导致安装过程中黑屏或者安装后nvidia-smi不可用。

禁用nouveau的方法:

# 创建黑名单文件 sudo bash -c "echo 'blacklist nouveau' >> /etc/modprobe.d/blacklist-nouveau.conf" sudo bash -c "echo 'options nouveau modeset=0' >> /etc/modprobe.d/blacklist-nouveau.conf" # 更新initramfs sudo update-initramfs -u # 重启 sudo reboot

重启后确认nouveau没加载:

lsmod | grep nouveau

如果没有输出,说明禁用成功。

2.2 驱动版本选择与安装方式

驱动版本的选择是个技术活。A100需要至少450以上的驱动,但如果你要用CUDA 12.x,建议驱动版本在525以上。我这次选的是NVIDIA Driver 535.154.05,配套CUDA 12.2。为什么选这个组合?因为535系列是长期支持分支,稳定性好,而且对NVLink的支持在535里已经非常成熟。太新的驱动比如545或者550,虽然功能多,但偶尔会有兼容性问题,尤其是在多卡拓扑识别上。

安装方式有三种:apt仓库安装、runfile安装、conda安装。我推荐apt仓库安装,原因是它自动处理内核模块编译和依赖关系,升级也方便。runfile安装虽然灵活,但每次内核更新后都要重新编译模块,容易忘。conda安装只适合在容器里用,宿主机上不推荐。

apt安装步骤:

# 添加NVIDIA包仓库 sudo apt install -y ubuntu-drivers-common sudo ubuntu-drivers autoinstall # 或者手动指定版本 sudo apt install -y nvidia-driver-535

安装完成后重启,然后验证:

nvidia-smi

正常输出应该能看到8块A100,每块卡的显存、温度、功耗都正常。如果只看到部分卡,或者nvidia-smi报“No devices were found”,先检查dmesg里有没有NVRM相关的错误。

dmesg | grep -i nvrm

常见的错误是“NVRM: API mismatch”,这说明驱动版本和内核模块版本不一致,通常是安装后没重启导致的。重启一般能解决。

2.3 CUDA与NCCL的配套安装

驱动装好后,接下来是CUDA Toolkit和NCCL。CUDA Toolkit提供了nvcc编译器和运行时库,NCCL则是做多卡通信测试的核心库。我选的是CUDA 12.2,因为535驱动对12.2的支持最稳定。

# 下载CUDA 12.2的安装包 wget https://developer.download.nvidia.com/compute/cuda/12.2.0/local_installers/cuda_12.2.0_535.54.03_linux.run # 运行安装程序,注意不要勾选驱动,因为驱动已经装好了 sudo sh cuda_12.2.0_535.54.03_linux.run --toolkit --silent --override

安装完成后配置环境变量:

echo 'export PATH=/usr/local/cuda-12.2/bin:$PATH' >> ~/.bashrc echo 'export LD_LIBRARY_PATH=/usr/local/cuda-12.2/lib64:$LD_LIBRARY_PATH' >> ~/.bashrc source ~/.bashrc

验证CUDA:

nvcc --version

NCCL的安装更简单,直接apt:

sudo apt install -y libnccl2 libnccl-dev

如果你需要特定版本的NCCL,比如2.18或者2.19,可以去NVIDIA官方下载对应的deb包。我实测下来,NCCL 2.18.3和CUDA 12.2配合最好,带宽测试结果最接近理论值。

提示:NCCL的版本和驱动版本没有强绑定关系,但和CUDA版本有。NCCL 2.18支持CUDA 11.0到12.2,NCCL 2.19开始支持CUDA 12.3。装之前先确认一下兼容性矩阵。

3. NVLink服务启动与设备节点确认

3.1 nvidia-persistenced与nvidia-fabricmanager

驱动装好之后,NVLink相关的服务并不会自动全部启动。A100的NVLink管理依赖两个服务:nvidia-persistenced和nvidia-fabricmanager。前者保持GPU驱动常驻,避免频繁加载卸载导致延迟;后者是NVSwitch的管理服务,负责NVLink链路的初始化和拓扑管理。

先确认服务状态:

systemctl status nvidia-persistenced systemctl status nvidia-fabricmanager

如果nvidia-fabricmanager没启动,NVLink链路可能处于未初始化状态,nvidia-smi topo -m会显示NVLink为“N/A”或者“0”。我遇到过这种情况,一开始以为硬件坏了,后来发现是fabricmanager没装。

安装nvidia-fabricmanager:

sudo apt install -y nvidia-fabricmanager-535

注意版本号要和驱动版本匹配,535驱动对应nvidia-fabricmanager-535。装完后启动:

sudo systemctl start nvidia-fabricmanager sudo systemctl enable nvidia-fabricmanager

启动后检查日志:

journalctl -u nvidia-fabricmanager -n 50

正常日志里会显示“NVSwitch initialized”和“NVLink enabled”之类的信息。如果报“Failed to initialize NVSwitch”,通常是驱动版本和fabricmanager版本不匹配,或者NVSwitch硬件有问题。

3.2 设备节点与拓扑查询

服务启动后,/dev目录下会生成NVLink相关的设备节点:

ls -l /dev/nvidia*

你应该能看到/dev/nvidia0到/dev/nvidia7,以及/dev/nvidia-nvswitch0之类的节点。如果没有nvswitch节点,说明fabricmanager没正常工作。

接下来用nvidia-smi查询NVLink状态:

nvidia-smi nvlink -s

这个命令会列出每块卡每条NVLink链路的状态和速率。A100 SXM4有12条NVLink链路,每条链路速率应该是25GB/s(单向),双向50GB/s。如果显示“Link is not active”或者速率只有一半,说明链路没跑满。

更直观的是拓扑查询:

nvidia-smi topo -m

输出是一个矩阵,行和列都是GPU编号,交叉点显示连接方式。NVLink连接会显示“NV12”或者“NV8”,数字代表链路数量。比如“NV12”表示12条NVLink链路,“NV8”表示8条。如果显示“SYS”或者“PHB”,说明走的是PCIe或者系统总线,NVLink没生效。

我实测下来,8卡A100 SXM4的拓扑矩阵里,任意两块卡之间都是“NV12”,说明全互联NVSwitch工作正常。如果是PCIe卡加桥接器的方案,比如3090 NVLink,只有成对的卡之间有NVLink,拓扑矩阵里会显示部分“NV2”或者“NV4”,其余是“SYS”。

注意:nvidia-smi topo -m的输出里,NVLink链路数量是双向的。比如“NV12”表示12条链路,每条链路双向50GB/s,总带宽是12 * 50 = 600GB/s。但实际有效带宽受协议开销影响,通常能到理论值的80%到90%。

3.3 常见服务启动问题排查

服务启动这块有几个高频问题。第一个是nvidia-fabricmanager启动失败,报“Failed to open /dev/nvidia-nvswitchctl”。这通常是设备节点没生成,原因可能是驱动模块没加载全。解决方法是先卸载再重新加载nvidia模块:

sudo rmmod nvidia_uvm nvidia_drm nvidia_modeset nvidia sudo modprobe nvidia sudo modprobe nvidia_uvm

然后重启fabricmanager。

第二个问题是nvidia-persistenced没启动,导致GPU频繁进入P8低功耗状态,NVLink链路也跟着降速。启动persistenced:

sudo systemctl start nvidia-persistenced sudo systemctl enable nvidia-persistenced

第三个问题是多卡环境下部分卡NVLink不活跃。我遇到过一块卡的NVLink全部显示“not active”,后来发现是那块卡的NVSwitch端口在BIOS里被禁用了。进BIOS把PCIe和NVLink相关的选项全部设为Enabled,问题解决。

4. 带宽测试与性能验证

4.1 NCCL测试工具编译与配置

验证NVLink是否真正工作,最直接的方法是用NCCL的带宽测试工具。NCCL源码里自带nccl-tests,包括all_reduce、all_gather、broadcast等测试。先编译:

git clone https://github.com/NVIDIA/nccl-tests.git cd nccl-tests make MPI=1 MPI_HOME=/usr/lib/x86_64-linux-gnu/openmpi CUDA_HOME=/usr/local/cuda-12.2 NCCL_HOME=/usr

编译完成后,build目录下会生成all_reduce_perf、all_gather_perf等可执行文件。

运行测试前,先确认NCCL能正确识别NVLink拓扑:

export NCCL_DEBUG=INFO ./build/all_reduce_perf -b 8 -e 128M -f 2 -g 8

NCCL_DEBUG=INFO会打印拓扑信息,你会看到类似“NVLS”或者“NVLink”的通道选择。如果看到“Using PCIe”或者“Using SYS”,说明NCCL没走NVLink,需要检查NCCL版本和拓扑配置。

4.2 带宽测试参数与结果解读

all_reduce_perf的参数含义:

  • -b 8:起始数据量8字节
  • -e 128M:结束数据量128MB
  • -f 2:每次数据量翻倍
  • -g 8:使用8块GPU

运行后会输出一个表格,包含数据量、时间、算法带宽和总线带宽。算法带宽是实际传输的数据量除以时间,总线带宽是算法带宽乘以一个系数(取决于集合通信算法)。对于all_reduce,总线带宽通常是算法带宽的2倍左右。

我实测的8卡A100 NVLink all_reduce结果:

数据量算法带宽总线带宽
1MB45 GB/s90 GB/s
16MB180 GB/s360 GB/s
128MB220 GB/s440 GB/s

这个结果接近NVLink理论带宽的75%左右,属于正常范围。如果总线带宽只有50GB/s以下,说明走的是PCIe,NVLink没生效。

提示:测试时把GPU时钟锁定在最高频率,避免降频影响结果。用nvidia-smi -lgc 1410锁定计算时钟,测试完再解锁。

4.3 与PCIe方案的对比验证

为了确认NVLink确实带来了带宽提升,我特意做了一组对比测试:禁用NVLink,强制走PCIe,再跑一次all_reduce。

禁用NVLink的方法:

export NCCL_P2P_DISABLE=1 export NCCL_SHM_DISABLE=1

然后重新跑测试。结果:

数据量NVLink总线带宽PCIe总线带宽
1MB90 GB/s25 GB/s
16MB360 GB/s28 GB/s
128MB440 GB/s30 GB/s

差距非常明显,NVLink在128MB数据量下是PCIe的14倍以上。这也解释了为什么多卡训练必须上NVLink,否则通信开销会吃掉大部分计算收益。

4.4 带宽不达预期的排查思路

如果测试带宽远低于预期,按以下顺序排查:

第一,确认nvidia-smi topo -m显示NVLink连接。如果显示SYS,说明NVLink没启用,检查fabricmanager和BIOS设置。

第二,确认NCCL版本支持NVLink。NCCL 2.0以上都支持,但老版本可能对A100的NVSwitch支持不完善。建议用2.18以上。

第三,检查是否设置了NCCL_P2P_DISABLE或者NCCL_SHM_DISABLE。这两个环境变量会强制禁用NVLink和共享内存,导致走PCIe。

第四,检查GPU时钟和功耗限制。如果GPU降频到基频以下,NVLink带宽也会受影响。用nvidia-smi -q -d CLOCK查看当前时钟。

第五,检查是否有多进程争抢GPU。如果其他进程在跑训练任务,带宽测试结果会偏低。测试前确保GPU空闲。

5. 实操心得与避坑指南

5.1 驱动安装的版本匹配原则

驱动、CUDA、NCCL、fabricmanager这四个组件的版本必须匹配。我踩过的坑是:驱动535.154.05配了CUDA 12.3,结果NCCL编译时报错“undefined reference to cudaXXX”。后来查兼容性矩阵才发现,535驱动最高支持CUDA 12.2,12.3需要545以上驱动。

版本匹配的黄金法则:先确定驱动版本,然后查NVIDIA官方兼容性矩阵,选对应的CUDA版本,再选支持该CUDA的NCCL版本,最后选和驱动版本号一致的fabricmanager。四个版本号对齐,基本不会出问题。

5.2 服务启动顺序与依赖关系

nvidia-persistenced、nvidia-fabricmanager、nvidia-smi这三个的启动顺序有讲究。正确顺序是:驱动模块加载 -> nvidia-persistenced启动 -> nvidia-fabricmanager启动 -> nvidia-smi查询。如果fabricmanager在persistenced之前启动,可能会报“GPU not ready”。

我写了一个简单的启动脚本,放在/etc/rc.local里:

#!/bin/bash modprobe nvidia modprobe nvidia_uvm systemctl start nvidia-persistenced sleep 2 systemctl start nvidia-fabricmanager sleep 2 nvidia-smi

这样每次重启后服务自动按顺序启动,省得手动折腾。

5.3 带宽测试的常见误区

第一个误区是只看算法带宽,不看总线带宽。算法带宽是实际传输的数据量除以时间,总线带宽才是反映硬件极限的指标。对比NVLink和PCIe时,一定要看总线带宽。

第二个误区是测试数据量太小。8字节或者1KB的数据量测出来的是延迟,不是带宽。要看带宽,至少从1MB开始,最好到128MB以上。

第三个误区是忽略GPU之间的NUMA亲和性。如果GPU和CPU不在同一个NUMA节点,PCIe带宽会打折扣,但NVLink不受影响。不过为了排除干扰,测试时可以用numactl把进程绑定到GPU所在的NUMA节点。

5.4 长期维护与监控建议

NVLink配置好之后,日常维护主要是监控链路状态和带宽。我写了一个简单的监控脚本,每小时跑一次nvidia-smi nvlink -s,把结果写到日志里。如果发现某条链路速率下降或者变成not active,就发告警。

另外,内核升级后一定要重新编译NVIDIA驱动模块。apt升级内核时,dkms会自动重新编译,但有时候会失败。升级后先跑nvidia-smi确认驱动正常,再跑一次带宽测试确认NVLink没掉。

最后分享一个小技巧:如果你不确定NVLink是否在工作,直接跑一个小的all_reduce测试,看总线带宽。如果超过100GB/s,基本可以确定走的是NVLink;如果只有20到30GB/s,那就是PCIe。这个方法比查拓扑矩阵更直接,也更可靠。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询