分布式訓(xùn)練的通訊原語

針對分布式訓(xùn)練服務(wù)器的集群進(jìn)行架構(gòu)設(shè)計,是為了更好地解決機(jī)器學(xué)習(xí)中分布式訓(xùn)練中的通訊問題。目前機(jī)器學(xué)習(xí)中主要由兩種分布式架構(gòu):

  1. 參數(shù)服務(wù)器架構(gòu)(Parameter Server,PS)
  2. 去中心化架構(gòu)(Decentralized Network)

其中,分布式訓(xùn)練通常在計算集群上進(jìn)行,集群的每個節(jié)點分別執(zhí)行一部分計算。不同節(jié)點的計算之間有數(shù)據(jù)依賴和共享,需要將數(shù)據(jù)在不同節(jié)點間傳輸,這就是通信。分布式的通信一般有兩大類:

  1. 集合通信(Collective communication,CC):在一組節(jié)點內(nèi)進(jìn)行通信
  2. 點對點通信(Point to point communication,P2P):在兩個節(jié)點之間進(jìn)行通信

深度學(xué)習(xí)訓(xùn)練過程中因為需要傳輸大量的網(wǎng)絡(luò)模型權(quán)重參數(shù)和訓(xùn)練過程中產(chǎn)生的大量臨時變量等,因此主要使用集合通信的方式。可以理解為,機(jī)器學(xué)習(xí)/深度學(xué)習(xí)的分布式訓(xùn)練,主要是采用在PS架構(gòu)下的集合通訊模式;而在大模型的分布式訓(xùn)練中,因為減少跟單點參數(shù)服務(wù)器統(tǒng)一更新,更多直接采用純集合通訊模式。

在深度學(xué)習(xí)框架中,分布式訓(xùn)練的通訊原語和通訊實現(xiàn)方式對AI框架分布式訓(xùn)練起著非常重要的作用,如果想要訓(xùn)練大模型(Foundation Model)肯定離不開進(jìn)行通訊操作,下面橙色標(biāo)簽的是分布式訓(xùn)練中通訊原語在AI框架中的的位置。

image

為什么需要對通訊操作

當(dāng)將神經(jīng)網(wǎng)絡(luò)的訓(xùn)練并行化到集群中不同的節(jié)點時,必須選擇如何將不同的計算操作分配到集群中可用的節(jié)點,這就離不開對分布式集群的通訊進(jìn)行操作。

數(shù)據(jù)并行通訊問題

通常神經(jīng)網(wǎng)絡(luò)的訓(xùn)練學(xué)習(xí)過程中,使用隨機(jī)梯度下降算法SGD進(jìn)行訓(xùn)練。

以分布式數(shù)據(jù)并行為例,在數(shù)據(jù)并行訓(xùn)練中,每塊NPU都有整個神經(jīng)網(wǎng)絡(luò)模型的完整副本,每次進(jìn)行迭代的時候,只分配了小批次Batch中數(shù)據(jù)樣本的子集,每塊NPU利用該Batch樣本數(shù)據(jù)進(jìn)行網(wǎng)絡(luò)模型的前向計算,然后計算損失誤差進(jìn)行反向傳播,以計算損耗相對于網(wǎng)絡(luò)參數(shù)的梯度。

最后,NPU 之間進(jìn)行相互通信,計算由不同 NPU 得到的梯度的平均值,將平均梯度應(yīng)用于總體權(quán)重以獲得網(wǎng)絡(luò)模型中本次迭代的最新權(quán)重。任何一塊 NPU 都在鎖定步驟的迭代中前進(jìn),一旦某塊 NPU 完成了本輪迭代,必須等待集群中所有 NPU 完成各自的迭代,這樣神經(jīng)網(wǎng)絡(luò)的總體權(quán)重才能被正確更新。簡單地理解,相當(dāng)于在單個 NPU 上執(zhí)行SGD,但是通過在多個 NPU 之間分發(fā)數(shù)據(jù),通過并行執(zhí)行計算來獲得加速。這就是簡單的分布式數(shù)據(jù)并行(DP)方式。

