目录
独立研究者 Karanbir Chahal 和 Manraj Singh Grover 与 IBM 的研究者 Kuntal Dey 近日发布了一篇论文,对深度神经网络的分布式训练方法进行了全面系统的总结,其中涉及到训练算法、优化技巧和节点之间的通信方法等。
自从深度学习提出以来,已经在视觉、语言、推荐等领域取得非常好的效果。但不幸的是,这种算法需要大量的数据才能有效的完成训练。因此,训练耗时非常高,如:第一个在ImageNet分类任务上取得当前最佳结果的深度学习算法在单个GPU上训练足足耗费了一周时间。这是难以接受的,有什么方法能够加速深度学习的训练呢?回答是分布式训练。
神经网络的分布式训练有两种方法来实现:数据并行和模型并行。
数据并行化的目标是将数据集均等地分配到系统的各个训练节点,其中每个节点都有该神经网络的一个副本及其本地的权重。每个节点都会处理该数据集的一个不同子集并更新其本地权重集。这些本地权重会在整个集群中共享,从而通过一个累积算法计算出一个新的全局权重集。这些全局权重又会被分配至所有节点,然后节点会在此基础上处理下一批数据。
模型并行化则是通过将该模型的架构切分到不同的节点上来实现训练的分布化。AlexNet是使用模型并行化的最早期模型之一,其方法是将网络分摊到 2个GPU上以便模型能放入内存中。当模型架构过大以至于无法放入单台机器且该模型的某些部件可以并行化时,才能应用模型并行化。模型并行化可用在某些模型中,比如目标检测网络,这种模型的绘制边界框和类别预测部分是相互独立的。一般而言,大多数网络只可以分配到2个GPU上,这限制了可实现的可扩展数量,因此数据并行是分布式训练最常用的方法。
数据并行需要解决问题:
同步SGD:网络中的节点首先在它们的本地数据批上计算出梯度,然后每个节点都将它们的梯度发送给主服务器(master server)。主服务器通过求这些梯度的平均来累积这些梯度,从而为权重更新步骤构建出新的全局梯度集。这些全局梯度会通过使用与单机器 SGD 同样的方法来更新每个节点的本地权重。这整个过程都类似于在单台机器上通过单个数据 mini-batch 计算前向计算和反向传播,因此同步 SGD 能保证收敛。但是同步 SGD 也存在一些局限性,如:每台机器某一batch数据训练完成,参数统一更新之后才可以进行下一批次训练(也称同步屏障问题/synchronization barrier)。
异步SGD:每个模型副本都会向参数服务器请求全局权重,处理一个 mini-batch 来计算梯度并将它们发回参数服务器,然后参数服务器会据此更新全局权重。因为每个节点都独立计算梯度且无需彼此之间的交互,所以它们可以按自己的步调工作,也对机器故障更为稳健,即如果一个节点故障,其它节点还能继续处理,因此能消除由同步 SGD 引入的同步屏障(synchronization barrier)问题。
较大的mini-batch大小具有一些优势,主要的一个优势是:在大mini-batch上训练时,模型能以更大的步幅到达局部最小值,由此能够加快优化过程的速度。但是在实践中,使用大mini-batch会导致网络的测试准确度有时会低于在更小mini-batch上训练的模型。最近的一些研究mini-batch大小与学习率之间的关系,实验发现,增加批量大小就相当于降低学习率,因而在使用大mini-batch时,可以等比例调整学习速率。另外,使用大批量进行训练还有一个额外的好处是可以使训练中所要更新的总参数减少。
神经网络最初是使用单精度或双精度数作为默认数据类型,因为这些数据类型在获取网络想要建模的任务的表征上表现很好。单精度数是32位浮数,双精度数是64位浮点数。近期有研究表明通过在更低精度数据类型进行训练,可将神经网络的速度和大小降低 50%-80%。更具体而言,将低精度梯度与学习率相乘有时会导致数值溢出16位的范围,从而导致计算不正确,进而导致最终验证准确度降低。混合精度训练的目标是通过使用单精度(32 位)的权重及梯度结合半精度(16位)的输入输出值来解决这个问题。混合精度训练能实现更高的吞吐量,从而能降低计算与通信瓶颈。但是,混合精度训练也存在一些数值溢出问题。
简而言之,对每台机器上的梯度采用一定策略来进行压缩,然后进行传输。
为了打造一个高效且可扩展的分布式训练框架,推荐使用以下技术: