[深度学习] 分布式模式介绍(一)
[深度學(xué)習(xí)] 分布式模式介紹(一)
[深度學(xué)習(xí)] 分布式Tensorflow介紹(二)
[深度學(xué)習(xí)] 分布式Pytorch 1.0介紹(三)
[深度學(xué)習(xí)] 分布式Horovod介紹(四)
一? 分布式訓(xùn)練策略
數(shù)據(jù)較多或者模型較大時(shí),為提高機(jī)器學(xué)習(xí)模型訓(xùn)練效率,一般采用多GPU的分布式訓(xùn)練。
按照并行方式,分布式訓(xùn)練一般分為數(shù)據(jù)并行和模型并行兩種, 模型并行:分布式系統(tǒng)中的不同GPU負(fù)責(zé)網(wǎng)絡(luò)模型的不同部分。例如,神經(jīng)網(wǎng)絡(luò)模型的不同網(wǎng)絡(luò)層被分配到不同的GPU,或者同一層內(nèi)部的不同參數(shù)被分配到不同GPU;
數(shù)據(jù)并行:不同的GPU有同一個(gè)模型的多個(gè)副本,每個(gè)GPU分配到不同的數(shù)據(jù),然后將所有GPU的計(jì)算結(jié)果按照某種方式合并。
注意,上述中的不用GPU可以是同一臺(tái)機(jī)上的多個(gè)GPU,也可以是不用機(jī)上的GPU。
?
當(dāng)然也有數(shù)據(jù)并行和模型并行的混合模式
?
因?yàn)槟P筒⑿懈鱾€(gè)部分存在一定的依賴,規(guī)模伸縮性差(意思是不能隨意增加GPU的數(shù)量),在實(shí)際訓(xùn)練中用的不多。而數(shù)據(jù)并行,則各部分獨(dú)立,規(guī)模伸縮性好,實(shí)際訓(xùn)練中更為常用,提速效果也更好。
數(shù)據(jù)并行會(huì)涉及到各個(gè)GPU之間同步模型參數(shù),一般分為同步更新和異步更新。同步更新要等到所有GPU的梯度計(jì)算完成,再統(tǒng)一計(jì)算新權(quán)值,然后所有GPU同步新值后,才進(jìn)行下一輪計(jì)算。異步更新,每個(gè)GPU梯度計(jì)算完后,無(wú)需等待其他GPU的梯度計(jì)算(有時(shí)可以設(shè)置需要等待的梯度個(gè)數(shù)),可立即更新整體權(quán)值,然后同步此權(quán)值,即可進(jìn)行下一輪計(jì)算。同步更新有等待,異步更新基本沒(méi)有等待,但異步更新涉及到梯度過(guò)時(shí)等更復(fù)雜問(wèn)題。
?
1.模型并行
所謂模型并行指的是將模型部署到很多設(shè)備上(設(shè)備可能分布在不同機(jī)器上,下同)運(yùn)行,比如多個(gè)機(jī)器的GPUs。當(dāng)神經(jīng)網(wǎng)絡(luò)模型很大時(shí),由于顯存限制,它是難以在跑在單個(gè)GPU上,這個(gè)時(shí)候就需要模型并行。比如Google的神經(jīng)機(jī)器翻譯系統(tǒng),其可能采用深度LSTM模型,如下圖所示,此時(shí)模型的不同部分需要分散到許多設(shè)備上進(jìn)行并行訓(xùn)練。深度學(xué)習(xí)模型一般包含很多層,如果要采用模型并行策略,一般需要將不同的層運(yùn)行在不同的設(shè)備上,但是實(shí)際上層與層之間的運(yùn)行是存在約束的:前向運(yùn)算時(shí),后面的層需要等待前面層的輸出作為輸入,而在反向傳播時(shí),前面的層又要受限于后面層的計(jì)算結(jié)果。所以除非模型本身很大,一般不會(huì)采用模型并行,因?yàn)槟P蛯优c層之間存在串行邏輯。但是如果模型本身存在一些可以并行的單元,那么也是可以利用模型并行來(lái)提升訓(xùn)練速度,比如GoogLeNet的Inception模塊。
?
2.數(shù)據(jù)并行
深度學(xué)習(xí)模型最常采用的分布式訓(xùn)練策略是數(shù)據(jù)并行,因?yàn)橛?xùn)練費(fèi)時(shí)的一個(gè)重要原因是訓(xùn)練數(shù)據(jù)量很大。數(shù)據(jù)并行就是在很多設(shè)備上放置相同的模型,并且各個(gè)設(shè)備采用不同的訓(xùn)練樣本對(duì)模型訓(xùn)練。訓(xùn)練深度學(xué)習(xí)模型常采用的是batch SGD方法,采用數(shù)據(jù)并行,可以每個(gè)設(shè)備都訓(xùn)練不同的batch,然后收集這些梯度用于模型參數(shù)更新。前面所說(shuō)的Facebook訓(xùn)練Resnet50就是采用數(shù)據(jù)并行策略,使用256個(gè)GPUs,每個(gè)GPU讀取32個(gè)圖片進(jìn)行訓(xùn)練,如下圖所示,這樣相當(dāng)于采用非常大的batch(256 × 32 = 8192)來(lái)訓(xùn)練模型。
數(shù)據(jù)并行可以是同步的(synchronous),也可以是異步的(asynchronous)。所謂同步指的是所有的設(shè)備都是采用相同的模型參數(shù)來(lái)訓(xùn)練,等待所有設(shè)備的mini-batch訓(xùn)練完成后,收集它們的梯度然后取均值,然后執(zhí)行模型的一次參數(shù)更新。這相當(dāng)于通過(guò)聚合很多設(shè)備上的mini-batch形成一個(gè)很大的batch來(lái)訓(xùn)練模型,Facebook就是這樣做的,但是他們發(fā)現(xiàn)當(dāng)batch大小增加時(shí),同時(shí)線性增加學(xué)習(xí)速率會(huì)取得不錯(cuò)的效果。同步訓(xùn)練看起來(lái)很不錯(cuò),但是實(shí)際上需要各個(gè)設(shè)備的計(jì)算能力要均衡,而且要求集群的通信也要均衡,類似于木桶效應(yīng),一個(gè)拖油瓶會(huì)嚴(yán)重拖慢訓(xùn)練進(jìn)度,所以同步訓(xùn)練方式相對(duì)來(lái)說(shuō)訓(xùn)練速度會(huì)慢一些。異步訓(xùn)練中,各個(gè)設(shè)備完成一個(gè)mini-batch訓(xùn)練之后,不需要等待其它節(jié)點(diǎn),直接去更新模型的參數(shù),這樣總體會(huì)訓(xùn)練速度會(huì)快很多。但是異步訓(xùn)練的一個(gè)很嚴(yán)重的問(wèn)題是梯度失效問(wèn)題(stale gradients),剛開始所有設(shè)備采用相同的參數(shù)來(lái)訓(xùn)練,但是異步情況下,某個(gè)設(shè)備完成一步訓(xùn)練后,可能發(fā)現(xiàn)模型參數(shù)其實(shí)已經(jīng)被其它設(shè)備更新過(guò)了,此時(shí)這個(gè)梯度就過(guò)期了,因?yàn)楝F(xiàn)在的模型參數(shù)和訓(xùn)練前采用的參數(shù)是不一樣的。由于梯度失效問(wèn)題,異步訓(xùn)練雖然速度快,但是可能陷入次優(yōu)解(sub-optimal training performance)。
異步訓(xùn)練和同步訓(xùn)練在TensorFlow中不同點(diǎn)如下圖所示:
?
?
為了解決異步訓(xùn)練出現(xiàn)的梯度失效問(wèn)題,微軟提出了一種Asynchronous Stochastic Gradient Descent方法,主要是通過(guò)梯度補(bǔ)償來(lái)提升訓(xùn)練效果。應(yīng)該還有其他類似的研究,感興趣的可以深入了解一下。
?
二 分布式訓(xùn)練系統(tǒng)架構(gòu)
系統(tǒng)架構(gòu)層包括兩種架構(gòu):
Parameter Server Architecture(就是常見的PS架構(gòu),參數(shù)服務(wù)器)
Ring-allreduce Architecture
1.Parameter server架構(gòu)
在Parameter server架構(gòu)(PS架構(gòu))中,集群中的節(jié)點(diǎn)被分為兩類:parameter server和worker。其中parameter server存放模型的參數(shù),而worker負(fù)責(zé)計(jì)算參數(shù)的梯度。在每個(gè)迭代過(guò)程,worker從parameter sever中獲得參數(shù),然后將計(jì)算的梯度返回給parameter server,parameter server聚合從worker傳回的梯度,然后更新參數(shù),并將新的參數(shù)廣播給worker。
?
PS架構(gòu)是深度學(xué)習(xí)最常采用的分布式訓(xùn)練架構(gòu)。采用同步SGD方式的PS架構(gòu)如下圖所示:
?
?
2.Ring-allreduce架構(gòu)
在Ring-allreduce架構(gòu)中,各個(gè)設(shè)備都是worker,并且形成一個(gè)環(huán),如下圖所示,沒(méi)有中心節(jié)點(diǎn)來(lái)聚合所有worker計(jì)算的梯度。在一個(gè)迭代過(guò)程,每個(gè)worker完成自己的mini-batch訓(xùn)練,計(jì)算出梯度,并將梯度傳遞給環(huán)中的下一個(gè)worker,同時(shí)它也接收從上一個(gè)worker的梯度。對(duì)于一個(gè)包含N個(gè)worker的環(huán),各個(gè)worker需要收到其它N-1個(gè)worker的梯度后就可以更新模型參數(shù)。其實(shí)這個(gè)過(guò)程需要兩個(gè)部分:scatter-reduce和allgather,百度的教程對(duì)這個(gè)過(guò)程給出了詳細(xì)的圖文解釋。百度開發(fā)了自己的allreduce框架,并將其用在了深度學(xué)習(xí)的分布式訓(xùn)練中。
?
相比PS架構(gòu),Ring-allreduce架構(gòu)是帶寬優(yōu)化的,因?yàn)榧褐忻總€(gè)節(jié)點(diǎn)的帶寬都被充分利用。此外,在深度學(xué)習(xí)訓(xùn)練過(guò)程中,計(jì)算梯度采用BP算法,其特點(diǎn)是后面層的梯度先被計(jì)算,而前面層的梯度慢于前面層,Ring-allreduce架構(gòu)可以充分利用這個(gè)特點(diǎn),在前面層梯度計(jì)算的同時(shí)進(jìn)行后面層梯度的傳遞,從而進(jìn)一步減少訓(xùn)練時(shí)間。在百度的實(shí)驗(yàn)中,他們發(fā)現(xiàn)訓(xùn)練速度基本上線性正比于GPUs數(shù)目(worker數(shù))。
一般的多卡gpu訓(xùn)練有一個(gè)很大的缺陷,就是因?yàn)槊看味夹枰粋€(gè)gpu(cpu)從其他gpu上收集訓(xùn)練的梯度,然后將新的模型分發(fā)到其他gpu上。這樣的模型最大的缺陷是gpu 0的通信時(shí)間是隨著gpu卡數(shù)的增長(zhǎng)而線性增長(zhǎng)的。
所以就有了ring-allreduce,如下圖:
?
該算法的基本思想是取消Reducer,讓數(shù)據(jù)在gpu形成的環(huán)內(nèi)流動(dòng),整個(gè)ring-allreduce的過(guò)程分為兩大步,第一步是scatter-reduce,第二步是allgather。
先說(shuō)第一步:首先我們有n塊gpu,那么我們把每個(gè)gpu上的數(shù)據(jù)(均等的)劃分成n塊,并給每個(gè)gpu指定它的左右鄰居(圖中0號(hào)gpu的左鄰居是4號(hào),右鄰居是1號(hào),1號(hào)gpu的左鄰居是0號(hào),右鄰居是2號(hào)……),然后開始執(zhí)行n-1次操作,在第i次操作時(shí),gpu j會(huì)將自己的第(j - i)%n塊數(shù)據(jù)發(fā)送給gpu j+1,并接受gpu j-1的(j - i - 1)%n塊數(shù)據(jù)。并將接受來(lái)的數(shù)據(jù)進(jìn)行reduce操作,示意圖如下:
當(dāng)n-1次操作完成后,ring-allreduce的第一大步scatter-reduce就已經(jīng)完成了,此時(shí),第i塊gpu的第(i + 1) % n塊數(shù)據(jù)已經(jīng)收集到了所有n塊gpu的第(i + 1) % n塊數(shù)據(jù),那么,再進(jìn)行一次allgather就可以完成算法了。
第二步allgather做的事情很簡(jiǎn)單,就是通過(guò)n-1次傳遞,把第i塊gpu的第(i + 1) % n塊數(shù)據(jù)傳遞給其他gpu,同樣也是在i次傳遞時(shí),gpu j把自己的第(j - i - 1)%n塊數(shù)據(jù)發(fā)送給右鄰居,接受左鄰居的第(j - i - 2) % n數(shù)據(jù),但是接受來(lái)的數(shù)據(jù)不需要像第一步那樣做reduce,而是直接用接受來(lái)的數(shù)據(jù)代替自己的數(shù)據(jù)就好了。
最后每個(gè)gpu的數(shù)據(jù)就變成了這樣:?
?
首先是第一步,scatter-reduce:
然后是allgather的例子:?
 ?
?
 鏈接
 https://www.jianshu.com/p/9c462bbb6628
 https://www.jianshu.com/p/bf17ac9e6357
 ?
總結(jié)
以上是生活随笔為你收集整理的[深度学习] 分布式模式介绍(一)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
                            
                        - 上一篇: 吉吉影音怎么样
 - 下一篇: 图文讲解Android ImageVie