image

當(dāng)只有兩個 NPU 和以兆字節(jié)數(shù)據(jù)衡量網(wǎng)絡(luò)模型參數(shù)的時候,NPU 的通信方式可能并不重要。然而,當(dāng)網(wǎng)絡(luò)模型的參數(shù)量去到十億甚至萬億個參數(shù)時,僅僅是計算梯度所產(chǎn)生的臨時變量就需要數(shù)十億字節(jié)的 NPU 內(nèi)存空間,并且需要協(xié)調(diào)數(shù)十個 NPU 共同工作,這個時候通信機(jī)制變得至關(guān)重要。

例如,考慮上圖中最直接的數(shù)據(jù)并行通信方式:每一個 NPU 都計算其小Batch上的梯度,然后每個 NPU 將其梯度發(fā)送到 CPU 上,該 CPU 取所有梯度的平均值,并將平均值發(fā)送回所有其他 NPU。

直接從單個 CPU 發(fā)送和接收數(shù)據(jù)的機(jī)制中,CPU 必須從所有 NPU 中接收參數(shù),并將所有參數(shù)逐一發(fā)送到所有 NPU中,當(dāng)分布式集群系統(tǒng)中的 NPU 節(jié)點越多,通信成本就越大。

現(xiàn)在來以上述的通信策略評估在真實網(wǎng)絡(luò)模型上運行的帶寬效果。以三億個可訓(xùn)練參數(shù)的網(wǎng)絡(luò)模型為例:假設(shè)每個參數(shù)四個字節(jié),三億個參數(shù)約1.2千兆字節(jié),分布式系統(tǒng)的網(wǎng)絡(luò)硬件可以支持每秒1千兆字節(jié)的帶寬。在這種情況下,將系統(tǒng)并行化到兩個 NPU 上將使每次迭代減慢1.2秒,將訓(xùn)練并行化到10個 NPU 將使每次迭代減慢10.8秒。隨著 NPU 數(shù)量的增長,每次迭代所需的時間將會呈線性增長。

需要發(fā)送的數(shù)據(jù)越多,通訊的時間就越長。每個通信通道都有一個最大的吞吐量,即網(wǎng)絡(luò)帶寬。例如,一個Internet連接可以提供每秒15兆字節(jié)的帶寬,而千兆以太網(wǎng)連接可以提供每秒125兆字節(jié)的帶寬,HPC集群上的專用網(wǎng)絡(luò)硬件Infiniband可以在節(jié)點之間提供每秒GB級的帶寬。即使每次迭代花費幾秒鐘,通信成本的線性增長也會使得分布式并行,并沒有帶來實際的優(yōu)化,反而會降低訓(xùn)練效率。

異步 vs 同步通訊

異步 vs 同步通信屬于網(wǎng)絡(luò)模型參數(shù)更新的策略。

數(shù)據(jù)并行中,在各個 NPU 分別根據(jù)各自獲得的batch,前向計算獲得損失,進(jìn)而反向傳播計算梯度。計算好梯度后,就涉及到一個梯度同步的問題:每個節(jié)點都有根據(jù)自己的數(shù)據(jù)計算的梯度,如何在不同節(jié)點之間維護(hù)模型的不同副本之間的一致性?

如果不同的模型以某種方式最終獲得不同的權(quán)重,則權(quán)重更新將變得不一致,最終導(dǎo)致網(wǎng)絡(luò)模型參數(shù)收斂迭代收斂情況前后不一致,這稱為模型一致性問題(consistency of model),如何同步更新網(wǎng)絡(luò)模型參數(shù),這是分布式機(jī)器學(xué)習(xí)系統(tǒng)的一個核心問題。

為了解決模型一致性問題,分布式訓(xùn)練的梯度同步策略可分為異步(Asynchronous)梯度更新和同步(Synchronous)梯度更新機(jī)制。

