分布式深度學(xué)習(xí)在NLP,機(jī)器翻譯,計算機(jī)視覺等領(lǐng)域不斷刷新業(yè)界的最高水平。今年來其發(fā)展很快,一年前還是頂尖水平的方法,框架和算法已經(jīng)要被淘汰。但在這種巨變中有一點是不變的,那就是深度學(xué)習(xí)在向分布式發(fā)展。

如上圖所示,如果我們想訓(xùn)練最好的模型有五種通常的做法。改進(jìn)正則化算法和最優(yōu)化算法常常是學(xué)術(shù)界和超大規(guī)模AI公司的著眼點。對于其他三種方法,只要用分布式訓(xùn)練就可以讓你改進(jìn)你的模型的精度,即通過
????1. 發(fā)現(xiàn)更好的超參數(shù)
? ? 2. 借助更大規(guī)模的訓(xùn)練數(shù)據(jù)來訓(xùn)練
? ? 3. 通過AutoML技術(shù)發(fā)現(xiàn)更好的神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)

多年來,分布式訓(xùn)練推動了AI前沿水平的發(fā)展。在上圖中,你可以看到從2012年起,在OpenAI實驗室中,為了訓(xùn)練最好的機(jī)器學(xué)習(xí)系統(tǒng),差不多每3.5個月訓(xùn)練的計算量就得翻倍。比如2017年的AlphaGo Zero和2012年的AlexNet相比,訓(xùn)練的計算量翻了30萬倍。雖然近些年Nvidia,google, AMD 和Intel在硬件加速增加晶體管數(shù)量方面干得不錯,但并沒有每3.5個月倍增他們的計算能力。于是深度學(xué)習(xí)模型的訓(xùn)練走向了分布式的道路。例如2018年Google提出的用于NLP的著名模型BERT,如果用單張Nvidia 2080Ti卡訓(xùn)練需要396天。但是通過分布式訓(xùn)練(20臺DeapLearning11服務(wù)器),你可以將訓(xùn)練時間減少的1-2天。
神經(jīng)網(wǎng)絡(luò)的并行化模型
神經(jīng)網(wǎng)絡(luò)的分布式訓(xùn)練有數(shù)據(jù)并行和模型并行兩種模式。數(shù)據(jù)并行中被劃分的是數(shù)據(jù),模型可以被放到一張單獨的GPU卡上,每張GPU卡處理不同分區(qū)的數(shù)據(jù)來并行訓(xùn)練??梢酝ㄟ^參數(shù)平均(model averageing)算法更新各個節(jié)點模型中的參數(shù)。如下圖所示:

而模型并行被劃分的是模型,即把模型的網(wǎng)絡(luò)結(jié)構(gòu)拆了,放到不同的GPU上進(jìn)行運算,對于卷積神經(jīng)網(wǎng)絡(luò)來說就是把對應(yīng)的矩陣運算做了分塊處理??梢詫⒛P偷牟煌W(wǎng)絡(luò)層被分配到不同的機(jī)器,或者同一層內(nèi)部的不同參數(shù)被分配到不同機(jī)器。模型并行允許支持更大的模型,所有工作節(jié)點針對相同數(shù)據(jù)進(jìn)行訓(xùn)練,每個 GPU 上分布著并運行模型的一部分,需要在GPU之間交換神經(jīng)網(wǎng)絡(luò)的輸出激活部分(activation)。

Parameter Server和Ring All Reduce架構(gòu)
數(shù)據(jù)并行由于不需要拆分模型在實踐中更加常用。第一代數(shù)據(jù)并行分布式訓(xùn)練由參數(shù)服務(wù)器(Parameter Server)架構(gòu)主導(dǎo)。 在參數(shù)服務(wù)器架構(gòu)中,一個或多個參數(shù)服務(wù)器保存當(dāng)前模型,并在每個迭代中對一組工作節(jié)點的參數(shù)或梯度進(jìn)行同步。

?這種架構(gòu)的問題是參數(shù)服務(wù)器和工作節(jié)點之間的網(wǎng)絡(luò)連接成為瓶頸。當(dāng)參數(shù)服務(wù)器的帶寬成為瓶頸時,工作節(jié)點無法利用自己的全部帶寬, 當(dāng)GPU之間的權(quán)值更新通信所需的時間線性增長時,網(wǎng)絡(luò)I/O很快就會成為阻止訓(xùn)練進(jìn)一步擴(kuò)展的瓶頸,減慢了訓(xùn)練速度。這個問題促使了All Reduce分布式訓(xùn)練架構(gòu)的產(chǎn)生。

