背景
隨着各大企業和研究機構在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-EckTKHH9lNYdc6QacH