前置讲 P5 · 分布式与通信基础:互连、集合通信与并行策略 · Distributed Systems & Communication

AI Inference Infrastructure · 预备知识 5。个人学习讲义与配套实验,按主题整理并持续修订。

课程源码 ZIP ↓

个人整理的学习笔记,非官方讲义;课程来源与整理说明见课程介绍。配套示例未逐一运行验证。

本篇目录

对应 Maps to:原课没有对应的一次课。CS349D 默认学生熟悉分布式系统和 GPU 集群;第 6–9 讲(并行、prefill / decode 解耦、MoE、上下文管理)都建立在”多卡之间通信要多久”的账上。这篇前置讲为没有这类背景的读者补上这本账。 依据说明:硬件规格来自 NVIDIA 的公开资料(DGX H100 用户指南、NVLink / NVSwitch 的规格;GB200 NVL72 的数字来自公开资料的汇总)。集合通信算法依据 R. Thakur, R. Rabenseifner, W. Gropp, Optimization of Collective Communication Operations in MPICH(IJHPCA 2005)和 P. Patarasuk, X. Yuan, Bandwidth Optimal All-reduce Algorithms for Clusters of Workstations(JPDC 2009);NCCL 的算法、协议与传输方式依据 Z. Hu 等的 Demystifying NCCL: An In-depth Analysis of GPU Communication Protocols and Algorithms(2025)。并行方式依据 Megatron-LM(Shoeybi 等,2019)、Megatron 的序列并行(Korthikanti 等,2022)、GPipe(Huang 等,2019)、Ring Attention(Liu 等,2023)。 配套代码 Code:code/prereq5/(numpy;5 个脚本 + 1 个共享模块;全部 1 秒左右跑完) 预计阅读时间:3 小时(含运行代码)


0. 本讲导航 · How to read this lecture

0.1 学习目标 Learning goals

学完这一篇,你应该能够:

  1. 说出推理为什么要用多块 GPU,以及代价是什么。
  2. 画出 GPU 集群的互连层次(HBM、NVLink / NVSwitch、PCIe、网卡与 InfiniBand / RoCE、存储),说出各层带宽和延迟的数量级;解释 RDMA 和 GPUDirect RDMA 省掉了什么。
  3. 用 α–β 模型估计一次传输的时间,判断它受限于延迟还是带宽。
  4. 说出 broadcast、reduce、all-reduce、reduce-scatter、all-gather、all-to-all 各做什么,以及 all-reduce = reduce-scatter + all-gather。
  5. 比较 ring、递归加倍、Rabenseifner、树、交换机内归约这几种 all-reduce 算法的代价,解释为什么要按消息大小和拓扑选算法、为什么要分层。
  6. 说出数据并行、张量并行(以及序列并行)、流水线并行、专家并行、上下文并行各要通信什么,它们适合放在哪一层互连上。
  7. 用切块流水、逐层传输、两批交错把通信藏在计算后面,并说出它的条件和极限。

0.2 先修与本讲范围 Prerequisites & scope

默认你已经会 Assumed本讲不展开 Out of scope
第 1 讲:权重与 KV 的显存账、decode 受限于带宽网络协议栈(TCP、拥塞控制)、交换机的内部结构
前置讲 P1(roofline、HBM)、P2(参数量、KV、显存预算)并行策略的搜索与具体系统(第 6 讲 FlexFlow、Pope 等)
前置讲 P4(建议):Little 定律、扇出与尾延迟训练里的通信(梯度同步、ZeRO)只点到

0.3 本讲地图 Map

§1  为什么要多卡,代价是什么
§2  互连:HBM、NVLink / NVSwitch、PCIe、InfiniBand / RoCE、RDMA 与 GPUDirect、存储      ← 代码 01
§3  α–β 模型:延迟受限还是带宽受限                                                  ← 代码 01
§4  集合通信:六种操作、它们的关系、每个设备至少要传多少;MoE 的 all-to-all           ← 代码 02
§5  all-reduce 的算法:ring、递归加倍、Rabenseifner、树、交换机内归约;分层;NCCL      ← 代码 03
§6  并行方式的通信模式:数据 / 张量(序列)/ 流水线 / 专家 / 上下文并行               ← 代码 04
§7  计算与通信的重叠:切块、逐层传输、两批交错                                        ← 代码 05
§8  与推理系统的联系(只想快速浏览的读者读这一节)
§9–13  小结、常见误区、练习、延伸阅读、下一步

0.4 记号 Notation

符号含义
kk参与通信的设备(GPU)数
DD每个设备上要参与集合通信的数据量(字节)
α\alpha每条消息(每一步)的启动延迟:软件开销、同步、链路和交换机的延迟
β\beta每个设备每个方向的有效带宽(字节 / 秒)
TP / PP / DP / EP / CP / SP张量 / 流水线 / 数据 / 专家 / 上下文 / 序列并行

本篇的带宽都是每个 GPU、每个方向的有效带宽(标称值 × 80%,和第 6 讲相同)。厂商常报”双向合计”,例如 H100 的 NVLink”900 GB/s”是两个方向加起来,每个方向 450 GB/s。

0.5 关于数字 · About the numbers

本篇的时间来自 α–β 模型:有效带宽 = 标称 × 80%,α 是数量级的假设值(NVLink 2 µs、PCIe / InfiniBand 5 µs 等)。代码 02 用逐条消息的记账核对了每种算法的字节数和公式。数字说明量级和交叉点的位置,不是某台机器、某个 NCCL 版本的实测;真实的小消息延迟往往比这里低(NCCL 的低延迟协议、推理引擎的自定义内核)。


1. 为什么要多卡 · Why multiple GPUs