Ring All Reduce是2017年由百度最先提出的【1】(All Reduce起源于HPC應(yīng)用的開發(fā)),用于深度神經(jīng)網(wǎng)絡(luò)的數(shù)據(jù)并行訓(xùn)練,應(yīng)用于PaddlePaddle平臺,只有也被移植到TensorFlow的contrib包中。在Ring All Reduce架構(gòu)中,如上圖所示,每個節(jié)點對應(yīng)一個硬件加速器(GPU),在訓(xùn)練中,每個服務(wù)器步伐一致的處理訓(xùn)練數(shù)據(jù)的一個minibatch,每個服務(wù)器在其minibatch的本地分區(qū)上計算梯度,并同時從環(huán)形中的上一個節(jié)點接收梯度,向下一個節(jié)點發(fā)送梯度。由于使用了每個節(jié)點的上傳和下載能力,相比All Reduce算法通信更少。之后所有的梯度以相同的方向在環(huán)上移動,當(dāng)有所的服務(wù)器都接收到minibatch的所有的梯度信息后,通過隨機(jī)梯度下降等最優(yōu)化算法更新本地模型副本的參數(shù)。在這一步更新后,所有的服務(wù)器就擁有了相同的模型副本。想要了解All Reduce(AllReduce是一種將所有process中的目標(biāo)數(shù)組,減少為單個數(shù)組并將結(jié)果數(shù)組返回給所有process的操作。比如將所有GPU上的梯度值,假設(shè)數(shù)組表示,合并并執(zhí)行reduce操作成一個數(shù)組,并返回給所有GPU)和Ring All Reduce算法細(xì)節(jié)的同學(xué)請移步【2】。
Horovod框架
Horovod【3】是Uber于2017年發(fā)布的一個易于使用的高性能的分布式訓(xùn)練框架,他支持TensorFlow,Keras,PyTorch和MXNet。Horovod依賴于Nvidia的NCCL2做All Reduce,依賴于MPI做進(jìn)程間通信,簡化了同步多 GPU 或多節(jié)點分布式訓(xùn)練的開發(fā)流程。由于使用了NCCL2,Horovod也可以利用以下功能:NVLINK,RDMA,GPUDirectRDMA,自動檢測通信拓?fù)?,能夠回退?PCIe 和 TCP/IP 通信。

從上圖中可以看到,Horovod對于Inception v3和ResNet-101這樣的中小型模型,在256個GPU上的性能幾乎可以線性擴(kuò)展,在VGG-16種大模型上也有較好的縮放因子。正式由于Horovod有簡潔的API和優(yōu)異的性能,目前已經(jīng)被廣泛采用(github 8.4k star)。
5行代碼入門Horovod

上面代碼中,加粗的第一行hvd.init()初始化Horovod,然后和在Tensorflow中一樣構(gòu)建模型,第二處修改是聲明訓(xùn)練會話的配置,給當(dāng)前進(jìn)程分配對應(yīng)的GPU,local_rank()返回的是當(dāng)前是第幾個進(jìn)程。第三處修改添加Horovod分布式優(yōu)化器,第四處修改定義初始化的時候廣播參數(shù)的hook,這個是為了在一開始的時候同步各個GPU之間的參數(shù)。最后用MonitoredTrainingSession實現(xiàn)會話的初始化,讀寫checkpoint。啟動該程序只需要執(zhí)行如下命令:
horovodrun -np 16 -H server1:4,server2:4,server3:4,server4:4 python?tensorflow_mnist.py
這里?-np指的是進(jìn)程的數(shù)量,server1:4表示server1節(jié)點上4個GPU,完整代碼參見tensorflow_mnist.py?
附實驗環(huán)境:
login 10.208.2.253?
運行腳本t4.sh腳本登錄實驗環(huán)境
啟動容器
login t4-3:
nvidia-docker run -it -d --network=host -v /mnt/newkdl_nfs/ssh:/root/.ssh --name horovod-test newkdl.images.hub:11180/kdl/horovod:0.18.0-tf1.14.0-torch1.2.0-mxnet1.5.0-py3.6 bash
login t4-2 & t4-1:
nvidia-docker run -it -d --network=host -v /mnt/share/ssh:/root/.ssh --name horovod-test newkdl.images.hub:11180/kdl/horovod:0.18.0-tf1.14.0-torch1.2.0-mxnet1.5.0-py3.6 \ bash -c "/usr/sbin/sshd -p 12345; sleep infinity"
啟動訓(xùn)練
login t4-3:
代碼目錄: cd /examples
horovodrun -np 12 -H localhost:4,172.31.0.8:4,172.31.0.52:4 -p 12345 python pytorch_mnist.py?