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