分布式深度学习part1:神经网络的分布式训练

2023-10-26

这篇文章是关于神经网络分布式训练的三部系列文章中的第一篇。

在第1部中,我们将了解如何通过GPU上的分布式计算显著地加速深度学习模型的训练,并讨论一些挑战并调查当前关于该主题的研究。 我们还将考虑神经网络的分布式训练是否适用于特定用例。

介绍

在大型数据集上训练的现代神经网络架构可以在各种领域获得令人印象深刻的性能表现,从语音和图像识别,到自然语言处理,再到欺诈检测和推荐系统等行业关注的应用。 但是训练这些神经网络模型在计算上要求很高。 虽然近年来在GPU硬件、网络架构和训练方法方面取得了重大进展,但事实仍然是网络训练在单个机器上可能花费很长时间。 幸运的是,我们并不局限于一台机器:已经开展了大量的工作和研究,以实现神经网络的高效分布式训练。

我们首先考虑两种并行/分布训练计算的方法。
在这里插入图片描述

模型并行(model parallelism)中,分布式系统中的不同机器负责单个网络的不同部分的计算 - 例如,神经网络中的每个层可以被分配给不同的机器。

数据并行(data parallelism)中,不同的机器具有完整的模型副本; 每台机器只是获取数据的不同部分,并且每个机器的结果以某种方式组合。

当然,这些方法并不相互排斥。 考虑一组多GPU的系统,我们可以为每台机器使用模型并行(模型跨GPU分割),并在机器之间使用数据并行。

在这里插入图片描述
虽然模型并行在实践中可以很好地工作,但数据并行可以说是分布式系统的首选方法,并且一直是更多研究的重点。 一方面,数据并行比模型并行性更容易实现,在容错和集群利用率上也容易。 分布式系统环境中的模型并行很有趣,并且确实具有一些优点(例如大型模型的可扩展性),但在这里我们将关注数据并行。

数据并行

分布式训练的数据并行方法在每个工作机器上保留整个模型的副本,在每个工作机器上处理训练数据集的不同子集。 数据并行训练方法都需要一些组合结果和在每个worker之间同步模型参数的方法,文献中讨论了许多不同的方法,方法之间的主要区别是:

  • 参数平均方法 vs 基于更新(梯度)的方法
  • 同步方法 vs 异步方法
  • 中心化同步 vs 分布式同步

Deeplearning4j的当前Spark实现是一个同步参数平均,其中Spark driver和reduction操作取代了参数服务器。

参数平均

Parameter Averaging
参数平均是概念上最简单的数据并行方法。 通过参数平均,训练如下进行处理:

  1. 根据模型配置随机初始化网络参数;
  2. 把当前参数分发到每个worker;
  3. 在数据子集上训练每个worker;
  4. 把全局参数设置为每个worker上参数的均值;
  5. 如果还有数据处理,回到第二步;

第二步到第四步通过下图展示,在途中,W代表神经网络中参数(weights, biases),下标用于做随着时间参数版本的索引,必要时为每个机器确定下标。
在这里插入图片描述
实际上,可以直接证明参数平均的受限版本在数学上与单个机器上的训练相同; 这些重组是每个小批量后的参数平均值,没有更新(即没有动量momentum等 - 只是乘以学习率),以及每个worker处理的相同数量的样本。 证明如下。
In fact, it’s straightforward to prove that a restricted version of parameter averaging is mathematically identical to training on a single machine; these restructions are parameter averaging after each minibatch, no updater (i.e., no momentum etc - just multiplication by learning rate), and an identical number of examples processed by each worker.

考虑具有n个worker的集群的情况,其中每个worker处理m个示例,对于在平均值之间处理的总共 n m nm nm个样本。 如果我们在用学习率α的单台机器上处理所有nm个样本,我们的权重更新规则由下式给出:
W i + 1 = W i − α n m ∑ j = 1 n m ∂ L j ∂ W i W_{i+1}=W_{i}-\dfrac{α}{nm}\sum_{j=1}^{nm}\dfrac{∂L^j}{∂W_i} Wi+1=Winmαj=1nmWiLj
如果我们改为在n个worker每个中学习m个样本(其中worker1得到样本 1 , . . . . . . , m 1,......,m 1......m,worker2得到样本 m + 1 , . . . , 2 m m + 1,...,2m m+1...2m等等),我们有:
在这里插入图片描述