同步指的是所有的節(jié)點都采用相同的模型參數(shù)來訓(xùn)練,等待所有設(shè)備的batch訓(xùn)練完成后,收集它們的梯度然后取均值,最后所有網(wǎng)絡(luò)模型的參數(shù)一次性更新。

由于每一輪迭代結(jié)束時,計算的比較快的節(jié)點都需等待算得慢的節(jié)點信息進(jìn)行同步,再進(jìn)行下一輪迭代。類似于木桶效應(yīng),所以同步方式的性能取決于集群通訊最慢的節(jié)點。

image

異步通訊中,各節(jié)點完成一個batch數(shù)據(jù)的訓(xùn)練之后,不需要等待其它節(jié)點,直接更新Server中的網(wǎng)絡(luò)模型參數(shù),因為是異步更新參數(shù)的因此不需要阻塞性等待單節(jié)點的數(shù)據(jù),使得總體會訓(xùn)練速度會快很多。

異步通訊的問題是梯度失效(stale gradients),剛開始所有節(jié)點采用相同的參數(shù)來訓(xùn)練,但是異步情況下,某節(jié)點完成 T 步迭代訓(xùn)練后,可能發(fā)現(xiàn)模型參數(shù)其實已經(jīng)被其它設(shè)備在 T+n 步更新過了,如果當(dāng)前節(jié)點把 T 步迭代訓(xùn)練參數(shù)更新到 Server中,會造成 n 步內(nèi)的梯度更新無效。由于梯度失效問題,異步訓(xùn)練雖然速度快,但是可能陷入次優(yōu)解(sub-optimal training performance)。

image

回到上面三億個可訓(xùn)練參數(shù)的網(wǎng)絡(luò)模型案例中,另一種參數(shù)更新的選擇是異步通訊,雖然異步更新會使得數(shù)據(jù)同步不需要阻塞性地等待,減少通訊的延時,但是消除了參數(shù)的同步更新后會使得SGD很難調(diào)試和收斂,因此不考慮異步更新的策略。

總的來說,在訓(xùn)練大模型的時候離不開分布式并行操作,需要利用分布式集群中的帶寬通訊優(yōu)化操作,優(yōu)化深度學(xué)習(xí)參數(shù)同步策略來解決通信瓶頸。

通訊原語操作

集合通訊中包含多個sender和多個receiver,一般的通信原語包括broadcast、gather、all-gather、scatter、reduce、all-reduce、reduce-scatter、all-to-all等通信操作進(jìn)行數(shù)據(jù)傳輸,下面將會分別介紹其具體含義。

Broadcast

在集合通信中,如果某個節(jié)點想把自身的數(shù)據(jù)發(fā)送到集群中的其他節(jié)點,那么就可以使用廣播Broadcast的操作。

如圖所示,圓圈表示分布式系統(tǒng)中的獨立節(jié)點,一共4個節(jié)點,小方塊則代表了數(shù)據(jù),顏色相同表示數(shù)據(jù)一樣。Broadcast代表廣播行為,執(zhí)行Broadcast時,數(shù)據(jù)從主節(jié)點0廣播至其他各個指定的節(jié)點(0~3)。

image

Broadcast操作是將某節(jié)點的輸入廣播到其他節(jié)點上,分布式機(jī)器學(xué)習(xí)中常用于網(wǎng)絡(luò)參數(shù)的初始化。如圖中,從單個sender數(shù)據(jù)發(fā)送到其他節(jié)點上,將0卡大小為1xN的Tensor進(jìn)行廣播,最終每張卡輸出均為[1xN]的矩陣。

image

Scatter

Scatter操作表示一種散播行為,將主節(jié)點的數(shù)據(jù)進(jìn)行劃分并散布至其他指定的節(jié)點。

image

實際上,Scatter與Broadcast非常相似,都是一對多的通信方式,不同的是Broadcast的0號進(jìn)程將相同的信息發(fā)送給所有的進(jìn)程,而Scatter則是將數(shù)據(jù)的不同部分,按需發(fā)送給所有的進(jìn)程。