一块 H100 有 80 GB 显存、3.35 TB/s 带宽、989 TFLOP/s 算力。推理在三件事上会撞到它的天花板(前置讲 P2 §6):

  1. 放不下:Llama-3-70B 的 BF16 权重 141 GB,一块卡放不下;即使放得下,剩下的显存也装不了多少 KV。DeepSeek-V3 的 FP8 权重 671 GB,要 8 块 141 GB 的 H200。
  2. 不够快:batch 1 的 decode 每步要把权重读一遍,时间 = 字节 ÷ 带宽。把权重切到 8 块卡上,每块只读 1/8,8 块卡的带宽加起来让每个 token 快近 8 倍(前置讲 P2 §6.2:70B 的 TPOT 下界从单卡放不下变成 8 卡约 5 ms)。
  3. 不够多:一个副本能同时服务的请求有限,多放几个副本,吞吐就翻几倍。

代价是通信:模型一旦切开,每一层都可能要在卡之间交换数据;而卡与卡之间的链路比卡内的 HBM 慢一个数量级以上。多卡推理的全部学问,就是”怎么切,才能让通信少、通信快、通信藏得住”。


2. 互连 · Interconnects

2.1 一张层次图

GPU 内部          HBM:3.35 TB/s(H100)                                    ← 最快
  │
节点内(8 块卡)   NVLink 4 经 NVSwitch:每块卡每方向 450 GB/s(双向 900 GB/s)
  │               PCIe Gen5 x16:每方向约 64 GB/s(CPU 内存、网卡、SSD 都挂在 PCIe 上)
  │
节点之间          网卡:InfiniBand NDR 或 RoCE,每张 400 Gb/s = 50 GB/s;通常每块 GPU 配一张
  │               以太网:25–400 Gb/s
  │
存储              NVMe SSD:每块几 GB/s;远端存储更慢                         ← 最慢

代码 01 演示 1 列出 9 种链路的有效带宽(标称 × 80%)和假设的 α:

链路带宽(每方向)α半带宽消息传 1 MB传 1 GB
NVLink 5(B200 / GB200)720 GB/s2 µs1.44 MB3.39 µs1.39 ms
NVLink 4(H100)360 GB/s2 µs720 KB4.78 µs2.78 ms
PCIe Gen5 x1651 GB/s5 µs256 KB24.53 µs19.54 ms
InfiniBand NDR 400 Gb/s40 GB/s5 µs200 KB30.00 µs25.01 ms
以太网 100 Gb/s10 GB/s15 µs150 KB115.00 µs100.02 ms
NVMe SSD(一块)5.6 GB/s50 µs280 KB228.57 µs178.62 ms
以太网 25 Gb/s2.5 GB/s20 µs50 KB420.00 µs400.02 ms

节点内的 NVLink 比跨节点的网卡快近一个数量级,比普通以太网快两个多数量级;而最快的 NVLink 也比 HBM 慢近 10 倍——在卡与卡之间搬数据,永远比在一块卡里读数据贵。

NVLink 是 NVIDIA GPU 之间的专用高速链路。H100 有 18 条 NVLink 4,合计每方向 450 GB/s;B200 的 NVLink 5 翻倍到每块卡双向 1.8 TB/s。NVSwitch 是 NVLink 的交换芯片:DGX H100 里 8 块 GPU 都连到 NVSwitch 上,任意两块卡之间都能以全速通信(全互连),而不是只能和相邻的卡说话。H100 这一代的 NVSwitch 还能在交换机里直接做加法(NVLink SHARP,§5.4)。

NVLink 能直接连通的范围叫一个 NVLink 域。DGX H100 是 8 块卡;GB200 NVL72 用 NVSwitch 把一整个机柜的 72 块 GPU 连成一个 NVLink 域,合计约 130 TB/s。这改变了并行的设计空间:以前张量并行、专家并行只能限制在 8 块卡里,现在可以在 72 块卡上全走 NVLink(第 7 讲 Dynamo 和第 8 讲 Helix 的很多结果都建立在它上面)。

2.3 节点之间:网卡、InfiniBand 与 RoCE

跨节点要经过网卡。GPU 服务器通常给每块 GPU 配一张就近的网卡:DGX H100 有 8 张 400 Gb/s 的 ConnectX-7(另有几张给存储和管理用)。主流的两种网络:

  • InfiniBand:为高性能计算设计的网络,原生支持 RDMA,延迟低,交换机还能做集合通信的归约(SHARP)。NDR 一个端口 400 Gb/s。
  • RoCE(RDMA over Converged Ethernet):在以太网上跑 RDMA,成本和生态上更接近普通数据中心网络。

代码 01 演示 5 算了这个落差:一个 DGX H100 节点内部 8 块卡的 NVLink 合计每方向 3.6 TB/s,对外 8 张网卡合计每方向 400 GB/s——节点内是节点间的 9 倍。所以”每一层都要通信”的切法(张量并行、专家并行)尽量放在 NVLink 域内;跨节点只放通信少的(流水线并行、数据并行、解耦部署的 KV 传输)。

2.4 RDMA 与 GPUDirect

普通的网络通信要经过操作系统内核:数据从应用的缓冲区拷到内核、再交给网卡,接收方再反过来拷一遍,每一步都要 CPU 参与。RDMA(remote direct memory access)让网卡不经过内核、直接读写远端机器的内存:零拷贝、几乎不占 CPU、延迟低。

GPUDirect RDMA 再进一步:网卡直接读写 GPU 显存,数据不再经过 CPU 内存中转。代码 01 演示 4(跨节点传 1 GB):经主机中转、不流水时要 64 ms(GPU → CPU 内存 → 网络 → CPU 内存 → GPU,三段依次),分块流水也要 25 ms 且占用 CPU 内存带宽;GPUDirect RDMA 只有网络本身的 25 ms。NCCL 只在 GPU 和网卡挂在同一个 PCIe 交换机下时才用它——这也是为什么每块 GPU 要配一张”就近”的网卡。

