当前位置: 首页 > 科技观察

上帝的巴别塔正在倒塌?阿里翻译一年调用2500亿次,节省25亿美元

时间:2023-03-16 21:54:45 科技观察

神经机器翻译(NeuralMachineTranslation,NMT)模型自2013年首次在学术界提出以来,发展迅速。目前已支持部分语言和在这种场景下,翻译质量甚至可以达到人工翻译的水平。阿里翻译团队自2016年10月正式开始自主研发NMT模型,2016年11月首次将NMT系统的输出结果应用于中英新闻传播语境的外部评价,取得了良好的成绩结果。翻译质量有所提高。急剧上升。然而,由于NMT模型结构复杂,深度神经网络模型本身的训练过程一般涉及大量计算,NMT系统往往需要较长的训练周期。例如,在单个GPU上使用3000万训练数据,一般需要在卡上训练20多天才能得到一个初步可用的模型。基于以上问题,从2017年2月开始,阿里翻译团队与阿里云大规模学习的木卓团队合作,共同开发了支持分布式训练的NMT系统,并完成了第一版分布式训练2017年3月底,NMT系统。项目成果在2017年4月的英俄电商翻译质量优化项目中,分布式NMT系统大大提升了训练速度,将模型训练时间从20天缩短至4天,为整体迭代和优化节省了大量时间项目成本的推进。图1:当使用不同数量的卡时,在汉英100万训练语料上获得的收敛加速比在4块GPU卡上可以达到3倍以上,在8块GPU卡上达到5倍以上收敛加速比可以在16张GPU卡上达到9倍以上的收敛加速比。通过不断积累GPU卡数,收敛加速比有望不断提升。图2:2机4卡分布式训练在中英文2000万训练集上的收敛过程图3:各种分布式策略加速效果对比除了基于MA的分布式实现,项目组还尝试了许多其他各种分布式实现方法也获得了不同程度的加速效果,包括DownpourSGD、AllReduceSGD,以及使用BMUF(BlockwiseModel-UpdateFiltering,ModelAverage方法的改进方案)策略的ModelAverage方法。实施方案数据并行的多机多卡分布式方案的讨论是基于数据并行的同步SGD算法,即采用多个worker分摊整个batch的计算量,每个GPU(worker)存储模型的完整副本。可以直接使用Tensorflow本身提供的PS框架来实现该算法。标准同步SGD算法的每次迭代分为三个步骤。首先将模型参数从parameterserver拉取到本地,然后使用新的模型参数计算本地mini-batch的梯度,最后将计算出的梯度推送到parameterserver。参数服务器需要收集所有worker的梯度,然后统一处理和更新模型参数。因此在ps框架下,同步SGD算法传输数据的通信总流量=2*num_of_gpus*size_of_whole_model。通过对模型大小和一个mini-batch的计算时间的评估,发现在单机两卡的情况下,由于PCIe的高带宽(~10GB/s),提速可以获得接近2倍的比例,但是两台机器在两张单卡的情况下,计算与通信的比例是1:1,但是随着机器数量的增加,不仅没有带来加速,但它比单卡慢。可见,通信优化是同步SGD算法的主要问题。在下面的具体方案介绍中,我们也展示了相关的实验结果。混合并行混合并行模型可以通过模型参数的存储策略,利用参数的稀疏性,减少参数的实际通信量,加速训练过程。一般适用于稀疏模型的训练,但对于特殊的网络结构,可以将模型并行与数据并行相结合,提高全局计算通信比,我们这里称之为混合并行。以AlexNet为例,模型结构可以分为全连接层和卷积层两部分,分别分析计算两部分的通信比例。全连接层的计算和通信比例极低,没有可扩展性,而卷积层的计算和通信比例比较高,适合数据并行。因此,混合并行方案是:多个worker使用数据并行计算卷积层,而只需要一个worker(或极少数worker)计算全连接层,以获得最高的计算通信比,并且只有一个小的特征图需要在卷积层和全连接层之间进行通信。通过对NMT模型中的每一层进行profiling,发现各部分网络的参数相差不大,计算量也相当。不仅计算和通信比不高,而且各层结构之间传递的featuremap也很大,不适合使用混合并行。分布式方案的进一步探索基于以上分析,我们对分布式方案进行了进一步的探索。为了最大化多机多卡的可扩展性,我们选择了Modelaverage、BMUF、downpour等分布式方式。与简单的数据并行相比,模型平均(Modelaverage,MA)方法有两个显着的优点:1.通信量可以通过同步的频率进行调整,两次同步的间隔可以以step甚至epoch为单位进行控制。一般来说,通信开销几乎可以忽略不计,从而获得线性的计算加速比;2.batchsize的大小可以和单机baseline保持一致。基于数据并行的同步SGD通常会逐年增加batchsize以维持计算通信率,导致精度损失。但是MA方法、BMUF方法、基于异步更新的downpour方法对调参的要求更高。不同的参数设置会对模型的收敛结果产生较大的影响。计算加速比的提高并不意味着收敛。增加加速。下面是各个实现方案的消息介绍和结果展示。基于模型平均方法的分布式训练方案概述。ModelAverage方法,即每个worker负责训练一个局部模型,以固定(或动态)频率在多个GPU之间求出每个模型的平均值,以此作为继续训练的基础.基于Tensorflow的ModelAverage设计主要分为图构建和分步运行两部分。1、首先,由于每个worker需要在自己的进程中求解,所以需要在每个worker上建立一个forward-backward子图。这部分子图在上图中用红色箭头线表示。需要注意的是每个worker应该有独立的op和variable。2、其次,需要在ps上维护一份模型,并构建ReduceAverage的子图。这部分子图在上图中用黑色箭头线表示。3、然后,需要构造一个广播子图,在上图中用蓝线表示。(为了美观,图中没有画出所有的广播依赖,ps的变量1和变量2都应该和worker1和worker2中的变量1和变量2建立依赖关系)4.构建完以上依赖关系最后,我们需要通过客户端启动ModelAverage机制。用户只需要通过控制会话运行的顺序来指定每个子图的解。这里,红色子图需要每一轮都运行,一定轮数后,开始依次运行黑色子图和蓝色子图,完成ModelAverage机制。在实现上,可以使用主worker完成所有子图的构建,其他worker处于join状态。在运行时,每个worker将根据图中的依赖关系被驱动。超参数的调整当两机四卡的参数与单机单卡的基线参数一致时,从多组实验可以观察到不同的同步频率对模型质量有影响,而最快的加速比仅为1.5.通过推导,我们发现MA方法中每次计算多个worker的模型均值,相当于将每个训练样本对模型梯度的贡献减少到原来的1/num_of_gpus,大大抵消了多卡带来的加速度。因此,MA中的局部训练学习率(lr)应调整为原始基线lr的num_of_gpus倍。实验结果其中bs代表batchsize,lr代表学习率,横坐标为训练时间,纵坐标代表翻译质量。使用BMUF方法改进ModelAverage方案概述上面提到的ModelAverage方法在两卡、四卡、八卡上都取得了很高的加速比。在不断平行扩展的过程中,需要根据个体的不同,lr的大小要有一个合适的范围,不能无限增大。随着机器数量的增加,这种朴素的MA方法逐渐暴露出它的局限性。BMUF(BlockwiseModel-UpdateFiltering)是模型平均(naiveMA)的优化算法。主要区别在于引入了历史梯度量。MA算法相当于将每次同步时所有worker上的模型增量相加并平均为“blockgradients”,用于更新parameterserver上的全局参数,而BMUF的“blockgradients”就是基于此之上,又增加了一个历史梯度,历史梯度的权重为区块动量率。具体推导如下:MA:一个mini-batch训练数据对最终模型的贡献公式为:BMUF:一个mini-batch训练数据对最终模型的贡献公式为:从公式可以看出,单个mini-batch在MA中batch的贡献在average阶段降低到原来的1/N。如果要保持和baseline一样的贡献,就需要增加lr。BMUF相对于baseline的贡献率是:Adjustmentofhyperparameters上面的公式可以指导BMUF训练时参数的调整。BMUF有两个主要参数,一个是blocklearningrate(blr),这个超参数一般设置为1.0,和MA算法一致,另一个是blockmomentumrate(bmr),可以调整为1-1/Nbybmr,以保持lr不变,总贡献与baseline一致。此外,在引入历史梯度后,还可以结合Nesterov方法在训练前的局部训练中更新局部模型已知的历史梯度,从而进一步加速收敛。实验结果上图中横坐标表示训练数据总量,即每个计算节点的训练数据之和(理想情况下收敛曲线应该与基线重合甚至更高),纵坐标表示模型的翻译质量。可以看出,MA和BMUF在两机四卡上都能获得相当可观的加速比。BMUF的优点是通过调整bmr可以使学习率(lr)与单机单卡的baseline保持在同一水平,因为lr有一个比较合适的范围,不能无限制的增加asGPU的数量增加。BMUF的作用已经在较大的lr和16cal实验中得到体现。基于DownpourSGD方法的分布式训练方案的概述类似于MA的设计。DownpourSGD的设计也比较自然。也分为图构建和分布运行两部分。这里需要注意的是,DownpourSGD方法是ASGD的一种异步分布式训练方法,在应用梯度时不需要多个worker之间的同步。下面详细介绍倾盆大雨的整体流程。1.将ps上的模型权重拉到每个worker上。2.每个worker自己解决局部模型。在求解过程中,不仅需要更新局部模型的参数,还要将梯度累加到另一组变量中存储。3.localworker在求解一定轮数后,将本地存储的累积梯度异步应用到ps的模型参数上。在这个方法的实现中,需要在每个worker上保存一个变量来存储梯度的累积量,并且在合成图像的时候需要改变优化器,主要体现在需要应用AdaDelta计算出的梯度到它自己在模型被添加到局部变量之前,它然后被应用到它自己的参数。这里还有一个累加梯度的问题,因为在AdaDelta的实现中,应用于模型的量实际上包括梯度和delta量两部分,所以累加时可能需要考虑到这些delta量。实现时,无需重写新的优化器,只需将调用applygradients前后的模型权重相减即可得到正确的结果。DownpourSGD会带来一些其他的超参数,包括pushgradients和pullweights之间的间隔数,我们称之为step。另外如果push和pull的步长过大,这段时间的累积梯度也会过大。如果此时直接对权重应用累积梯度,很可能会出现NAN,所以需要对累积梯度进行裁剪。所以裁剪累积梯度的范数也是一个额外的超参数。由于ASGD带来的异步性,超参数的调整比同步SGD更难,而DownpourSGD确实有更多的超参数。为了加快训练速度,减少每个epoch的迭代时间,我们采用了更激进的weakscaling方法,即每个worker使用更大的batchsize。但是需要注意的是,虽然增加batchsize会加快数据的处理速度,但同时也会降低每个数据的学习效果。这是因为与小批量相比,更新模型的频率大大降低,所以我们需要同时提高学习率。此外,在异步条件下,每个worker计算的累积梯度可能会变成陈旧的梯度。这些梯度的方向不一定是最优的,相反,有时是很差的。如果我们不裁剪这些累积的梯度,那么很可能会出现NAN,所以我们需要调整累积梯度的裁剪范数值。但是clippingnorm值越小,梯度值被削弱的越厉害,模型的学习效果越差。它与学习率的调整是一对权衡。最后,push和pull的步长间隔值不能太大,因为步长太大会导致累积梯度太大,如果此时用更小的裁剪范数切割累积梯度,那么这就意味着这么长按轮数计算的累积梯度效果会被切掉。在实验中,我们发现步长间隔数设置在20左右比较理想。综上所述,参数调优的基本目标是选择更大的batchsize,在步长间隔数固定后适当提高学习率在push和pull之间,逐渐调整和增加clippingnorm的大小,使学习效果最大化。实验结果其中bs代表batchsize,lr代表学习率,norm以累积梯度作为裁剪的最大值,fetch代表倾盆大雨中push和pull的间隔值,纵坐标代表翻译质量值,横坐标代表训练时间。基于Ring-allReduceSGD方法的分布式训练方案概述如前所述,同步SGD算法的每次迭代都需要两次通信,拉参数和推梯度。这样一个push+pull的过程是针对整个系统的。相当于一次allreduce操作,通信量相当于2*nGPUs*model_size。随着GPU数量的增加,allreduce成为主要的性能瓶颈。Ring-allReduceopAllreduce聚合通讯有比较成熟的优化方法,最常用的方法之一是Ringallreduce。基本思想是将allreduce拆分为reduce_scatter和allgather。1、首先将要通信的消息按照节点数进行分片,分片数与通信节点数相同(不需要额外的参数server)。2.启动reduce_scatter操作。对于worker(i)来说,第j次通信就是将自己的第j条消息发送给worker(i+1),并将收到的消息添加到消息的对应段中。经过n-1轮循环管道通信后,每个worker都有一个fragment是reduceallworker的结果。3.然后开始allgather操作。第j次通信是将自己的j+1条消息发送给worker(i+1),所以经过n-1轮通信后,所有worker的整条消息都进行了reduce操作,即all_reduce操作完成了。ring-allreduce方式可以使集群中的通信总量保持在一个常数值,略小于2*mdoel_size,不会随着并行规模的增加而增加,具有很好的扩展性。gRPCvsMPIRing-allreduce方式能够带来性能提升的前提是延迟的开销相对于带宽可以忽略不计,因为ringallreduce虽然减少了通信总量,但是增加了通信次数。目前的tensorflow通信协议只支持gRPC,通信的高延迟不能简单忽略。但是,使用支持RDMA的cuda-awareMPI来实现allreduceop会有更显着的效果。另外,Allreduce操作也存在于Modelaverage算法中,也能带来一定的性能优势。超参数的调整是因为对于同步SGD分布式算法,如果TotalBatchsize不变,每个GPU卡上的minibatchsize会随着GPU卡数量的增加而减少,其计算时间不会线性减少,因为当batchsize足够小,计算时间会逐渐稳定。虽然通过优化大大减少了通信,但计算的可扩展性仍然有限。因此,在使用多机多卡同步SGD时,batchsize与GPU数量成正比增加。同样,为了保持单个训练样本的贡献,lr也同比增加。实验结果上图中,Doka同步SGD的总batchsize设置为1280,是baseline(batchsize=160)的8倍。横坐标表示已训练的数据总量,纵坐标表示模型的翻译质量。在InfiniBand(10GB/s)网络上,计算加速比为4倍,在10Gb(1GB/s)以太网上,计算加速比为2.56倍。但是,批量大小的增加会影响收敛精度。从上图可以看出,收敛的最高点略低于基线,有明显的精度损失。Futurework前一阶段的工作主要集中在模型训练阶段的加速策略上。接下来的工作主要分为两个方面:一方面,继续挖掘分布式训练的加速潜力。通过系统与算法相结合的优化策略,最大限度地利用硬件资源,提高收敛加速比,将分布式优化策略与算法模型本身解耦,实现复杂系统分布式加速功能的组件化和泛化化深度学习模型。另一方面,在现有面向服务的解决方案的基础上,需要通过模型精度压缩、网络结构简化等方法,在保证模型效果的同时,进一步提高解码速度,降低在线延迟,从而加强在线服务。能力,节省服务所需的硬件成本。【本文为专栏作者《阿里巴巴官方技术》原创稿件,转载请联系原作者】点此查看作者更多好文