深度學習分散式模型
背景
隨著各大企業和研究機構在PyTorch、TensorFlow、Keras、MXNet等深度學習框架上面訓練模型越來越多,專案的資料和計算能力需求急劇增加。在大部分的情況下,模型是可以在單個或多個GPU平臺的伺服器上執行的,但隨著資料集的增加和訓練時間的增長,有些訓練需要耗費數天甚至數週的時間,我們拿COCO和Google最近Release出來的Open Image dataset v4來做比較,訓練一個resnet152的檢測模型,在COCO上大概需要40個小時,而在OIDV4上大概需要40天,這還是在各種超引數正確的情況下,如果加上除錯的時間,可能一個模型調完就該過年了吧。單張CPU卡、或者單臺伺服器上的多張GPU卡,已經遠遠不能夠滿足內部訓練任務的需求。因此,分散式訓練的效率,即使用多臺伺服器協同進行訓練,現在成為了深度學習系統的核心競爭力。
一、分散式訓練系統架構
分散式訓練系統架構主要有兩種:
- Parameter Server Architecture(就是常見的PS架構,引數伺服器)
- Ring-allreduce Architecture
1.1 Parameter Server架構
在Parameter Server架構(PS架構)中,叢集中的節點被分為兩類:parameter server和worker。其中parameter server存放模型的引數,而worker負責計算引數的梯度。在每個迭代過程,worker從parameter sever中獲得引數,然後將計算的梯度返回給parameter server,parameter server聚合從worker傳回的梯度,然後更新引數,並將新的引數廣播給worker。見下圖的左邊部分。
1.2 Ring-allreduce架構
在Ring-allreduce架構中,各個裝置都是worker,並且形成一個環,如上圖所示,沒有中心節點來聚合所有worker計算的梯度。在一個迭代過程,每個worker完成自己的mini-batch訓練,計算出梯度,並將梯度傳遞給環中的下一個worker,同時它也接收從上一個worker的梯度。對於一個包含N個worker的環,各個worker需要收到其它N-1個worker的梯度後就可以更新模型引數。其實這個過程需要兩個部分:scatter-reduce和allgather,百度開發了自己的allreduce框架,並將其用在了深度學習的分散式訓練中。
相比PS架構,Ring-allreduce架構有如下優點:
- 頻寬優化,因為叢集中每個節點的頻寬都被充分利用。而PS架構,所有的worker計算節點都需要聚合給parameter server,這會造成一種通訊瓶頸。parameter server的頻寬瓶頸會影響整個系統性能,隨著worker數量的增加,其加速比會迅速的惡化。
- 此外,在深度學習訓練過程中,計算梯度採用BP演算法,其特點是後面層的梯度先被計算,而前面層的梯度慢於前面層,Ring-allreduce架構可以充分利用這個特點,在前面層梯度計算的同時進行後面層梯度的傳遞,從而進一步減少訓練時間。在百度的實驗中,他們發現訓練速度基本上線性正比於GPUs數目(worker數)。
二、通用機器學習框架對分散式模型的支援
2.1 Tensorflow原生PS架構
通過TensorFlow原生的PS-Worker架構可以採用分散式訓練進而提升我們的訓練效果,但是實際應用起來並不輕鬆:
- 概念多,學習曲線陡峭:tensorflow的叢集採用的是parameter server架構,因此引入了比較多複雜概念
- 修改的程式碼量大:如果想把單機單卡的模型,移植到多機多卡,涉及的程式碼量是以天記的,慢的話甚至需要一週。
- 需要多臺機子跑不同的指令碼:tensorflow叢集是採用parameter server架構的,要想跑多機多卡的叢集,每個機子都要啟動一個client,即跑一個指令碼,來啟動訓練,100個機子,人就要崩潰了。
- ps和worker的比例不好選取:tensorflow叢集要將伺服器分為ps和worker兩種job型別,ps設定多少效能最近並沒有確定的計算公式。
- 效能損失較大:tensorflow的叢集效能並不好,當超過一定規模時,效能甚至會掉到理想效能的一半以下。
2.2 Pytorch分散式簡介
PyTorch用1.0穩定版本開始,torch.distributed軟體包和torch.nn.parallel.DistributedDataParallel模組由全新的、重新設計的分散式庫提供支援。 新的庫的主要亮點有:
- 新的 torch.distributed 是效能驅動的,並且對所有後端 (Gloo,NCCL 和 MPI) 完全非同步操作
- 顯著的分散式資料並行效能改進,尤其適用於網路較慢的主機,如基於乙太網的主機
- 為torch.distributed package中的所有分散式集合操作新增非同步支援
- 在Gloo後端新增以下CPU操作:send,recv,reduce,all_gather,gather,scatter
- 在NCCL後端新增barrier操作
- 為NCCL後端新增new_group支援
1.0的多機多卡的計算模型並沒有採用主流的Parameter Server結構,而是直接用了Uber Horovod的形式,也是百度開源的RingAllReduce演算法。
2.3 分散式Horovod介紹
Horovod 是一套支援TensorFlow, Keras, PyTorch, and Apache MXNet 的分散式訓練框架,由 Uber 構建並開源,Horovod 的主要主要有兩個優點:
- 採用Ring-Allreduce演算法,提高分散式裝置的效率;
- 程式碼改動少,能夠簡化分散式深度學習專案的啟動與執行。
Horovod 是一個相容主流計算框架的分散式機器學習訓練框架,主要基於的演算法是 AllReduce。 使用 horovod 有一定的侵入性,程式碼需要一定的修改才能變成適配分散式訓練,但是有一個好處就是適配的成本不高,並且 horovod 提供的各種框架的支援可以讓 horovod 比較好的在各個框架的基礎上使用,他支援 tensorflow/keras/mxnet/pytorch,MPI 的實現也有很多,比如 OpenMPI 還有 Nvidia 的 NCCL,還有 facebook 的 gloo,他們都實現了一種平行計算的通訊和計算方式。而且 horovod 的本身的實現也很簡單。
參考文獻:
https://eng.uber.com/horovod/
https://www.aiuai.cn/aifarm740.html
https://zhuanlan.zhihu.com/p/40578792
https://ggaaooppeenngg.github.io/zh-CN/2019/08/30/horovod-實現分析/
https://blog.csdn.net/zwqjoy/article/details/89552432
https://www.jiqizhixin.com/articles/2019-04-11-21
https://zhuanlan.zhihu.com/p/50116885
https://zhuanlan.zhihu.com/p/70603273
https://juejin.im/post/5cbc6dbd5188253236619ccb
https://zhpmatrix.github.io/2019/07/18/speed-up-pytorch/
https://cloud.tencent.com/developer/article/1117910
https://www.infoq.cn/article/J-EckTKHH9lNYdc6