还有 GPUDirect Storage:NVMe SSD 直接读写 GPU 显存,用于从存储加载权重或 KV。Mooncake 的传输引擎(第 9 讲)、DeepSeek 的 DeepEP(第 16 讲)都建立在 RDMA 之上。

2.5 推理里的具体传输

代码 01 演示 3(Llama-3-70B,BF16):

传输大小NVLink 4IB NDR
张量并行 decode:一层的激活(批 1)16 KB2.05 µs5.41 µs
张量并行 decode:一层的激活(批 64)1 MB4.91 µs31.21 µs
张量并行 prefill:一层的激活(4,096 token)67 MB188 µs1.68 ms
解耦部署:4,096 token 提示的全部 KV1.34 GB3.73 ms33.56 ms
冷启动:全部权重141 GB392 ms3.53 s
  • decode 时张量并行每层传的激活只有十几 KB 到 1 MB:时间几乎全是 α,而一步 decode 有 80 层、每层 2 次集合通信。
  • 解耦部署要把 prefill 算出的 KV 搬到 decode 的机器:4K 的提示有 1.34 GB,经一张网卡要 30 多毫秒(8 块卡 prefill 这个提示约 105 ms)。8 张网卡并行只要 4 ms,再逐层边算边传(§7.3),就几乎藏住了(第 7、9 讲)。
  • 冷启动:从一块 NVMe SSD 读 141 GB 的权重要 25 秒,已经在 CPU 内存里时经 8 条 PCIe 只要 0.34 秒——第 12 讲多模型服务的冷启动就是这笔账。

3. α–β 模型 · The α–β model

传一条 nn 字节的消息:

T(n)=α+nβ.T(n) = \alpha + \frac{n}{\beta}.

α\alpha 是不管消息多大都要付的固定开销,n/βn / \beta 是真正传数据的时间。两项相等时,n1/2=αβn_{1/2} = \alpha \beta 叫半带宽消息大小:消息比它小时,连一半的带宽都用不上。代码 01 演示 2:

链路 \ 消息16 KB256 KB1 MB16 MB
NVLink 42%26%58%96%
InfiniBand NDR7%56%83%99%
以太网 25 Gb/s24%84%95%100%

(表里是有效带宽占峰值的比例。)同样传 256 KB,NVLink 只用到四分之一的带宽,以太网反而用到 84%——不是以太网好,而是它本来就慢。链路越快,要用满它需要的消息越大。NVLink 4 的 n1/2n_{1/2} 是 720 KB,而 decode 时张量并行每层传的激活往往比它小得多。

这个模型给出两条贯穿全篇的经验:

  • 消息小时优化 α:减少步数、减少消息条数、把小消息合并成大消息(§5 的算法选择、推理引擎的自定义 all-reduce 内核)。
  • 消息大时优化 β:减少每个设备要传的字节(带宽最优的算法、分层通信、交换机内归约)、让通信和计算重叠(§7)。

4. 集合通信 · Collective communication

4.1 六种操作

集合通信(collective)是一组设备一起参与的通信操作。代码 02 演示 1 用 4 个设备、每个设备一个长度 4 的数组展示:

操作做什么例子(输入 GPU i 有 [10i, 10i+1, 10i+2, 10i+3])
broadcast一个设备的数据发给所有人每人都得到 GPU0 的 [0, 1, 2, 3]
reduce求和,结果只在一个设备上GPU0 得到 [60, 64, 68, 72]
all-reduce求和,每个人都拿到每人都得到 [60, 64, 68, 72]
reduce-scatter求和,结果切成 kk 块、每人拿一块GPU0 拿到第 1 块 [64],GPU1 拿到 [68]……
all-gather每人一块,拼成完整的给每个人每人都得到 [0, 10, 20, 30]
all-to-allGPU i 的第 j 份发给 GPU jGPU j 得到 [j, 10+j, 20+j, 30+j]:一次”矩阵转置”

外加最基本的点对点(send / recv):一个设备发、另一个收。

它们之间有一个很重要的关系:all-reduce = reduce-scatter + all-gather。先把和切开、每人负责一块(reduce-scatter),再把各块拼回来发给所有人(all-gather)。这个拆法有两个用处:ring all-reduce 就是这样实现的(§5.1);序列并行可以在两步之间插入别的计算(§6.2)。

推理里最常用的是:all-reduce(张量并行,每层两次)、all-gather 与 reduce-scatter(序列并行、DP 注意力)、all-to-all(专家并行)、点对点(流水线并行、解耦部署的 KV 传输)。

4.2 每个设备至少要传多少

all-reduce 的结果依赖所有设备的数据。可以证明,每个设备至少要发送 2(k−1)kD\frac{2(k-1)}{k} D 字节(reduce-scatter 和 all-gather 各 k−1kD\frac{k-1}{k} D)。代码 02 演示 2(8 个设备,每个 8 MB,NVLink 4):

算法步数每个设备发送÷ 下界时间
朴素(每人发给所有人)156 MB4.00157.56 µs
ring1414 MB1.0066.89 µs
递归加倍324 MB1.7172.67 µs
Rabenseifner614 MB1.0050.89 µs
二叉树(reduce + broadcast)624 MB1.71145.33 µs

五种算法的结果完全一样,差别全在”怎么传”:步数(决定付几次 α\alpha)和每个设备传的字节(决定 D/βD/\beta 那一项)。ring 和 Rabenseifner 恰好达到下界,叫带宽最优;而且这个量 2(k−1)kD\frac{2(k-1)}{k} D 几乎不随设备数增长——加卡不会让每块卡多传。

4.3 all-to-all 与 MoE

