🏠 总目录📚 本教程 互联与拓扑 ← →
📑 本页目录(点开跳转)

05 · 互联与集群拓扑

⏱ 24 分钟 | ⭐ 它决定了你能用哪种并行策略


🎯 一句话

卡和卡之间怎么连,直接决定了后面五章的并行策略能不能用。 张量并行离不开 NVLink,流水线并行能忍受慢网络 —— 这不是偏好问题,是带宽差 15 倍造成的硬约束。


🔌 一、四个层级的带宽

对照

卡内 HBM ~2000-3350 GB/s ← 基准

NVLink(同机卡间) ~450-900 GB/s ⭐ 约为 HBM 的 1/4

PCIe 4.0/5.0 ~32-64 GB/s ⚠️ 慢 15-30 倍

InfiniBand(跨机) ~25-50 GB/s ⚠️ 和 PCIe 同量级

以太网(普通) ~1-12 GB/s 💀 慢两个数量级

🔑 最重要的一条断层在 NVLink 和 PCIe 之间 —— 差 15 倍以上。 这条断层把并行策略分成了两类: "必须在 NVLink 域内"的(张量并行)和"可以跨机"的(数据/流水线并行)。

💡 为什么延迟也重要

关键信息

带宽决定"搬 1GB 要多久"
延迟决定"搬 1KB 要多久"
NVLink 延迟 ~1-2 微秒
InfiniBand 延迟 ~1-3 微秒(RDMA)
以太网 TCP 延迟 ~20-100 微秒 ⭐ 差一个数量级
小消息频繁通信时,【延迟比带宽更致命】
这就是为什么大规模训练必须用 RDMA 而不是普通 TCP

NVSwitch 全互联:8 张卡都挂在同一颗交换芯片上 GPU0 GPU1 GPU2 GPU3 GPU4 GPU5 GPU6 GPU7 NVSwitch ← 任意两卡全带宽 不用绕路,没有慢路径 每条线都是 NVLink ⚠️ 便宜实例常常是 8 卡直接挂 PCIe —— 没有中间这颗芯片
NVSwitch 把 8 张卡接成真正的全互联:任意两张卡之间都是全带宽直连,不存在"绕路"的卡对。

⚠️ 一个必须自己确认的事: 不是所有"8 卡机器"都有 NVSwitch。 很多云厂商的便宜实例是 8 卡挂在 PCIe 上, 跑张量并行会慢到不可用。开机第一件事是查拓扑。

nvidia-smi topo -m

结果对照

输出解读(关键的几个值):
NV8 / NV12→NVLink 直连,几条链路 ✅ 最好
NODE→同 NUMA 节点,走 PCIe ⚠️
SYS→跨 NUMA / 跨 CPU socket 💀 最慢
PIX / PXB→经过 1 个 / 多个 PCIe 交换机

📡 三、跨机通信:RDMA 是关键

结果对照

❌ 传统 TCP/IP:
GPU 显存→CPU 内存→内核协议栈→网卡→·→反向一遍
多次拷贝,CPU 全程参与,延迟高
✅ RDMA(远程直接内存访问):
GPU 显存 → 网卡 → 远端 GPU 显存
⭐ 绕过 CPU 和内核,零拷贝
⭐ GPUDirect RDMA:GPU 显存直接和网卡对接,连 CPU 内存都不经过
技术 说明
InfiniBand 原生 RDMA,大规模训练集群的主流
RoCE 在以太网上跑 RDMA,便宜但需要无损网络配置(PFC/ECN),容易配错
GPUDirect RDMA GPU ↔ 网卡直通,必备

💥 一个常见的坑:RoCE 配置不当会导致丢包→重传→性能雪崩。 症状是"平时还行,一到大规模 AllReduce 就卡死"。 排查时先看网卡的 PFC 计数器。


🔄 四、集合通信原语(后面天天见)

原语 做什么 用在哪
AllReduce 所有卡的数据求和,结果发回所有卡 数据并行同步梯度 ⭐
ReduceScatter 求和后每卡只拿一部分 ZeRO / FSDP
AllGather 每卡的一部分拼成完整的发给所有卡 ZeRO 取回参数
Broadcast 一张卡发给所有卡 初始化
All2All 每卡给每卡发不同的数据 MoE 专家并行 ⭐
P2P Send/Recv 点对点 流水线并行