如圖所示,從單個sender數(shù)據(jù)發(fā)送到其他節(jié)點上。

image

Reuduce

Reuduce稱為規(guī)約運算,是一系列簡單運算操作的統(tǒng)稱,細(xì)分可以包括:SUM、MIN、MAX、PROD、LOR等類型的規(guī)約操作。Reuduce意為減少/精簡,因為其操作在每個進(jìn)程上獲取一個輸入元素數(shù)組,通過執(zhí)行操作后,將得到精簡的更少的元素。下面以Reduce sum為例子。

image

在NCCL中的Reduce,從多個sender那里接收數(shù)據(jù),最終combine到一個節(jié)點上。

image

All Reduce

Reduce是一系列簡單運算操作的統(tǒng)稱,All Reduce則是在所有的進(jìn)程上都應(yīng)用同樣的Reduce操作。以All Reduce Sum為例。

image

All Reduce操作可通過單節(jié)點上Reduce + Broadcast操作完成。在NCCL中的All Reduce中,則是從多個sender那里接收數(shù)據(jù),最終合并和分發(fā)到每一個節(jié)點上。

image

Gather

Gather操作將多個sender上的數(shù)據(jù)收集到單個節(jié)點上,Gather可以理解為反向的Scatter。

image

Gather操作會從多個進(jìn)程里面收集數(shù)據(jù)到一個進(jìn)程上面,而不是從一個進(jìn)程分發(fā)數(shù)據(jù)到多個進(jìn)程。這個機(jī)制對很多平行算法很有用,比如并行的排序和搜索。

image

All Gather

很多時候發(fā)送多個元素到多個進(jìn)程也很有用,即在多對多通信模式的場景。這個時候就需要 All Gather操作。

image

對于分發(fā)在所有進(jìn)程上的一組數(shù)據(jù)來說,All Gather會收集所有數(shù)據(jù)到所有進(jìn)程上。從最基礎(chǔ)的角度來看,All Gather相當(dāng)于一個Gather操作之后跟著一個Bcast操作。下面的示意圖顯示了All Gather調(diào)用之后數(shù)據(jù)是如何分布的。

image

Reduce Scatter

Reduce Scatter操作會將個進(jìn)程的輸入先進(jìn)行求和,然后在第0維度按卡數(shù)切分,將數(shù)據(jù)分發(fā)到對應(yīng)的卡上。例如上圖所示,每卡的輸入均為4x1的Tensor。Reduce Scatter先對輸入求和得到[0, 4, 8, 12]的Tensor,然后進(jìn)行分發(fā),每卡獲得1x1大小的Tensor。例如卡0對應(yīng)的輸出結(jié)果為[[0.0]],卡1對應(yīng)的輸出結(jié)果為[[4.0]]。

image

All to All

All to All作為全交換操作,通過All to All通信,可以讓每個節(jié)點都獲取其他節(jié)點的值。

在使用 All to All 時,每一個進(jìn)程都會向任意一個進(jìn)程發(fā)送消息,每一個進(jìn)程也都會接收到任意一個進(jìn)程的消息。每個進(jìn)程的接收緩沖區(qū)和發(fā)送緩沖區(qū)都是一個分為若干個數(shù)據(jù)塊的數(shù)組。All to All 的具體操作是:將進(jìn)程i的發(fā)送緩沖區(qū)中的第j塊數(shù)據(jù)發(fā)送給進(jìn)程j,進(jìn)程j將接收到的來自進(jìn)程i的數(shù)據(jù)塊放在自身接收緩沖區(qū)的第i塊位置。

All to All 與 All Gather 相比較,區(qū)別在于:All Gather 操作中,不同進(jìn)程向某一進(jìn)程收集到的數(shù)據(jù)是完全相同的,而在 All to All 中,不同的進(jìn)程向某一進(jìn)程收集到的數(shù)據(jù)是不同的。在每個進(jìn)程的發(fā)送緩沖區(qū)中,為每個進(jìn)程都單獨準(zhǔn)備了一塊數(shù)據(jù)。