专家并行(第 8 讲)里,每块卡放一部分专家;每个 token 要被发到它选中的专家所在的卡上(dispatch),算完再发回来(combine)——两次 all-to-all。all-to-all 的麻烦在于负载不均:一个热门专家所在的卡要收的数据比别人多,而所有卡都要等它收完才能开始算。代码 02 演示 3(8 块卡、每块一个专家、top-2):均匀路由时 dispatch 约 181 µs;一个专家热 4 倍时,它所在的卡要收的数据是平均的约 2.5 倍,dispatch 变成 415 µs(2.3 倍)。这是前置讲 P4 §4.3”扇出”在通信上的样子;第 8 讲的冗余专家和负载均衡都是为了压低这个”最忙的卡”。


5. all-reduce 的算法 · All-reduce algorithms

5.1 ring:带宽最优,步数线性

设备排成一个环,数组切成 kk 块:

  1. reduce-scatter:k−1k-1 步。每一步,每个设备把手上一块的”部分和”发给下一个设备,对方加到自己的同一块上。结束时每块都在某个设备上加齐了 kk 份。
  2. all-gather:再 k−1k-1 步,把加齐的块沿环转发,直到每个设备都有全部 kk 块。

每步每个设备只发 D/kD/k 字节、所有链路同时在忙,总时间:

Tring=2(k−1) α+2(k−1)k⋅Dβ.T_\text{ring} = 2(k-1)\,\alpha + \frac{2(k-1)}{k} \cdot \frac{D}{\beta}.

字节是最优的,但要走 2(k−1)2(k-1) 步:8 块卡 14 步,64 块卡 126 步。(第 6 讲 §1.3 的代码逐步打印了它的每一步。)

5.2 递归加倍与 Rabenseifner:步数对数

  • 递归加倍(recursive doubling):第 ss 步,每个设备和”编号只在第 ss 位不同”的设备交换整个数组再相加。log⁡2k\log_2 k 步就完成,延迟最优;但每步都传整个数组,共 log⁡2k⋅D\log_2 k \cdot D,带宽很差:
TRD=log⁡2k⋅(α+Dβ).T_\text{RD} = \log_2 k \cdot \left(\alpha + \frac{D}{\beta}\right).
  • Rabenseifner(递归减半 + 递归加倍):reduce-scatter 阶段每步和一个伙伴交换一半(第一步和距离 k/2k/2 的设备交换各自”对方负责的那一半”,下一步在剩下的一半里和距离 k/4k/4 的设备交换……);all-gather 阶段倒过来。2log⁡2k2\log_2 k 步,字节和 ring 一样最优:
TRab=2log⁡2k⋅α+2(k−1)k⋅Dβ.T_\text{Rab} = 2\log_2 k \cdot \alpha + \frac{2(k-1)}{k} \cdot \frac{D}{\beta}.

两头都好,代价是要求设备数是 2 的幂、通信对象每步都在变。

  • 树:先沿一棵二叉树把数据归约到根,再沿树广播下去。朴素的树每步都传整个数组,根附近的设备最忙;NCCL 用的是双二叉树:两棵互补的树(一个设备在一棵树里是内部节点,在另一棵里就是叶子),数据切成两半各走一棵,再分块流水——既有对数级的步数,又能接近满带宽。

5.3 消息大小决定算法

代码 03 演示 1(8 块卡,NVLink 4):

算法 \ 消息4 KB1 MB16 MB1 GB
ring28.0 µs32.9 µs105.8 µs4.9 ms
递归加倍6.0 µs14.3 µs139.3 µs8.3 ms
Rabenseifner12.0 µs16.9 µs89.8 µs4.9 ms
二叉树(不流水)12.1 µs28.7 µs278.7 µs16.7 ms
交换机内归约4.0 µs6.8 µs48.4 µs2.8 ms

小消息时只看 α 的次数,递归加倍最快;大消息时只看字节,ring 和 Rabenseifner 最快。代码 03 演示 2 把设备数增加到 64 块、全部走 InfiniBand:ring 要走 126 步,1 MB 的 all-reduce 光 α 就要 630 µs,递归加倍只要 180 µs;交叉点向更大的消息移动。没有”最好的算法”,通信库要按消息大小、设备数、拓扑选择。

5.4 交换机内归约

如果交换机自己会做加法,每块卡只需要把数据发给交换机一次、再从交换机收一次结果:

Tin-network≈2α+Dβ,T_\text{in-network} \approx 2\alpha + \frac{D}{\beta},

传输量约是 ring 的一半,步数也最少。InfiniBand 交换机的 SHARP 和 H100 这一代 NVSwitch 的 NVLink SHARP(NCCL 里的 NVLS 算法)都提供这种能力。上表里它在各种大小下都最快(这是理想值;真实的收益要扣掉实现开销)。

5.5 分层 all-reduce

跨节点时,一个”所有卡排成一个环”的扁平 ring,每一步都要等最慢的那条链路(网卡),节点内的 NVLink 完全没被利用。分层的做法:

  1. 每个节点内用 NVLink 做 reduce-scatter:每块卡只剩 D/GD/G(GG 是每节点的卡数);
  2. 各节点里本地编号相同的卡之间,对各自那 D/GD/G 做跨节点的 all-reduce——GG 张网卡同时在用;
  3. 每个节点内 all-gather。

代码 03 演示 3(4 个节点 × 8 块卡):分层在 64 KB 到 1 GB 的各种大小下都比扁平的环快约 5 倍(1 GB:9.61 ms vs 48.75 ms)。NCCL 会根据拓扑自动这样组织。

5.6 NCCL