💡 一个关键恒等式:AllReduce = ReduceScatter + AllGather 这解释了为什么 ZeRO-2 的通信量和普通数据并行一样—— 它只是把一次 AllReduce 拆成了两半,中间插入了参数分片。

⭐ Ring AllReduce:为什么它是标准做法

结果对照

朴素做法:所有卡把梯度发给 0 号卡,0 号求和后发回
0 号卡的网络成为瓶颈,通信量 O(N × 数据量) 💀
Ring AllReduce:卡排成一个环,分两个阶段
① ReduceScatter:转 N-1 步,每卡最终持有 1/N 的完整求和结果
② AllGather: 再转 N-1 步,把各自那份传遍全环
⭐ 每张卡收发的数据量 = 2 × (N-1)/N × 数据量 ≈ 2 × 数据量
【和卡数几乎无关】—— 这是它的关键性质

对照

通信量对比(8 卡,1GB 梯度):

朴素:0 号卡要收 7GB、发 7GB 💀

Ring:每卡收发约 1.75GB ✅ 且完全并行

🔑 但注意 Ring 的代价:延迟随卡数线性增长(要转 2(N−1) 步)。 所以超大规模会用分层 AllReduce: 先在机内 NVLink 做一次,再跨机做一次,最后机内广播 —— 把慢的跨机通信量降到 1/8。


🧮 五、通信量估算:决定并行策略的那个数

算一算

数据并行:每步同步一次梯度

通信量 = 2 × 参数量(Ring AllReduce)

→ 7B 模型 BF16 = 14GB × 2 = 28GB/步

→ 跨机 25GB/s:约 1.1 秒/步 ⚠️ 如果计算只要 0.5 秒,通信就是瓶颈

张量并行:每层前向和反向各要 AllReduce 一次激活

通信量 = 层数 × batch × seq × hidden × 2 × 2

→ 【每一层都要通信】,频率极高

→ ⭐ 必须在 NVLink 域内,跨机绝对不可用

流水线并行:只在切分点传递激活

通信量 = 切分点数 × batch × seq × hidden

→ ⭐ 通信量小得多,可以跨机

⭐ 这三行直接推出了第 14 章的黄金法则:

   张量并行 → 放在【机器内部】(NVLink)
   流水线并行 → 跨【机器】
   数据并行 → 最外层

不是经验,是带宽算出来的。


🧪 六、上手先做的三件事

# ① 看拓扑
nvidia-smi topo -m

# ② 实测卡间带宽(NCCL 官方测试工具)
./build/all_reduce_perf -b 8 -e 4G -f 2 -g 8
#   看 busbw 那一列,和理论值对比

# ③ 看有没有 GPUDirect RDMA
nvidia-smi topo -m | grep -i mlx      # 网卡和 GPU 的亲和性
ibstat                                 # InfiniBand 状态

⚠️ 常见的性能陷阱: - NCCL 走错网卡(走了管理网口而不是 IB)→ 用 NCCL_SOCKET_IFNAME 指定 - NUMA 亲和性错(GPU 和网卡不在同一个 socket)→ 用 numactl 绑定 - 没开 GPUDirect → 数据绕道 CPU 内存,带宽腰斩

export NCCL_DEBUG=INFO       # ⭐ 启动时打印它实际选了哪条路径

NCCL_DEBUG=INFO 是排查通信问题的第一步 —— 它会告诉你 NCCL 实际用的是 NVLink 还是 PCIe、走的哪张网卡。


🔗 和站内其他章的关系

相关的地方 这里的位置
第 3 章 内存层次 本章是它"出卡之后"的部分
第 2 章 4090 只有 PCIe 所以不适合张量并行 ⭐
第 10 章 Ring AllReduce 的详细展开
第 14 章 本章的通信量估算是它的依据 ⭐
《Kaggle竞赛方法论》04 超参数调优与工程实践 分布式训练选型表 那张 DP / DDP / DeepSpeed / FSDP 的表没说前提 —— 前提就是本章的带宽层级 ⭐
《强化学习基础》12 RLHF 全流程 PPO 要同时装四个模型 四个模型每步都要互相传数据,装不进一台机器时,本章的 NVLink/PCIe 断层决定怎么摆

