Pipeline Parallelism
流水线并行会将模型的连续层放置在不同 GPU 上,并让微批次在各 GPU 间流动,从而训练大于单个 GPU 容量的模型。
流水线并行是一种分布式训练技术,它按深度将神经网络拆分为连续的层组(称为阶段),将每个阶段放在独立的 GPU上,并将激活值从一个阶段传递到下一个阶段。为了让每个 GPU 都保持繁忙,每个批次会切分成更小的微批次,像装配线上的零件一样流经各个阶段。这种方法也称为层间模型并行。由 Yanping Huang 领导的 Google 研究人员通过 2018 年 11 月推出的 GPipe推广了微批次方法:他们训练了一个拥有 5.57 亿参数的 AmoebaNet,在 ImageNet上取得 84.4% 的 top-1 准确率,还训练了一个拥有 60 亿参数、128 层的多语言翻译 Transformer。
微批次与流水线气泡#
如果一次只处理一个批次,那么只有一个阶段在工作,其余阶段都在等待:阶段 2 必须等阶段 1 完成后才能开始;进行反向传播时,顺序则会反过来。微批次使阶段 1 在把第一个微批次交给阶段 2 后,就能立即开始处理第二个微批次。流水线填充和排空时留下的空闲时段称为气泡。打印一个包含 4 个阶段和 6 个微批次的 GPipe 风格前向调度,可以看到它的形状:
stages, micro_batches = 4, 6
steps = micro_batches + stages - 1 # time steps until the last micro-batch leaves the last stage
for stage in range(stages):
row = ""
for t in range(steps):
m = t - stage # stage s starts micro-batch m once stage s-1 hands it over
row += f" F{m}" if 0 <= m < micro_batches else " ."
print(f"GPU {stage}:{row}")
# Every stage idles for stages - 1 of the steps, in the forward and again in the backward pass
bubble = (stages - 1) / steps
print(f"Idle fraction: {bubble:.0%}")输出呈阶梯状:GPU 0 在九个步骤中的前六步执行前向传播 F0 至 F5,随后等待;GPU 3 等待三步后才开始执行 F0;最后一行是 Idle fraction: 33%。气泡占比为(阶段数 − 1)/(微批次数 + 阶段数 − 1),因此,同样经过这 4 个阶段的 24 个微批次会将气泡占比降至 11%。所有微批次的梯度会先累加,再执行一次优化器更新;这与梯度累积的计算方式相同,因此更新结果等同于使用完整批次训练。GPipe 还会丢弃每个阶段内部的激活值,并在反向传播时重新计算,这是梯度检查点的一种形式。
流水线调度方案#
后续的调度方案会重新安排相同的工作,以节省内存或缩小气泡:
- 1F1B:由 PipeDream 系统于 2018 年引入。流水线填满后,它会让每个阶段交替处理一个前向微批次和一个反向微批次。这样一来,每个阶段最多只需保存与阶段数相同的微批次激活值,而不是保存所有激活值。
- 交错式 1F1B:让每个 GPU 负责多个较小且彼此不相邻的阶段。NVIDIA 的 Megatron-LM 团队报告称,采用这种方案后吞吐量提高了 10% 以上,并在 3072 个 GPU 上以 502 petaFLOP/s 的速度训练了一个 1 万亿参数模型,达到峰值算力的 52%。
- 零气泡:将反向传播拆分为阶段输入的梯度(前一个阶段需要它)和权重的梯度(可用于填补之后的空闲时段)。在相似的内存预算下,其吞吐量比 1F1B 最多高出 23%。
PyTorch 在其流水线 API中以 ScheduleGPipe、Schedule1F1B、ScheduleInterleaved1F1B、ScheduleInterleavedZeroBubble 和 ScheduleDualPipeV 提供这些方案,该 API 也能将模型拆分为多个阶段。DualPipe 来自 DeepSeek-V3;其团队运行了 16 个流水线阶段,并用它来重叠计算与通信、缩小气泡。
流水线并行的适用场景#
各阶段每个微批次只在边界处交换一次激活值,因此,与需要在每一层内部通信的张量并行相比,流水线并行更能适应服务器之间较慢的连接。因此,大规模训练通常会将两者结合使用。Meta 训练 Llama 3 405B 时,在每台 8-GPU 服务器内采用 8 路张量并行,在服务器之间使用 16 个流水线阶段,并在 64 至 128 个副本间使用数据并行;vLLM 等服务引擎也会在大型语言模型(LLM)需要多个节点时采用同样的拆分方式。速度最慢的阶段决定整个流水线的速度;语言模型的首尾阶段还要负责嵌入表和输出层,因此 Llama 3 为这两个阶段各少分配了一层 Transformer。
相关方法会以不同方式拆分工作:
- 张量并行:拆分每一层内部的权重矩阵,让每个 GPU 都参与每一层的计算。
- 上下文并行:将长输入序列分配到多个 GPU 上。
- 拆分学习:同样按深度拆分网络,但拆分边界位于不同组织之间,这样数据所有者就无需向运行后续层的服务器发送原始数据。
数据并行会让每个 GPU 都保存所有层,而是拆分批次;如果模型能装进单个设备,这通常就够用了。Ultralytics YOLO26便是通过这种方式在多个 GPU 上训练的:在训练模式下使用 device=[0, 1, 2, 3] 和 batch=64 时,每个 GPU 都会用 16 张图像运行完整的目标检测模型,而 PyTorch DistributedDataParallel 会在每次反向传播后跨 GPU 对梯度求平均。










