[分布式训练] 单机多卡的正确打开方式:理论基础
[分布式訓(xùn)練] 單機(jī)多卡的正確打開方式:理論基礎(chǔ)
轉(zhuǎn)自:https://fyubang.com/2019/07/08/distributed-training/
瓦礫由于最近bert-large用的比較多,踩了很多分布式訓(xùn)練的坑,加上在TensorFlow和PyTorch之間更換,算是熟悉了一下各類框架的分布式訓(xùn)練接口,由于集中在一起講可能比較亂,筆者準(zhǔn)備分三到四篇來講一下深度學(xué)習(xí)的分布式訓(xùn)練。這一篇先講一下“分布式訓(xùn)練的類型與算法”。
分布式訓(xùn)練的需求和重要性不需要多說,隨著GPT、BERT、xlnet這些預(yù)訓(xùn)練模型的出現(xiàn),普通的16G的顯存已經(jīng)不足以支撐深度學(xué)習(xí)模型訓(xùn)練的要求了,這時候就需要用到分布式訓(xùn)練來提高效率。
注意:這個系列主要介紹單機(jī)多卡的分布式訓(xùn)練情況(這種情況比較常見,土豪和大佬們請忽略)。
總的來說,分布式訓(xùn)練分為這幾類:
- 按照并行方式來分:模型并行 vs 數(shù)據(jù)并行
- 按照更新方式來分:同步更新 vs 異步更新
- 按照算法來分:Parameter Server算法 vs AllReduce算法
模型并行 vs. 數(shù)據(jù)并行
假設(shè)我們有n張GPU:
- 模型并行:不同的GPU輸入相同的數(shù)據(jù),運(yùn)行模型的不同部分,比如多層網(wǎng)絡(luò)的不同層。
- 數(shù)據(jù)并行:不同的GPU輸入不同的數(shù)據(jù),運(yùn)行相同的完整模型。
當(dāng)模型非常大,一張GPU已經(jīng)存不下的時候,可以使用模型并行,把模型的不同部分交給不同的機(jī)器負(fù)責(zé),但是這樣會帶來很大的通信開銷,而且模型并行各個部分存在一定的依賴,規(guī)模伸縮性差。因此,通常一張可以放下一個模型的時候,會采用數(shù)據(jù)并行的方式,各部分獨(dú)立,伸縮性好。
同步更新 vs. 異步更新
對于數(shù)據(jù)并行來說,由于每個GPU負(fù)責(zé)一部分?jǐn)?shù)據(jù),那就涉及到如果更新參數(shù)的問題,分為同步更新和異步更新兩種方式。
- 同步更新:每個batch所有GPU計算完成后,再統(tǒng)一計算新權(quán)值,然后所有GPU同步新值后,再進(jìn)行下一輪計算。
- 異步更新:每個GPU計算完梯度后,無需等待其他更新,立即更新整體權(quán)值并同步。
同步更新有等待,速度取決于最慢的那個GPU;異步更新沒有等待,但是涉及到更復(fù)雜的梯度過時,loss下降抖動大的問題。所以實(shí)踐中,一般使用同步更新的方式。
Parameter Server算法 vs. Ring AllReduce算法
這里講一下常用的兩種參數(shù)同步的算法:PS 和 Ring AllReduce。
假設(shè)有5張GPU:
- Parameter Server:GPU 0將數(shù)據(jù)分成五份分到各個卡上,每張卡負(fù)責(zé)自己的那一份mini-batch的訓(xùn)練,得到grad后,返回給GPU 0上做累積,得到更新的權(quán)重參數(shù)后,再分發(fā)給各個卡。
- Ring AllReduce:5張以環(huán)形相連,每張卡都有左手卡和右手卡,一個負(fù)責(zé)接收,一個負(fù)責(zé)發(fā)送,循環(huán)4次完成梯度累積,再循環(huán)4次做參數(shù)同步。分為Scatter Reduce和All Gather兩個環(huán)節(jié)。
Parameter Server算法
Parameter Server的思想其實(shí)有點(diǎn)類似于MapReduce,以上講同步異步的時候,都是用的這種算法,但是它存在兩個缺點(diǎn):
假設(shè)有NNN個GPU,通信一次完整的參數(shù)所需時間為KKK,那么使用PS架構(gòu),花費(fèi)的通信成本為:
T=2(N?1)KT=2(N-1)K T=2(N?1)K
所以我們亟需一種新的算法來提高深度學(xué)習(xí)模型訓(xùn)練的并行效率。
Ring AllReduce算法
2017 年 Facebook 發(fā)布了《Accurate, large minibatch SGD: Training ImageNet in 1 hour 》驗(yàn)證了大數(shù)據(jù)并行的高效性,同年百度發(fā)表了《Bringing HPC techniques to deep learning 》,驗(yàn)證了全新的梯度同步和權(quán)值更新算法的可行性,并提出了一種利用帶寬優(yōu)化環(huán)解決通信問題的方法——Ring AllReduce。
Parameter Service最大的問題就是通信成本和GPU的數(shù)量線性相關(guān)。而Ring AllReduce的通信成本與GPU數(shù)量無關(guān)。Ring AllReduce分為兩個步驟:Scatter Reduce和All Gather。
Scatter Reduce過程:首先,我們將參數(shù)分為N份,相鄰的GPU傳遞不同的參數(shù),在傳遞N-1次之后,可以得到每一份參數(shù)的累積(在不同的GPU上)。
All Gather:得到每一份參數(shù)的累積之后,再做一次傳遞,同步到所有的GPU上。
根據(jù)這兩個過程,我們可以計算到All Reduce的通信成本為:
T=2(N?1)KNT=2(N-1)\frac{K}{N} T=2(N?1)NK?
可以看到通信成本T與GPU數(shù)量無關(guān)。
由于All Reduce算法在通信成本上的優(yōu)勢,現(xiàn)在幾個框架基本上都實(shí)現(xiàn)了其對于的官方API,后面幾篇,瓦礫會跟大家一起過一遍TF,Torch的分布式訓(xùn)練API具體是怎么用的,有哪些坑。
Reference
總結(jié)
以上是生活随笔為你收集整理的[分布式训练] 单机多卡的正确打开方式:理论基础的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 麦克维尔中央空调怎样解除压缩机预热时间?
- 下一篇: endnote国标_Citavi 与 E