GPipe:微批流水线并行
GPipe: Easy Scaling with Micro-Batch Pipeline Parallelism · Yanping Huang 等(Google)· arXiv 2018 · Ilya 推荐书单 i26
Ilya 为什么选它
缩放定律(i25)说「要大」,工程立刻反问:「大」到一张显卡装不下怎么办?深度网络每一层的参数、还有层与层之间流传的中间结果,都要占显存;模型一大,单卡显存先亮红灯——这不是「练得慢」,而是「根本放不下」。
GPipe 给出的答案朴素而漂亮:装不下就切开。网络按层切成几段,各段住一张卡;数据不等整批到齐,而是拆成小份「微批」排队依次灌入。它没有发明什么深奥理论,却解决了一个绕不开的物理约束,是大模型训练「并行切分」思路的代表。
在书单里,它与 i25 恰好互补:一个论证「必须变大」,一个回答「怎么装得下」。想大,先解决装得下——工程与科学在这两篇之间咬合得严丝合缝。
从生活说起
想象洗衣房里有三台机器:洗衣机、烘干机、折叠台,一批衣物要走完三步。最笨的干法是「一批做到底」:第一批洗 30 分钟、烘 30 分钟、叠 30 分钟。全程里,洗衣机在第一批烘干、折叠时闲着,烘干机在第一批折叠时闲着——大部分时间,三台机器里总有两台在发呆。
聪明的干法是流水作业:第一批一进烘干机,第二批立刻进洗衣机;第一批上折叠台,第二批进烘干机,第三批进洗衣机。任一时刻三台机器都在干活,空转只发生在开工和收工的边角。同样的活儿,时间几乎省一半。
GPipe 把洗衣房搬进了显卡集群:洗衣机、烘干机、折叠台对应网络切出的三段,各占一张卡;一批批衣物就是数据微批,排队依次流过每张卡。
核心思想拆解
问题的本质是显存:模型大到单卡装不下。最直接的切法是「按层切分」——把网络沿着纵深方向切成几段,比如前几层放第一张卡,中间几层放第二张卡,尾部几层放第三张卡。数据像接力一样依次穿过每张卡,每张卡只须容纳自己那一段。
但单纯接力有个尴尬:第一张卡算的时候,第二、三张卡闲着;轮到第三张卡算时,前两张又闲了——并行变成了轮流。GPipe 的关键一步是把每一批数据再拆成更小的「微批」(Micro-Batch):第一段算微批 2 的时候,第二段正在算微批 1,第三段刚送走上一份——流水线灌满之后,每张卡都有活干,空转被压到开工与收工的边角。
效果:多张普通卡协作,能训练远超单卡容量的大模型。切口越多、微批越细,流水线越接近「满负荷」,但每段之间的接力缝永远存在——就像洗衣房开工时洗衣机先转、收工时折叠台最后收尾,这一点点空档是流水线的天然成本。
动手算一算
算一笔洗衣房的时间账(示意数字)。设洗、烘、叠各需 30 分钟,共 4 批衣物。「一批做到底再做下一批」:每批 30×3 = 90 分钟,4 批共 360 分钟——大部分时间三台机器里总有两台在发呆。改成流水作业呢?
串行:30 × 3 × 4 = 360 分钟;流水作业:30 × (4 + 3 − 1) = 180 分钟
流水作业为什么是 30×(4+3−1)?4 是批数,3 是工位数,减 1 是因为第一批只经过 1 个工位就开始往下传、不必等满 3 个工位。批数越多,边角空档占比越小:10 批时流水线要 30×(10+3−1) = 360 分钟,串行却要 30×3×10 = 900 分钟——效率差距越拉越大。
对应回 GPipe:把 1 个大批拆成 8 个微批,就像把一大桶水分成 8 杯依次倒——每次接力的步子小了,等待自然就短了;网络切出的段数相当于工位数,微批数相当于批数,算式完全同构。
它改变了什么
论文效果 GPipe 让「模型大小」的上限从「单卡显存」改写成「你能凑到多少张卡」。多卡协作从此可以训练远超单卡容量的大模型,大模型训练的「并行切分」思路就此立住了代表之作。
本站推断 它的贡献更在于思路示范:硬件约束不是天花板,而是可以拆解、排队、流转的调度题。这种「先把大问题切成能装下的小块」的思维方式,贯穿了此后大模型基础设施的设计;它让 i25 缩放定律所呼唤的规模化训练真正落了地。
系列内相关阅读:i25 缩放定律(为什么必须变大)、i24 Deep Speech 2(大规模 GPU 集群训练的先行实践)、i27 机器超级智能(书单压轴:规模之后的问题)。