NCCL(NVIDIA Collective Communications Library)是 GPU 上集合通信的事实标准,PyTorch、vLLM、SGLang 都用它。它做几件事:

  • 拓扑感知:探测 NVLink、PCIe、网卡的连接方式,建立环和树(分层的)。
  • 算法:Ring、Tree(双二叉树)、CollNet(用网络交换机的 SHARP)、NVLS(用 NVSwitch 的 NVLink SHARP)等。
  • 协议:同一个算法,数据怎样从一块卡交到下一块卡,有三种协议。“Demystifying NCCL” 报告的量级:
协议同步方式带宽每跳延迟
Simple大块数据 + 内存屏障接近峰值约 6 µs
LL(low latency)每 4 字节数据配 4 字节标志,接收方轮询标志峰值的 25%–50%约 1 µs
LL128每 128 字节里 8 字节做标志约 95%约 2 µs

代码 03 演示 4 用这些量级算 8 块卡的 ring all-reduce:64 KB 以下 LL 最快、16 MB 时 LL128 最快、256 MB 以上 Simple 最快——和算法的选择是同一个道理。

  • 自动选择:NCCL 对每种”算法 + 协议”用代价模型估计时间,每次调用选最快的。
  • 传输方式:节点内走 NVLink 的点对点(或者 PCIe、共享内存),节点间走 InfiniBand / RoCE 的 RDMA(能用时用 GPUDirect RDMA),都不行时退回 TCP 套接字。

5.7 推理里的小消息

代码 03 演示 5:Llama-3-70B 用张量并行 TP8(NVLink 4),decode 一步要做 80 层 × 2 = 160 次 all-reduce,每次 B×8192×2B \times 8192 \times 2 字节:

批 B每次大小ring递归加倍交换机内归约读显存的时间
116 KB4.49 ms0.98 ms0.65 ms6.61 ms
641 MB5.30 ms2.36 ms1.11 ms8.58 ms
2564 MB7.74 ms6.55 ms2.50 ms14.59 ms

用通用的 ring,160 次小通信一步就要 4.5 ms,是读显存时间的三分之二。(这里每步 α\alpha = 2 µs、ring 走 14 步,对小消息是偏悲观的估计。)所以推理引擎为小消息写了专门的 all-reduce 内核:vLLM 的 custom all-reduce 在 NVLink 全互连、消息小于 8 MiB 时直接读写其他卡的显存,一两步完成;或者用 NCCL 的 LL 协议、NVLS。这也是第 6 讲 §2.3”张量并行的通信不随卡数减少、TP 太宽反而变慢”的一个原因。


6. 并行方式的通信模式 · Communication patterns of parallelism

6.1 数据并行(副本)

推理里的数据并行就是多放几个完整的副本,各自服务不同的请求,彼此不通信(训练时要同步梯度,推理不用)。代价是每个副本都要放下全部权重。它是吞吐的最简单扩展方式,多个副本之间靠路由器分配请求(第 11 讲)。

6.2 张量并行与序列并行

张量并行把每一层的矩阵切到 kk 块卡上。Megatron-LM 的切法:MLP 的第一个矩阵(SwiGLU 的 gate 和 up)按列切,每块卡负责 dff/kd_{ff}/k 个中间神经元;第二个矩阵(down)按行切。SiLU 和逐元素乘法只作用在每块卡自己的那几列上,所以两个矩阵乘法之间不用通信;最后一次 all-reduce 把各卡的部分和加起来。注意力同理:按头切 Q、K、V(每块卡负责几个头),输出投影按行切,一次 all-reduce。所以每层两次 all-reduce。

代码 04 演示 1 验证了这个切法和单卡结果一致,并比较了一个”错误”的切法:如果第一个矩阵按行切,SiLU 之前就必须先 all-reduce 出完整的 T×dffT \times d_{ff} 中间结果——两次、每次是输出的 3.5 倍大,每块卡要多传 7 倍的字节。切法的设计就是在”哪里非线性、哪里必须通信”之间找缝隙。

序列并行(Megatron-SP,Korthikanti 等 2022):张量并行下,MLP 和注意力之外的 RMSNorm、残差在每块卡上都是完整的一份(重复计算、重复存储)。序列并行把这部分按 token 切开,每块卡只处理 T/kT/k 个 token;进入 MLP 前 all-gather 拼出完整的输入,出 MLP 时用 reduce-scatter 代替 all-reduce,直接得到自己那 T/kT/k 个 token 的输出。演示 1 里它的通信量和张量并行完全一样(all-reduce = reduce-scatter + all-gather),但激活的显存和逐元素计算都分摊到了 kk 块卡上。第 16 讲 SGLang 的 DP 注意力用的也是这对组合。

张量并行每层都要通信、而且是”小而多”的通信,所以几乎总是放在一个 NVLink 域内:代码 04 演示 3,TP8 decode 一步在 NVLink 上通信约 2–5 ms,走 InfiniBand 要 15–19 ms,比读一遍权重(约 6.6 ms)还慢好几倍。

6.3 流水线并行

流水线并行把模型按层切成 pp 段,每段放在一块卡上,激活从一段传到下一段(点对点)。通信量很小:一步 decode 每个微批只在 7 个段边界各传一次激活(批 64 时每次 1 MB),跨节点也不怕。

它的问题在别处。代码 04 演示 4(4 段,每段 2 ms):一个微批生成下一个 token,必须先让上一个 token 走完 4 段(自回归的依赖),所以只有一个微批时每块卡只有 1/4 的时间在干活;要有至少 4 个微批同时在流水线里,利用率才到 98%。而且每个 token 的间隔始终是 4 × 2 ms ≈ 8.15 ms,不比单卡更短:流水线并行提高吞吐,不降低延迟。训练时的”流水线气泡”(第一个微批进入前、最后一个微批离开后,有的段在空等)在推理里表现为”同时在跑的微批不够多”。第 6 讲 §2.5 有更完整的讨论。

