0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

以Gpipe作为流水线并行的范例进行介绍

jf_pmFSk4VX 来源:GiantPandaCV 2023-05-25 11:41 次阅读

回顾ChatGPT的发展历程,我们可以总结出大语言模型(LLM)取得惊艳效果的要点(重要性从高到低排序):

愿意烧钱,且接受“烧钱 != 好模型”的现实

高质量的训练语料

高效的分布式训练框架和充沛优质的硬件资源

算法的迭代创新

在大模型训练这个系列里,我们将一起探索学习几种经典的分布式并行范式,包括流水线并行(Pipeline Parallelism),数据并行(Data Parallelism)和张量并行(Tensor Parallesim。微软开源的分布式训练框架FastSpeed,融合了这三种并行范式,开发出3D并行的框架,实现了千亿级别模型参数的训练。

本篇文章将探索流水线并行,经典的流水线并行范式有Google推出的Gpipe,和微软推出的PipeDream。两者的推出时间都在2019年左右,大体设计框架一致。主要差别为:在梯度更新上,Gpipe是同步的,PipeDream是异步的。异步方法更进一步降低了GPU的空转时间比。虽然PipeDream设计更精妙些,但是Gpipe因为其“够用”和浅显易懂,更受大众欢迎(torch的PP接口就基于Gpipe)。因此本文以Gpipe作为流水线并行的范例进行介绍。内容包括:

1、优化目标
2、模型并行
3、流水线并行

切分micro-batch

Re-materialization (active checkpoint)

4、实验效果

推荐阅读: ChatGPT技术解析系列之:训练框架InstructGPT ChatGPT技术解析系列之:GPT1、GPT2与GPT3 ChatGPT技术解析系列之:赋予GPT写代码能力的Codex

一、优化目标

当你从单卡穷人变成多卡富翁时,你做分布式训练的总体目标是什么呢?(虽然手握一张A100怎么能是穷呢)

能训练更大的模型。理想状况下,模型的大小和GPU的数量成线性关系。即GPU量提升x倍,模型大小也能提升x倍。

能更快地训练模型。理想状况下,训练的速度和GPU的数量成线性关系。即GPU量提升x倍,训练速度也能提升x倍。

这是目标,也是难点,难在于:

训练更大的模型时,每块GPU里不仅要存模型参数,还要存中间结果(用来做Backward)。而更大的模型意味着需要更多的训练数据,进一步提高了中间结果的大小。加重了每块GPU的内存压力。我们将在下文详细分析这一点。(对应着GPU中的内存限制)

网络通讯开销。数据在卡之间进行传输,是需要通讯时间的。不做设计的话,这个通讯时间可能会抹平多卡本身带来的训练速度提升。(对应着GPU间的带宽限制)

明确这两个训练目标后,我们来看并行范式的设计者,是如何在现有硬件限制的条件下,完成这两个目标的。

二、模型并行

当你有一个单卡装不下的大模型时,一个直接的解决办法是,把模型隔成不同的层,每一层都放到一块GPU上,如下图:

f8d25756-fa29-11ed-90ce-dac502259ad0.png

此时,模型做一轮forward和backward的过程如下

f8d97a2c-fa29-11ed-90ce-dac502259ad0.png

其中下标表示GPU编号,例如表示在GPU0上做foward,表示在GPU0上做backward。图中的横轴表示timestep。

这张图的含义是:我在GPU0上做完一次forward,然后将GPU0上最后一层的输入传给GPU1,继续做forward,直到四块GPU都做完forward后,我再依次做backward。等把四块GPU上的backward全部做完后,最后一个时刻我统一更新每一层的梯度。

这样做确实能训更大的模型了,但也带来了两个问题:


(1)GPU利用度不够。

f8e2c532-fa29-11ed-90ce-dac502259ad0.png

如图,阴影部分所表示的时间段里,总有GPU在空转。在Gpipe中,将阴影部分定义为bubble。我们来计算一下bubble。假设有块GPU,而单块GPU上做一次forward和backward的时间为:。则:

图中灰色长方形的整体面积为:(宽=,长=)

图中实际在做forward和backward的面积为:

图中阴影部分的面积为:

图像阴影部分的占比为:

则我们定义出bubble部分的时间复杂度为:,当K越大,即GPU的数量越多时,空置的比例接近1,即GPU的资源都被浪费掉了。因此这个问题肯定需要解决。

(2)中间结果占据大量内存

f8eb1a8e-fa29-11ed-90ce-dac502259ad0.png

在做backward计算梯度的过程中,我们需要用到每一层的中间结果z。假设我们的模型有L层,每一层的宽度为d,则对于每块GPU,不考虑其参数本身的存储,额外的空间复杂度为。从这个复杂度可以看出,随着模型的增大,N,L,d三者的增加可能会平滑掉K增加带来的GPU内存收益。因此,这也是需要优化的地方。

三、训练数据与训练方法

朴素的模型并行存在GPU利用度不足,中间结果消耗内存大的问题。而Gpipe提出的流水线并行,就是用来解决这两个主要问题的。

3.1 切分micro-batch

流水线并行的核心思想是:在模型并行的基础上,进一步引入数据并行的办法,即把原先的数据再划分成若干个batch,送入GPU进行训练。未划分前的数据,叫mini-batch。在mini-batch上再划分的数据,叫micro-batch

图例如下:

f8f34394-fa29-11ed-90ce-dac502259ad0.png

其中,第一个下标表示GPU编号,第二个下标表示micro-batch编号。假设我们将mini-batch划分为M个,则流水线并行下,bubble的时间复杂度为(推导过程略,可参照第二部分的bubble推导流程)。Gpipe通过实验证明,当$M>=4K时,bubble产生的空转时间占比对最终训练时长影响是微小的,可以忽略不计。

将batch切好,并逐一送入GPU的过程,就像一个流水生产线一样(类似于CPU里的流水线),因此也被称为Pipeline Parallelism

3.2 re-materialization(active checkpoint)

解决了GPU的空置问题,提升了GPU计算的整体效率。接下来,就要解决GPU的内存问题了。

前文说过,随着模型的增加,每块GPU中存储的中间结果也会越大。对此,Gpipe采用了一种非常简单粗暴但有效的办法:用时间换空间,在论文里,这种方法被命名为re-materalization,后人也称其为active checkpoint。

具体来说,就是几乎不存中间结果,等到backward的时候,再重新算一遍forward,图例如下:

f8faa2ba-fa29-11ed-90ce-dac502259ad0.png

每块GPU上,我们只保存来自上一块的最后一层输入z,其余的中间结果我们算完就废。等到backward的时候再由保存下来的z重新进行forward来算出。

现在我们来计算每块GPU峰值时刻的内存:

每块GPU峰值时刻存储大小 = 每块GPU上的输入数据大小 + 每块GPU在forward过程中的中间结果大小

每块GPU上固定需要保存它的起始输入,我们记起始输入为(即mini-batch的大小)。

每个micro-batch是流水线形式进来的,算完一个micro-batch才算下一个。在计算一个micro-batch的过程中,我们会产生中间变量,它的大小为(其中M为micro-batch个数)。

因此,每块GPU峰值时刻的空间复杂度为

将其与朴素模型并行中的GPU空间复杂度比较,可以发现,由于采用了micro-batch的方法,当L变大时,流水线并行相比于朴素模型并行,对GPU内存的压力显著减小。

如果你使用Pytorch提供的PP接口,其中有一个参数叫checkpoint,就是用来做这一项的。

f9036008-fa29-11ed-90ce-dac502259ad0.png

最后,再提一点,在micro-batch的划分下,我们在计算Batch Normalization时会有影响。Gpipe的方法是,在训练时计算和运用的是micro-batch里的均值和方差,但同时持续追踪全部mini-batch的移动平均和方差,以便在测试阶段进行使用。Layer Normalization则不受影响。

四、实验效果

回顾第二部分的两个目标,Gpipe真的实现了吗?如果实现不了,又是因为什么原因呢?我们来看下实验效果。

4.1 GPU数量 VS 模型大小

f90e9568-fa29-11ed-90ce-dac502259ad0.png

Gpipe分别在AmoebaNet(图像)和Transformer(自然语言)两个大模型上做了实验。

Naive表示单卡

Pipeline-N表示re-materalization + N卡。

AmeobaNet-D和Trasformer-L一行表示超参数的量

of Model Parameter表示模型的参数量

Total Model Parameter Memory表示模型参数所占内存大小

Peak Activation Memory表示峰值时中间结果大小。可以发现,中间结果占据的内存大小是相当可观的。

从实验结果里,我们可以发现:

在Transformer上,Gpipe基本实现了模型大小(参数量)和GPU个数之间的线性关系。例如从32卡增到128卡时,模型的大小也从21.08B增加到82.9B,约扩4倍

对AmoebaNet而言,却没有完全实现线性增长。例如从4卡到8卡,模型大小从1.05B到1.8B,不满足2倍的关系。本质原因是AmoebaNet模型在切割时,没有办法像Transformer一样切得匀称,保证每一块GPU上的内存使用率是差不多的。因此对于AmoebaNet,当GPU个数上升时,某一块GPU可能成为木桶的短板。

GPU数量 VS 训练速度

(1)关掉NVlinks

为了验证Gpipe框架带来的收益,实验中关掉了NVlinks(GPU间快速通信的桥梁。估计是通过强迫GPU先连CPU然后再连别的GPU做到的)。关掉的意义在于说明,不靠硬件本身的高效通讯带来的收益,Gpipe一样能做的很好。实验效果如下:

f91b2fda-fa29-11ed-90ce-dac502259ad0.png

M=32表示micro-batch的数量为32,K表示GPU数量。从实验结果可知,在关掉NVlinks的情况下,Gpipe一样也能实现随着GPU数量的增加,训练速度也增加的效果。虽然这两者间不是线性的。同样,因为模型切割不均的原因,AmoebaNet的表现不如Transformer。

(2)开启NVlinks,并寻找最佳M

f923b40c-fa29-11ed-90ce-dac502259ad0.png

当重新开启NVlinks后,我们来看M的大小(即流水线的核心)对训练速度的影响。

当M=1的时候,如前文所说,GPU的空置率太高,因此两个模型都没有实现训练速度和GPU个数间的线性关系

当M=4时,表现明显好转。

当M=32时,表现最佳,且Transformer基本实现了训练速度和GPU个数的线性关系。

4.3 Gpipe下时间消耗分布

f92ddeaa-fa29-11ed-90ce-dac502259ad0.png

对每块GPU来说,约2/3的时间,是真正花在计算上的。

其余1/3的时间,大部分花在re-materalization策略下的重计算上。因为采用流水线的方法,bubble的时间也被压缩到很短,可以忽略不计。

审核编辑:彭静
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 3D
    3D
    +关注

    关注

    9

    文章

    2756

    浏览量

    106455
  • 开源
    +关注

    关注

    3

    文章

    2985

    浏览量

    41718
  • 语言模型
    +关注

    关注

    0

    文章

    434

    浏览量

    10044

原文标题:图解大模型训练之:流水线并行(Pipeline Parallelism),以GPipe为例

文章出处:【微信号:GiantPandaCV,微信公众号:GiantPandaCV】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    什么是流水线?ARM处理器流水线简析

    流水线是为了提高效率,能并发同时进行多个任务。
    的头像 发表于 09-05 15:39 1243次阅读
    什么是<b class='flag-5'>流水线</b>?ARM处理器<b class='flag-5'>流水线</b>简析

    FPGA中的流水线设计

    令预取、 译码、 执行、 写回结果, openrisc采用的是 5 级整数流水线。当然它们的核心思想都是利用并行执行提高效率。总结一下,流水线就是插入寄存器,面积换取速度。`
    发表于 10-26 14:38

    基于流水线技术的并行高效FIR滤波器设计

    基于流水线技术的并行高效FIR滤波器设计 基于流水线技术,利用FPGA进行并行可重复配置高精度的FIR滤波器设计。使用VHDL可以很方便地
    发表于 03-28 15:12 740次阅读
    基于<b class='flag-5'>流水线</b>技术的<b class='flag-5'>并行</b>高效FIR滤波器设计

    什么是流水线技术

    什么是流水线技术 流水线技术
    发表于 02-04 10:21 3739次阅读

    流水线中的相关培训教程[1]

    流水线中的相关培训教程[1]  学习目标     理解流水线中相关的分类及定义;
    发表于 04-13 15:56 885次阅读

    基于流水线并行FIR滤波器设计

    基于流水线技术,利用FPGA进行并行可重复配置高精度的 FIR滤波器 设计。使用VHDL可以很方便地改变滤波器的系数和阶数。在DSP中采用这种FIR滤波器的设计方法可以充分发挥FPGA的优势。
    发表于 07-18 17:09 63次下载
    基于<b class='flag-5'>流水线</b>的<b class='flag-5'>并行</b>FIR滤波器设计

    CPU流水线的定义

    cpu流水线技术是一种将指令分解为多步,并让不同指令的各步操作重叠,从而实现几条指令并行处理,以加速程序运行过程的技术。
    发表于 12-14 15:29 4524次阅读

    电镀流水线的PLC控制

    电镀流水线的PLC控制电镀流水线的PLC控制电镀流水线的PLC控制
    发表于 02-17 17:13 36次下载

    Verilog基本功之:流水线设计Pipeline Design

    ,并暂存中间数据的方法。 目的是将一个大操作分解成若干的小操作,每一步小操作的时间较小,所以能提高频率,各小操作能并行 执行,所以能提高数据吞吐率(提高处理速度)。 二. 什么时候用流水线设计 使用流水线一般是时序比较紧张
    发表于 09-25 17:12 4540次阅读

    FPGA之为什么要进行流水线的设计

    流水线又称为装配线,一种工业上的生产方式,指每一个生产单位只专注处理某一个片段的工作。以提高工作效率及产量;按照流水线的输送方式大体可以分为:皮带流水装配线、板链线、倍速链、插件线、网带线、悬挂线及滚筒
    的头像 发表于 11-28 07:04 3282次阅读

    各种流水线特点及常见流水线设计方式

    按照流水线的输送方式大体可以分为:皮带流水装配线、板链线、倍速链、插件线、网带线、悬挂线及滚筒流水线这七类流水线
    的头像 发表于 07-05 11:12 6337次阅读
    各种<b class='flag-5'>流水线</b>特点及常见<b class='flag-5'>流水线</b>设计方式

    嵌入式_流水线

    流水线一、定义流水线是指在程序执行时多条指令重叠进行操作的一种准并行处理实现技术。各种部件同时处理是针对不同指令而言的,他们可同时为多条指令的不同部分
    发表于 10-20 20:51 6次下载
    嵌入式_<b class='flag-5'>流水线</b>

    GTC 2023:深度学习之张星并行流水线并行

    张星并行流水线并行技术通常被描述为模型并行,在开源社区中,最著名的两个系统是NVIDIA的Megatron- M和Microsoft的DeepSpeed。
    的头像 发表于 03-23 17:21 1448次阅读
    GTC 2023:深度学习之张星<b class='flag-5'>并行</b>和<b class='flag-5'>流水线</b><b class='flag-5'>并行</b>

    什么是流水线 Jenkins的流水线详解

    jenkins 有 2 种流水线分为声明式流水线与脚本化流水线,脚本化流水线是 jenkins 旧版本使用的流水线脚本,新版本 Jenkin
    发表于 05-17 16:57 668次阅读

    Google GPipe为代表的流水线并行范式

    但在实际应用中,流水线并行并不特别流行,主要原因是模型能否均匀切割,影响了整体计算效率,这就需要算法工程师做手调。因此,今天我们来介绍一种应用最广泛,最易于理解的并行范式:数据
    的头像 发表于 05-26 14:40 629次阅读
    Google <b class='flag-5'>GPipe</b>为代表的<b class='flag-5'>流水线</b><b class='flag-5'>并行</b>范式