微软和谷歌一直在积极研究用于训练深度神经网络的新框架,并且在最近将各自的成果开源——微软的 PipeDream 和谷歌的 GPipe。
原则上看,他们都遵循了类似的原则来训练深度学习模型。这两个项目已在各自的研究论文(PipeDream,GPipe)中进行了详细介绍,这篇文章将对此进行总结。
先放上 GitHub 开源地址:
微软:
https://github.com/msr-fiddle/pipedream谷歌:
https://github.com/tensorflow/lingvo/blob/master/lingvo/core/gpipe.py众所周知,在实验过程中,虽然训练基本模型比较琐碎,但复杂度却随模型的质量和大小线性增加。例如,2014 年 ImageNet 视觉识别挑战赛的冠军是 GoogleNet,它通过 400 万个参数获得了 74.8% 的 top1 准确性,而仅仅三年之后,2017 年 ImageNet 挑战赛的冠军就使用 1.458 亿个参数(多了 36 倍)的最新神经网络实现了 top1 准确率——82.7%。但是,在同一时期,GPU 内存仅增加了约 3 倍。
随着模型缩放以达到更高的准确性,对这些模型的训练变得越来越具有挑战性。前面的样本也显示了,依靠 GPU 基础结构的改进来实现更好的训练是不可持续的。我们需要分布式计算方法,这些方法可以并行化跨不同节点的训练工作量,以扩展训练规模。分布式训练的概念听起来很琐碎,但实际上却极其复杂。
谷歌的 GPipe GPipe专注于扩展深度学习计划的训练工作量。从基础架构的角度来看,训练过程的复杂性是深度学习模型经常被忽视的一个方面。训练数据集越来越大,越来越复杂。例如,在医疗保健领域,需要使用数百万个高分辨率图像进行训练的模型并不罕见。结果,训练过程通常要花费很长时间才能完成,并且内存和 CPU 消耗非常大。
思考深度学习模型的分布式的有效方法是将其划分为数据分布式和模型分布式。数据分布式方法采用大型机器集群,将输入数据拆分到它们之间。模型分布式尝试将模型移至具有特定硬件的加速器,例如 GPU 或 TPU,以加速模型训练。
概念上看,几乎所有训练数据集都可以按照一定的逻辑进行分布式训练,但是关于模型的说法却不尽相同。例如,一些深度学习模型由可以独立训练的并行分支组成。在那种情况下,经典策略是将计算划分为多个分区,并将不同的分区分配给不同的分支。但是,这种策略在按顺序堆叠各层的深度学习模型中是不足的。
GPipe 通过利用一种称为流水线的技术将数据和模型分布式结合在一起。从概念上讲,GPipe 是一个分布式机器学习库,它使用同步随机梯度下降和流水线分布式进行训练,适用于由多个连续层组成的任何 DNN。
GPipe 在不同的加速器之间划分模型,并自动将一小批训练样本拆分为较小的微批。该模型允许 GPipe 的加速器并行运行,从而最大限度地提高了训练过程的可扩展性。
下图说明了具有连续层的神经网络的 GPipe 模型在四个加速器之间分配。Fk 是第 k 个分区的复合正向计算函数。Bk 是相应的反向传播函数。Bk 取决于上层的 Bk + 1 和 Fk 的中间激活。在顶级模型中,我们可以看到网络的顺序性质如何导致资源利用不足。下图显示了 GPipe 方法,其中将输入的迷你批处理分为较小的宏批处理,这些宏批处理可由加速器同时处理。
图片来源:
https://arxiv.org/pdf/1811.06965.pdf