拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

PCIe、NVLink、NVSwitch:看懂GPU服务器通信架构与性能排查

PCIe、NVLink、NVSwitch:看懂GPU服务器通信架构与性能排查

如果你组装过一台8卡GPU服务器,或者第一次跑大模型训练时在日志里看到长时间卡在“all_reduce”这一步,你很快就会意识到一个问题:GPU之间的通信,和GPU本身的算力一样关键。这个领域绕不开三个词——PCIe、NVLink、NVSwitch。它们分别代表了三代不同定位的数据通路,决定了一张显卡上的数据能不能快速搬到另一张显卡上。这篇文章我从实际部署和性能排查的角度,把这三样东西放在一起讲清楚,包括它们各自的带宽、拓扑、在训练推理中怎么配合,以及你拿到机器之后如何验证通信路径、排查“明明八卡全用上了但速度就是上不去”的经典问题。

这篇文章适合谁?准备采购GPU服务器但看不懂规格表里“600GB/s NVLink”是什么意思的架构师;刚上手多卡训练、被NCCL日志和nvidia-smi topo -m搞得一头雾水的算法工程师;以及做AI基础设施运维、需要快速判断机器通信是否正常的朋友。懂得这三样东西,你看一台GPU服务器的眼光会完全不一样。

1. 先搞清楚为什么通信会成为瓶颈

1.1 多卡训练里数据到底要怎么搬

大模型训练最常见的是数据并行,也就是每张卡都放一份完整的模型副本,各自拿着不同的mini-batch做前向和反向。反向传播算完梯度之后,所有卡必须把梯度加起来得到全局梯度,再做参数更新。这个“把梯度加起来”的过程就是all-reduce,是集合通信里最典型的操作。

以8卡A100训练一个70亿参数模型为例,模型大小约14GB(FP16),梯度和它一样大。每一轮迭代都要把这14GB梯度在所有GPU之间做一次全交换。如果通信带宽只有几十GB每秒,你就会发现GPU算力越强,通信等待占比越高。好的情况是计算和通信能重叠一部分,但在all-reduce这种强同步点上,通信带宽直接决定了训练效率。

这也是为什么GPU之间需要一套比传统总线更快的互联方案。PCIe在一开始还能应付,后来算力翻倍、模型疯长,PCIe的带宽逐渐不够用了,NVIDIA才推出NVLink和NVSwitch去填这个坑。

1.2 算力增长和总线带宽增长完全不在一个量级

比较一下你会更直观。单块GPU的FP16算力,从V100的约125 TFLOPS涨到H100的约989 TFLOPS,涨了大约8倍;而PCIe的带宽,从Gen3的约32GB/s(x16双向)到Gen5的约128GB/s(x16双向),只涨了4倍。如果只靠PCIe做多卡通信,算力越强,通信占比越高,扩展性越差。

NVIDIA在Volta架构之后给出的答案就是NVLink。它的定位很明确:不是替代PCIe,而是专门在GPU之间提供一条高带宽、低延迟的私有通道。NVSwitch则是把NVLink从“点对点”升级成“全互联交换网络”的关键设备。三者不是竞争关系,而是各管一段:PCIe负责常规外设连接和上行,NVLink负责GPU间近邻高速通信,NVSwitch负责把多颗GPU组织成一张无阻塞的交换网。

2. 先补基础课:PCIe 是怎么把GPU接起来的

2.1 lane、版本和带宽,看懂这些参数才算入门

PCIe是当前计算机里最通用的总线协议,从显卡、NVMe SSD到网卡全在用它。它的基本单位是lane(通道),每个lane是一对差分发送线加一对差分接收线。一条PCIe链路可以同时使用1、2、4、8、16条lane,显卡和NVMe盘最常见的是x4或x16。

带宽由“版本x lane数”决定。以x16为例,各代双向总带宽大概是:

版本单lane速率x16双向带宽编码效率
PCIe 3.08 GT/s约32 GB/s128b/130b
PCIe 4.016 GT/s约64 GB/s128b/130b
PCIe 5.032 GT/s约128 GB/s128b/130b