6.4 专家并行

专家并行把 MoE 层的专家分到不同的卡上,每层两次 all-to-all(§4.3)。decode 时每个 token 只去 top-k 个专家、token 又少,代码 04 演示 3 里 Mixtral-8x7B 用 EP8 时 decode 一步每块卡只发约 7 MB,但每层要和 7 块卡各交换一次,时间主要花在 α 上;prefill 或大批时字节就大了。再加上负载不均,大规模专家并行跨节点时通信是主要矛盾,要靠专门的通信库(DeepEP 用 RDMA 和 NVLink 直接在 GPU 上发起通信)和计算—通信重叠(§7.4、第 8、16 讲)。

6.5 上下文并行与 ring attention

长上下文时,一段序列的 KV 一块卡放不下,或者 prefill 太慢。上下文并行把序列按 token 切到 kk 块卡上。ring attention(Liu 等 2023):每块卡拿着自己那段的 Q;K、V 的块沿环传一圈,每一步用自己的 Q 和”这一步手上的 KV 块”算部分注意力,用在线 softmax(第 4 讲 §3.2 的 mm 和 ℓ\ell)把各块的结果合并。代码 04 演示 2 验证它和单卡完全一致(误差 7×10−167 \times 10^{-16})。

关键在于:每一步的注意力计算随块长 nn 平方增长,要传的 KV 块只线性增长。对 Llama-3-70B 的一层(64 个 query 头、8 个 KV 头),每块卡的 token 数超过约 240(NVLink)/ 2,163(InfiniBand)时,传 KV 就能完全藏在计算后面。所以长上下文的 prefill 很适合这样切(第 6 讲 §5.2 的 LoongServe)。带因果掩码时,各卡的工作量不均,实际系统用”之字形”的切法来平衡。

6.6 一张对照表

并行方式切什么通信每层 / 每步适合的链路主要收益
数据并行(副本)请求无—任意吞吐
张量并行每层的矩阵(按头 / 按列行)all-reduce每层 2 次NVLink 域内延迟(分摊读权重)、放得下
序列并行MLP 外的 tokenreduce-scatter + all-gather每层 2 对NVLink 域内激活显存
流水线并行层点对点每个段边界 1 次可以跨节点放得下、吞吐
专家并行专家all-to-all每 MoE 层 2 次NVLink 或 RDMA放得下、专家的批更大
上下文并行token(KV)点对点(环)每层 k−1k-1 步视块长而定长上下文

真实部署常常是组合:例如节点内 TP8、节点间 PP2;或者注意力用数据并行、MoE 用专家并行(DeepSeek-V3 的部署,第 8 讲)。通信多的放在快链路上,通信少的才能跨慢链路——这是第 6 讲 Alpa 的核心观察,也是 FlexFlow 一类自动搜索要处理的问题。


7. 计算与通信的重叠 · Overlapping computation and communication

7.1 切块流水

通信和计算用的是不同的硬件(网卡 / NVLink 的拷贝引擎 vs SM),可以同时进行。把一份工作切成 nn 块,第 ii 块算完就开始传,同时开始算第 i+1i+1 块:

Toverlap≈Tcompn+(n−1)⋅max⁡ ⁣(Tcompn,Tcommn+α)+Tcommn+α.T_\text{overlap} \approx \frac{T_\text{comp}}{n} + (n - 1) \cdot \max\!\left(\frac{T_\text{comp}}{n}, \frac{T_\text{comm}}{n} + \alpha\right) + \frac{T_\text{comm}}{n} + \alpha.

代码 05 演示 1(计算 1 ms,每块通信多付 10 µs 的 α):通信 1 ms 时,不重叠 2.01 ms,切成 8 块 1.20 ms,切成 256 块反而 3.56 ms——每块都要多付一次 α,切得太细反而更慢。通信比计算长时(2 ms),再怎么重叠也省不掉通信本身,这时要减少通信量。

7.2 张量并行的 prefill

代码 05 演示 2:Llama-3-70B、TP8、prefill 4,096 个 token。每层每块卡计算约 1.32 ms,两次 64 MB 的 all-reduce 约 0.71 ms(ring,NVLink 4),约占每层时间的三分之一。按 token 切成 4 块、一块的 all-reduce 和下一块的矩阵乘法同时进行,80 层一共省下约 38 ms 的 TTFT;切成 16 块又因为 α 变慢。重叠的前提是”下一块的计算不依赖这一块的通信结果”——按 token 切块正好满足。

7.3 逐层传输 KV

代码 05 演示 3:解耦部署时,prefill 的 KV 要传给 decode 的机器。算完再传,传输直接加在 TTFT 上:4K 的提示用 1 张网卡多出 33.6 ms、8 张网卡多出 4.2 ms。逐层传输:每算完一层就把这一层的 KV 传走,和下一层的计算同时进行,prefill 结束时只剩最后一层的 KV 露在外面——8 张网卡时只多出 57 µs。32K 的长提示也一样:每层的计算(约 13 ms)仍然比传输长。DistServe、Mooncake(第 7、9 讲)都按层传输 KV。

7.4 两批交错

MoE 的一层里,all-to-all 和专家计算是串行的:dispatch → 算专家 → combine。两批交错(two-batch overlap,TBO):把一批请求分成两半,一半在做 all-to-all 时另一半在计算。代码 05 演示 4(计算 c = 1):通信和计算差不多大时(a = 1)收益最大,1.33 倍;通信很小时没什么可藏,通信远大于计算时最多只能把计算藏进去。SGLang 的 TBO(第 16 讲)、MegaScale-Infer 的 ping-pong 流水线(第 8 讲)都是这个思路。

