此文翻译自[1],[1]对数据并行和模型并行进行了很好地区分,因此这里推荐给大家。

∇\nabla∇ 联系方式:

e-mail: FesianXu@gmail.com

QQ: 973926198

github: https://github.com/FesianXu

知乎专栏: 计算机视觉/计算机图形理论与应用

微信公众号


介绍

现在深度学习模型的参数量已经变得越来越多了,数据集的尺寸也随之疯狂地增长。为了在一个巨大的数据集上训练一个复杂的深度学习模型,我们不得不使用多节点的并行方式,否则我们永远不可能达到这个目的。这里谈到的并行,通常指的有两种,或者它们各自的混合:

  1. 数据并行 (Data Parallel)
  2. 模型并行 (Model Parallel)
  3. 数据模型并行(Data-Model Parallel)

鉴于第三种方式是前面两种方式的结合,在此我们只讨论前两种并行方式的区别。

数据并行

在现代深度学习中,因为数据集越来越大,以至于我们很难将其把它全部载入内存,我们通常使用所谓的随机梯度下降法[2],对数据集的每个批次(batch)进行梯度求导。举例而言,如果我们的数据集有10K个数据点,每次我们只从中取出16个数据点去计算根据这个批次得到的对梯度的估计,如果我们尝试一次性去计算所有数据点的梯度,我们的GPU显存极可能无法容纳那么多的数据。

然而,随机梯度下降法的缺点在于其对梯度的估计, 相比于用整个数据集进行梯度计算得到的真实梯度来说,可能不够精确。因此,随机梯度下降法通常需要更多的训练时间去达到模型收敛。

有个自然的做法就是在一个更大的批次尺寸上进行更为精确的梯度估计,甚至我们可以使用整个的数据集大小的批次。为了实现这个目的,我们把这个大批次分割为很多小批次,在每个GPU上计算一个小批次,若干个GPU的梯度估计结果进行汇总后,进行加权平均,最终求和就得到了最终的大批次的梯度估计结果。

而这个过程,可以用数学过程进行保证,如:
∂L∂w=∂[1n∑i=1nf(xi,yi)]∂w=1n∑i=1n∂f(xi,yi)∂w=m1n∂[1m1∑i=1m1f(xi,yi)]∂w+m2n∂[1m2∑i=m1+1m1+m2f(xi,yi)]∂w+⋯+mkn∂[1mk∑i=mk−1+1mk−1+mkf(xi,yi)]∂w=m1n∂l1∂w+m2n∂l2∂w+⋯+mkn∂lk∂w(1)\begin{aligned} \dfrac{\partial \mathcal{L}}{ \partial w} &= \dfrac{\partial [\frac{1}{n} \sum_{i=1}^n f(x_i,y_i)]}{\partial w} \\ &= \dfrac{1}{n} \sum_{i=1}^n \dfrac{\partial f(x_i,y_i)}{\partial w} \\ &= \dfrac{m_1}{n} \dfrac{\partial [\frac{1}{m_1} \sum_{i=1}^{m_1} f(x_i,y_i)]}{\partial w} + \dfrac{m_2}{n} \dfrac{\partial [\frac{1}{m_2} \sum_{i={m_1+1}}^{m_1+m_2} f(x_i,y_i)]}{\partial w} + \cdots \\ & +\dfrac{m_k}{n} \dfrac{\partial [\frac{1}{m_k} \sum_{i={m_{k-1}+1}}^{m_{k-1}+m_k} f(x_i,y_i)]}{\partial w} \\ &= \dfrac{m_1}{n} \dfrac{\partial l_1}{\partial w} + \dfrac{m_2}{n} \dfrac{\partial l_2}{\partial w} + \cdots + \dfrac{m_k}{n} \dfrac{\partial l_k}{\partial w} \end{aligned} \tag{1} ∂w∂L​​=∂w∂[n1​∑i=1n​f(xi​,yi​)]​=n1​i=1∑n​∂w∂f(xi​,yi​)​=nm1​​∂w∂[m1​1​∑i=1m1​​f(xi​,yi​)]​+nm2​​∂w∂[m2​1​∑i=m1​+1m1​+m2​​f(xi​,yi​)]​+⋯+nmk​​∂w∂[mk​1​∑i=mk−1​+1mk−1​+mk​​f(xi​,yi​)]​=nm1​​∂w∂l1​​+nm2​​∂w∂l2​​+⋯+nmk​​∂w∂lk​​​(1)
其中:
www是模型的参数;

∂L∂w\dfrac{\partial \mathcal{L}}{\partial w}∂w∂L​是采用尺寸为n的大批次的计算得到的真实梯度;

∂lk∂w\dfrac{\partial l_k}{\partial w}∂w∂lk​​是节点k的梯度;

xix_ixi​和yiy_iyi​是数据点i的特征和标签;

f(xi,yi)f(x_i, y_i)f(xi​,yi​)是对于数据点i,在前向传播过程中计算得到的损失函数;

nnn是整个数据集的大小, kkk是节点数,mkm_kmk​是分配到节点k的数据量,其中有:
m1+m2+⋯+mk=nm_1+m_2+\cdots+m_k = nm1​+m2​+⋯+mk​=n;

如果我们对每个节点的数据量进行平分,我们有:
m1=m2=⋯=mk=nk∂L∂w=1k[∂l1∂w+∂l2∂w+⋯+∂lk∂w](2)\begin{aligned} m_1 &= m_2 = \cdots = m_k = \dfrac{n}{k} \\ \dfrac{\partial \mathcal{L}}{\partial w} &= \dfrac{1}{k} \left[ \dfrac{\partial l_1}{\partial w} + \dfrac{\partial l_2}{\partial w} + \cdots + \dfrac{\partial l_k}{\partial w} \right] \end{aligned} \tag{2} m1​∂w∂L​​=m2​=⋯=mk​=kn​=k1​[∂w∂l1​​+∂w∂l2​​+⋯+∂w∂lk​​]​(2)
对于每个节点来说,我们使用相同的模型参数进行前向传播,我们把整个大批次数据分割成很多个小批次数据,发送到不同的节点上,每个节点都正常地计算其梯度,计算完结后返回其梯度计算结果到主节点(译者:我们称之为output_device)。这一步通常是异步的,因为每个节点的速度可能都稍有差别。一旦我们得到了所有的梯度,我们计算这些梯度的平均值(也就是平均加权),并且使用这个平均加权的梯度去更新整个模型的参数。接着,我们就继续下个迭代。

模型并行

模型并行性乍一听挺唬人的,但是其实和令人生畏的数学没太大关系。模型并行更多的是一种对计算机资源的分配问题。有时候我们的模型可能太大了,甚至大到不能把整个模型载入一个GPU中,因为其中有着太多的层,太多的参数。因此,我们可以考虑把整个模型按层分解成若干份,把每一份(其中的层是连续的)载入不同的节点中,也即是每个不同的节点计算着整个模型的不同的层,计算着不同的层的梯度。通过这种方法,单个节点的参数量就减少了,并且使得用更为精确的梯度进行计算提供了可能性。

举例而言,假如我们有10个GPU节点,我们想要训练一个ResNet50网络(其中有50层)。我们可以将前5层分配给GPU#1, 下一个5层分给GPU #2,如此类推,最后的5层自然是分配给了GPU #10。在训练过程中,在每个迭代中,前向传播首先在GPU #1进行,接下来是GPU #2, #3等等。这个过程是串行的,后面的节点必须等待前面的节点运算完之后才能接着运算,但是,反过来说,后面节点在进行运算的时候,并不妨碍前面的节点进行下一个批次的运算,这个其实就是一个流水线(pipeline)的结构了。当涉及到反向传播时,我们首先计算GPU #10的梯度,并且根据此,更新网络参数。然后我们继续计算前一节点GPU #9的梯度,并且更新,以此类推。每个节点就像是一个工厂中的生产部门,所有节点组成了一个流水线。

简评

在我看来,模型并行的名字其实有点误导性,因为我们发现模型并行有时候并不是一个并行计算的良好例子。一个更为精确的名字应该类似于“模型串行化”,因为它使用了一种串行化的方法而不是一种并行的方法。然而,在一些模型场景中,神经网络中的一些层的确可以做到并行化,比如siamese network,其不同的分支是可以看成完全的并行的。在这种场景中,模型并行可以表现得和真正的并行计算一样。数据并行,的确是100%的并行计算了。

Reference

[1]. https://leimao.github.io/blog/Data-Parallelism-vs-Model-Paralelism/
[2]. https://blog.csdn.net/LoseInVain/article/details/78243051

