ARTICLE DETAIL

资讯详情

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

GPU分布式通信实战:PCIe、NVLink与NVSwitch的带宽与调优

GPU分布式通信实战:PCIe、NVLink与NVSwitch的带宽与调优 先说我上个月帮朋友排查的一个真实问题。一台8卡机器跑7B模型微调四张卡利用率都压在90%以上可是每个step耗时接近3秒怎么看都不正常。把NVIDIA的Nsight Systems打开一看算力kernel只占了一小半时间剩下的大头全部耗在梯度同步的AllReduce上。原因很简单GPU之间搬运数据走的路带宽不够路也绕。很多人在接触GPU集群、大模型训练、推理服务部署时第一反应是看算力看显存很少去关心GPU与GPU之间怎么通信。但只要你的任务从单卡变成多卡通信就是绕不开的生死线。这篇文章想聊的就是GPU分布通信里最核心的三样东西PCIe、NVLink、NVSwitch。它们分别承担什么角色、带宽怎么算、实际排查和调优时怎么看我都会结合实测经验写清楚适合正在搭GPU集群、做分布式训练、或者刚接触AI基础设施的工程师参考。1. 分布式训练里最容易被忽略的瓶颈梯度同步到底有多“吃”带宽1.1 数据并行中的AllReduce每个GPU都必须拿到全局梯度大模型训练最常用的并行方式是数据并行Data Parallelism。每个GPU上放一份完整的模型副本各自读一批不一样的数据前向传播算出损失反向传播算出各自的梯度。问题来了每个GPU算出来的梯度都是基于自己那一份数据得到的是“局部梯度”必须把8张卡甚至更多的梯度加起来取平均变成“全局梯度”然后才能拿去更新模型参数。这个“局部梯度汇总后广播回每个GPU”的操作在集合通信里叫AllReduce。AllReduce的底层并不是一个简单的“全收全发”。以目前最主流的Ring AllReduce为例通信过程被拆成ReduceScatter和AllGather两个阶段数据在GPU之间按环状拓扑流动最后每个GPU手里都拿到一份完整的全局梯度。这个过程听上去不复杂但它对带宽的要求极其苛刻因为数据要实打实地在GPU之间过一遍。1.2 一次梯度同步到底要搬多少数据算给你看用一个具体的例子来感受数量级。假设你要训练一个70亿参数的模型用BF16精度做混合精度训练。70亿个参数每个参数对应一个梯度每个梯度是2字节那么一次梯度同步需要处理的原始数据就是7B × 2B 14GB在8卡Ring AllReduce场景下理论上每张卡需要发送和接收的数据量大约是 2 × (N - 1) / N × 14GBN8时这个系数约1.75也就是大约24.5GB的通信量。这个数字是固定的跟你的batch size无关只跟模型大小和GPU数量有关。现在把24.5GB放到不同带宽上跑差距就非常直观了。通道典型双向带宽24.5GB通信量估算耗时PCIe Gen4 x16约64GB/s实际单向约32GB/sAllReduce主要吃单向0.7 ~ 1.2秒PCIe Gen5 x16约126GB/s0.4 ~ 0.6秒NVLink 3.0A100每GPU 600GB/s每方向300GB/s0.05 ~ 0.1秒NVLink 4.0H100 SXM每GPU 900GB/s每方向450GB/s0.03 ~ 0.07秒注意上面PCIe场景我写的是“典型”因为实际AllReduce通信是单向为主的不是双向同时跑满所以用单向带宽算更接近真实。于是你就会看到一个训练step里如果模型够大、GPU数量够多梯度同步耗掉的时间可能比纯计算时间还长通信就成了名副其实的瓶颈。1.3 通信带宽如何决定训练step时间训练一个step的总时间大致等于计算时间加上通信时间。在单卡上通信时间是0在8卡上如果梯度同步要走PCIe通信时间可能高达1秒左右而7B模型在单卡上算一个step的纯计算时间可能也就是1到2秒。这意味着总耗时直接翻倍甚至更多。GPU利用率看着很高但大量时间都花在等待别人的数据。这也是为什么业界要把GPU之间的互联带宽做得越来越高。PCIe从Gen3、Gen4、Gen5一路升级带宽确实在涨但依然追不上GPU算力膨胀的速度。于是NVIDIA才在PCIe之外另起炉灶搞了NVLink和NVSwitch这样的私有互联技术。后面几章我们就分别拆开来看。2. PCIe通用“国道”的带宽上限与拓扑陷阱2.1 PCIe的本质CPU与所有外设之间的公共国道PCIePCI Express是CPU和几乎所有外设之间的通用互联标准。GPU、NVMe固态硬盘、万兆网卡、RDMA网卡、声卡都挂在PCIe总线上。它的设计目标是通用、兼容、即插即用而不是为某一种设备做极致优化。在PCIe体系里CPU内部的Root Complex根复合体是总出口所有PCIe设备都通过它接入CPU。CPU的PCIe通道数有限比如一颗AMD EPYC 9004系列处理器能提供128条PCIe Gen5通道Intel Xeon可扩展处理器通常也能提供80到100多条。多张GPU不可能每张都直接接到CPU上所以服务器主板上普遍会放PCIe Switch。PCIe Switch本质上是一颗交换芯片它把上行的一根x16链路拆成下面多个x8、x16端口或者在各个下游端口之间转发流量。它的好处是能让GPU、网卡共享有限的CPU通道代价是多了一级转发延迟和带宽都会有一定损耗。2.2 带宽计算GT/s、编码效率与有效带宽很多人在看PCIe规格时会困惑为什么标称8GT/s的Gen3算出来的带宽只有不到1GB/s每通道这里有两层原因一是GT/s是“每秒传输的Gigabit数据”不是字节二是PCIe有编码开销。Gen3及以上使用128b/130b编码每传输130个bit里只有128个bit是有效数据编码效率约98.46%。以PCIe Gen3 x16为例单通道单向带宽 8GT/s × 128/130 ≈ 7.88Gbps ≈ 0.985GB/sx16单向带宽 0.985GB/s × 16 ≈ 15.76GB/sx16双向带宽 15.76GB/s × 2 ≈ 31.5GB/s按同样的方法把几代PCIe的有效带宽算出来你会得到一个非常清晰的表格。PCIe版本每通道单向速率x16单向有效带宽x16双向有效带宽Gen38GT/s约15.8GB/s约31.5GB/sGen416GT/s约31.5GB/s约63GB/sGen532GT/s约63GB/s约126GB/sGen664GT/s约126GB/s约252GB/s注意这些数字都是双向同时传输时的总和。很多厂商宣传时会直接写双向带宽因为数字好看。但实际在做AllReduce这类集合通信时数据流主要是单向的所以更贴近瓶颈的是单向带宽。A100时代一张A100 80G的PCIe Gen4版GPU走PCIe和走NVLink之间的带宽差距能达到一个数量级这也是为什么追求性能的机型几乎都选SXM形态。2.3 为什么PCIe做GPU间通信很吃力P2P与CPU中转的代价PCIe本身支持Peer-to-PeerP2P传输可以让GPUA直接读取GPUB的显存不需要先经过CPU内存中转。听起来好像也挺好实际跑起来问题不少。第一跨CPU Socket时PCIe P2P往往要经过CPU之间的UPI/QPI链路延迟大幅上升带宽也可能打折。第二PCIe的一致性协议开销比较大GPU之间高频小报文通信时性能会明显下降。第三PCIe Switch的共享上游带宽会形成瓶颈。比如8张GPU挂在两颗CPU下面的两个PCIe Switch里跨Switch的流量不仅要经过Switch还要经过CPU间的互联路径非常绕。我在实际测试中见过最典型的情况nvidia-smi topo -m显示两块GPU之间是SYS经过CPU互联或者PXB经过PCIe桥跑NCCL的all_reduce_perf时带宽只能用个位数GB/s到十几GB/s而同一台机器上NVLink相连的GPU之间能跑到几百GB/s。差异不是一个量级是几十倍。PCIe的意义在于承担“出入通道”的角色GPU访问存储、CPU下发指令、网卡收发数据这些场景它够用但当GPU之间需要高频、大流量地互访时它确实不是为这种事设计的。3. NVLink为GPU对话单独修的“高速直达线”3.1 NVLink的设计动机PCIe再快也追不上GPU互访需求既然PCIe不够用最直接的办法就是绕开它单独给GPU之间修一条私有的高速通道。NVLink就是这么来的。NVLink是NVIDIA的私有高速互联协议初衷就是连接GPU与GPU后来也扩展到了GPU与CPU比如IBM POWER、NVIDIA Grace。它不遵循PCIe那套通用标准而去掉了大量通用性包袱专注做一件事让GPU之间以极高的速度和极低的延迟互相读写显存。NVLink支持GPU直接访问另一块GPU的显存就像访问自己的本地显存一样这在NCCL这类通信库里被称为GPUDirect P2P。3.2 NVLink演进与带宽变化NVLink从P100时代发展到现在已经有好几代带宽一路翻着跟头涨。这里我把关键代际整理成一个表方便对照。版本代表GPU每GPU链路数每链路双向带宽每GPU总双向带宽NVLink 1.0P1004条40GB/s160GB/sNVLink 2.0V1006条50GB/s300GB/sNVLink 3.0A100 SXM12条50GB/s600GB/sNVLink 4.0H100 SXM18条50GB/s900GB/sNVLink 5.0B20018条100GB/s1.8TB/s看到这里你应该有个感觉NVLink每一代的升级逻辑很直白要么加链路数要么提升每条链路的速率要么两个一起上。A100的12条NVLink双向总带宽600GB/s是同一时期PCIe Gen4 x16双向带宽的接近10倍。到了H100 SXM18条NVLink撑到900GB/s双向几乎能把一个10GB级别的张量在几十毫秒内从一块卡搬到另一块卡。3.3 “点对点”的局限为什么还需要交换NVLink虽然是高速通道但它本质上是点对点连接。一张A100有12条NVLink那它最多可以和12个不同的对端相连一张H100有18条最多也是18个对端。但一个GPU集群里的GPU数量远不止2个或者8个一个能装几十张GPU的机柜里GPU与GPU之间的通信需求是全网状的。你可能想那张卡和所有卡都连一条不就行了问题是物理上做不到。GPU的面积、封装、功耗都有限NVLink的引脚和SerDes资源吃紧不可能每张卡拉出几十上百条NVLink。而且即使能做到两两直连的拓扑在工程上也非常难布线密度和可靠性都扛不住。这就需要引入交换设备把点对点的“单行道”组合成“路网”NVSwitch就登场了。4. NVSwitch把“点对点小路”升级成“全网无阻塞立交桥”4.1 NVSwitch是什么一颗GPU专用的交换芯片NVSwitch是NVIDIA为NVLink设计的高密度交换芯片。它的作用类似于网络里的交换机只不过交换的是NVLink协议的数据。一颗NVSwitch芯片上集成了大量NVLink端口内部是交叉开关矩阵能把任意输入端口的流量按线速转发到任意输出端口。以DGX/HGX这类8卡机器为例板上8颗GPU并不需要两两直连而是每颗GPU把自己的NVLink链路分出来接向若干颗NVSwitch。任意两颗GPU之间要通信时数据只需要进入NVSwitch再转发到目标GPU即可。这个设计让N卡的全互联不再需要N×(N-1)/2条物理连接而是把连接成本集中到少量交换芯片上拓扑一下就简化了。4.2 为什么说它是“无阻塞”的NVSwitch最常被提到的词是“无阻塞”Non-Blocking。什么意思拿8卡全互联来说如果所有GPU同时两两通信比如GPU0发给GPU1GPU2发给GPU3……这些流量如果同时发生交换芯片需要有足够的内部带宽把所有流量都转发出去不能因为内部瓶颈而互相等待。NVSwitch的交叉矩阵设计保证了这一点只要输入端口的总带宽等于输出端口的总带宽交叉开关就能以线速进行转发。只要端口的线速满足要求交换芯片就不会成为瓶颈。这就是把它和普通PCIe Switch区分开的关键点PCIe Switch在很多场景下会有上游端口带宽共享、目标地址冲突之类的限制而NVSwitch在NVLink带宽设计范围内能做到类似电话交换机一样互不干扰地接通每一对话路。实际效果就是8卡A100/H100机器里你用NCCL做AllReduce带宽可以逼近单卡NVLink总带宽的80%以上如果是PCIe P2P可能连这个数字的十分之一都到不了。4.3 NVSwitch和PCIe Switch不是一回事这里很容易把两者搞混我特意分开说。PCIe Switch工作在PCIe协议层连接的是CPU的Root Complex和下游的PCIe设备传输距离较远、通用性强但它要处理的是PCIe总线的地址空间、配置空间、分发路由这些复杂机制延迟和开销相对大。NVSwitch工作在NVLink协议层不兼容PCIe设备它只服务NVLink域内的GPU通信。它不在意PCIe的配置空间和地址映射只管在端口之间转发明文数据。NVSwitch的出现本质上是在PCIe体系之外建立了一套并行的互连网络让“GPU之间的数据搬运”彻底摆脱PCIe的限制。一个形象的类比PCIe是城市的普通市政道路任何车都能走但路况复杂、限速多NVLink是专门在数据中心里修的高架快速路只有特定车辆能上速度极快NVSwitch则是这个快速路网里的交通枢纽让不同方向的车流互不干扰地同时通行。5. 打开一台8卡服务器三条通道到底怎么各司其职5.1 一台8卡DGX/HGX节点内部的分工到了真实服务器里PCIe、NVLink、NVSwitch并不是谁替代谁的关系而是各干各的活。以典型的8卡SXM机型为例8颗GPU之间通过NVLink和NVSwitch组成一个高速互联域负责GPU与GPU之间的数据交换比如梯度同步、模型并行里的张量传输每颗GPU同时也通过PCIe连接到CPU和PCIe Switch用于访问CPU内存、NVMe存储、以及网卡。外部网络比如RoCE或InfiniBand通过PCIe连接到GPU实现跨节点通信时数据从GPU走到网卡这一段的路径仍然是PCIe。这个分工非常清晰NVLink管GPU域内部的“热数据”交换PCIe管进出GPU域的“冷数据”和对外连接。两者配合才能既保证节点内通信的高带宽又保证与外界的数据通路正常。5.2 用nvidia-smi topo -m看真实拓扑想知道自己手头这台机器里GPU之间到底是什么拓扑最快的办法是运行nvidia-smi topo -m输出会得到一张矩阵表里面会显示GPU0、GPU1、GPU2等节点之间的关系标记。常见的标记含义如下。标记含义通信性能特点NV#有NVLink连接#表示链路数如NV12带宽最高延迟最低PIX处于同一PCIe交换机下性能较好但受PCIe带宽限制PXB经过PCIe桥转发延迟较高SYS经过CPU间的UPI/QPI互联延迟和带宽都较差尽量避免高频通信我拿到一台机器后会先跑这个命令心里就有数了。比如两台GPU之间显示NV12意味着它们之间有12条NVLink通路做集合通信时NCCL会优先走NVLink如果显示PIX或者SYS那就要留意这块区域可能是通信短板。另外可以用nvidia-smi nvlink -s查看每块GPU当前NVLink链路的状态和速率确认链路没有降速或失效。5.3 采购和组网时最容易忽略的形态差异SXM与PCIe很多人在选购GPU时只关注“显存大小”和“算力”忽略了一个关键差异同样的GPUSXM形态和PCIe形态通信能力可能天差地别。SXM形态的GPU通常拥有完整的NVLink连接。比如A100 SXM是12条NVLinkH100 SXM是18条NVLink配合NVSwitch能组成极高带宽的互联域。而PCIe形态的GPUNVLink要么被大幅削减要么干脆不支持通信主要依赖PCIe性能差出一个数量级。在实际项目中如果做大规模分布式训练我会优先选择SXM机型。如果是推理场景模型并行度不高GPU之间通信量相对小PCIe形态也能用成本能低不少。关键是搞清楚自己的业务负载通信密集选SXM通信稀疏选PCIe这个决策比纠结多几个百分点的算力重要得多。6. 实测带宽与通信调优我的实测数据和踩坑记录6.1 用什么工具测nccl-tests、nvbandwidth与nvidia-smi理论带宽归理论实际能跑多少是另一回事。我最常用的测试工具是NVIDIA官方的nccl-tests其中最有代表性的是all_reduce_perf直接测多卡AllReduce的吞吐。./build/all_reduce_perf -b 8 -e 512M -f 2 -g 8 -n 100 -w 20参数意思是从8字节测到512MB按2倍递增用8张卡跑100次前20次做预热。输出的busbw列就是各卡相对拓扑下实际测出的有效带宽。比如在H100的8卡机器上小报文时吞吐可能只有几十GB/s但到512MB大报文时会稳定爬升到600GB/s以上。如果想单独测点对点P2P能力可以用NVIDIA的nvbandwidth工具./nvbandwidth -p p2p它会枚举两两GPU之间的实际读写带宽和延迟。测试结果的横向对比非常直观同一个机型里走NVLink的P2P带宽和走PCIe的P2P带宽能差一个数量级以上。6.2 NCCL参数和协议选择不是默认就最优NCCL是NVIDIA的集合通信库绝大多数分布式训练框架底层都依赖它。默认设置下NCCL表现通常不差但遇到瓶颈时几个环境变量非常值得关注。NCCL_P2P_LEVEL控制允许使用P2P传输的层级。可选值包括PIX、PXB、PHB、SYS等默认值通常是根据拓扑自动判断的。如果你发现某台机器上NCCL没有走NVLink而是走了PCIe很可能是这个变量设置得太保守。反过来如果设置得太激进跨CPU通信时会因为过度依赖P2P导致性能下降。这个变量需要根据实际机器微调。NCCL_PROTO决定通信协议。NCCL支持Simple、LLLow Latency、LL128三种协议。LL128在高带宽的NVLink环境中通常表现更好因为它用128字节的数据块同时带校验信息能更好地利用带宽。实际选择没有绝对正确最好的做法是手动对比测试。我一般在8卡机上会分别用NCCL_PROTOLL128和默认配置跑一遍all_reduce_perf看哪个高用哪个。还有NCCL_BUFFSIZE、NCCL_NET_GDR_LEVEL这些在跨节点通信时影响很大节点内通信时可以暂时不折腾。总之一切以实测为准NCCL的默认值不是魔法。6.3 实战踩坑P2P不可用、驱动/固件不一致、跨节点通信最后分享几个我踩过的实际坑。第一个坑是P2P不可用。有次在一台机器上nvidia-smi topo -m显示部分GPU之间明明有NVLink但NCCL跑起来却走了共享内存和CPU性能断崖。查下来是驱动版本和CUDA版本不匹配P2P特性被禁用。nvidia-smi -q -d P2P能看到P2P支持状态遇到性能异常时一定要先查这个。第二个坑是PCIe Switch和固件设置。新装机时BIOS里如果没开启Resizable BAR、Above 4G Decoding之类的选项硬件寻址能力会受限GPU和网卡之间的DMA性能也会受影响。很多机器装好后“莫名其妙”性能低其实都是BIOS默认设置拖后腿。第三个坑是跨节点通信。节点内NVLink再快节点之间还是要过网卡和网络。比如一台8卡H100 SXM的NVLink总带宽是900GB/s但通常配的8张400Gbps网卡总带宽只有3.2Tbps也就是400GB/s算上网络协议开销实际跨节点带宽比节点内低很多。做分布式训练时如果并行策略设计不当把高频通信放到跨节点链路上整体性能会被网络拖到地板。所以高端的训练集群都会有意识地减少跨节点通信量尽量让通信发生在NVLink域内。踩过这几轮坑之后我的体会是看GPU通信性能不能只看单卡规格表真正决定分布式训练天花板的是“带宽拓扑”和“通信路径”。PCIe、NVLink、NVSwitch这三层各有各的定位搞明白它们再配合工具实测才能把一套昂贵的GPU集群真正榨出该有的性能。
返回列表