2. 硬件基础与网络拓扑
做分布式训练,说白了就是让一堆GPU一起干活。但怎么让它们高效协作,关键就看硬件怎么连的。我刚开始接触NCCL时,以为只要把网线插上就能跑,结果性能惨不忍睹。后来才明白——拓扑结构决定了通信的上限。
核心观点:NCCL的性能瓶颈,90%出在拓扑理解不到位。你想想看,数据从GPU A传到GPU B,中间经过了多少跳?PCIe、NVLink、网卡、交换机……每一跳都是延迟和带宽的损耗点。
一、GPU服务器内部拓扑
先看单机内部。一台8卡GPU服务器,GPU之间怎么互联?主要有两种方式:
1. NVLink/NVSwitch
NVLink是NVIDIA的高速互联技术。我习惯把它理解成GPU之间的“高速公路”。
- NVLink 2.0:单条带宽50GB/s(双向),V100时代的产品
- NVLink 3.0:单条带宽100GB/s(双向),A100开始支持
- NVLink 4.0:单条带宽150GB/s(双向),H100的标配
NVSwitch则像个智能交换机,让所有GPU都能全互联。我记得第一次在DGX A100上跑测试,8卡之间all-reduce带宽直接拉满,那种感觉——嗯,很爽。
个人经验:我曾经在DGX-1(V100)上调试一个模型,发现GPU0和GPU3通信特别慢。查了半天,原来是它们之间没有直连NVLink,走了两跳。后来我把通信对重新映射,性能提升了30%。
2. PCIe拓扑
没有NVLink的服务器,GPU只能走PCIe。这里有个坑——PCIe的带宽是共享的。
举个例子:一台4卡服务器,如果所有GPU都挂在同一个PCIe Root Complex下,那么它们共享x16的带宽。你想想看,4个GPU同时通信,每个只能分到x4的带宽,不卡才怪。
| PCIe版本 | 单通道带宽 | x16带宽 |
|---|---|---|
| PCIe 3.0 | ~1 GB/s | ~16 GB/s |
| PCIe 4.0 | ~2 GB/s | ~32 GB/s |
| PCIe 5.0 | ~4 GB/s | ~64 GB/s |
避坑指南:我曾经遇到过一台服务器,4张卡插在同一个PCIe switch下,结果NCCL all-reduce性能只有理论值的1/4。后来用nvidia-smi topo -m一看,果然所有GPU都在同一个PCIe域里。解决方案?换主板,或者用NVLink桥接。
二、跨节点网络拓扑
单机搞定了,多机怎么办?跨节点通信靠网络,目前主流就两种:InfiniBand和RoCE。
1. InfiniBand(IB)
IB是高性能计算的标配。它有几个特点:
- RDMA原生支持:数据直接从GPU到网卡,不经过CPU内存
- 低延迟:微秒级,比TCP快一个数量级
- 高带宽:HDR 200Gbps,NDR 400Gbps
我个人习惯用IB,因为稳定。在超算中心调过上百台IB集群,很少出幺蛾子。
2. RoCE(RDMA over Converged Ethernet)
RoCE是跑在以太网上的RDMA。说白了,就是拿普通网卡干IB的活。成本低,但配置麻烦。
RoCE v2是目前的主流,它把RDMA封装在UDP里。这里有个关键点——需要PFC(优先级流控)和ECN(显式拥塞通知)。没有这些,RoCE在丢包时性能会断崖式下跌。
我的经验:有一次客户用RoCE跑训练,性能时好时坏。我上去一看,交换机没开PFC。开了之后,性能稳定了,但延迟比IB高了20%。所以我的建议是:预算够就上IB,省钱就用RoCE,但要做好调优准备。
三、NUMA亲和性
NUMA(非统一内存访问)是个容易被忽略的点。简单说:CPU和内存不是对等的。
在双路服务器上,CPU0访问自己的内存快,访问CPU1的内存慢。GPU也是同理——GPU挂在哪个CPU的PCIe总线上,就优先用那个CPU的内存。
怎么查?用lstopo或者numactl --hardware。我习惯先画一张拓扑图:
# 查看GPU和CPU的亲和关系
nvidia-smi topo -m
# 输出示例:
# GPU0 GPU1 GPU2 GPU3 CPU Affinity
# GPU0 X NV1 NV2 NV3 0-15
# GPU1 NV1 X NV2 NV3 0-15
# GPU2 NV2 NV2 X NV1 16-31
# GPU3 NV3 NV3 NV1 X 16-31
看到没?GPU0和GPU1挂在CPU0上,GPU2和GPU3挂在CPU1上。跨NUMA通信会有额外延迟。
避坑指南:我曾经在调试时发现,NCCL all-reduce在跨NUMA节点时性能下降30%。后来用numactl --membind把进程绑定到对应NUMA节点,问题解决。记住:进程跑在哪个CPU,就让它用哪个CPU的内存和GPU。
四、知识体系总览
下面这张图,是我自己总结的拓扑知识体系。建议你保存下来,调优时对照着看:
这张图把整个知识体系串起来了。你想想看,从单机内部的NVLink、PCIe,到跨节点的IB、RoCE,再到NUMA亲和性——每一层都可能是瓶颈。
总结一下:理解拓扑,就是理解数据从哪来、到哪去、中间经过什么。我每次接手新集群,第一件事就是画拓扑图。画清楚了,调优就成功了一半。