首页 > 其他分享 >流水线并行(Pipeline Parallelism)原理详解

流水线并行(Pipeline Parallelism)原理详解

时间:2024-09-30 17:49:45浏览次数:3  
标签:Pipeline GPipe 模型 并行 传递 详解 Parallelism GPU microbatches

文章目录


0. 概览

数据并行(Data Parallelism):在不同的GPU上运行同一批数据的不同子集;

流水并行(Pipeline Parallelism):在不同的GPU上运行模型的不同层;

模型并行(Model Parallelism):将单个数学运算(如矩阵乘法)拆分到不同的GPU上运行;

流水线并行(Pipeline Parallelism)是一种在分布式计算环境中实现模型并行的技术,主要用于深度学习领域,特别是在处理大规模神经网络模型时。通过将模型的不同部分(如神经网络的层)分配到不同的计算节点上,流水线并行能够在不牺牲训练效率的情况下,利用集群中的多台机器共同完成模型训练。

数据并行参考:
《训练中的数据并行DP详细讲解》

1. 简单流水并行

我们将模型拆分成多个部分,并将每个部分分配给一个 GPU。然后,我们在小批量上进行常规训练,在拆分模型的边界处插入通信步骤。

我们以 4 层顺序模型为例:
o u t p u t = L 4 ( L 3 ( L 2 ( L 1 ( i n p u t ) ) ) ) output=L_4(L_3(L_2(L_1(input)))) output=L4​(L3​(L2​(L1​(input))))

我们将计算划分到两个 GPU 上,如下所示:

  • GPU1 计算:

i n t e r m e d i a t e = L 2 ( L 1 ( i n p u t ) ) intermediate = L_2(L_1(input)) intermediate=L2​(L1​(input))

  • GPU2 计算:

o u t p u t = L 4 ( L 3 ( i n t e r m e d i a t e ) ) output=L_4(L_3(intermediate)) output=L4​(L3​(intermediate))

前向传递,itermediate 在 GPU1 上进行计算并将结果张量传输到 GPU2。然后,GPU2 计算模型的输出并开始反向传递。

反向传递,intermediateGPU2 的梯度发送到 GPU1。然后,GPU1 根据发送的梯度完成反向传递。

流水线并行卵石图

在上图中,我们可以观察到一些简单模型并行的低效率。

  1. GPU 利用率低:在任何给定时间,只有一个 GPU 处于繁忙状态,而另一个 GPU 处于空闲状态。低利用率表明可以通过将有用的工作分配给当前处于空闲状态的 GPU 来加快训练速度。
  2. 通信和计算不交错:当我们通过网络发送中间输出 (FWD) 和梯度 (BWD) 时,没有 GPU 执行任何操作。
  3. 高内存需求:GPU1 一直到最后都需要缓存整个批次的激活状态。如果批量很大,这可能会产生内存问题。

下面介绍 GPipe 算法,与简单流水并行算法相比,该算法的 GPU 利用率要高得多。

2. GPipe 算法

GPipe 通过将每个 minibatch 分割成更小、大小相等的 microbatches 来提高效率。我们可以为每个 microbatches 独立计算前向和反向传递。如果我们将每个 microbatches 的梯度相加,我们就会得到整个批次的梯度。该过程称为梯度积累

由于每一层只存在于一个 GPU 上,因此 microbatches 梯度的累加可以在本地执行,无需任何通信。

让我们考虑一个跨 4 个 GPU 划分的模型。对于简单的管道并行性,最终的调度将如下所示:

Timestep01234567
GPU3FWDBWD
GPU2FWDBWD
GPU1FWDBWD
GPU0FWDBWD

在任何给定时间点,只有一个 GPU 处于繁忙状态。此外,每个时间步骤都会花费相当长的时间,因为 GPU 必须为整个小批量运行前向传递。

使用 GPipe,我们现在将 minibatch 分成多个 microbatches,假设有 4 个。

Timestep012345678910111213
GPU3F1F2F3F4B4B3B2B1
GPU2F1F2F3F4B4B3B2B1
GPU1F1F2F3F4B4B3B2B1
GPU0F1F2F3F4B4B3B2B1

这里的 F1 意思是使用当前 GPU 上存储的层分区执行 microbatches 1 的前向传递。

由于模型各个层之间的依赖关系,流水线中还是存在没有进行任何有用工作的点,称为气泡,图中圈出来的部分。