数据并行和模型并行的区别相关推荐

  1. 深度学习的分布式训练--数据并行和模型并行

    <div class="htmledit_views"> 在深度学习这一领域经常涉及到模型的分布式训练(包括一机多GPU的情况).我自己在刚刚接触到一机多卡,或者分布式 ...

  2. Pytorch:数据并行和模型并行,解决训练过程中内存分配不均衡的问题

    文章目录 数据并行 单机多卡训练,即并行训练.并行训练又分为数据并行 (Data Parallelism) 和模型并行两种. 数据并行指的是,多张 GPU 使用相同的模型副本,但是使用不同的数据批进行 ...

  3. 分布式机器学习——模型并行训练

    首先还是来介绍一下分布式系统中的并行方式,分为数据并行和模型并行,其实还有一种并行方式:Pipeline并行. Pipeline并行方式有的时候会单独存在,有的时候又归为模型并行.这篇文章重点就介绍一 ...

  4. 模型并行,数据并行,参数平均,ASGD

    欢迎转载,转载请注明:本文出自Bin的专栏blog.csdn.net/xbinworld. 2017年3 月,谷歌大脑负责人 Jeff Dean 在 UCSB 做了一场题为<通过大规模深度学习构 ...

  5. 分布式机器学习系统笔记(一)——模型并行,数据并行,参数平均,ASGD

    欢迎转载,转载请注明:本文出自Bin的专栏blog.csdn.net/xbinworld. 技术交流QQ群:433250724,欢迎对算法.技术.应用感兴趣的同学加入. 文章索引::"机器学 ...

  6. 3模型大小_分布式训练中数据并行远远不够,「模型并行+数据并行」才是王道...

    选自arXiv 作者:Saptadeep Pal等 机器之心编译参与:魔王.杜伟 数据并行(DP)是应用最广的并行策略,对在多个设备上部署深度学习模型非常有用.但该方法存在缺陷,如随着训练设备数量不断 ...

  7. 程序如何在两个gpu卡上并行运行_【他山之石】如何支撑上亿类别的人脸训练?显存均衡的模型并行(PyTorch实现)...

    18年的工作,一直没抽出时间整理出来,模型并行看似神秘,在网上搜索相关资料的时候大部也是以谈原理的居多,唯独少了有人拿出代码来捅破这层窗户纸.这里我放出一个PyTorch版本的Demo供大家参考交流. ...

  8. [源码解析] 模型并行分布式训练 Megatron (4) --- 如何设置各种并行

    [源码解析] 模型并行分布式训练 Megatron (4) - 如何设置各种并行 文章目录 [源码解析] 模型并行分布式训练 Megatron (4) --- 如何设置各种并行 0x00 摘要 0x0 ...

  9. [源码解析] 模型并行分布式训练Megatron (5) --Pipedream Flush

    [源码解析] 模型并行分布式训练Megatron (5) --Pipedream Flush 文章目录 [源码解析] 模型并行分布式训练Megatron (5) --Pipedream Flush 0 ...

最新文章

  1. 处理 Exception 的几种实践,很优雅,被很多团队采纳!
  2. 摘抄 :methodology 怎么写
  3. [Swift]LeetCode1017. 负二进制转换 | Convert to Base -2
  4. 前端框架 Bootstrap 5.0 alpha 发布
  5. @程序员,欠下的技术债怎么还?
  6. 【学生研究课题】CSDN博客数据获取、分析、分享
  7. python实用模块(持续更新)
  8. U-net使用, 图像分割(边缘检测)
  9. 【专项测试】京东“安全测试”
  10. Javassist-手写字节码文件
  11. fatal: unable to access ‘‘xxx‘ : Faile to connect to github.com port 443: vscode提交到github 443错误 有梯子
  12. Mysql分区大全及讲解
  13. 浅析安全架构中遇到的问题
  14. java——》Supplie
  15. Java知识大全 - 十二、Java和大数据
  16. Matlab中reshape函数的使用
  17. 图片去水印接口,模糊图片中水印
  18. 模糊数学 5、模糊综合评判
  19. 对云计算,大数据和人工智能的浅谈(一)
  20. 张五常先生谈读书和思考的方法

热门文章

  1. FileZilla_Server_1.3.0_win64-setup
  2. Python 实用代码工具集目录
  3. php网络电视,高清网络电视源码
  4. 大维德选媳妇之责任链模式
  5. 由于找不到msvcr110.dll 无法继续执行的解决方法-丢失msvcr110.dll安装步骤
  6. CC2640R2F学习笔记(6)——UART串口使用
  7. php展厅播控系统,展厅智能中控系统解决方案
  8. 倾听您的游戏面板说话
  9. P1638 逛画展(尺取)
  10. 刷圈兔下载_刷圈兔最新版