注意这里都是双向总带宽,实际读或者写是单向的,要再除以2。而且PCIe是包交换协议,还有包头、流量控制等开销,实测有效带宽通常打八到九折。很多人跑nvidia-smi看到的PCIe Gen4 x16是64GB/s双向,就以为单方向能跑满32GB/s,实际上测出来经常只有25GB/s左右,这是正常的。

2.2 三层协议做一次完整的数据搬运

PCIe通信在逻辑上分成事务层、数据链路层和物理层。我们平时不太需要关注每一层的细节,但有几个概念是排查问题时常见的。

事务层传输的数据包叫TLP(Transaction Layer Packet),里面有Header和数据。Header里最关键的是地址信息,用来告诉对端数据要写到哪个地址。GPU显存的BAR空间就是通过这种方式映射到系统地址空间里的,CPU和GPU之间其实是在做“内存语义”的访问,而不是像网线那样发字节流。

物理层里有件事值得单独说,叫弹性缓冲(Elastic Buffer)。PCIe两端时钟不是完全同频的,即使标称都是8GHz,实际频率也会有几百分之一的偏差。如果没有弹性缓冲去吸收时钟频偏,数据流里就会时不时多一位或少一位,整个链路就崩了。这和以太网里收发电协调时钟是类似的问题,但PCIe处理方式很优雅——在串行数据流里插入SKP字符,接收端通过弹性缓冲把它们扔掉或补上,从而对齐本地时钟。很多人调试PCIe信号不稳定时,第一反应是改差分对等长,其实先确认链路训练是否稳定、是否出现大量错误校验才是更关键的。

2.3 PCIe Switch到底做了什么

PCIe协议设计上每个Root Complex(根复合体)能挂的设备数量有限,lane数也有限,一颗CPU通常只有几十条PCIe lane。比如一颗64 lane的CPU,你插一张x16显卡、一张x16网卡就差不多用完了,再想加卡只能想别的办法。

办法就是PCIe Switch。它本质上是一个PCIe交换机,把上游的一路PCIe拆分成下游的多路,相当于把一根大口径水管分成多个水龙头。最常见的场景是把CPU的x16拆成两个x8,或者把x32拆成四个x8。多卡服务器里,CPU通过PCIe Switch再连到多张GPU,让一张CPU能带得动8张卡。

代价也有:所有下游设备共享上游带宽。如果一张x16网卡和一张GPU挂在同一个PCIe Switch下,两边同时跑满数据,PCIe Switch和CPU之间的链路口就会成为瓶颈。这也是为什么高端GPU服务器里,软件层要特意区分“同一PCIe Switch下的GPU”和“不同PCIe Switch下的GPU”,因为后者的通信延迟和带宽都更差。

3. NVLink:专为GPU之间的高频访问设计

3.1 PCIe的短板在哪里:延迟和双向同时传输

PCIe做通用设备互联很称职,但做GPU间通信有两个先天不足。第一是延迟,PCIe通信要经过根复合体、PCIe Switch等多级转发,加上事务层协议的打包解析,延迟通常在微秒量级。第二是双向传输时会互相挤占,虽然标称双向总带宽很高,但实际all-reduce这类操作需要同时收发,很容易打到瓶颈。

NVLink的思路完全是为GPU间通信定制的。它不经过CPU或根复合体,直接在两颗GPU之间建立物理链路,而且是多lane并行。更关键的是,NVLink支持“直接内存访问”,GPU可以像访问自己显存一样去访问另一颗GPU的显存,驱动层可以把它当成一块更大的显存来用。

打个比方:PCIe像是两个小区之间走公共马路,NVLink则是在两栋楼之间架了一座专属天桥,不走红绿灯,不跟其他车辆抢道。

3.2 每代NVLink的带宽演进

NVLink从2016年P100开始商用,之后几乎每一代GPU架构都在加宽加量。

GPU架构NVLink版本单卡链路数总双向带宽
P100NVLink 1.04条160 GB/s
V100NVLink 2.06条300 GB/s
A100NVLink 3.012条600 GB/s
H100NVLink 4.018条900 GB/s

以A100为例,12条NVLink每条双向约50GB/s,换算成单向也有25GB/s。前面说PCIe Gen4 x16单向约32GB/s,看起来差不多,但NVLink是点对点的,两卡之间独享带宽,不经过Switch也不会被其他设备挤占,实际使用体验明显更快。到了H100,900GB/s的双向带宽已经远超PCIe Gen5能提供的上限,这也是为什么高端训练卡之间一定要走NVLink。

3.3 NVLink和PCIe在同一台机器里怎么共存

这里要澄清一个很多人误解的点:NVLink并没有取代PCIe。即使在最顶级的8卡机器里,每张GPU照样会留出一条PCIe链路作为“常规通道”,用于加载驱动、访问配置空间、和CPU进行控制面通信。NVLink则作为数据面的加速通道存在。

SXM形态的GPU(就是那种不带风扇、插在底座上的计算卡)同时拥有两条通路:一条PCIe Gen4/Gen5 x16连到CPU或PCIe Switch,用于基本控制和少量数据传输;多条NVLink连到相邻GPU或NVSwitch,用于大规模显存交换。两者并行工作,互不干扰。这也是为什么nvidia-smi里看到的PCIe带宽数字很小,但NCCL实测通信带宽却能跑出几百GB/s——因为真正的大流量都走了NVLink。

4. NVSwitch:把“点对点”升级成“全互联”

4.1 为什么不能一直用NVLink做全连接

你可能马上会想到一个问题:既然NVLink带宽这么高,那我让8张卡两两之间都拉满NVLink不就行了?答案是物理上做不到。

假设每张GPU只有6条或12条NVLink,而8卡全互联意味着每张卡要同时连接其他7张卡。如果每对连接要占用2条链路,那每张卡需要14条NVLink。V100/A100时代链路数量不够,只能组成不完美的拓扑。比如A100的12条NVLink实际构成的是“立方体”拓扑,任意两张卡都可能不是直连,需要中间卡转发。

直连转发会带来两个问题:一是转发占用了中间卡的NVLink带宽,导致通信效率下降;二是延迟变高。NCCL里的ring all-reduce调度得很精细,但再精细也架不住拓扑不是全互联。

NVSwitch就是来解决这个拓扑问题的。它的角色类似以太网交换机:每颗NVSwitch上有几十条NVLink口,可以把任意输入口的数据交换到任意输出口,所有端口同时双向跑满。GPU之间不再需要两两直连,而是把所有链路插到NVSwitch上,由交换芯片做交叉互连。

4.2 一颗芯片撑起一个无阻塞的网络

一台HGX基板上的4颗NVSwitch,配合8张SXM GPU,构成的就是一个无阻塞的全互联网络。所谓“无阻塞”,意思是任何两张GPU之间通信时,都不会因为其他GPU同时在通信而速下降。这是多卡训练里最理想的状态。

NVSwitch本质上是一个巨大的交叉开关(Crossbar),多个输入口和多个输出口同时工作。每颗NVSwitch有算力极高的交换能力,多个NVSwitch并联还能做冗余和扩展。从H100开始,NVSwitch还加入了多播加速功能,对all-reduce、all-gather这类“一个数据发给多个目标”的集合操作特别友好。NCCL在做集合通信时,如果检测到底层是NVSwitch,会启用多播策略把广播数据一次推给多张卡,而不是一张一张发。

如果你用的机器是“NVLink直连”方案(比如部分8卡V100或更早的4卡配置),两颗GPU之间的通信路径是固定的,某些对间的通信可能要走多跳,表现就不如NVSwitch机型稳定。这也是为什么训练大模型时,大家更倾向于选择HGX基板的机器,而不是拿四张卡自己拼。

4.3 从机内走向机外:NVLink域和跨节点扩展

NVSwitch不只是管一块基板,它还能把多个基板连成更大的域。NVIDIA在DGX等大型系统里,用NVSwitch把多台机器拉进同一个NVLink域。在这个域里,任意两颗GPU之间的通信都能保持非常高的带宽,延迟远低于走网卡的方案。

不过要注意,跨节点通信目前在绝大多数场景下还是走InfiniBand或RoCE网络。NVLink域更多是降低单机内通信开销,而跨机通信的瓶颈通常在网卡和交换网络。这里也踩过很多坑:明明机内NVLink速度极快,但跨节点训练时因为网络没调好,整机性能被拖垮。所以做分布式训练调优时,我把“机内通信”和“跨机通信”作为两个独立的性能域分开看,不要混在一起调。