重叠不是免费的:通信内核也要占用一些 SM 和显存带宽,计算会被拖慢一点;切块、分批还要额外的显存和调度复杂度。实践中要用性能分析工具(如 Nsight Systems)确认通信是不是真的被藏住了。


8. 与推理系统的联系 · Connections to inference systems

有系统背景的读者可以只读这一节。

本篇的概念在推理系统里的体现哪一讲
为什么要多卡70B 放不下一块卡;8 块卡的带宽让每个 token 更快第 6 讲
NVLink 域、节点内 vs 节点间的落差TP 放在节点内、PP 跨节点;NVL72 扩大了 TP / EP 的范围第 6、7、8 讲
α–β 模型、半带宽消息decode 的 TP 通信受限于 α;自定义 all-reduce 内核第 6、16 讲
ring / 树 / 递归算法、分层、SHARPNCCL 的算法与协议选择;多节点 all-reduce第 6 讲
all-to-all 与负载不均MoE 的专家并行、冗余专家、DeepEP第 8、16 讲
张量并行的切法、序列并行Megatron 的列切 + 行切;KV 头少于卡数时复制;DP 注意力第 6、8、16 讲
流水线并行跨节点部署;要有足够多的微批;不降延迟第 6、7 讲
上下文并行、ring attention长上下文的 prefill;LoongServe 的弹性序列并行第 6、10 讲
RDMA、GPUDirect解耦部署的 KV 传输;Mooncake 的传输引擎第 7、9 讲
PCIe、NVMe、冷启动KV 卸载到 CPU / SSD;模型加载第 9、12 讲
计算—通信重叠逐层传 KV;TBO;ping-pong;分块 prefill 与通信交错第 7、8、16 讲

9. 小结 · Summary

  1. 多卡是为了放得下、算得快(带宽加起来)、服务得多;代价是通信,而卡与卡之间比卡内的 HBM 慢一个数量级以上。
  2. 互连有层次:NVLink 域内(每卡每方向 450 GB/s)> 节点间网卡(50 GB/s)> 以太网 > 存储。节点内的总带宽是节点对外的 9 倍。RDMA 和 GPUDirect RDMA 让网卡直接读写远端的显存。
  3. α–β 模型:T=α+n/βT = \alpha + n/\beta。消息小于 αβ\alpha\beta 时受限于延迟——优化步数和消息条数;消息大时受限于带宽——优化每个设备传的字节。
  4. 集合通信:all-reduce = reduce-scatter + all-gather;带宽下界是每个设备 2(k−1)kD\frac{2(k-1)}{k} D。ring 带宽最优但步数线性,递归加倍步数对数但字节多,Rabenseifner 两头兼顾,双二叉树、交换机内归约、分层各有用处;NCCL 按消息大小和拓扑自动选择算法和协议。
  5. 并行方式:张量并行每层两次 all-reduce,放在 NVLink 域内;序列并行通信量相同、省激活;流水线并行通信少、不降延迟、要有足够多的微批;专家并行是 all-to-all,怕负载不均;ring attention 用环传 KV,块越长越容易藏住通信。
  6. 重叠:切块流水、逐层传输、两批交错能把通信藏在计算后面;切得太细会被 α 吃掉,通信比计算长时只能减少通信本身。

10. 常见误区 · Common pitfalls

  • “NVLink 900 GB/s,所以传 900 MB 只要 1 毫秒”。900 GB/s 是双向合计,每个方向 450 GB/s,再打个折约 360 GB/s;小消息还要加上 α。
  • “带宽高的链路,小消息也快”。小消息的时间几乎全是 α,NVLink 和 PCIe 传 1 KB 都是几微秒。
  • “ring all-reduce 是最好的”。它带宽最优,但要走 2(k−1)2(k-1) 步;小消息、设备多时,步数少的算法快得多。
  • “加卡就能降低张量并行的延迟”。每块卡读的权重少了,但每层两次 all-reduce 的通信不随卡数减少,而且卡越多步数越多;TP 跨节点时通信会比计算还慢。
  • “流水线并行能降低延迟”。它只提高吞吐;每个 token 仍然要走完所有段。
  • “专家并行的通信量和张量并行一样”。decode 时它的字节少得多,难点在 α 和负载不均。
  • “通信可以全部和计算重叠”。只有”下一块的计算不依赖这块的通信结果”时才能重叠;通信比计算长时最多藏住计算;通信内核还会占用 SM。
  • “跨节点传数据要经过 CPU”。有 GPUDirect RDMA 时网卡直接读写显存;没有时才经主机内存中转,慢两倍以上。

11. 练习 · Exercises

练习 1(半带宽消息)。NVLink 4 的有效带宽 360 GB/s、α = 2 µs。半带宽消息多大?传 64 KB 要多久、用到了峰值带宽的百分之几?

参考答案

n1/2=2 μs×360 GB/s=720n_{1/2} = 2\ \mu\text{s} \times 360\ \text{GB/s} = 720 KB。64 KB:2+64 KB/360 GB/s≈2.18 μs2 + 64\ \text{KB} / 360\ \text{GB/s} \approx 2.18\ \mu\text{s},有效带宽约是峰值的 8%。

练习 2(ring all-reduce)。4 块卡、每块 100 MB,在 NVLink 4 上做 ring all-reduce:每块卡发送多少字节?要几步?多久?

参考答案

每块卡发送 2×3/4×1002 \times 3/4 \times 100 = 150 MB;2×3=62 \times 3 = 6 步;时间 6×2 μs+150 MB/360 GB/s≈12+417≈429 μs6 \times 2\ \mu\text{s} + 150\ \text{MB} / 360\ \text{GB/s} \approx 12 + 417 \approx 429\ \mu\text{s}(t_ring(100e6, 4, NVLINK4))。

