3. 流水线并行(Pipeline Parallelism):GPipe、PipeDream 等经典方案对比
流水线并行,说白了就是把一个大模型切成好几段,每段放在不同的GPU上。你想想看,一个几百层的Transformer,单卡根本塞不下。这时候就得靠流水线并行来救场。
我最早接触这个概念是在2019年,当时要部署一个GPT-2级别的模型。单卡显存不够,数据并行又解决不了模型放不下的问题。嗯,那时候GPipe刚出来没多久,我就硬着头皮上了。
3.1 流水线并行的核心思想
流水线并行的思路其实很简单:
- 把模型按层切分成多个阶段(Stage)
- 每个阶段分配到不同的GPU上
- 数据像流水线一样,依次经过每个阶段
举个例子,一个12层的Transformer,切成4段,每段3层。GPU0负责第1-3层,GPU1负责第4-6层,以此类推。前向传播时,数据从GPU0流到GPU3。反向传播时,梯度从GPU3流回GPU0。
关键点:流水线并行解决的是"模型太大,单卡放不下"的问题。它跟数据并行是两码事——数据并行解决的是"数据太多,单卡算不完"。
3.2 GPipe:简单粗暴的流水线方案
GPipe是Google在2019年提出的。它的设计哲学就一个字——"等"。
具体怎么做呢?GPipe把一个小批次(micro-batch)切成多个微批次(micro-batch)。比如一个批次有32条数据,切成4个微批次,每个8条。然后让这些微批次依次流过流水线。
前向传播时,每个微批次依次经过所有阶段。反向传播时,也是依次进行。等所有微批次都算完了,再统一更新参数。
我刚开始用GPipe时,最头疼的就是显存问题。为什么呢?因为GPipe在前向传播时,会把所有微批次的中间激活值都存下来,等反向传播时再用。这导致显存占用特别高。
避坑指南:我曾经在一个8卡集群上部署GPipe,结果发现显存占用比预期高了3倍。后来一查,原来是微批次数量设太大了。每个微批次的中间激活值都要存,微批次越多,显存占用越大。建议微批次数量不要超过GPU数量的2倍。
GPipe的优点是简单,实现起来不复杂。但缺点也很明显——流水线中有大量空闲时间(bubble)。你想想看,GPU0算完第一个微批次后,要等GPU1算完,才能继续算第二个微批次。这段时间GPU0就闲着。
3.3 PipeDream:让流水线忙起来
PipeDream是微软提出的,它的目标就是减少bubble。怎么做呢?PipeDream用了两个技巧:
- 1F1B调度:一个前向传播,紧接着一个反向传播。不用等所有微批次都前向完再反向。
- 权重同步:每个阶段维护多份权重副本,减少通信开销。
我举个例子你就明白了。在GPipe中,流程是这样的:
GPU0: F1 F2 F3 F4 | B4 B3 B2 B1
GPU1: F1 F2 F3 F4 | B4 B3 B2 B1
GPU2: F1 F2 F3 F4 | B4 B3 B2 B1
F表示前向,B表示反向。竖线表示所有微批次前向完成。你看,GPU0在F4之后要等很久才开始B4。
PipeDream的1F1B调度是这样的:
GPU0: F1 F2 F3 F4 B1 B2 B3 B4
GPU1: F1 F2 F3 F4 B1 B2 B3 B4
GPU2: F1 F2 F3 F4 B1 B2 B3 B4
GPU0算完F1后,马上开始B1。这样流水线就紧凑多了,bubble时间大幅减少。
个人经验:我在实际部署中,PipeDream比GPipe快了大概30%。但PipeDream的权重同步策略比较复杂,调试起来比较费劲。如果你团队不大,我建议先从GPipe上手,等熟悉了再换PipeDream。
3.4 两种方案的对比
| 维度 | GPipe | PipeDream |
|---|---|---|
| 调度策略 | 先全部前向,再全部反向 | 1F1B交替调度 |
| bubble占比 | 较高(约30-50%) | 较低(约10-20%) |
| 显存占用 | 高(需存所有中间激活) | 低(只需存当前微批次) |
| 实现复杂度 | 简单 | 中等 |
| 权重一致性 | 严格一致 | 近似一致(有多个副本) |
| 适用场景 | 小规模集群,快速验证 | 大规模集群,追求吞吐 |
你看这个表格,GPipe和PipeDream各有千秋。GPipe简单可靠,适合快速验证。PipeDream效率高,但实现起来麻烦一些。
3.5 实际部署中的选择建议
我个人习惯这样选:
- 模型在100亿参数以下:用GPipe就够了。bubble虽然大,但模型小,影响不大。
- 模型在100亿到1000亿参数:建议用PipeDream。bubble节省的时间很可观。
- 模型超过1000亿参数:光靠流水线并行不够,还得结合张量并行。这时候PipeDream的1F1B调度优势更明显。
避坑指南:我曾经在一个项目里,为了追求极致性能,强行上了PipeDream。结果调试了整整两周,各种权重不一致的问题。后来发现,其实用GPipe配合梯度累积,效果也差不多。所以别盲目追求新技术,适合的才是最好的。
3.6 流水线并行的未来趋势
现在业界在流水线并行上,主要往两个方向走:
- 自动切分:不用手动指定每层放哪张卡,让框架自动算最优切分方案。
- 异构流水线:不同阶段用不同型号的GPU。比如前几层计算量大,用A100;后几层计算量小,用V100。
我记得去年参加一个技术分享,有团队已经在尝试用强化学习来优化流水线切分。效果还不错,比人工切分快了15%左右。
嗯,流水线并行这块,核心就是平衡好bubble和显存。GPipe和PipeDream是两个经典方案,理解透了,其他变种方案也就触类旁通了。
核心总结:流水线并行的本质是用空间换时间——把模型切开放到多卡上,通过调度策略减少GPU空闲。GPipe适合快速上手,PipeDream适合追求极致性能。选哪个,看你的场景和团队能力。