当然,这个结果在实践中并不成立(每个小批量的平均并且不使用诸如动量或RMSProp之类的updater都是不明智的,出于性能和收敛的原因),但它确实让我们对参数平均为什么工作很好有个直观感觉,特别是当参数频繁平均时。

现在,参数平均在概念上很简单,但是我们已经掩盖了一些并发症。

首先,我们应该如何实现平均? 简单的方法是在每次迭代后简单地取参数平均值。 虽然这可行,但我们可能会发现这样做的开销不切实际; 网络通信同步成本可能会超过从额外机器获得的好处。 因此,参数平均通常在平均周期(根据worker的minibatch数量)大于1的情况下实施。但是,如果我们平均太不频繁,则每个worker的局部参数可能会发生过大的偏离,导致平均后的模型很差。 这里的直觉是N个不同的局部最小值的平均值不能保证是局部最小值:
在这里插入图片描述

什么平均时期才是太高了? 这个问题尚未得到最终解答,并且通过与其他超参数的交互变得更加复杂,例如学习率、minibatch大小和worker数量。 关于该主题的一些初步研究(如[8])表明,每10至20个minibatch(每个worker)一次的平均周期仍然表现地很好。 随着平均周期的增加,模型精度当然会降低。

与adagrad,动量和RMSProp等优化方法相关的额外复杂性。 这些优化方法(在Deeplearning4j中称为“updaters”)已经被证明可以显着改善神经网络训练期间的收敛性。 但是,这些updaters具有内部状态(每个网络参数通常为1或2个状态值) - 我们是否应该对这些状态算平均值? 在每个worker里算内部updater状态平均值应该能导致更快地收敛,代价是双倍或者更多的网络传输的总大小。 一些工作还考虑在参数服务器级别应用类似的“updater”机制,而不仅仅是在每个worker([1])中。

异步随机梯度下降

Asynchronous Stochastic Gradient Descent

概念上类似于参数平均的方法是我们可以称之为“基于更新(update based)”的数据并行。 两者之间的主要区别在于,我们不是将参数从worker传递到参数服务器,而是传递update(即,学习率和动量的梯度等)。 这里提供了update的方式:
W i + 1 = W i − λ ∑ j = 1 N Δ W i , j W_{i+1} = W_i - λ\sum_{j=1}^{N}ΔW_{i,j} Wi+1=Wiλj=1NΔWi,j
其中 λ λ λ是缩放因子(类似于learning rate超参)

架构上,看起来和parameter averaging很像:
在这里插入图片描述
熟悉训练神经网络数学的读者可能已经注意到参数平均和基于更新的方法之间存在直接的相似性。 如果我们再次将我们的损失函数定义为L,那么对于具有学习率α的简单SGD训练,在迭代 i + 1 i + 1 i+1处的参数向量W通过以下方式获得(假设n个参数):
W i + 1 , j = W i − α ∇ L j W_{i+1,j} = W_i - α∇L_j Wi+1,j=WiαLj
其中:
∇ L j = ( ∂ L ∂ w 1 , . . . . . . ∂ L ∂ w n ) ∇L_j = (\dfrac{∂L}{∂w_1},......\dfrac{∂L}{∂w_n}) Lj=(w1L,......wnL)

如果我们采取上面的更新规则,并对n个executor令 λ = 1 n λ=\dfrac{1}{n} λn1,为简介起见,再次使用只有学习率α的SGD,则更新为 ∇ W i , j = α ∇ L j ∇W_{i,j} = α∇L_j Wi,j=αLj,然后可以得到:
在这里插入图片描述
因此,当参数同步更新时(这一部分是关键),参数平均和基于更新的数据并行之间存在等价关系。 这种等价性也适用于多个平均step和其他updater(不仅仅是简单的SGD)。