5. 一台8卡机器的通信全景:三者如何协同

5.1 实际拓扑拆解:CPU、PCIe Switch、NVSwitch各管什么

为了把前面这些讲成一个整体,我们来拆一台典型的8卡 SXM 服务器,比如A100/H100 HGX基板的机型。

从CPU视角看,机器里有两条总线系统。一条是PCIe总线:CPU通过PCIe链路连到PCIe Switch,PCIe Switch再分出多条PCIe x16链路连到各张GPU的PCIe控制器,同时还有PCIe链路连到网卡和NVMe盘,负责控制面和常规数据传输。另一条是NVLink域:8颗GPU各自拉出多条NVLink连到板载的4颗NVSwitch,NVSwitch之间也有高速互连,形成全互联网络。

数据搬运时,GPU驱动会自动判断目的地。如果目标显存在同一颗GPU上,直接走本地显存;如果目标在另一颗GPU上,第一选择是走NVLink/NVSwitch路径;如果NVLink不可用或距离较远,退而求其次走PCIe;跨机器时则要通过网卡走网络。这个路径选择是NCCL等通信库在运行前通过拓扑探测完成的,不是随机决策。

5.2 数据路径选择:为什么不是所有卡都“点对点直连”

NCCL做的第一件事是构建一张拓扑图,记录每对GPU之间的相对位置。它读的信息就来自nvidia-smi topo -m的输出,判断两颗GPU是在同一NVSwitch下、同一PCIe Switch下,还是要经过CPU。

不同路径的通信性能差别很大,实测下来NVLink路径通常比PCIe路径快5到10倍。如果软件层面错误地把通信调度到了PCIe上,整个训练速度会断崖式下跌。所以很多跑大模型训练的人会格外关注NCCL_P2P_LEVEL这类环境变量。默认情况下,NCCL会启用P2P通信,也就是让GPU绕过CPU和内存,直接在NVLink或PCIe上交换数据。如果驱动或容器配置有问题,P2P被禁掉,数据就要先从源GPU拷贝到CPU内存,再拷到目标GPU,带宽和延迟都恶化一个数量级。

这里有个排查技巧:如果训练日志显示通信占比特别高,先用nvidia-smi topo -m确认卡的布局,再用NCCL的测试工具跑一次all-reduce带宽,直接看实际速度是否符合预期。不要一上来就怀疑代码。

5.3 软件栈怎么感知到这些硬件差异

CUDA层面有一个概念叫“可访问对等”,通过cudaDeviceCanAccessPeer和cudaDeviceEnablePeerAccess来判断并开启GPU间P2P。如果可以,CUDA会让GPU直接读写对方显存,跳过CPU。这一层对上层框架是透明的,PyTorch会通过CUDA Runtime API自动启用这些能力。

再往上是NCCL。它负责把复杂的集合操作分解成适合具体拓扑的通信原语。比如all-reduce在环形拓扑下是“分块+流水线”,在树形拓扑下是“多播+累加”。NVSwitch出现后,NCCL还能利用多播特性做更高效的方案。所以你会看到同样8张H100,老的NCCL版本和新的NCCL版本跑出来的带宽不一样,很多时候就是新版本对NVSwitch多播路径的调度做了优化。

6. 实操中的通信路径查看、验证与调优

6.1 三分钟看懂nvidia-smi topo -m

拿到一台多卡机器,第一件事就是跑nvidia-smi topo -m,看GPU之间和CPU之间的连接情况。输出结果是一个矩阵,里面的标记含义很重要:

  • NV#:两颗GPU之间有NVLink直连,通信最快。
  • PIX:两颗GPU挂在同一个PCIe Switch下,走PCIe通信但距离较近。
  • PXB:经过PCIe Bridge,多了一级转发。
  • PHB:经过CPU上的不同PCIe根端口,可能需要绕过CPU内部。
  • SYS:最差,要跨CPU甚至跨节点,通信延迟最高。

实际使用中,我的经验是先看有没有NVLink直连的卡,再看PIX级别的卡有多少。如果一个训练任务被调度到了大量SYS级别的卡上,性能一定好不了。早期很多人在云厂商租多卡实例时没注意这点,结果训练速度远不如预期。

