今天介紹一種新的GPU多卡計(jì)算的通信優(yōu)化算法——Ring Allreduce。
先來講一下常規(guī)的GPU多卡分布式計(jì)算的原理,。
第一點(diǎn):我們知道GPU在矩陣并行化計(jì)算方面非常有優(yōu)勢,,所以適合深度學(xué)習(xí)的訓(xùn)練。
第二點(diǎn):使用多個GPU卡訓(xùn)練同一個深度學(xué)習(xí)任務(wù)就是分布式計(jì)算,。
第三點(diǎn):在分布式計(jì)算過程中,,需要對計(jì)算任務(wù)資源進(jìn)行分片,通常的方式是將完整的網(wǎng)絡(luò)結(jié)構(gòu)放到每一個GPU上,,然后將訓(xùn)練數(shù)據(jù)進(jìn)行分片分發(fā)到不同的GPU卡上,。
于是GPU分布式計(jì)算的具體形式就比較清晰了,以上圖為例,。GPU1~4卡負(fù)責(zé)網(wǎng)絡(luò)參數(shù)的訓(xùn)練,,每個卡上都布置了相同的深度學(xué)習(xí)網(wǎng)絡(luò),每個卡都分配到不同的數(shù)據(jù)的minibatch,。每張卡訓(xùn)練結(jié)束后將網(wǎng)絡(luò)參數(shù)同步到GPU0,,也就是Reducer這張卡上,然后再求參數(shù)變換的平均下發(fā)到每張計(jì)算卡,,整個流程有點(diǎn)像mapreduce的原理,。
這里面就涉及到了兩個問題:
問題一,每一輪的訓(xùn)練迭代都需要所有卡都將數(shù)據(jù)同步完做一次Reduce才算結(jié)束,。如果卡數(shù)比較少的情況下,,其實(shí)影響不大,但是如果并行的卡很多的時候,,就涉及到計(jì)算快的卡需要去等待計(jì)算慢的卡的情況,,造成計(jì)算資源的浪費(fèi),。
問題二,每次迭代所有的計(jì)算GPU卡多需要針對全部的模型參數(shù)跟Reduce卡進(jìn)行通信,,如果參數(shù)的數(shù)據(jù)量大的時候,那么這種通信開銷也是非常龐大,,而且這種開銷會隨著卡數(shù)的增加而線性增長,。
為了解決這樣的問題,就引入了一種通信算法Ring Allreduce,,通過將GPU卡的通信模式拼接成一個環(huán)形,,從而減少隨著卡數(shù)增加而帶來的資源消耗,如下圖所示:
將GPU卡以環(huán)形通信之后,,每張卡都有一個左手卡和右手卡,,那么具體的模型參數(shù)是如何傳遞的呢,可以看下圖:
因?yàn)槊繌埧ㄉ厦娴木W(wǎng)絡(luò)結(jié)構(gòu)是固定的,,所以里面的參數(shù)結(jié)構(gòu)相同,。每次通信的過程中,只將參數(shù)send到右手邊的卡,,然后從左手邊的卡receive數(shù)據(jù),。經(jīng)過不斷地迭代,就會實(shí)現(xiàn)整個參數(shù)的同步,,也就是reduce,。
形成以下這張圖的樣式:
通過Ring Allreduce的方式,基本上可以實(shí)現(xiàn)當(dāng)GPU并行卡數(shù)的增加,,實(shí)現(xiàn)計(jì)算性能的線性增長,。