HiHuo
首页
博客
手册
工具
关于
首页
博客
手册
工具
关于

NVLink 和 PCIe:GPU 之间怎么通信

单张 GPU 显存有限,跑大模型经常要用多卡。多卡就涉及一个问题:卡和卡之间怎么传数据?

这篇讲清楚 GPU 互联的两种主要方式:PCIe 和 NVLink。搞懂它们的区别,才能理解为什么有些多卡方案效果好、有些效果差。


为什么需要 GPU 互联

先说为什么要关心这个。

场景一:模型太大,一张卡放不下

比如 70B 的模型,FP16 精度需要 140GB 显存。一张 80GB 的 A100 放不下,必须拆到多张卡上。

这叫模型并行。模型被切成几块,分别放在不同的卡上。前向传播时,数据要从一张卡传到另一张卡。

场景二:训练要同步梯度

多卡训练时,每张卡算一部分数据的梯度。算完之后,所有卡的梯度要汇总、平均,然后更新模型参数。

这叫数据并行。梯度同步需要大量的卡间通信。

场景三:推理要拼结果

多卡推理时,每张卡负责模型的一部分计算。最后要把结果拼起来。


这些场景都需要 GPU 之间高速传输数据。传得快,整体效率就高;传得慢,GPU 大部分时间在等,利用率上不去。


PCIe:通用但慢

PCIe(Peripheral Component Interconnect Express)是计算机上最通用的高速接口,显卡、网卡、SSD 都用它。

带宽

版本单通道带宽x16 带宽(单向)
PCIe 3.01 GB/s16 GB/s
PCIe 4.02 GB/s32 GB/s
PCIe 5.04 GB/s64 GB/s

目前主流是 PCIe 4.0,高端服务器开始支持 PCIe 5.0。

GPU 通过 PCIe 通信的路径

两张 GPU 通过 PCIe 通信,数据要走这条路:

GPU A → PCIe → CPU/PCIe Switch → PCIe → GPU B

数据要经过 CPU 或 PCIe Switch 中转,不是直连。

问题

PCIe 用来插显卡、传数据没问题。但用来做 GPU 间的高速通信,带宽就捉襟见肘了。

算一笔账:

  • A100 的显存带宽是 2 TB/s
  • PCIe 4.0 x16 带宽是 32 GB/s(单向)

差了 60 多倍。这意味着 GPU 内部算得再快,数据传不出去也白搭。


NVLink:NVIDIA 的高速直连

NVLink 是 NVIDIA 专门为 GPU 互联设计的高速接口,2016 年随 Pascal 架构(P100)推出。

核心思路

不走 PCIe,GPU 之间直接连。

GPU A ←—— NVLink ——→ GPU B

带宽对比

互联方式带宽(单向)
PCIe 4.0 x1632 GB/s
PCIe 5.0 x1664 GB/s
NVLink 3.0(A100)300 GB/s
NVLink 4.0(H100)450 GB/s

NVLink 比 PCIe 快一个数量级。

NVLink 的版本演进

版本架构单链路带宽最大链路数总带宽
NVLink 1.0Pascal(P100)20 GB/s480 GB/s
NVLink 2.0Volta(V100)25 GB/s6150 GB/s
NVLink 3.0Ampere(A100)50 GB/s12600 GB/s
NVLink 4.0Hopper(H100)50 GB/s18900 GB/s

每一代都在提升。H100 的 NVLink 4.0 总带宽达到 900 GB/s(双向),是 PCIe 5.0 的 7 倍多。


NVLink 的连接拓扑

NVLink 不是随便连的,有固定的拓扑结构。

8 卡 NVLink 拓扑(DGX A100)

DGX A100 是 NVIDIA 的 8 卡 A100 服务器,NVLink 拓扑大概是这样:

     GPU0 ←→ GPU1
      ↕  ╲ ╱  ↕
     GPU2 ←→ GPU3
      ↕       ↕
     GPU4 ←→ GPU5
      ↕  ╲ ╱  ↕
     GPU6 ←→ GPU7

不是每两张卡之间都有直连。有些卡之间要通过其他卡中转。

为什么不全连接

因为 NVLink 数量有限。A100 每张卡有 12 条 NVLink,不可能和其他 7 张卡都直连(那需要 7×2=14 条)。