✅ 检查点

  1. 四个层级的带宽大概各是多少?最重要的断层在哪?
  2. 为什么延迟也重要?什么场景下延迟比带宽更致命?
  3. NVSwitch 解决了什么问题?为什么不能假设"8 卡机器"都有它?
  4. 怎么查拓扑?SYS 和 NV8 分别代表什么?
  5. RDMA 相比 TCP 好在哪?什么是 GPUDirect RDMA?
  6. AllReduce = ? + ? 这个恒等式解释了什么?
  7. Ring AllReduce 的关键性质是什么?它的代价是什么?
  8. 为什么张量并行必须在机内、流水线并行可以跨机?
  9. 排查 NCCL 通信问题的第一步是什么?
👀 答案
  1. HBM ~2000-3350 GB/s、NVLink ~450-900、PCIe ~32-64、InfiniBand ~25-50、以太网 ~1-12 GB/s。最重要的断层在 NVLink 和 PCIe 之间,差 15 倍以上。
  2. 带宽决定"搬 1GB 要多久",延迟决定"搬 1KB 要多久"。小消息频繁通信时延迟更致命——以太网 TCP 延迟 20-100μs 比 RDMA 的 1-3μs 差一个数量级,所以大规模训练必须用 RDMA。
  3. 解决早期 NVLink 点对点连接下有些卡对之间要绕路的问题,让任意两卡全带宽直连。不能假设是因为很多云厂商的便宜实例是 8 卡挂 PCIe,跑张量并行会慢到不可用。
  4. nvidia-smi topo -m。NV8/NV12 = NVLink 直连(最好),SYS = 跨 NUMA/跨 CPU socket(最慢)。
  5. RDMA 绕过 CPU 和内核协议栈,零拷贝,延迟低得多。GPUDirect RDMA 是 GPU 显存直接和网卡对接,连 CPU 内存都不经过。
  6. AllReduce = ReduceScatter + AllGather。解释了为什么 ZeRO-2 的通信量和普通数据并行一样——它只是把一次 AllReduce 拆成两半,中间插入参数分片。
  7. 关键性质:每卡收发的数据量 ≈ 2×数据量,和卡数几乎无关。代价:延迟随卡数线性增长(要转 2(N−1) 步),所以超大规模用分层 AllReduce(先机内 NVLink 再跨机)。
  8. 张量并行每一层前向和反向都要 AllReduce 激活,频率极高,跨机撑不住;流水线并行只在切分点传递激活,通信量小得多。
  9. export NCCL_DEBUG=INFO——它会打印 NCCL 实际选了哪条路径(NVLink 还是 PCIe、哪张网卡)。

🛑 可以停在这里

⚡ 走神救援

⭐ 卡怎么连,决定了你能用哪种并行策略。

带宽有四层,从显存到卡间高速互联、到 PCIe、到机间网络逐级下降。⭐⭐ 最关键的断层在「卡间高速互联」和「PCIe」之间——它把并行策略分成「必须待在高速域内」和「可以跨机」两类。

⚠️ 延迟也要看:小消息频繁通信时,延迟比带宽更致命——所以大规模训练必须上 RDMA。

⚠️ 不是所有「八卡机器」都一样:很多便宜实例是八张卡挂在 PCIe 上。⭐ 开机第一件事就是打印拓扑表看看谁和谁是直连的。

集合通信原语里有一个恒等式值得单记:⭐ AllReduce = ReduceScatter + AllGather——它直接解释了为什么某一级的显存切分方案通信量和普通数据并行一样。

⭐ Ring AllReduce 的关键性质:每张卡收发的数据量几乎和卡数无关;⚠️ 代价是延迟随卡数线性增长——所以超大规模要用分层方案,先在机内高速域内做、再跨机。

⭐⭐ 通信量估算能直接推出并行策略的黄金法则:张量并行每层都要同步激活,必须待在机内高速域;流水线并行只在切分点传,可以跨机;数据并行放最外层。⭐ 这不是经验,是带宽算出来的。

⭐ 排查的第一步是打开通信库的调试日志;常见陷阱是走错网卡、NUMA 亲和性配错、没开 GPU 直连。

下一节 👉 06-混合精度.md

打卡记录保存在你的浏览器里,首页能看到总进度