当我们放松同步更新要求时,基于更新的数据并行变得更有趣(并可以说更有用)。也就是说,通过允许更新 Δ W i , j ΔW_{i,j} ΔWij一旦被计算就应用于参数向量(而不是等待所有worker的N≥1次迭代),我们获得异步随机梯度下降算法Async SGD有两个主要好处:

  • 首先,我们可以在分布式系统中获得更高的吞吐量:worker可以花更多的时间执行有用的计算,而不是等待参数平均步骤完成。
  • 其次,worker可能比使用同步(每N步)更新时更快地合并来自其他worker的信息(参数更新)。

然而,这些好处并非没有代价。 通过向参数向量引入异步更新,我们引入了一个新问题,称为陈旧梯度问题(stale gradient problem)。 陈旧的梯度问题非常简单:梯度(更新)的计算需要时间。 当worker完成这些计算并将结果应用于全局参数向量时,参数可能已经多次更新。 这个问题如下图所示。
在这里插入图片描述
异步SGD的简单实现可能导致梯度的非常高的陈旧值。 例如,引用 [3]中表明平均梯度陈旧度等于worker的数量。 对于N个执行器,这意味着在将梯度应用于全局参数向量时,梯度将平均过时N步。 这具有现实世界的影响:高梯度过时会显著降低网络收敛速度,甚至会阻止某些配置收敛。 早期的异步SGD实现(例如Google的DistBelief系统[2])没有考虑到这种影响,因此学习效率远远低于原本应有水平。

异步随机梯度下降的大多数变体保持相同的基本方法,但应用各种策略来最小化陈旧梯度的影响,同时尝试维持高集群利用率。 应当注意,由于算法的同步性质,参数平均不受陈旧梯度问题的影响。

一些处理陈旧梯度的方法包括:

  • 基于梯度的陈旧性,针对每次更新 Δ W i , j ΔW_{i,j} ΔWij分别缩放值λ;
  • 实现‘软’同步协议(引用[9]);
  • 使用同步来绑定陈旧性(Use synchronization to bound staleness.)。 例如,引用[4]的系统在必要时延迟更快的worker,以确保最大陈旧度低于某个阈值;

所有这些方法都被证明可以改善原始异步SGD算法的收敛性。 值得注意的是前两个:基于陈旧性的缩放更新(陈旧的梯度对参数向量的影响较小)和软同步。 软同步(引用[9])非常简单:参数服务器不是立即更新全局参数向量,而是等待从n个learner中的(其中 1 ≤ s ≤ n 1≤s≤n 1sn)收集数量s个更新 Δ W j ΔW_j ΔWj。 然后根据以下方式更新参数:
W i + 1 = W i − 1 s ∑ j = 1 s λ ( Δ W j ) Δ W j W_{i+1} = W_i - \dfrac{1}{s}\sum_{j=1}{s}λ(ΔW_j)ΔW_j Wi+1=Wis1j=1sλ(ΔWj)ΔWj
其中 λ ( Δ W j ) λ(ΔW_j) λ(ΔWj)是标量的陈旧依赖缩放因子(staleness-dependent scaling factor),引用[9]提出 λ ( x ) = λ 0 τ λ(x) = \dfrac{λ_0}{τ} λ(x)=τλ0,其中 τ ≥ 1 τ≥1 τ1是基于参数陈旧性的整数,但其他方法也是可能的(参见引用[6])。 soft sync和与staleness-dependent scaling 的组合比单独使用它们更好。

注意,通过设置 s = 1 s = 1 s=1 λ ( ⋅ ) = λ(·)= λ()=常数,我们获得了原始异步SGD算法(如[2]所述); 类似地,通过设置 s = n s = n s=n,我们获得与同步参数平均相似(但不相同)的算法。

分散的异步随机梯度下降

decentralized asychronous stochastic gradient descent

引用[7]提出了一种用于执行神经网络分布式训练的更有趣的替代架构。 我将这种方法称为分散的同步随机梯度下降(尽管作者没有使用这个术语)。 这篇论文很有趣,主要有两个原因:

  • 系统中不存在集中式参数服务器(相反,点对点peer to peer通信用于在worker之间传输模型更新)。
  • 更新被大量压缩,导致网络通信的大小减少了大约3个数量级。

在这里插入图片描述