GPipe 气泡

浪费在气泡上的时间比例取决于管道深度 n 和 microbatches 数量 m,其实就是计算图中气泡的面积占整体的比例:
1 − 2 n m 2 n ( m + n − 1 ) = 1 − m m + n − 1 1-\frac{2nm}{2n(m+n-1)}=1-\frac{m}{m+n-1} 1−2n(m+n−1)2nm​=1−m+n−1m​
因此,增加 m,即 microbatches 数量可以降低气泡的占比。

3. GPipe 空间复杂度

增加批量大小会线性增加缓存激活的内存需求,在 GPipe 论文中,作者利用 gradient checkpointing 来降低内存需求。在 gradient checkpointing 中,我们不会缓存计算梯度所需的所有激活,而是在反向传递过程中动态重新计算激活,这降低了内存需求但增加了计算成本。

假设所有层的大小大致相同,如果不执行 gradient checkpointing ,则缓存激活的空间复杂度为:
O ( b a t c h s i z e ⋅ L a y e r s G P U s ) O(batchsize ⋅ \frac{Layers}{GPUs}) O(batchsize⋅GPUsLayers​)
相反,执行 gradient checkpointing 只缓存层边界上的输入(即缓存从前一个 GPU 发送给我们的张量),这可以降低每个GPU的显存峰值需求,空间复杂度:
O ( b a t c h s i z e + L a y e r s G P U s b a t c h s i z e m i c r o b a t c h e s ) O(batchsize+ \frac{Layers}{GPUs}\frac{batchsize}{microbatches}) O(batchsize+GPUsLayers​microbatchesbatchsize​)
GPipe gradient checkpointing

4. PipeDream 算法

PipeDream 在最终管道阶段完成相应的前向传递后立即开始 microbatches 的反向传递。我们可以在执行相应的反向传递后立即丢弃第 m 个 microbatches 的缓存激活。使用 PipeDream,此反向传递比在 GPipe 中发生得更早,从而减少了内存需求。

下面是 PipeDream 时间表的图,有 4 个 GPU 和 8 个 microbatches。蓝色框表示前向传递,以其 microbatches ID 进行编号,而反向传递则为绿色。
PipeDream 时间表

