NCCL是Nvidia Collective multi-GPU Communication Library的簡(jiǎn)稱,它是一個(gè)實(shí)現(xiàn)多GPU的collective communication通信(all-gather, reduce, broadcast)庫(kù),Nvidia做了很多優(yōu)化,以在PCIe、Nvlink、InfiniBand上實(shí)現(xiàn)較高的通信速度。
下面分別從以下幾個(gè)方面來(lái)介紹NCCL的特點(diǎn),包括基本的communication primitive、ring-base collectives、NCCL在單機(jī)多卡上以及多機(jī)多卡實(shí)現(xiàn)、最后分享實(shí)際使用NCCL的一些經(jīng)驗(yàn)。
(1)communication primitive
并行任務(wù)的通信一般可以分為Point-to-point communication和Collective communication。P2P通信這種模式只有一個(gè)sender和一個(gè)receiver,實(shí)現(xiàn)起來(lái)比較簡(jiǎn)單。第二種Collective communication包含多個(gè)sender多個(gè)receiver,一般的通信原語(yǔ)包括broadcast,gather,all-gather,scatter,reduce,all-reduce,reduce-scatter,all-to-all等。簡(jiǎn)單介紹幾個(gè)常用的操作:
Reduce:從多個(gè)sender那里接收數(shù)據(jù),最終combine到一個(gè)節(jié)點(diǎn)上。
All-reduce:從多個(gè)sender那里接收數(shù)據(jù),最終combine到每一個(gè)節(jié)點(diǎn)上。
而傳統(tǒng)Collective communication假設(shè)通信節(jié)點(diǎn)組成的topology是一顆fat tree,如下圖所示,這樣通信效率最高。但實(shí)際的通信topology可能比較復(fù)雜,并不是一個(gè)fat tree。因此一般用ring-based Collective communication。
(2) ring-base collectives
ring-base collectives將所有的通信節(jié)點(diǎn)通過(guò)首尾連接形成一個(gè)單向環(huán),數(shù)據(jù)在環(huán)上依次傳輸。以broadcast為例, 假設(shè)有4個(gè)GPU,GPU0為sender將信息發(fā)送給剩下的GPU,按照環(huán)的方式依次傳輸,GPU0-->GPU1-->GPU2-->GPU3,若數(shù)據(jù)量為N,帶寬為B,整個(gè)傳輸時(shí)間為(K-1)N/B。時(shí)間隨著節(jié)點(diǎn)數(shù)線性增長(zhǎng),不是很高效。
下面把要傳輸?shù)臄?shù)據(jù)分成S份,每次只傳N/S的數(shù)據(jù)量,傳輸過(guò)程如下所示:
GPU1接收到GPU0的一份數(shù)據(jù)后,也接著傳到環(huán)的下個(gè)節(jié)點(diǎn),這樣以此類推,最后花的時(shí)間為
S*(N/S/B) + (k-2)*(N/S/B) = N(S+K-2)/(SB) --> N/B,條件是S遠(yuǎn)大于K,即數(shù)據(jù)的份數(shù)大于節(jié)點(diǎn)數(shù),這個(gè)很容易滿足。所以通信時(shí)間不隨節(jié)點(diǎn)數(shù)的增加而增加,只和數(shù)據(jù)總量以及帶寬有關(guān)。其它通信操作比如reduce、gather以此類推。
那么在以GPU為通信節(jié)點(diǎn)的場(chǎng)景下,怎么構(gòu)建通信環(huán)呢?如下圖所示:
單機(jī)4卡通過(guò)同一個(gè)PCIe switch掛載在一棵CPU的場(chǎng)景:
單機(jī)8卡通過(guò)兩個(gè)CPU下不同的PCIe switch掛載的場(chǎng)景:
(3)NCCL實(shí)現(xiàn)
NCCL實(shí)現(xiàn)成CUDA C++ kernels,包含3種primitive operations: Copy,Reduce,ReduceAndCopy。目前NCCL 1.0版本只支持單機(jī)多卡,卡之間通過(guò)PCIe、NVlink、GPU Direct P2P來(lái)通信。NCCL 2.0會(huì)支持多機(jī)多卡,多機(jī)間通過(guò)Sockets (Ethernet)或者InfiniBand with GPU Direct RDMA通信。
下圖所示,單機(jī)內(nèi)多卡通過(guò)PCIe以及CPU socket通信,多機(jī)通過(guò)InfiniBand通信。
同樣,在多機(jī)多卡內(nèi)部,也要構(gòu)成一個(gè)通信環(huán)
下面是單機(jī) 4卡(Maxwel GPU)上各個(gè)操作隨著通信量增加的帶寬速度變化,可以看到帶寬上限能達(dá)到10GB/s,接近PCIe的帶寬。
下圖是Allreduce在單機(jī)不同架構(gòu)下的速度比較:
先不看DGX-1架構(gòu),這是Nvidia推出的深度學(xué)習(xí)平臺(tái),帶寬能達(dá)到60GB/s。前面三個(gè)是單機(jī)多卡典型的三種連接方式,第三種是四張卡都在一個(gè)PCIe switch上,所以帶寬較高,能達(dá)到>10GB/s PCIe的帶寬大小,第二種是兩個(gè)GPU通過(guò)switch相連后再經(jīng)過(guò)CPU連接,速度會(huì)稍微低一點(diǎn),第一種是兩個(gè)GPU通過(guò)CPU然后通過(guò)QPI和另一個(gè)CPU上的兩塊卡相連,因此速度最慢,但也能達(dá)到>5GB/s。
下圖是Allreduce多機(jī)下的速度表現(xiàn),左圖兩機(jī)8卡,機(jī)內(nèi)PCIe,機(jī)間InfiniBand能達(dá)到>10GB/s的速度,InfiniBand基本上能達(dá)到機(jī)內(nèi)的通信速度。
下圖是NCCL在CNTK ResNet50上的scalability,32卡基本能達(dá)到線性加速比。
(4)我們的實(shí)測(cè)經(jīng)驗(yàn)
首先,在一臺(tái)K40 GPU的機(jī)器上測(cè)試了GPU的連接拓?fù)洌缦拢?/p>
可以看到前四卡和后四卡分別通過(guò)不同的CPU組連接,GPU0和GPU1直接通過(guò)PCIe switch相連,然后經(jīng)過(guò)CPU與GPU2和GPU3相連。
下面是測(cè)試PCIe的帶寬,可以看到GPU0和GU1通信能達(dá)到10.59GB/s,GPU0同GPU2~3通信由于要經(jīng)過(guò)CPU,速度稍慢,和GPU4~7的通信需要經(jīng)過(guò)QPI,所以又慢了一點(diǎn),但也能達(dá)到9.15GB/s。
而通過(guò)NVlink連接的GPU通信速度能達(dá)到35GB/s:
NCCL在不同的深度學(xué)習(xí)框架(CNTK/Tensorflow/Torch/Theano/Caffe)中,由于不同的模型大小,計(jì)算的batch size大小,會(huì)有不同的表現(xiàn)。比如上圖中CNTK中Resnet50能達(dá)到32卡線性加速比,Facebook之前能一小時(shí)訓(xùn)練出ImageNet,而在NMT任務(wù)中,可能不會(huì)有這么大的加速比。因?yàn)橛绊?span>并行計(jì)算效率的因素主要有并行任務(wù)數(shù)、每個(gè)任務(wù)的計(jì)算量以及通信時(shí)間。我們不僅要看絕對(duì)的通信量,也要看通信和計(jì)算能不能同時(shí)進(jìn)行以及計(jì)算/通信比,如果通信占計(jì)算的比重越小,那么并行計(jì)算的任務(wù)會(huì)越高效。NMT模型一般較大,多大幾十M上百M(fèi),不像現(xiàn)在image的模型能做到幾M大小,通信所占比重會(huì)較高。
下面是NMT模型單機(jī)多卡加速的一個(gè)簡(jiǎn)單對(duì)比圖:
以上就是對(duì)NCCL的一些理解,很多資料也是來(lái)自于NCCL的官方文檔,歡迎交流討論。
聯(lián)系客服