所以只能部分直连,剩下的通过 NVSwitch 或多跳中转。

NVSwitch

NVSwitch 是 NVIDIA 的 NVLink 交换芯片,让所有 GPU 可以全互联。

DGX H100 用了 4 个 NVSwitch,实现 8 张 H100 的全连接:任意两张卡之间都是 NVLink 直连,带宽一致。


实际影响

训练场景

分布式训练时,梯度同步是关键瓶颈。

假设模型参数 10GB,每次迭代要同步一次梯度:

  • PCIe 4.0:10GB / 32 GB/s ≈ 0.3 秒
  • NVLink 3.0:10GB / 300 GB/s ≈ 0.03 秒

差 10 倍。如果每次迭代的计算时间是 0.1 秒,那么:

  • PCIe:计算 0.1s + 通信 0.3s = 0.4s,通信占比 75%
  • NVLink:计算 0.1s + 通信 0.03s = 0.13s,通信占比 23%

NVLink 场景下,GPU 大部分时间在算;PCIe 场景下,GPU 大部分时间在等。

推理场景

模型并行推理时,层和层之间要传激活值。

比如 70B 模型切成 8 份,每次前向传播,中间结果要在卡之间传 7 次。NVLink 快,延迟就低;PCIe 慢,延迟就高。

实际建议

  • 多卡训练:尽量用 NVLink 机器。PCIe 多卡训练效率很低。
  • 多卡推理:NVLink 优先,但对延迟不敏感的场景 PCIe 也能用。
  • 单卡场景:不用管互联,选对卡就行。

怎么看机器的互联拓扑

nvidia-smi topo

$ nvidia-smi topo -m
        GPU0    GPU1    GPU2    GPU3    GPU4    GPU5    GPU6    GPU7
GPU0     X      NV12    NV12    NV12    NV12    NV12    NV12    NV12
GPU1    NV12     X      NV12    NV12    NV12    NV12    NV12    NV12
GPU2    NV12    NV12     X      NV12    NV12    NV12    NV12    NV12
...
  • NV12:通过 NVLink 连接,数字表示 NVLink 数量
  • PIX:同一个 PCIe Switch 下
  • PHB:同一个 CPU 的 PCIe 总线
  • SYS:跨 CPU,要走 QPI/UPI

带宽测试

用 NVIDIA 的 p2pBandwidthLatencyTest 工具:

$ /usr/local/cuda/samples/1_Utilities/p2pBandwidthLatencyTest/p2pBandwidthLatencyTest

会测试每对 GPU 之间的实际带宽和延迟。


PCIe 直通(P2P)

有一种优化叫 PCIe P2P(Peer-to-Peer),让 GPU 之间通过 PCIe 直接传数据,不经过 CPU 内存。

条件

  • GPU 必须在同一个 PCIe Switch 下
  • 操作系统和驱动要支持
  • 有些平台不支持(比如某些 AMD CPU 平台)

效果

能省一次内存拷贝,延迟更低。但带宽还是受限于 PCIe。


常见问题

Q:为什么 4090 多卡效果差?

4090 没有 NVLink,只能走 PCIe。而且 4090 的 PCIe 是 x16 4.0,理论带宽 32 GB/s,实际可能更低。

多卡训练时,通信成为瓶颈,GPU 利用率上不去。

Q:云服务器的 GPU 是 NVLink 连接吗?

看具体机型。

  • AWS p4d/p5(A100/H100):有 NVLink
  • AWS g5(A10G):没有 NVLink
  • 阿里云 gn7i(A100):有 NVLink

选云服务器时要看清楚实例规格,不是所有多卡实例都有 NVLink。

Q:NVLink 能跨机器吗?

不能。NVLink 只能连接同一台机器内的 GPU。

跨机器要用 InfiniBand 或以太网,下一篇会讲。


小结

GPU 互联的两种方式:

  • PCIe:通用接口,带宽 32-64 GB/s,适合单卡或对通信要求不高的场景
  • NVLink:NVIDIA 专用高速互联,带宽 300-900 GB/s,多卡训练必备

选择建议:

  • 多卡训练:必须要 NVLink
  • 多卡推理:NVLink 优先,PCIe 凑合能用
  • 单卡:不用管

下一篇讲跨机器的高速网络:InfiniBand。