练习 3(选算法)。16 块卡、全部走 InfiniBand(40 GB/s、α = 5 µs),all-reduce 256 KB:ring、递归加倍、Rabenseifner、二叉树各要多久?选哪个?

参考答案

ring:30×5+2×15/16×256 KB/40 GB/s≈150+12=162 μs30 \times 5 + 2 \times 15/16 \times 256\ \text{KB} / 40\ \text{GB/s} \approx 150 + 12 = 162\ \mu\text{s};递归加倍:4×(5+6.4)≈45.6 μs4 \times (5 + 6.4) \approx 45.6\ \mu\text{s};Rabenseifner:8×5+12=52 μs8 \times 5 + 12 = 52\ \mu\text{s};二叉树(不流水):8×(5+6.4)≈91 μs8 \times (5 + 6.4) \approx 91\ \mu\text{s}。选递归加倍:消息不大,α 的次数说了算。

练习 4(分层的收益)。代码 03 演示 3 里,4 个节点 × 8 块卡、1 GB 的 all-reduce,分层 9.61 ms、扁平的环 48.75 ms。为什么差不多是 5 倍?如果每个节点有 16 块卡呢?

参考答案

扁平的环里每一步都走网卡(40 GB/s),字节 ≈2D\approx 2D;分层时跨节点只传 2×N−1N×DG2 \times \frac{N-1}{N} \times \frac{D}{G}(1/8 的数据、8 张网卡并行),节点内的两步走 NVLink(9 倍快)。主项之比大约是 2D/βIB2D/(G βIB)+2D/βNV\frac{2D/\beta_\text{IB}}{2D/(G\,\beta_\text{IB}) + 2D/\beta_\text{NV}} ≈ 11/8+1/9≈4.2\frac{1}{1/8 + 1/9} \approx 4.2,再加上步数少,约 5 倍。每节点 16 块卡时跨节点的数据只剩 1/16,节点内的 NVLink 那两步变成主要部分,收益约 6–7 倍(可以用 t_hierarchical 算)。

练习 5(张量并行 prefill 的通信量)。Llama-3-70B、TP8,prefill 一个 4,096 token 的提示,每块卡一共要发送多少字节?

参考答案

每次 all-reduce 的数据 4096×8192×2≈674096 \times 8192 \times 2 \approx 67 MB,ring 下每块卡发送 2×7/8×67≈1172 \times 7/8 \times 67 \approx 117 MB;每层两次 → 235 MB;80 层 → 约 18.8 GB。在 NVLink 上约 57 ms(代码 05 演示 2),所以 prefill 的通信一定要和计算重叠。

练习 6(流水线 decode)。模型切成 8 段、每段 1 ms、段间传输 0.1 ms。要让每块卡都忙起来,至少要多少个微批同时在跑?每个微批生成一个 token 的间隔至少多久?

参考答案

至少 8 个微批(段间传输让 8 个微批时利用率约 91%,再多一两个才完全填满);每个 token 的间隔至少 8×1+7×0.1=8.78 \times 1 + 7 \times 0.1 = 8.7 ms,和微批数无关(pp_decode(8, 8, 1e-3, 1e-4, 100) 给出 8.77 ms)。

练习 7(ring attention 能不能藏住通信)。一个 128K token 的提示切到 8 块卡上(每块 16K token),跨节点用 InfiniBand。按代码 04 演示 2 的估计,传 KV 能藏住吗?如果是 8K token 的提示呢?

参考答案

阈值约 2,163 个 token / 块(IB)。128K / 8 = 16K ≫ 2,163,能藏住;8K / 8 = 1K < 2,163,藏不住——短提示不值得用上下文并行。

练习 8(KV 传输)。Llama-3-70B 一个 32K token 的提示,KV 有多大?经 1 张、8 张 400 Gb/s 的网卡算完再传各要多久?逐层传输时呢?

参考答案

32,768×327,680≈10.732{,}768 \times 327{,}680 \approx 10.7 GB。1 张网卡约 268 ms,8 张约 33.6 ms;逐层传输时 8 张网卡只多出约 0.42 ms(代码 05 演示 3)。


12. 延伸阅读 · Further reading

  • R. Thakur, R. Rabenseifner, W. Gropp. Optimization of Collective Communication Operations in MPICH. IJHPCA, 2005。集合通信算法与 α–β 代价的经典文献。
  • P. Patarasuk, X. Yuan. Bandwidth Optimal All-reduce Algorithms for Clusters of Workstations. JPDC, 2009。ring all-reduce 的带宽最优性。
  • Z. Hu et al. Demystifying NCCL: An In-depth Analysis of GPU Communication Protocols and Algorithms. 2025。
  • M. Shoeybi et al. Megatron-LM. 2019;V. Korthikanti et al. Reducing Activation Recomputation in Large Transformer Models. 2022(序列并行)。
  • Y. Huang et al. GPipe. NeurIPS 2019;H. Liu et al. Ring Attention with Blockwise Transformers for Near-Infinite Context. 2023。
  • NVIDIA. DGX H100 用户指南;NVLink / NVSwitch 的技术资料;NCCL 文档。
  • DeepSeek. DeepEP(专家并行的通信库,开源)。

13. 下一步 · What’s next

五篇前置讲到这里全部结束:P1 讲一块 GPU 内部,P2 讲一个模型的账,P3 讲操作系统的调度、分页和缓存,P4 讲排队和实验方法,P5 讲多块卡之间的通信。按 SYLLABUS 第 0.2 节的顺序,读完 P5 就可以进入第 6 讲(并行):它在本篇的基础上讨论 FlexFlow 的策略搜索和 Pope 等人对 Transformer 推理分区的系统分析;之后的第 7–9 讲(解耦、MoE、上下文管理)都会反复用到本篇的通信账。

← 返回课程目录