并行计算范式:数据并行、模型并行与流水线并行

说到大规模训练,并行计算是绕不开的话题。我刚开始接触分布式训练时,也一度被各种并行方式搞晕。其实说白了,并行计算的核心就一句话:把大任务拆成小任务,分给多个设备一起干。但怎么拆、拆完怎么协调,这里面的门道可不少。

今天咱们就聊聊三种最主流的并行范式——数据并行、模型并行和流水线并行。这三种方式,我在不同项目里都踩过坑,也积累了一些实战经验,分享给你。

数据并行:最直观的并行方式

数据并行,顾名思义,就是把数据切分到多个设备上。每个设备都有一份完整的模型副本,各自处理不同的数据批次。最后再把梯度汇总,更新模型参数。

嗯,这里要注意:数据并行虽然直观,但通信开销是个大问题。每个设备都要把梯度广播出去,设备越多,通信压力越大。

核心公式:梯度更新 = 1/N * Σ(grad_i),其中 N 是设备数量,grad_i 是第 i 个设备的梯度。

我在项目中遇到过这样一个场景:用 64 张 GPU 做数据并行训练一个 BERT 模型。结果发现,随着 GPU 数量增加,加速比并没有线性增长。为什么?因为通信开销占了很大比例。尤其是 AllReduce 操作,每次都要等所有设备算完才能开始通信。

数据并行有几个关键点需要关注:

  • 同步 vs 异步:同步模式保证梯度一致性,但慢;异步模式快,但可能收敛不稳定。我个人习惯用同步模式,除非网络带宽特别紧张。
  • 梯度累积:当单卡显存放不下大 batch 时,可以用梯度累积模拟大 batch 效果。但要注意,梯度累积会增加训练步数,影响收敛速度。
  • 混合精度:数据并行时,混合精度能显著减少通信量。FP16 的梯度只有 FP32 的一半,通信时间直接减半。

避坑指南:我曾经在数据并行时忽略了 batch size 对学习率的影响。batch size 翻倍,学习率也要相应调整。否则模型可能不收敛,或者收敛到次优解。

模型并行:当模型放不下时

模型并行解决的是另一个问题:模型太大,单卡显存放不下。比如 GPT-3 这种千亿参数模型,单卡根本装不下。这时候就需要把模型切分到多个设备上。

模型并行有两种常见方式:

  1. 层内并行:把一层网络的参数切分到多个设备。比如一个 4096 维的全连接层,可以切成 4 份,每份 1024 维,分布在 4 张卡上。
  2. 层间并行:把不同层分配到不同设备。比如第 1-10 层放在 GPU0,第 11-20 层放在 GPU1。

你想想看,层内并行的问题是什么?通信太频繁了。每次前向传播和反向传播,设备之间都要交换中间结果。我做过一个实验,层内并行时,通信时间占了总训练时间的 60% 以上。

层间并行相对好一些,但又有新的问题:设备利用率不均衡。前面的设备算完了,后面的设备还在忙,导致大量设备空闲等待。

并行方式 优点 缺点 适用场景
层内并行 负载均衡好 通信开销大 单层参数极大
层间并行 通信量小 设备利用率低 层数多、每层参数适中

注意:模型并行对网络带宽要求极高。如果用的是千兆以太网,建议别碰模型并行。NVLink 或 InfiniBand 是基本要求。

流水线并行:让设备忙起来

流水线并行是对模型并行的一种改进。它的思路是把模型分成多个阶段(stage),每个阶段放在一个设备上。数据像流水线一样,依次经过各个阶段。

举个例子:假设模型有 4 层,分成 4 个 stage,每个 stage 放在一张卡上。第一个 batch 进入 stage1 计算,算完后传给 stage2,同时 stage1 开始处理第二个 batch。这样,所有设备都能同时工作,利用率大幅提升。

但流水线并行也有自己的问题:

  • 气泡(bubble):流水线启动和结束时,部分设备会空闲。比如第一个 batch 进入 stage4 时,stage1 已经空闲了。气泡大小和 stage 数量成正比。
  • 负载不均衡:如果各 stage 的计算量不一样,快的 stage 要等慢的 stage,形成新的气泡。

我记得在训练一个 100 层的 ResNet 时,用了 4 个 stage 的流水线并行。结果发现气泡占了总时间的 15% 左右。后来改用 GPipe 的微批次策略,把每个 batch 再切分成更小的 micro-batch,气泡才降到了 5% 以下。

关键技巧:流水线并行中,micro-batch 的数量一般设为 stage 数量的 4-8 倍。这样能有效减少气泡比例。

三种范式的对比与选择

说了这么多,到底该用哪种?我个人的经验是:

  • 模型能放进单卡:优先用数据并行。简单、稳定、效果好。
  • 模型太大,单卡放不下:考虑模型并行或流水线并行。如果网络带宽好,用模型并行;如果带宽一般,用流水线并行。
  • 超大规模训练:三种方式混合使用。比如数据并行 + 流水线并行,或者数据并行 + 模型并行 + 流水线并行。

下面这张图展示了三种范式的核心逻辑:

三种并行范式核心逻辑 数据并行 数据1 数据2 模型 模型 梯度 梯度 AllReduce 模型并行 完整数据 层1-5 层6-10 激活值 激活值 设备间通信 流水线并行 Stage1: 层1-3 Stage2: 层4-6 Stage3: 层7-9 Stage4: 层10-12 数据流方向

最后说一句:没有银弹。每种并行方式都有其适用场景,关键是根据你的模型大小、硬件配置和训练目标来选。我见过不少团队盲目追求大规模并行,结果训练效率反而下降了。记住,并行不是目的,加速才是。

实战建议:刚开始做分布式训练时,先从数据并行入手。等熟悉了通信模式和性能瓶颈,再尝试更复杂的并行策略。一步一个脚印,稳扎稳打。

想要更多资料,联系可可