image

AI框架中的通信實現(xiàn)

分布式集群的網(wǎng)絡(luò)硬件多種多樣,可以是Ethernet、InfiniBand 等,深度學(xué)習(xí)框架通常不直接操作硬件,而是使用通信庫。之所以采用通信庫屏,是因為其蔽了底層硬件細(xì)節(jié),提供了統(tǒng)一封裝的通信接口。其中MPI和NCCL是最常用的通訊庫,MPI專注于CPU的并行通訊,NCCL則專注于GPU的通訊。

Message Passing Interface (MPI)

MPI 信息傳遞接口,是一個用于編寫并行計算程序的編程接口。它提供了豐富全面的通信功能。

MPI 常用于在計算集群、超算上編寫程序,比如很多傳統(tǒng)科學(xué)計算的并行程序。MPI 接口的兼容性好,通信功能豐富,在深度學(xué)習(xí)框架中主要用于 CPU 數(shù)據(jù)的通信。

MPI是一個開放接口,有多種實現(xiàn)的庫,一種廣泛使用的開源實現(xiàn)是 Open MPI。一些硬件廠商也提供針對硬件優(yōu)化的實現(xiàn)。

NVIDIA Collective Communication Library (NCCL)

NCCL 英偉達(dá)集合通信庫,是一個專用于多個 GPU 乃至多個節(jié)點間通信的實現(xiàn)。它專為英偉達(dá)的計算卡和網(wǎng)絡(luò)優(yōu)化,能帶來更低的延遲和更高的帶寬。

NCCL 也提供了較豐富的通信功能,接口形式上與 MPI 相似,可滿足大多數(shù)深度學(xué)習(xí)任務(wù)的通信需求。它在深度學(xué)習(xí)框架中專用于 GPU 數(shù)據(jù)的通信。因為NCCL則是NVIDIA基于自身硬件定制的,能做到更有針對性且更方便優(yōu)化,故在英偉達(dá)硬件上,NCCL的效果往往比其它的通信庫更好。

MPI和NCCL的關(guān)系

openMPI的通訊算法和通訊操作原語最晚在2009年就都已經(jīng)成熟并開源了,而Nvidia在2015年下半年首次公開發(fā)布NCCL。

既然openMPI已經(jīng)實現(xiàn)了這么多All Reduce算法,為什么英偉達(dá)還要開發(fā)NCCL?是不是從此只要NCCL,不再需要MPI了呢?

NO

從openMPI的源碼里能看到,其完全沒有考慮過深度學(xué)習(xí)的場景,基本沒有考慮過GPU系統(tǒng)架構(gòu)。很明顯的一點,MPI中各個工作節(jié)點基本視為等同,并沒有考慮節(jié)點間latency和帶寬的不同,所以并不能充分發(fā)揮異構(gòu)場景下的硬件性能。

Nvidia的策略還是比較聰明,不和MPI競爭,只結(jié)合硬件做MPI沒做好的通信性能優(yōu)化。在多機(jī)多卡分布式訓(xùn)練中,MPI還是廣泛用來做節(jié)點管理,NCCL只做GPU的實際規(guī)約通信。NCCL可以輕松與MPI結(jié)合使用,將MPI用于CPU到CPU的通信,將NCCL用于GPU到GPU的通信。

而NCCL的優(yōu)勢就在于完全貼合英偉達(dá)自己的硬件,能充分發(fā)揮性能。但是基本的算法原理其實相比openMPI里實現(xiàn)的算法是沒有太大變化。

NCCL1.x只能在單機(jī)內(nèi)部進(jìn)行通信,NCCL2.0開始支持多節(jié)點(2017年Q2)。所以在NCCL2之前大家還會依賴MPI來進(jìn)行集合通信。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容