在标准数据并行实现中(使用参数平均或异步SGD),网络传输的大小等于参数向量大小(因为我们传输参数向量的副本,或每个参数一个梯度值)。 虽然压缩参数或更新的想法并不是全新的,但实现方式远远超出了其他简单的压缩机制(例如应用压缩编解码器或转换为16位浮点表示)。

这个设计的巧妙之处在于更新向量 δ i , j δ_{i,j} δi,j是:

  • 稀疏:在每个向量中只传递一些梯度 δ i , j δ_{i,j} δi,j(假设其余的为0) - 使用整数索引对稀疏项进行编码;
  • 量化为单个bit:稀疏更新向量的每个元素取值 + τ +τ +τ − τ -τ τ。该 τ τ τ值对于向量的所有元素是相同的,因此仅需要一个比特来区分两个选项;
  • 整数索引(用于标识稀疏数组中的项)可选地使用熵编码(entropy coding)进行压缩,以进一步减少更新大小(作者引用额外计算成本进一步降低3倍大小,但这种好处可能不值得额外成本);

此外,为了解释压缩方法有损的事实,原始更新向量 Δ W i , j ΔW_{i,j} ΔWij与压缩/量化的更新向量 δ i , j δ_{i,j} δij之间的差被存储在每个执行器j上的所谓的残差向量 r j r_j rj中,而不是简单地被丢弃。 将残差向量加到原始更新中:即我们在每个步骤中量化并发送 Δ W i , j + r j ΔW_{i,j} + r_j ΔWij+rj的压缩版本,适当地更新 r j r_j rj。 得到的效果是来自原始更新向量 Δ W i ΔW_i ΔWi,j的全部信息仅被延迟而不会丢失。 换句话说,大的更新(每个参数)以比小更新以更高的速率动态传输。

这里出现两个问题:(a)这对减少网络传输有多大帮助? (b)这如何影响准确性?答案比你想象的要少。

以Strom的论文中所报告的为例,1460万个参数:

 	    Compression	               Update Size       Reduction
        None (32-bit floating point)	58.4 MB	           -
        16-bit floating point	        29.2 MB	       50%
        Quantized, \(\tau=2\)	        0.21 MB	       99.6%

可以使用更大的 τ τ τ值,并且导致更大的压缩(例如, τ = 15 τ= 15 τ=15时每个小批量的更新大小仅为4.5 KB!)但是随着 τ τ τ增加,模型精度明显受损。

结果令人印象深刻,这种方法似乎有三个主要缺点。

  • Strom报告说,在训练的早期阶段收敛会受到影响(在一个epoch的一小部分使用较少的计算节点似乎有帮助)
  • 压缩和量化不是无代价的:这些过程导致每个小批量的额外计算时间,以及每个执行器的少量内存开销
  • 该过程引入了两个额外的超参数: τ τ τ的值以及是否对更新使用熵编码(尽管参数平均和异步SGD都引入了额外的超参数)

最后,(以作者的知识)没有异步SGD和分散异步SGD的任何实验比较。

分布式神经网络训练:哪种方法最好?

我们已经看到有多种方法来训练分布式神经网络,每种类型都有多种变体。 那么我们应该在实践中选择哪一个呢? 不幸的是,这个问题没有一个简单的答案。 首先,我们可以根据以下任何标准定义不同的方法:

  • 最快的训练速度(每秒最高训练样本数,或每个epoch最短时间)
  • 最大可达到的准确度为nepochs→∞
  • 给定数量的挂钟时间的最大可达精度
  • 给定数量的epoch可达到的最大精度

此外,这些问题的答案可能取决于许多因素,例如神经网络的类型和大小,群集硬件,压缩等功能的使用,以及训练方法的具体实施和配置。
在这里插入图片描述

也就是说,我们可以从研究中得出一些结论:
同步参数平均(或等效的,基于同步更新的)方法在每个epoch的准确度和总体可达到的准确度方面胜出,尤其是在小的平均更新周期时。 例如,参见[9]中的’hardsync’结果,或者N = 1平均周期的同步平均最接近单机训练的事实。 然而,额外的同步成本意味着这种方法每个epoch必然更慢; 也就是说,InfiniBand等快速网络互连可以在很大程度上保持同步方法的竞争力(参见示例[5])。 但是,即使在商用硬件上,我们也看到DL4J的同步参数平均实现在实践中具有良好的集群利用率。 添加压缩应该进一步有助于减少网络通信开销。

