大模型训练之流水线并行(Pipeline Parallelism)详解
前言
随着深度学习的飞速发展,大语言模型(LLM)的参数规模从数亿迅速膨胀到数千亿甚至万亿级别。GPT-3 拥有 1750 亿参数,PaLM 达到 5400 亿,而 Switch Transformer 更是突破了万亿大关。如此庞大的模型,单张 GPU 的显存早已无法容纳,分布式并行训练成为了必然选择。
在主流的并行策略中,流水线并行(Pipeline Parallelism) 是一种核心且优雅的方案。本文将从原理到实践,全面介绍流水线并行的来龙去脉。
一、并行策略全景图
在深入流水线并行之前,先简要了解大模型训练中的几种主要并行策略:
| 并行策略 | 切分对象 | 核心思想 |
|---|---|---|
| 数据并行(Data Parallelism) | 数据 | 每个设备持有完整模型副本,切分训练数据 |
| 张量并行(Tensor Parallelism) | 层内参数 | 将单个算子/层的权重矩阵切分到多个设备 |
| 流水线并行(Pipeline Parallelism) | 层间结构 | 将模型的不同层分配到不同设备 |
| 专家并行(Expert Parallelism) | MoE 专家 | 将不同专家分配到不同设备 |
实际训练超大模型时,通常会将这些策略组合使用,形成3D 并行 甚至4D/5D 并行。而流水线并行是其中不可或缺的一环。
二、为什么需要流水线并行?
2.1 单卡显存瓶颈
以一个拥有 1750 亿参数的模型为例,仅模型参数(FP16)就需要约 350 GB 显存,而当前主流的 NVIDIA A100 GPU 单卡仅有 80 GB 显存。即使不考虑优化器状态、激活值等额外开销,也需要至少 5 张卡才能放下模型参数。
2.2 数据并行的局限
数据并行要求每个设备都持有完整的模型副本,当单卡放不下整个模型时,数据并行就无能为力了。
2.3 张量并行的局限
张量并行虽然能拆分单层的参数,但它需要在每一层的前向和反向过程中进行高频通信(AllReduce),因此通常要求设备之间有极高的通信带宽(如 NVLink),跨节点使用效率较低。
流水线并行 的优势在于:将模型按层切分到不同设备上,设备之间只需在层的边界 传递激活值(前向)和梯度(反向),通信量相对较小,且通信模式为点对点(P2P),非常适合跨节点部署。
三、朴素流水线并行(Naive Pipeline Parallelism)
3.1 基本思想
最简单的流水线并行思路非常直观:
-
将一个 LLL 层的模型分成 KKK 个阶段(stage)
-
将每个阶段分配到一个 GPU 上
-
前向传播时,数据从 Stage 0 依次流向 Stage K-1
-
反向传播时,梯度从 Stage K-1 依次流回 Stage 0
GPU 0: [Layer 0, Layer 1, ..., Layer l₁]
GPU 1: [Layer l₁+1, ..., Layer l₂]
GPU 2: [Layer l₂+1, ..., Layer l₃]
GPU 3: [Layer l₃+1, ..., Layer L]
3.2 致命问题:流水线气泡(Pipeline Bubble)
朴素方案的最大问题是严重的设备空闲。来看一个 4 个 stage 的例子:
时间 →
GPU 0: [ Forward ][ Idle ][ Backward ][Idle]
GPU 1: [ Idle ][ Forward ][ Idle ][ Backward ][ Idle ]
GPU 2: [ Idle ][ Forward ][ Idle ][ Backward ][ Idle ]
GPU 3: [ Idle ][ Forward ][ Backward ][ Idle ]
在任意时刻,只有一个 GPU 在工作 ,其余 GPU 全部空闲。如果有 KKK 个 stage,理论设备利用率仅为 1K\frac{1}{K}K1,这意味着 4 张卡只有 25% 的利用率------这完全不可接受。
这些空闲时间被称为流水线气泡(Pipeline Bubble),是流水线并行需要解决的核心问题。
四、GPipe:微批次流水线并行
4.1 核心思想
GPipe(Google, 2019)是首个系统性解决流水线气泡问题的方案。其核心思想非常简洁:
将一个 mini-batch 切分成多个 micro-batch,依次注入流水线,让多个设备尽量同时工作。
具体步骤:
- 将一个 mini-batch BBB 切分为 MMM 个 micro-batch:b1,b2,...,bMb_1, b_2, ..., b_Mb1,b2,...,bM
- 依次将各 micro-batch 注入流水线
- 所有 micro-batch 的前向传播全部完成后,再依次执行反向传播
- 所有 micro-batch 的梯度累积后,统一更新参数
4.2 执行时序图
以 4 个 stage、8 个 micro-batch 为例(F = Forward, B = Backward):
时间步: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
GPU 0: [F1] [F2] [F3] [F4] [F5] [F6] [F7] [F8] [B8] [B7] [B6] [B5] [B4] [B3] [B2] [B1]
GPU 1: [F1] [F2] [F3] [F4] [F5] [F6] [F7] [F8] [B8] [B7] [B6] [B5] [B4] [B3] [B2] [B1]
GPU 2: [F1] [F2] [F3] [F4] [F5] [F6] [F7] [F8] [B8] [B7] [B6] [B5] [B4] [B3] [B2] [B1]
GPU 3: [F1] [F2] [F3] [F4] [F5] [F6] [F7] [F8] [B8] [B7] [B6] [B5] [B4] [B3] [B2] [B1]
4.3 气泡分析
GPipe 的气泡比例为:
Bubble ratio=K−1K−1+M\text{Bubble ratio} = \frac{K - 1}{K - 1 + M}Bubble ratio=K−1+MK−1
其中 KKK 是 stage 数量,MMM 是 micro-batch 数量。当 M≫KM \gg KM≫K 时,气泡比例趋近于 0。
例如,K=4,M=32K=4, M=32K=4,M=32 时,气泡比例 ≈ 8.6%,已经相当理想。
4.4 GPipe 的代价
GPipe 虽然有效减少了气泡,但存在一个问题:激活值的显存开销。
由于前向传播和反向传播是分离的(先做完所有 micro-batch 的前向,再做反向),所有 micro-batch 的中间激活值都需要保存在显存中,显存占用与 MMM 成正比。
解决方案:激活重计算(Activation Recomputation/Checkpointing)
GPipe 使用了激活重计算技术:前向时只保存每个 stage 边界的激活值,反向时需要某一层的激活值时重新前向计算得到。这用计算时间换显存空间,通常增加约 33% 的计算量,但可以大幅降低显存占用。
五、PipeDream 与 1F1B 调度
5.1 1F1B 调度策略
PipeDream (Microsoft, 2019)提出了一种更高效的调度策略------1F1B(One Forward One Backward):
在稳定状态下,每个设备交替执行一次前向和一次反向,而不是像 GPipe 那样集中执行所有前向后再集中执行所有反向。
5.2 非交错式 1F1B 时序图
以 4 个 stage、8 个 micro-batch 为例:
时间 →
GPU 0: [F1][F2][F3][F4] [B1][F5][B2][F6][B3][F7][B4][F8] [B5][B6][B7][B8]
← warmup → ← steady state (1F1B) → ← cooldown →
GPU 1: [F1][F2][F3] [F4][B1][F5][B2][F6][B3][F7][B4][F8] [B5][B6][B7][B8]
GPU 2: [F1][F2] [F3][F4][B1][F5][B2][F6][B3][F7][B4][F8] [B5][B6][B7][B8]
GPU 3: [F1] [F2][F3][F4][B1][F5][B2][F6][B3][F7][B4][F8] [B5][B6][B7][B8]
整个过程分为三个阶段:
- Warmup 阶段:流水线逐步填充,各 stage 只做前向
- Steady State(稳定阶段):每个 stage 交替执行 1 次前向和 1 次反向
- Cooldown 阶段:流水线逐步排空,各 stage 只做反向
5.3 1F1B 的优势:显存节省
1F1B 最大的优势在于显存效率。
- GPipe :需要同时保存 MMM 个 micro-batch 的激活值
- 1F1B :每个 stage 在任意时刻最多只需保存 KKK 个 micro-batch 的激活值(KKK 为 stage 数)
这是因为在稳定状态下,每完成一次反向就可以释放对应 micro-batch 的激活值,形成"先进先出"的效果。当 M≫KM \gg KM≫K 时,1F1B 的显存节省非常可观。
5.4 气泡比例
非交错式 1F1B 的气泡比例与 GPipe 相同:
Bubble ratio=K−1K−1+M\text{Bubble ratio} = \frac{K - 1}{K - 1 + M}Bubble ratio=K−1+MK−1
但其显存效率更高,因此在实践中更受欢迎。
六、交错式 1F1B(Interleaved 1F1B)
6.1 核心思想
Megatron-LM 团队进一步提出了交错式流水线调度。其核心思想是:
让每个 GPU 不再只持有连续的一段层,而是持有多个不连续的"模型块(model chunk)"。
例如,一个 16 层模型分到 4 个 GPU 上:
-
非交错式:GPU 0 持有 Layer 0-3,GPU 1 持有 Layer 4-7,...
-
交错式(2 chunks):GPU 0 持有 Layer 0-1 和 Layer 8-9,GPU 1 持有 Layer 2-3 和 Layer 10-11,...
非交错式:
GPU 0: [Layer 0-3]
GPU 1: [Layer 4-7]
GPU 2: [Layer 8-11]
GPU 3: [Layer 12-15]交错式 (2 chunks per GPU):
GPU 0: [Layer 0-1] + [Layer 8-9]
GPU 1: [Layer 2-3] + [Layer 10-11]
GPU 2: [Layer 4-5] + [Layer 12-13]
GPU 3: [Layer 6-7] + [Layer 14-15]
6.2 为什么能减少气泡?
交错式的关键洞察在于:由于每个 GPU 持有多个 chunk,虚拟 stage 数量增多(从 KKK 变为 K×vK \times vK×v,其中 vvv 是 chunk 数),每个虚拟 stage 的计算量变小,单次前向/反向的执行时间缩短。
气泡比例变为:
Bubble ratio=K−1v(K−1+M)\text{Bubble ratio} = \frac{K - 1}{v(K - 1 + M)}Bubble ratio=v(K−1+M)K−1
相比非交错式减少了 vvv 倍!
6.3 代价
通信量增加。由于虚拟 stage 更多,跨设备的点对点通信次数也相应增加。但在通信带宽充足的情况下,整体吞吐量仍然有明显提升。
七、进阶:零气泡流水线并行(Zero Bubble Pipeline Parallelism)
7.1 气泡的本质
无论是 GPipe 还是 1F1B,气泡都来源于流水线的启动和排空阶段 。2024 年,Qi 等人提出了 Zero Bubble Pipeline Parallelism,将气泡比例进一步压缩到接近零。
7.2 核心思想:拆分反向传播
在标准训练中,反向传播计算两部分梯度:
- BBB(输入梯度):计算 loss 对输入激活值的梯度,用于传递给上一层
- WWW(权重梯度):计算 loss 对本层权重的梯度,用于参数更新
传统方案将 BBB 和 WWW 绑定在一起计算,而 Zero Bubble 的关键创新是:
将 BBB(输入梯度计算)和 WWW(权重梯度计算)解耦,独立调度。
BBB 有严格的依赖关系(下一层的 BBB 依赖上一层的 BBB),但 WWW 没有跨 stage 的依赖------它只需要本 stage 的激活值和输出梯度。因此,WWW 可以被灵活地安排到任何空闲时间槽中,填补原本的气泡。
7.3 调度示例
时间 →
GPU 0: [F1][F2][F3][F4][B1][F5][B2][F6][B3][F7][B4][F8][B5][B6][B7][B8][W1][W2]...
GPU 1: [F1][F2][F3][B1][F4][B2][F5][B3][F6][W1][B4][F7][W2]...
GPU 2: [F1][F2][B1][F3][B2][W1][F4][B3][W2]...
GPU 3: [F1][B1][W1][F2][B2][W2][F3][B3][W3]...
通过将 WWW 填入气泡,理论上可以实现零气泡(在满足内存约束的前提下)。
7.4 自动搜索最优调度
由于手动设计调度方案非常复杂,论文提出使用**整数线性规划(ILP)**来自动搜索最优调度策略,在给定的内存约束下最小化总执行时间。
八、实践中的关键考量
8.1 如何切分模型(Stage 划分)
理想情况下,每个 stage 的计算量应尽量均衡,否则最慢的 stage 将成为瓶颈,增加气泡。
常见策略:
- 均匀切分:每个 stage 分配相同数量的 Transformer 层(最常用)
- 基于 profiling 的切分:考虑 embedding 层、最终分类层等非标准层的计算量差异
- 自动搜索:通过性能模型或实际测量来找最优划分
8.2 Micro-batch 数量的选择
MMM 的选择涉及多个 trade-off:
| MMM 增大 | 优势 | 劣势 |
|---|---|---|
| ✅ | 气泡比例降低 | 每个 micro-batch 更小,可能降低计算效率 |
| ✅ | 更接近理想并行 | 激活值显存占用增加(GPipe) |
| 需要更多梯度累积步骤 |
经验法则:M≥4KM \geq 4KM≥4K(KKK 为 stage 数)通常能将气泡控制在较低水平。
8.3 通信优化
流水线并行中,相邻 stage 之间传递的是激活值张量 和梯度张量,通信模式为点对点(Send/Recv)。
优化手段:
- 通信与计算重叠:在计算当前 micro-batch 时,同时传输上一个 micro-batch 的结果
- 激活值压缩:使用 FP16 甚至更低精度传输激活值
- 合理的设备放置:将相邻 stage 放在网络拓扑中邻近的设备上
8.4 与其他并行策略的组合
在实际的大模型训练系统(如 Megatron-LM、DeepSpeed)中,通常采用 3D 并行:
3D 并行 = 数据并行 × 张量并行 × 流水线并行
典型配置示例(训练一个千亿参数模型,使用 512 张 A100):
- 张量并行度 = 8:在单节点的 8 张 GPU 之间(NVLink 高带宽)
- 流水线并行度 = 8:跨 8 个节点(节点间带宽较低,P2P 通信量小)
- 数据并行度 = 8:512 / (8 × 8) = 8 路数据并行
这种层次化的设计充分利用了不同并行策略对通信带宽的不同需求。
九、主流框架支持
| 框架 | 流水线并行支持 | 调度策略 |
|---|---|---|
| Megatron-LM (NVIDIA) | ✅ 非常成熟 | 1F1B、交错式 1F1B |
| DeepSpeed (Microsoft) | ✅ 完善 | 1F1B、与 ZeRO 结合 |
| FairScale (Meta) | ✅ 支持 | GPipe 风格 |
| PyTorch Native | ✅ torch.distributed.pipelining | 多种调度 |
| ColossalAI | ✅ 支持 | 1F1B、交错式 |
十、总结与展望
| 方案 | 气泡比例 | 显存效率 | 通信量 | 实现复杂度 |
|---|---|---|---|---|
| 朴素流水线 | (K−1)/K(K-1)/K(K−1)/K | 差 | 低 | ★ |
| GPipe | (K−1)/(K−1+M)(K-1)/(K-1+M)(K−1)/(K−1+M) | 较差(需激活重计算) | 低 | ★★ |
| 1F1B | (K−1)/(K−1+M)(K-1)/(K-1+M)(K−1)/(K−1+M) | 好 | 低 | ★★★ |
| 交错式 1F1B | (K−1)/[v(K−1+M)](K-1)/[v(K-1+M)](K−1)/[v(K−1+M)] | 好 | 中 | ★★★★ |
| Zero Bubble | ≈ 0 | 好 | 低 | ★★★★★ |
流水线并行经过数年的发展,已经从简单的模型切分演进为一套精细的调度艺术。从 GPipe 的 micro-batch 思想,到 1F1B 的显存优化,再到 Zero Bubble 的极致气泡消除,每一步都在逼近理论最优。
展望未来,随着模型规模持续增长和硬件架构的演进(如更高带宽的互联、更大的显存),流水线并行的调度策略还将继续进化。特别是在以下方向值得关注:
- 异构流水线:支持不同类型的加速器混合部署
- 弹性流水线:支持动态调整 stage 数量和分配
- 与序列并行的深度结合:处理超长序列场景
- 自适应调度:根据运行时状态动态调整调度策略
参考文献
- Huang et al., GPipe: Efficient Training of Giant Neural Networks using Pipeline Parallelism, NeurIPS 2019
- Narayanan et al., PipeDream: Generalized Pipeline Parallelism for DNN Training, SOSP 2019
- Narayanan et al., Efficient Large-Scale Language Model Training on GPU Clusters Using Megatron-LM, SC 2021
- Qi et al., Zero Bubble Pipeline Parallelism, ICLR 2024
- Rajbhandari et al., ZeRO: Memory Optimizations Toward Training Trillion Parameter Models, SC 2020
本文作者注 :流水线并行是大模型训练中一个看似简单实则精妙的技术。理解它的关键在于认识到------计算资源的闲置就是最大的浪费 ,而所有调度优化的本质都是在与气泡做斗争。希望本文能帮助读者建立起对流水线并行的完整认知。
后记
2026年4月17日16点10分于上海,在opus 4.6辅助下完成。