6.2 怎么实测通信带宽

光看拓扑还不够,得跑一下真实带宽。常用方案是NCCl官方测试工具nccl-tests里面的all_reduce_perf,典型命令是:

mpirun -np 8 ./build/all_reduce_perf -b 8M -e 8G -f 2 -g 1

注意-g 1是每个进程用一张GPU,-f 2是带宽翻倍更新,数据量从8MB跑到8GB。输出里的Algbw是算法带宽,Busbw是总线带宽。对于8卡A100,单卡NVLink 600GB/s总带宽的机器,all-reduce的Algbw一般能跑到400GB/s以上;H100则有机会跑到700GB/s以上。如果只能跑到几十GB/s,多半是P2P被禁用、NCCL版本过老、或者驱动/容器配置有问题。

也可以直接用nvidia-smi -q -d NVLINK查每张卡NVLink的错误计数。NVLink链路如果因为信号问题降速或重训,错误计数会一直增长。这个数值在训练卡顿且报NVLink相关错误时很关键。

6.3 高频问题速查:通信相关的坑我基本都踩过

我把自己实际遇到过的问题整理成了一张速查表,新手照着查能省不少时间。

现象可能原因排查与解决
训练时GPU利用率忽高忽低,通信占比很大数据没走NVLink而是走了PCIe跑nvidia-smi topo -m确认拓扑,检查NCCL_P2P_LEVEL和驱动版本
all_reduce_perf带宽只有几十GB/sP2P被禁用,数据经过CPU中转用cudaDeviceCanAccessPeer做测试,或检查容器挂载的参数是否屏蔽了P2P
NVSwitch机型上NCCL版本较老性能上不去老版本不支持NVSwitch多播优化升级NCCL到较新版本,配合新CUDA驱动使用
跨节点训练慢,单机内正常InfiniBand或RoCE网络配置问题、网卡走了PCIe瓶颈用ib_write_bw测网络带宽,检查网卡是否被PCIe Switch挤占
训练刚开始报错“out of memory”但显存看着够NVLink连接异常导致CUDA启用了回退路径,占用了额外显存检查nvidia-smi -q -d NVLINK的错误计数,确认链路状态正常
容器里看不到P2P能力,裸机正常容器隔离了设备节点或驱动挂载不全用--gpus all方式启动,挂载/dev/nvidia-uvm等设备节点

6.4 硬件设计层面的通信质量提醒

如果你不只是用机器,还涉及到服务器硬件选型或者自己设计小板卡,PCIe的硬件质量同样影响通信稳定性。热搜里很多人问“PCIe差分对间需不需要等长”,这个问题我在硬件调试时的结论是:差分对内等长要求严格,但差分对之间允许一定长度差,PCIe规范对lane与lane之间的skew要求相对宽松,因为协议层有弹性缓冲和deskew机制。真正容易出问题的是电源完整性和参考层不连续,这比等长更难排查。信号质量可以用协议分析仪抓链路训练过程,或者看系统日志里有没有PCIe错误上报。

NVLink作为私有协议,硬件调试手段比PCIe少,一旦出现问题通常只能看驱动的NVLink错误计数和链路位宽是否降级。因此在实际运维中,我建议把NVLink状态检查纳入例行巡检,尤其在训练任务频繁切换、机器搬运过之后,一定要检查链路是否仍然跑在完整位宽和速率上。

一点个人体会

这套体系我花了不少时间才真正串起来。一开始我以为只要选型号够新、带宽数字够大就万事大吉,后来发现通信性能是“协议、拓扑、软件栈、硬件质量”四件事共同决定的结果。PCIe是基础,NVLink是加速器,NVSwitch是把加速器组织成网络的纽带,而NCCL和CUDA则是在这张网络上做流调度的“交警”。它们配合得好,才能让8卡、甚至更多卡的机器发挥出接近线性扩展的能力。

最后分享一个小技巧:新机器到手,我习惯先跑一遍nccl-tests的all_reduce_perf做基线,把结果记录下来存档。以后训练出问题、机器维修过、驱动升级过,再跑一次对比基线,几秒钟就能定位是不是通信链路的锅。这套方法帮我排查过太多“看起来训练很慢”的伪故障了。

返回列表