References

[1] Kai Chen and Qiang Huo. Scalable training of deep learning machines by incremental block training with intra-block parallel optimization and blockwise model-update filtering. In 2016 IEEE International Conference on Acoustics, Speech and Signal Processing (ICASSP), pages 5880–5884. IEEE, 2016.

[2] Jeffrey Dean, Greg Corrado, Rajat Monga, Kai Chen, Matthieu Devin, Mark Mao, Andrew Senior, Paul Tucker, Ke Yang, Quoc V Le, et al. Large scale distributed deep networks. In Advances in Neural Information Processing Systems, pages 1223–1231, 2012.

[3] Suyog Gupta, Wei Zhang, and Josh Milthrope. Model accuracy and runtime tradeoff in distributed deep learning. arXiv preprint arXiv:1509.04210, 2015.

[4] Qirong Ho, James Cipar, Henggang Cui, Seunghak Lee, Jin Kyu Kim, Phillip B. Gibbons, Garth A Gibson, Greg Ganger, and Eric P Xing. More effective distributed ml via a stale synchronous parallel parameter server. In C. J. C. Burges, L. Bottou, M. Welling, Z. Ghahramani, and K. Q. Weinberger, editors, Advances in Neural Information Processing Systems 26, pages 1223–1231. Curran Associates, Inc., 2013.

[5] Forrest N Iandola, Khalid Ashraf, Mattthew W Moskewicz, and Kurt Keutzer. Firecaffe: near-linear acceleration of deep neural network training on compute clusters. arXiv preprint arXiv:1511.00175, 2015.

[6] Augustus Odena. Faster asynchronous sgd. arXiv preprint arXiv:1601.04033, 2016.

[7] Nikko Strom. Scalable distributed dnn training using commodity gpu cloud computing. In Sixteenth Annual Conference of the International Speech Communication Association, 2015. http://nikkostrom.com/publications/interspeech2015/strom_interspeech2015.pdf.

[8] Hang Su and Haoyu Chen. Experiments on parallel training of deep neural network using model averaging. arXiv preprint arXiv:1507.01239, 2015.

[9] Wei Zhang, Suyog Gupta, Xiangru Lian, and Ji Liu. Staleness-aware async-sgd for distributed deep learning. IJCAI, 2016.

原文distributed-deep-learning-part-1-an-introduction-to-distributed-training-of-neural-networks

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

分布式深度学习part1:神经网络的分布式训练 的相关文章

