并行训练-流水线

简述

并行训练主要有三种策略:

  1. 数据并行训练加速比最高,但要求每个设备上都备份一份模型,显存占用比较高,但缺点是通信量大。
  2. 张量并行,通信量比较高,适合在机器内做模型并行。
  3. 流水线并行,训练设备容易出现空闲状态,加速效率没有DP高;但能减少通信边界支持更多的层数,适合在机器间使用。

流水线并行

Micro-batch(Gpipe)

将网络结构进行纵向拆分, 每张卡训练其中的几层. 下图把网络拆成4层. 如果是按照纯粹的mini-batch训练, 每层之间是纯串行的. 后面的卡会始终等待前面的卡. 所以引入了micro-batch的概念. 把mini-batch进行更细粒度的拆分, 这样在完成batch0的fp之后, 卡0可以进行batch1的fp, 卡1就能开始batch0的fp. 从而提高并行度.

存在的问题:

  1. 存在bubble_time: 每张卡的空闲时间 = (stage_num - 1) * (fp_time + bp_time)
\[\frac{(stageNum - 1)(tf + tp)}{(stageNum - 1)(tf + tp) + microNum(tf + tp)} = \frac{stageNum - 1}{microNum + stageNum - 1}
\]

实际应用中 当mico-batch个数大于stageNum的4倍时, 可以忽略bubble_time

  1. 显存浪费: 当进行stage3的micro-batch 3时, 还需要保存前面所有mico-batch的fp中间结果用于bp.
  2. 在每个mini-batch之间无法并行. 因为下一个minibatch需要等当前所有的micro-batch更新完参数

PipeDream(非交错式1F1B DeepSpeed)

在每个micro-batch fp完成之后立刻优先进行bp. 这样可以把当前batch的中间变量释放掉, bp完成后更新本机参数, 但这种方式存在参数更新冲突, 机器1和机器2使用的参数不一样, 机器1的batch5只用了 batch1反向后更新的参数, 但机器2的使用了batch2的, PipeDream通过多版本参数cache的思想来解决这个问题

为啥worker1需要保存4个版本参数, 而worker4只需要1个呢? 这里的版本数和同一个batch fp和bp的间隔决定的. 如果我跑完fp后, 中间有其他batch更新的bp. 那就需要把这些bp结果给缓存起来, 不然就会导致fp和bp使用的不是同一份参数. 可以看到worker1的batch5 中间间隔了2,3,4 3次bp, 再加上它本身. 就得保存4份...这种方法对显存极度不友好, 所以有了下面的flush方式

1F1B-flush

对比上面的F-then-B的方式, 1F1B优先bp计算. 每个micro-batch完成后直接释放掉了对应micro-batch的计算中间值.

只需要保存1份w, 在固定micro-batch个数后进行一次flush, 同步所有worker的权重使其保持同一个版本.

另外在stage3中 batch1 fp时, 因为batch0已经算完了. 所以可以直接复用batch0的显存不用重新分配.

[!NOTE]

这里有个疑问..越底层的stage需要缓存的中间值其实越多, 这种造成存储不均匀的问题怎么解决? 通过stage切分不同大小参数的方式么

1F1B-flush(交错式, megatron)

这个方案有个新的概念, virtual_pipeline, 方案要求一个小批次中的微批次数量是管道并行大小(流水线中的设备数量)的整数倍

按之前非交错式的方法. 一共有8层, worker1如果是1/2层, worker2是3/4层..worker4是7/8层, 每个worker计算连续的层

那么virtual_pipeline如果是2的话, 会把每个worker进一步拆分, worker1变成了计算1/5层, worker2: 2/6层..类推, 相当于通过把每个worker从单一流水线拆成了virtual_pipeline个流水线.

  • 在之前的1F1B模式里, 因为每个机器计算是有先后顺序的, worker2的通信接收worker1的fp结果必须等worker1的fp完成.
  • 而在交错式设计里, worker2计算的是2/6层, 当他计算2的时候, 可以同步从worker1拿上一个batch的5层结果, 算完2后的理想状态就是直接算5. 能更好的把通信隐藏起来.

总结这个方案的优点:

  • 相邻的计算与通信操作无依赖关系, 可以加速并行执行
  • 发起通信操作时,通信的对端通常已经准备好了要通信的数据,通信操作不需要额外的等待时间。

dense并行训练1-流水线并行的更多相关文章

  1. [源码解析] 深度学习流水线并行之PopeDream(1)--- Profile阶段

    [源码解析] 深度学习流水线并行之PopeDream(1)--- Profile阶段 目录 [源码解析] 深度学习流水线并行之PopeDream(1)--- Profile阶段 0x00 摘要 0x0 ...

  2. ML2021 | (腾讯)PatrickStar:通过基于块的内存管理实现预训练模型的并行训练

    ​  前言  目前比较常见的并行训练是数据并行,这是基于模型能够在一个GPU上存储的前提,而当这个前提无法满足时,则需要将模型放在多个GPU上.现有的一些模型并行方案仍存在许多问题,本文提出了一种名为 ...

  3. .Net中的并行编程-5.流水线模型实战

    自己在Excel整理了很多想写的话题,但苦于最近比较忙(其实这是借口).... 上篇文章<.Net中的并行编程-4.实现高性能异步队列>介绍了异步队列的实现,本篇文章介绍我实际工作者遇到了 ...

  4. [源码解析] 深度学习流水线并行Gpipe(1)---流水线基本实现

    [源码解析] 深度学习流水线并行Gpipe(1)---流水线基本实现 目录 [源码解析] 深度学习流水线并行Gpipe(1)---流水线基本实现 0x00 摘要 0x01 概述 1.1 什么是GPip ...

  5. [源码解析] 深度学习流水线并行GPipe (2) ----- 梯度累积

    [源码解析] 深度学习流水线并行GPipe (2) ----- 梯度累积 目录 [源码解析] 深度学习流水线并行GPipe (2) ----- 梯度累积 0x00 摘要 0x01 概述 1.1 前文回 ...

  6. [源码解析] 深度学习流水线并行 GPipe(3) ----重计算

    [源码解析] 深度学习流水线并行 GPipe(3) ----重计算 目录 [源码解析] 深度学习流水线并行 GPipe(3) ----重计算 0x00 摘要 0x01 概述 1.1 前文回顾 1.2 ...

  7. [源码解析] 深度学习流水线并行 PipeDream(2)--- 计算分区

    [源码解析] 深度学习流水线并行 PipeDream(2)--- 计算分区 目录 [源码解析] 深度学习流水线并行 PipeDream(2)--- 计算分区 0x00 摘要 0x01 前言 1.1 P ...

  8. [源码解析] 深度学习流水线并行 PipeDream(4)--- 运行时引擎

    [源码解析] 深度学习流水线并行 PipeDream(4)--- 运行时引擎 目录 [源码解析] 深度学习流水线并行 PipeDream(4)--- 运行时引擎 0x00 摘要 0x01 前言 1.1 ...

  9. [源码解析] 深度学习流水线并行 PipeDream(5)--- 通信模块

    [源码解析] 深度学习流水线并行 PipeDream(5)--- 通信模块 目录 [源码解析] 深度学习流水线并行 PipeDream(5)--- 通信模块 0x00 摘要 0x01 前言 0x02 ...

  10. [源码解析] 深度学习流水线并行 PipeDream(6)--- 1F1B策略

    [源码解析] 深度学习流水线并行 PipeDream(6)--- 1F1B策略 目录 [源码解析] 深度学习流水线并行 PipeDream(6)--- 1F1B策略 0x00 摘要 0x01 流水线比 ...

随机推荐

  1. 优秀的 Modbus 从站(从机、服务端)仿真器、串口调试工具

    目录 优秀的 Modbus 从站(从机.服务端)仿真器.串口调试工具 主要功能 软件截图 优秀的 Modbus 从站(从机.服务端)仿真器.串口调试工具 官网下载地址:http://www.redis ...

  2. k8s-1.28版本多master部署

    一.环境准备 k8s集群角色 IP 主机名 安装相关组件 kubernetes版本号 控制节点 192.168.10.20 master apiserver.controller-manager.sc ...

  3. C语言程序设计-笔记9-函数与程序结构

    C语言程序设计-笔记9-函数与程序结构 例10-1    有序表的增删查操作.首先输入一个无重复元素的.从小到大排列的有序表,并在屏幕上显示以下菜单(编号和选项),用户可以反复对该有序表进行插入.删除 ...

  4. sql计算列中并非零值的平均值

    avg不考虑空值 AVG (NULLIF(Value, 0)) NULLIF(expression, expression) 如果两个 expression 相等,则返回 NULL,该 NULL 为第 ...

  5. NumPy 数组创建方法与索引访问详解

    NumPy 创建数组 NumPy 中的核心数据结构是 ndarray,它代表多维数组.NumPy 提供了多种方法来创建 ndarray 对象,包括: 使用 array() 函数 array() 函数是 ...

  6. inno Setup 打包Java exe可执行文件和MySQL数据库,无需额外配置实现一键傻瓜式安装

    前言 出现有需要打包 Java 应用和 Mysql数据库成一个安装包给出去的需求,这里我把整个打包的流程整理一下. 环境 JDK17; MySQL 5.7; 流程 Jpackage打包EXE Jpac ...

  7. Chart.js (v2.9.4)--如何像高版本一样支持skipNull

    项目开发中,用到Chart.js展示图表,用起来也非常方便,配置很灵活,很好用,给个数据集,设置一些配置值,实例化一个Chart出来,图表就非常丝滑地展现出来了. 但是作为开发人员都知道的一个真理,永 ...

  8. ThreadLocal原理详解——终于弄明白了ThreadLocal

    目录 概述 API介绍 ThreadLocal的理解 ThreadLocal的原理分析 总结 概述 在java学习生涯中可能很多人都会听到ThreadLocal变量,从字面上理解ThreadLocal ...

  9. wpf 自定义轮播图组件

    轮播图组件代码: [Localizability(LocalizationCategory.None, Readability = Readability.Unreadable)][TemplateP ...

  10. 支持表格识别,PaddleOCRSharp最新发布

    PaddleOCRSharp 2.3.0已经发布nuget包. 项目开源地址:https://gitee.com/raoyutian/paddle-ocrsharp 2.3.0更新内容: 1.增加表格 ...