多GPU服务器如何选择PCIe与NVLink互联方案?带宽与通信效率解析

买多卡服务器时,很多配置单上只写了"4 卡""8 卡",却不写这些卡之间是怎么连的。这一步恰恰决定了多卡能不能跑出应有的加速比。同样八块卡,走 PCIe 交换机互联和走 NVLink/NVSwitch 全互联,卡间带宽可以差好几倍,做分布式训练时一个还能线性加速,另一个可能连单卡快不了多少。

问题的根源在于:多卡训练的每一步都要同步梯度或交换中间结果。如果卡间通信慢,GPU 就得停下来等数据,算力和带宽不匹配,加卡的钱就白花了。所以选互通方案,本质是在为"通信不成为瓶颈"买单。

这篇文章讲清 PCIe 与 NVLink 两条技术路线的差别:带宽量级差多少、拓扑结构怎么影响效率、什么负载值得上 NVLink、什么情况下 PCIe 够用。文中会给出真实可用的拓扑检测命令(nvidia-smi topo -m、lspci、nvidia-smi nvlink),并用表格对比带宽与适用场景。带宽数字是经验量级,随 PCIe 与 NVLink 代际变化,具体以平台规格为准。

先把通信需求算清楚

多卡并行主要有几种模式,对互联的要求不同:

  • 数据并行:每张卡拿一部分数据算出梯度,然后做一次全局归约(all-reduce)同步。通信量约等于模型参数量 × 精度字节数 × 系数。卡越多,通信越频繁。
  • 张量并行:把单层内部切分到多卡,前向和反向每一步都要通信,对带宽和延迟极其敏感,基本离不开高带宽互联。
  • 流水线并行:把不同层分到不同卡,通信量小于张量并行,但对负载均衡和微批调度要求高。

判断是否需要高端互联,可以用一个粗略原则:通信时间占比越高,互联越关键。经验上,当模型大到单卡装不下、必须张量并行时,NVLink 几乎是必选项;如果只是数据并行、模型能单卡装下,PCIe 往往够用。

PCIe 与 NVLink 的带宽量级

先建立直觉(均为单链路或单卡方向的经验量级,按代际不同会变化):

  • PCIe 4.0 x16:双向带宽约 32 GB/s 量级;
  • PCIe 5.0 x16:约为 PCIe 4.0 的两倍,约 64 GB/s 量级;
  • PCIe 6.0 x16:再翻倍,用于最新平台;
  • NVLink 早期代际:每卡聚合带宽每秒数百 GB 量级;
  • NVLink 较新代际:每卡聚合带宽可达每秒数 TB 量级(配合 NVSwitch)。

可见 NVLink 的带宽通常是 PCIe 的数倍到十数倍,而且延迟更低、更可控。这就是为什么做张量并行时差别巨大。

但要注意主板 PCIe 通道是共享的。一台机器上 CPU 提供的 PCIe 通道总数有限,插满 8 块卡后每块卡分到的可能是 x16,也可能被降为 x8 甚至 x4,带宽随之腰斩。选机时一定要问清每块卡实际分到的 PCIe 通道数。

拓扑结构决定实际效率

同样是 PCIe,拓扑不同效率差很多:

互联方式 典型带宽量级 卡数量级 特点 适用场景
PCIe 单根直连 数十 GB/s 少 无交换,简单 少量卡、轻通信
PCIe Switch 数十 GB/s 多 有 PCIe 交换机,带宽共享 中等规模多卡
跨 NUMA 的 PCIe 更低,且延迟高 多 跨 CPU 访问,性能打折 尽量避免
NVLink 点对点 数百 GB/s 起 少 卡间直连,部分拓扑 小规模高带宽
NVLink + NVSwitch 每秒数百 GB 至数 TB 多 全互联,任意两卡对等 大规模训练

NVSwitch 的意义在于把 NVLink 做成星形全互联:任意两块卡之间都有等价的高带宽通路,不再受"谁和谁连"的限制。没有 NVSwitch 时,NVLink 可能呈混合拓扑,部分卡对之间要走 PCIe 绕行,性能不稳定。

nvidia-smi topo -m 就是用来暴露这些细节的,下面会讲怎么看。

检测命令实操

先看拓扑矩阵:

nvidia-smi topo -m

输出示例(示意):

        GPU0    GPU1    GPU2    GPU3    NIC0    CPU Affinity
GPU0     X      NV4     NV4     NV4     PIX     SYS
GPU1    NV4      X      NV4     NV4     PIX     SYS
GPU2    NV4     NV4      X      NV4     SYS     SYS
GPU3    NV4     NV4     NV4      X      SYS     SYS

字段含义:

  • NV4:卡间通过 4 条 NVLink 互联,带宽高;
  • PIX:经过单层 PCIe 交换机,PCIe 级别带宽;
  • PHB:经过 PCIe 主机桥,性能一般;
  • SYS:跨 NUMA 节点或跨 CPU 插槽,走 SMP 互连,带宽和延迟最差;
  • X:对角线,自身;
  • 还有 NODE(同一 NUMA 节点内 PCIe)等标记。

判断原则:矩阵里如果出现大量 SYS,说明卡被分到了不同 CPU 插槽下,跨节点通信会成为训练瓶颈。 理想情况是全 NV#(有 NVSwitch 或全 NVLink),退一步是全 PIX/NODE。

进一步看每块卡的 PCIe 与最大链路宽度:

# 查看 PCIe 链路协商速率与宽度
sudo lspci -vvv | grep -A5 -i "LnkCap\|LnkSta" | grep -Ei "nvidia|Lnk"