随机推荐

  • risc系统服务器,精简的高端 解析四大RISC服务器处理器

    也许您很难相信 作为我们今天仍在广泛使用的诸如 扣肉 之类的最新双核乃至是CPU Center Prosessing Unit中央处理器 都是基于始创在上世纪60年代的CISC指令集 距今已有四十多年了 CISC是英文 Complex In
  • Latex系列3---页面设置+字体字号+颜色符号

    上一节中阐述的是简易的文本 本节在此基础上进行完善加工 页面设置 页边距 在平时写文章的时候 其实对于页边距的要求不高 但是论文这种就比较的严格 调整页边距需要使用 usepackage geometry 在这里我们平常使用此包进行调整页边
  • matlab如何读取txt文件

    格式化文本的读操作 只读形式打开txt文件 file t fopen mytxt txt r 以十进制读取 且读取的数据自动排成一列 排的顺序为 先从第一行左边到第一行右边 然后排第二行 A fscanf file t d 关闭文件 fcl
  • Proxy代理的作用

    Proxy代理的作用 Proxy 用于修改某些操作的默认行为 等同于在语言层面做出修改 所以属于一种 元编程 meta programming 即对编程语言进行编程 Proxy可以理解成 在目标对象之前架设一层 拦截 外界对该对象的访问 都
  • Babel转码器详解

    Babel转码器详解 Babel是一个广为使用的ES6转码器 可以将ES6代码转为ES5代码 从而在浏览器或其他环境运行 这意味着可以用ES6的方式编写程序而不用担心环境是否支持 Babel的配置文件是 babelrc 存放在根目录下 使用
  • 已解决 ZeroDivisionError: float division by zero 。

    问题 在使用YOLO算法系列时 需要将xml文件转换为txt文件 我在转换时遇到了这个问题ZeroDivisionError float division by zer 解决方法 简单的解决方法 找到报错的位置 将w h的值后面各加上一个极
  • Python进行ARMA模型建模

    import pandas as pd import matplotlib pyplot as plt import seaborn as sns import statsmodels api as sm from statsmodels
  • 使用Virtuoso和hspice进行电路输入与模拟

    总述 在这一次实验里 我学习了电路模拟的基本办法 具体而言是virtuoso和hspice 还有custom waveform软件基本功能的使用 达到了通过电路模拟验证延迟 验证功耗 验证逻辑功能的目的 反相器的设计 反相器是可以将输入信号
  • DBeaver 连接 Google BigQuery

    DBeaver 连接 Google BigQuery 毕业设计要用到Google BigQuery 但是想要用DBeaver进行远程连接 实在用不惯浏览器端的界面 结果发现DBeaver 真 的 可 以 DBeaver提供了Google B
  • Mysql Redo Log日志

    Mysql Redo Log日志 数据日志与数据落盘机制 Redo log写入磁盘时 必须进行一次操作系统fsync操作 防止redo log只是写入操作系统磁盘缓存中 参数innodb flush log at trx commit可以控
  • C++ 动态内存

    了解动态内存在 C 中是如何工作的是成为一名合格的 C 程序员必不可少的 C 程序中的内存分为两个部分 栈 在函数内部声明的所有变量都将占用栈内存 堆 这是程序中未使用的内存 在程序运行时可用于动态分配内存 很多时候 您无法提前预知需要多少
  • 公司名称注册,公司名称查询,企业名称注册事项

    公司名称的构成 名称一般由四部分依次组成 行政区划 字号 行业特点 组织形式 登记管辖 工商行政管理机关对企业名称实行分级登记管理 国家工商总局登记管辖范围 一 冠以 中国 中华 全国 国家 国际 字样的 二 在名称中间使用 中国 中华 全
  • Python中的三引号''' '''的用法

    链接 https blog csdn net GreenHandCGL article details 79703863
  • ERP仓库管理的操作与设计--开源软件诞生20

    赤龙ERP库房管理讲解 第20篇 用日志记录 开源软件 的诞生 点亮星标 祈盼着一个鼓励 博主开源地址 码云 https gitee com redragon redragon erp GitHub https github com red
  • minkwindow安装

    装库要记住三件事 官网 csdn 耐心 装库太慢就边看剧边装 不要影响心态 首先上官网 GitHub NVIDIA MinkowskiEngine Minkowski Engine is an auto diff neural networ
  • 国产超低功耗华大单片机HC32L136开发板上手入门

    今天介绍下国产超低功耗华大单片机HC32L136开发板上手后的入门操作 开发板可以在华大MCU应用交流群 164973950 免费申请 HC32L136开发板 如下图所示 分为板载调试模块 左半部分 和MCU开发电路 右半部分 二者中间通过
  • 当你的sklearn用不了mean_absolute_percentage_error函数

    今天将一份写好的python机器学习程序换了个电脑跑的时候 出现了如下报错 ImportError cannot import name mean absolute percentage error from sklearn metrics
  • 解决K8s安装中节点初始化时 [kubelet-check] The HTTP call equal to ‘curl -sSL http://localhost:10248/healthz‘ 问题.

    问题描述 安装K8s时 在节点初始化过程中出现 kubelet check The HTTP call equal to curl sSL http localhost 10248 healthz failed with error Get
  • WINDOWS 10 设置WSL 2

    确保已安装 WSL 可以在此处找到相关说明 并且运行的是 Windows 10内部版本 18917或更高版本 可以通过在 PowerShell 中运行以下命令来执行此操作 PowerShell dism exe online enable
  • 分布式深度学习part1:神经网络的分布式训练

    这篇文章是关于神经网络分布式训练的三部系列文章中的第一篇 在第1部中 我们将了解如何通过GPU上的分布式计算显著地加速深度学习模型的训练 并讨论一些挑战并调查当前关于该主题的研究 我们还将考虑神经网络的分布式训练是否适用于特定用例 介绍 在