对于 GPipe 和 PipeDream,缓存激活的空间复杂度可以形式化为(无 gradient checkpointing):
O ( max microbatches in flight ⋅ microbatch-size ⋅ L a y e r s G P U s O(\text{max microbatches in flight}⋅\text{microbatch-size}⋅\frac{Layers}{GPUs} O(max microbatches in flight⋅microbatch-size⋅GPUsLayers​
就气泡比例而言,PipeDream 和 GPipe 之间没有区别,由于 PipeDream 释放显存的时间更早,因此会降低对显存的需求。

5. 总结

流水线并行特别适用于那些层与层之间可以清晰划分的模型,例如由多个 Transformer 层组成的语言模型。这种方法已经被成功应用于训练大规模的预训练模型,如 BERT、GPT 系列等。

优点

  1. 内存优化:通过将模型分割成多个阶段并在不同的设备上处理,可以显著降低单个设备的内存需求,使得能够训练更大的模型。
  2. 计算效率:利用多个设备并行处理不同阶段的任务,可以大大提高计算效率。
  3. 扩展性:理论上可以无限扩展,只要设备足够,就能处理更大的模型。

缺点

  1. 通信开销:不同阶段之间的数据交换需要额外的通信开销,这可能会成为性能瓶颈。
  2. 负载均衡:如果各个阶段的计算复杂度不一致,可能会导致某些设备空闲而其他设备忙于计算,造成负载不平衡。
  3. 同步问题:需要精确控制各个阶段的同步,以确保数据正确传递,这增加了实现难度。

参考

[1] https://docs.aws.amazon.com/sagemaker/latest/dg/model-parallel-intro-v2.html

[2] https://siboehm.com/articles/22/pipeline-parallel-training

[3] https://pytorch.org/tutorials/intermediate/TP_tutorial.html

[4] https://huggingface.co/docs/transformers/v4.15.0/parallelism


欢迎关注本人,我是喜欢搞事的程序猿; 一起进步,一起学习;

欢迎关注知乎/CSDN:SmallerFL

也欢迎关注我的wx公众号(精选高质量文章):一个比特定乾坤

在这里插入图片描述

标签:Pipeline,GPipe,模型,并行,传递,详解,Parallelism,GPU,microbatches
From: https://blog.csdn.net/qq_36803941/article/details/142660578

相关文章

  • 【科芯智雲城】详解MCU 产业,有什么成长潜力?
    MCU相当于一台小型电脑,因为它仅仅利用一块不到数平方平米大小的IC便能完成运算、存取、控制等功能,虽然运算能力较弱,但小体积、低耗能和低成本特性,让它广泛被应用在许多不需大量运算应用的设备中,小到额温枪、塑胶玩具、智能家电,大到机械手臂、电动车,都需要MCU作为控制核心......
  • 详解Java之继承与多态
    目录继承派生类和基类各部分执行顺序protected访问权限总结final关键字组合多态向上转型向下转型动态绑定静态绑定方法重载方法重写 super关键字super和this的对比在构造方法中调用重写方法继承继承是为了解决多个类具有一些相同的属性和方法而造成的代......
  • H.264编解码 - I/P/B帧详解
    一、概述在H.264编解码中,I/P/B帧是一种常见的帧类型。以下是它们的解释:I帧(关键帧):也称为关键帧,它是视频序列中的第一个帧或每个关键时刻的第一个帧。I帧是完整的、自包含的图像帧,不依赖于其他帧进行解码。它存储了关键时刻的完整图像信息。P帧(预测帧):P帧是依赖于之前的关......
  • 大数据-155 Apache Druid 架构与原理详解 数据存储 索引服务 压缩机制
    点一下关注吧!!!非常感谢!!持续更新!!!目前已经更新到了:Hadoop(已更完)HDFS(已更完)MapReduce(已更完)Hive(已更完)Flume(已更完)Sqoop(已更完)Zookeeper(已更完)HBase(已更完)Redis(已更完)Kafka(已更完)Spark(已更完)Flink(已更完)ClickHouse(已更完)Kudu(已更完)Druid(正在更新…)章节内容上节我们完成了如......
  • java:详解java编译命令和启动命令
    编译命令在Java开发过程中,编译Java源文件(通常以.java为扩展名)是不可或缺的一步。这一步骤是通过javac命令完成的,该命令是Java编译器(JavaCompiler)的命令行工具。编译后的代码会生成字节码文件,这些文件以.class为扩展名,并可在Java虚拟机(JVM)上运行。基本语法......
  • Vue.js组件开发详解
    Vue.js组件开发详解Vue.js是一个用于构建用户界面的渐进式框架,其核心思想是通过数据驱动视图的变化,同时提供了一系列强大的工具来帮助开发者高效地开发复杂的单页应用。在Vue.js中,组件是构建复杂应用的基本单元,通过组件化开发,我们可以将应用拆分成可复用的、独立的模块,......
  • Java内部类详解
    Java内部类详解1.内部类基础在Java中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。广泛意义上的内部类一般来说包括这四种:成员内部类、局部内部类、匿名内部类和静态内部类。下面就先来了解一下这四种内部类的用法。1.1.成员内部类成员内部类是......
  • 服务器虚拟化详解
    服务器虚拟化详解服务器虚拟化是一种将物理服务器资源转化为虚拟服务器资源的技术,它允许在一台物理服务器上运行多个虚拟服务器,每个虚拟服务器都拥有独立的操作系统、应用程序和资源配置。这种技术极大地提高了服务器的利用率、灵活性和可扩展性,成为现代数据中心和云计算环......
  • 一文详解:跨国医疗机构安全合规文件流转的跨境传输解决办法
    跨国医疗机构是指那些能够在不同国家之间提供医疗服务的机构,它们通常具有国际化的医疗网络、专业的医疗团队和先进的医疗设备。这些机构不仅能够帮助患者获取国外优质的医疗资源,还能提供包括医疗咨询、治疗安排、病历翻译、签证办理、海外陪同等在内的全方位服务。跨国医疗机构......
  • 多态详解
    多态多态的概念1.多态概念:一个事物具有多种表现形态。2.在Java程序中,多态表现为定义一个方法,在不同环境下呈现不同的业务逻辑。多态的具体表现一、方法的多态方法的重载和重写均体现多态在Java中,方法的重载(Overloading)和重写(Overriding)确实是多态的两种体现方式,但它们各自......