# 更精确:用 lspci 定位显卡再单独查
lspci | grep -i nvidia
sudo lspci -s  -vvv | grep -Ei "LnkCap|LnkSta"

实例:

lspci | grep -i nvidia
# 01:00.0 3D controller: NVIDIA Corporation ...
sudo lspci -s 01:00.0 -vvv | grep -Ei "LnkCap|LnkSta"
# LnkCap: Port #0, Speed 32GT/s, Width x16   -> 能力上限 PCIe 5.0 x16
# LnkSta: Speed 32GT/s, Width x16            -> 当前协商值,应和 LnkCap 一致

如果 LnkSta 的 Width 小于 LnkCap,说明插槽或转接卡限制了通道数,需要检查硬件配置。如果 Speed 只有 8GT/s 而 Cap 是 32GT/s,可能是插槽、转接卡或链路训练问题。

查看 NVLink 状态与错误:

# 每块卡的 NVLink 链路状态
nvidia-smi nvlink --status

# 带宽使用(部分版本支持)
nvidia-smi nvlink -s

# 检查 NVLink 错误计数
nvidia-smi nvlink -e

# 输出拓扑图(部分版本)
nvidia-smi topo -mp

nvidia-smi nvlink --status 会逐条列出 NVLink 链路是 active 还是 inactive。如果有链路显示未激活,多卡性能会明显下降,要优先排查。

查看系统的 NUMA 与 PCIe 亲和性:

numactl --hardware
# 观察每个 NUMA 节点下挂了哪些卡
ls /sys/class/nvidia/ 2>/dev/null
cat /sys/bus/pci/devices/0000:01:00.0/numa_node

什么负载值得上 NVLink

给一个可操作的判断表(经验值,实际以实测加速比为准):

场景 建议互联 理由
单卡能装下,只做数据并行 PCIe 足够 通信占比低,减少成本
小模型多任务推理 PCIe 足够 各卡独立跑,几乎不通信
中等模型数据并行训练 PCIe 4.0/5.0,全 x16 归约频率中等
大模型张量并行训练 NVLink/NVSwitch 每步通信,带宽敏感
大模型分布式推理(TP) NVLink 优先 延迟敏感
大规模集群训练 NVLink 机内 + 高速网络机间 机内机间都要快

注意机间通信: 单机内 NVLink 解决了卡与卡的问题,但跨机训练要靠 RDMA/InfiniBand 或高速以太网。如果机间网络只有普通万兆,机内再把 NVLink 堆到顶也无济于事,木桶效应明显。集群网络见本系列另一篇文章。

选型注意事项与常见坑

第一,写清通道数。 采购时要求厂商明确"每卡 PCIe 通道数"和"是否走 PCIe Switch"。8 卡机型若无足够通道,可能被迫 x8 甚至 x4 运行。

第二,警惕跨 NUMA。 双路 CPU 分别带若干卡时,要配合 NUMA 绑定让进程优先访问本地卡和本地内存:

# 让进程优先使用 NUMA 节点 0
numactl --cpunodebind=0 --membind=0 python train.py

# 或使用 CUDA 的 NUMA 亲和
export CUDA_DEVICE_ORDER=PCI_BUS_ID
export CUDA_VISIBLE_DEVICES=0,1,2,3

第三,监控链路错误。 长期运行要定期查 NVLink 和 PCIe 的 AER 错误:

nvidia-smi nvlink -e
sudo dmesg | grep -Ei "nvlink|aer|pcie.*error"

第四,散热与供电。 高带宽互联往往伴随高功耗,机箱风道设计不当会导致卡过热降频,反过来拖慢通信。

第五,别只看峰值带宽。 实际有效带宽受协议开销、拓扑跳数、并发数影响,通常只能达到峰值的六七成。压测比看规格更靠谱,可用 NCCL 自带的带宽测试:

# NCCL 带宽测试(需安装 nccl-tests)
./build/all_reduce_perf -b 8 -e 8G -f 2 -g 8

常见问题

Q1:nvidia-smi topo -m 里出现 SYS 一定不能用吗?
不一定,但跨 NUMA 通信更慢。做大数据并行训练时性能会打折。能调整卡的位置就调,不能调就用 NUMA 绑定缓解。

Q2:NVLink 能跨服务器吗?
标准 NVLink 是机内的。跨机通信靠 RDMA/InfiniBand 或高速以太网,不要混淆。

Q3:PCIe 5.0 是不是就不需要 NVLink 了?
PCIe 5.0 带宽提升明显,但 NVLink 通常仍高数倍。是否够用取决于负载通信占比,谨慎做法是压测。

Q4:怎么验证多卡通信是否真成了瓶颈?
用 NCLL_DEBUG=INFO 看通信耗时,或在训练日志里看每步的前向/反向/通信时间占比。通信占比高就是瓶颈。

Q5:8 卡机插满后通道被降为 x8,影响大吗?
对纯数据并行影响有限,对张量并行和频繁通信影响明显。先测出实际加速比再决定是否升级平台。

总结

  • PCIe 与 NVLink 的核心差别是带宽量级:PCIe 每代约翻倍到数十 GB/s,NVLink 通常高数倍到十数倍。
  • 是否值得上 NVLink,取决于通信在总耗时中的占比:张量并行、大模型训练强烈建议,纯数据并行且模型单卡装得下时 PCIe 够用。
  • 用 nvidia-smi topo -m 看清卡间拓扑,出现大量 SYS 说明跨 NUMA,是常见性能陷阱。
  • 用 lspci -vvv 核对 LnkCap 与 LnkSta,确认每卡 PCIe 通道数没被降级。
  • 机内互联和机间网络要匹配,木桶效应下,任何一环慢都会拖垮整体加速比,最终以压测结果为准。