楊志剛,吳俊敏,2a,,徐 恒,尹 燕
(1.中國(guó)科學(xué)技術(shù)大學(xué) 計(jì)算機(jī)科學(xué)與技術(shù)學(xué)院,合肥 230022;2.中國(guó)科學(xué)技術(shù)大學(xué) a.蘇州研究院; b.軟件學(xué)院,江蘇 蘇州 215123)
由于GPU設(shè)備的特殊性,對(duì)GPU虛擬化的研究尚處于起步階段。而且在分布式環(huán)境下,如何有效使用集群中所有的GPU資源成為一大難題。將GPU本身的并行加速計(jì)算與GPU虛擬化技術(shù)有效結(jié)合在一起,可以有效地調(diào)用遠(yuǎn)程計(jì)算機(jī)的GPU資源,甚至可以將分布式集群環(huán)境中的GPU資源集中起來,更好地提高計(jì)算效率。
深度神經(jīng)網(wǎng)絡(luò)的GPU加速是當(dāng)下的研究熱點(diǎn)。在多GPU上的加速方法一般有數(shù)據(jù)并行和模型并行,但是與單機(jī)多GPU相比,如何在多機(jī)多GPU上部署模型加速訓(xùn)練,除了單個(gè)GPU的加速之外,分布式環(huán)境中的通信和接口也是需要重點(diǎn)解決的問題。
本文針對(duì)分布式環(huán)境中的多機(jī)多GPU的深度神經(jīng)網(wǎng)絡(luò)訓(xùn)練的問題,提出一種基于虛擬化的遠(yuǎn)程GPU調(diào)用的解決方案,并將該方案與單機(jī)多GPU的情況進(jìn)行對(duì)比,以分析其優(yōu)缺點(diǎn)。
GPU虛擬化的實(shí)現(xiàn)比CPU要復(fù)雜。CPU處理器自帶分時(shí)機(jī)制可以有效地實(shí)現(xiàn)上下文進(jìn)程間的迅速切換,同時(shí)分時(shí)機(jī)制支持不同虛擬化CPU之間的進(jìn)程切換。但是GPU本身并不支持分時(shí)機(jī)制,不能有效支持上下文之間的進(jìn)程切換,而且在相同的時(shí)間段內(nèi)只能單一地支持同一個(gè)任務(wù)。同時(shí),GPU制造商如NVIDIA,閉源關(guān)于GPU的驅(qū)動(dòng)源代碼,因此,其驅(qū)動(dòng)程序并不能由其他系統(tǒng)方案支持和控制,這也給GPU虛擬化造成很大的影響。迄今為止,GPU虛擬化還沒有一套完善的處理方案。
API重定向虛擬化的方法集中在在通用計(jì)算方面,主要是基于CUDA的解決方案[1]。目前比較成熟的框架有g(shù)Virtus、vCUDA[2]、rCUDA[3]、GViM等。這些框架都是采用類似的訪問機(jī)制,支持在虛擬機(jī)環(huán)境或者沒有GPU資源的環(huán)境中能夠訪問遠(yuǎn)程GPU資源。這種類似的訪問機(jī)制就是以支持前后端通信鏈路為基礎(chǔ),在虛擬機(jī)或者沒有GPU資源的環(huán)境中截獲CUDA API的函數(shù)調(diào)用,然后利用不同的通信方法,將調(diào)用的函數(shù)和參數(shù)轉(zhuǎn)發(fā)到被調(diào)用GPU資源的主機(jī)后端,主機(jī)后端執(zhí)行相應(yīng)的函數(shù)調(diào)用,并將執(zhí)行的結(jié)果通過通信方法返回給前端。這是圖形方法虛擬化的一種常見方法。與這些虛擬化框架不同的是在虛擬機(jī)和特權(quán)域之間的通信方式,vCUDA采用RPC的遠(yuǎn)程過程調(diào)用,GViM是基于XEN系統(tǒng),gVirtus提供多種不同類型的通信方式,rCUDA主要采用的是TCP/IP的通信方式。
利用TCP/IP通信實(shí)現(xiàn)的GPU虛擬化,可以使一臺(tái)沒有GPU資源的計(jì)算機(jī)調(diào)用通用網(wǎng)絡(luò)中其他的GPU資源進(jìn)行有效的CUDA加速計(jì)算。同樣,如果重新修改通信模式,讓沒有GPU資源的計(jì)算機(jī)同時(shí)調(diào)用分布式環(huán)境中的多個(gè)遠(yuǎn)程GPU資源,可以有效地實(shí)現(xiàn)分布式GPU資源的抽象。本文即是按照這樣的思路,實(shí)現(xiàn)分布式環(huán)境中多機(jī)多GPU的深度神經(jīng)網(wǎng)絡(luò)加速計(jì)算。在分布式多機(jī)多GPU的環(huán)境中,利用虛擬化的方法在不影響CUDA編程接口的情況下實(shí)現(xiàn)對(duì)多個(gè)遠(yuǎn)程GPU的并發(fā)調(diào)用,使得在虛擬機(jī)的節(jié)點(diǎn)或者沒有GPU的設(shè)備節(jié)點(diǎn)上具備集群中所有其他機(jī)器上GPU的計(jì)算能力[4]。這也是將GPU虛擬化和分布式深度神經(jīng)網(wǎng)絡(luò)訓(xùn)練結(jié)合起來的有效出發(fā)點(diǎn)。
雖然深度學(xué)習(xí)已經(jīng)有數(shù)十年的歷史,但是2個(gè)較為先進(jìn)的趨勢(shì)進(jìn)一步促進(jìn)了深度學(xué)習(xí)的廣泛應(yīng)用:海量訓(xùn)練數(shù)據(jù)的出現(xiàn)以及GPU計(jì)算所提供的強(qiáng)大而高效的并行計(jì)算。人們利用GPU來訓(xùn)練這些深度神經(jīng)網(wǎng)絡(luò)所使用的訓(xùn)練集大得多,所耗費(fèi)的時(shí)間大幅縮短,占用的數(shù)據(jù)中心基礎(chǔ)設(shè)施也少得多[5]。但是單個(gè)GPU的加速環(huán)境已經(jīng)漸漸不能滿足人們的需求。訓(xùn)練更大規(guī)模的數(shù)據(jù)量,更大規(guī)模的網(wǎng)絡(luò)結(jié)構(gòu)是隨著訓(xùn)練數(shù)據(jù)的急劇增長(zhǎng)與模型復(fù)雜度的不斷提高而提出的必然要求。但是采用單個(gè)GPU加速,在訓(xùn)練海量數(shù)據(jù)及超大規(guī)模的網(wǎng)絡(luò)時(shí)存在很嚴(yán)重的性能問題,模型需要很長(zhǎng)的時(shí)間,甚至超過人類的容忍范圍的時(shí)間中才能夠達(dá)到模型的收斂[6]。因此,多個(gè)GPU的并行加速已經(jīng)成為一個(gè)必然趨勢(shì)。常見的方法就是在服務(wù)器上部署多個(gè)GPU卡或者部署分布式GPU集群。多GPU卡的并行加速,不斷提高并行加速的程序性能,訓(xùn)練過程中有效存儲(chǔ)更大規(guī)模的網(wǎng)絡(luò)都是多GPU環(huán)境下發(fā)展的熱門方向[7]。
對(duì)于深度神經(jīng)網(wǎng)絡(luò)的單機(jī)多GPU并行訓(xùn)練,目前比較多的處理方法有數(shù)據(jù)并行和模型并行2種方式[8]。數(shù)據(jù)并行是在不同的GPU卡上部署相同的訓(xùn)練模型實(shí)例,然后將訓(xùn)練的數(shù)據(jù)有效切分到不同GPU卡上,對(duì)多GPU卡上的模型進(jìn)行并行訓(xùn)練,并在合理的時(shí)間進(jìn)行參數(shù)同步,保證最終只訓(xùn)練出一個(gè)模型。與之相對(duì)應(yīng)的是模型并行,模型并行并不劃分?jǐn)?shù)據(jù)塊,而是將大規(guī)模的網(wǎng)絡(luò)結(jié)構(gòu)進(jìn)行合理劃分,劃分的子結(jié)構(gòu)由不同的GPU資源擁有,最后不同的GPU資源共同協(xié)作,完成一個(gè)完整網(wǎng)絡(luò)結(jié)構(gòu)的有效訓(xùn)練。數(shù)據(jù)并行的通信開銷來自于參數(shù)同步,而模型并行的通信開銷來自于不同GPU上神經(jīng)元的依賴關(guān)系。無論是數(shù)據(jù)并行還是模型并行都可以有效地將深度神經(jīng)網(wǎng)絡(luò)的訓(xùn)練部署到多個(gè)GPU卡上,以達(dá)到訓(xùn)練時(shí)間加速的目的[9]。
另外在深度神經(jīng)網(wǎng)絡(luò)的多GPU訓(xùn)練過程中,需要處理一臺(tái)機(jī)器多GPU卡和多臺(tái)機(jī)器多GPU卡的情況。由于后者的延遲和帶寬遠(yuǎn)差于前者,因此需要對(duì)這2種情況做不同的技術(shù)考慮。單機(jī)多GPU是采用P2P拷貝到內(nèi)存,用stream開始多線程。在分布式環(huán)境下的多機(jī)多GPU是采用parameter server[10]或者M(jìn)PI還是部署一個(gè)新的框架,2個(gè)場(chǎng)景都有很多可選擇的方案。設(shè)計(jì)一個(gè)分布式代碼的困難是如何將并行的接口自然地獨(dú)立出來,使其不會(huì)影響GPU編碼和其他部分的實(shí)現(xiàn)。
本文利用虛擬化的方法,將單機(jī)多GPU和多機(jī)多GPU2種不同環(huán)境下的編程模式有效地統(tǒng)一起來。不管是單機(jī)多GPU還是多機(jī)多GPU,這2種情況中多GPU的CUDA編程模塊都是相似的,不同的是基于不同環(huán)境的通信模式和通信框架。利用虛擬化的方法可以將通信模式,通信框架和CUDA本身的編碼內(nèi)容分開,使得基于單機(jī)多GPU的CUDA代碼不需要修改,或者進(jìn)行少量的修改就可以直接執(zhí)行在分布式環(huán)境的多機(jī)多GPU上,從而實(shí)現(xiàn)兩者在編程模式上的統(tǒng)一。
為實(shí)現(xiàn)單機(jī)多GPU和多機(jī)多GPU環(huán)境下訓(xùn)練深度神經(jīng)網(wǎng)絡(luò)編程模式上的統(tǒng)一,首先討論在虛擬化環(huán)境下如何實(shí)現(xiàn)深度神經(jīng)網(wǎng)絡(luò)調(diào)用遠(yuǎn)程GPU資源加速訓(xùn)練的方法。
在常見的GPU虛擬化方案中始終貫徹著3個(gè)重要的設(shè)計(jì)目標(biāo):高效性,普適性,透明性。高效性是減少虛擬化所帶來的開銷,普適性是為了讓虛擬化方案能夠適應(yīng)不同的虛擬化平臺(tái)。而透明性是指虛擬化的平臺(tái)方案能夠有效地支持CUDA程序的有效移植移植。在虛擬機(jī)環(huán)境中,用戶并不知道GPU資源是物理的還是虛擬的,因此,所有的CUDA程序不需要進(jìn)行修改或者重新編譯就能運(yùn)行在虛擬GPU的資源上。這種機(jī)制中透明性的設(shè)計(jì)目標(biāo)將始終貫徹本文,也是能實(shí)現(xiàn)不同多GPU平臺(tái)編程模式統(tǒng)一的設(shè)計(jì)理念的出發(fā)點(diǎn)。
本節(jié)重點(diǎn)討論在單個(gè)GPU虛擬化中,如何將深度神經(jīng)網(wǎng)絡(luò)訓(xùn)練和虛擬化通信兩部分的內(nèi)容隔離,并以此類推得到多GPU中深度神經(jīng)網(wǎng)絡(luò)訓(xùn)練的平臺(tái)和方法。
在利用API重定向的GPU虛擬化方案中,以gVirtus為例,在虛擬機(jī)端或者沒有GPU資源的客戶端建立一個(gè)新的CUDA加速庫(kù)libcudart.so,替換原生CUDA中的原始庫(kù),并具備和CUDA相同的接口。其作用就是當(dāng)出現(xiàn)CUDA API的函數(shù)調(diào)用時(shí),新的加速庫(kù)libcudart.so會(huì)攔截函數(shù)調(diào)用,并通過合理的通信方式,如TCP/IP,將函數(shù)調(diào)用的函數(shù)名和函數(shù)參數(shù)發(fā)送到服務(wù)器端。在服務(wù)器端使用物理GPU進(jìn)行計(jì)算,最終將計(jì)算結(jié)果利用Socket返回給虛擬機(jī),以此達(dá)到虛擬化的目的。具體實(shí)現(xiàn)框圖如圖1所示。
圖1 API重定向的虛擬化框圖
這種GPU虛擬化方案針對(duì)NVIDIA CUDA框架,是目前應(yīng)用最廣泛的GPU虛擬化框架。該API重定向的虛擬化框架可以在虛擬機(jī)平臺(tái)下有效運(yùn)行,最終能夠使沒有GPU資源的虛擬機(jī)調(diào)用遠(yuǎn)程GPU資源進(jìn)行高性能的并行加速計(jì)算。這種方案不僅可以應(yīng)用在虛擬機(jī)中,同時(shí)對(duì)于沒有GPU資源或者擁有缺少CUDA支持GPU資源的計(jì)算機(jī),可以利用通用網(wǎng)絡(luò)的Socket通信來調(diào)用遠(yuǎn)程機(jī)器上的GPU資源。利用這種方法來調(diào)用遠(yuǎn)程的GPU資源訓(xùn)練本地機(jī)器上的深度神經(jīng)網(wǎng)絡(luò)。
使用遠(yuǎn)程GPU的調(diào)用方法和基于API重定向的GPU虛擬化方法并沒有本質(zhì)上的差異。唯一的區(qū)別在于通信方式在遠(yuǎn)程GPU中只能選擇通用網(wǎng)絡(luò)中的TCP/IP模式,而不能使用其他虛擬機(jī)和本地機(jī)器之間的通信方式。
如圖2所示,可以得到基于遠(yuǎn)程GPU的深度神經(jīng)網(wǎng)絡(luò)訓(xùn)練的基本方案:首先利用虛擬化的方法得到遠(yuǎn)程GPU的計(jì)算資源,然后上層可以直接利用通用的CUDA編程進(jìn)行深度學(xué)習(xí)的加速訓(xùn)練。兩者能夠互相獨(dú)立并且有效地結(jié)合在一起,主要是由于在虛擬化方案設(shè)計(jì)中的透明性。深度神經(jīng)網(wǎng)絡(luò)的CUDA加速代碼不需要進(jìn)行修改或者重新編譯,就可以直接運(yùn)行在虛擬化的遠(yuǎn)程GPU上。
圖2 深度神經(jīng)網(wǎng)絡(luò)的遠(yuǎn)程GPU調(diào)用流程
關(guān)于深度神經(jīng)網(wǎng)絡(luò)的CUDA加速訓(xùn)練是目前的研究熱點(diǎn)。單GPU的神經(jīng)網(wǎng)絡(luò)訓(xùn)練加速已經(jīng)有成熟的研究成果,本文不再贅述。這里主要考察基于遠(yuǎn)程GPU的深度神經(jīng)網(wǎng)絡(luò)的訓(xùn)練加速的性能。實(shí)驗(yàn)采用的環(huán)境是Intel(R) Core(TM) i5-4590 CPU,7.8 GHz的內(nèi)存,ubuntu14.04的操作系統(tǒng),配置一塊GeForce GTX 750的GPU卡。在虛擬環(huán)境或者沒有GPU資源的環(huán)境中,采用ubuntu14.04的操作系統(tǒng),除了顯卡外其他資源相同。
本文所采用的深度神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)如圖3所示,其中訓(xùn)練的數(shù)據(jù)為mnist手寫數(shù)字識(shí)別的數(shù)據(jù),訓(xùn)練方法采用隨機(jī)梯度下降,每一個(gè)batch的大小為200。
圖3 深度神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)
根據(jù)訓(xùn)練的實(shí)驗(yàn)結(jié)果,重點(diǎn)比較沒有GPU資源、調(diào)用遠(yuǎn)程GPU資源和調(diào)用本地GPU資源3種不同情況下的加速深度神經(jīng)網(wǎng)絡(luò)的訓(xùn)練效果。如圖4所示,其中橫坐標(biāo)代表訓(xùn)練1 000個(gè)batch的次數(shù),縱坐標(biāo)代表每訓(xùn)練1 000個(gè)batch需要的時(shí)間。
圖4 不同情況下的訓(xùn)練時(shí)間對(duì)比
通過計(jì)算,訓(xùn)練1 000個(gè)batch在沒有GPU的情況下平均需要3 451.02 s,而本地GPU和遠(yuǎn)程GPU平均所需要的時(shí)間分別為18.16 s和44.31 s。本地GPU的加速比可以達(dá)到190倍的加速比,而遠(yuǎn)程GPU的加速比也能達(dá)到78倍的加速比。最終本地GPU和遠(yuǎn)程GPU訓(xùn)練的正確率都能達(dá)到99.06%左右。說明這種遠(yuǎn)程GPU的方法并不對(duì)正確率和訓(xùn)練結(jié)果造成影響。
由于在遠(yuǎn)程GPU的調(diào)用過程中,采用的GPU虛擬化方案涉及到通用網(wǎng)絡(luò)的TCP/IP傳輸,有大量的訓(xùn)練數(shù)據(jù)和API參數(shù)數(shù)據(jù)交換。這里GPU并行加速不僅需要掩蓋CPU和GPU之間的傳輸時(shí)間,同時(shí)還要掩蓋CPU和CPU之間的傳輸時(shí)間。因此,遠(yuǎn)程GPU的加速訓(xùn)練神經(jīng)網(wǎng)絡(luò)的效果一定比不上本地GPU的加速效果,同時(shí)收斂速度也比本地GPU慢,但與傳統(tǒng)的不利用GPU加速的訓(xùn)練效果相比,優(yōu)勢(shì)還是很明顯的。
這就說明遠(yuǎn)程GPU資源的調(diào)用仍然可以對(duì)加速神經(jīng)網(wǎng)絡(luò)的訓(xùn)練達(dá)到一定效果。那么如果遠(yuǎn)程調(diào)用多個(gè)GPU資源環(huán)境,或者是在使用通用網(wǎng)絡(luò)連接的分布式環(huán)境中,這種方案是否可行。
與單GPU的遠(yuǎn)程調(diào)用類似,在討論多GPU深度神經(jīng)網(wǎng)絡(luò)訓(xùn)練的過程中,重點(diǎn)研究如何利用虛擬化方案調(diào)用多個(gè)遠(yuǎn)程GPU資源和深度神經(jīng)網(wǎng)絡(luò)如何在多GPU上加速訓(xùn)練。
在多GPU平臺(tái)上主要有2種類型:一種是單機(jī)多GPU;另一種是多機(jī)多GPU(也就是GPU集群),如圖5所示。兩者的不同之處在于:單機(jī)多GPU的環(huán)境可以直接利用CUDA編程進(jìn)行處理。在多機(jī)多GPU的環(huán)境中需要重點(diǎn)考慮分布式通信框架,同時(shí)分布式框架如何為CUDA編程提供有效的底層通信接口,將通信和CUDA代碼隔離開也是需要深入研究的問題。在目前常見的處理多GPU的方案中,一般是將2種情況區(qū)別對(duì)待,單機(jī)多GPU的CUDA代碼需要進(jìn)行較大的修改才能移植到多機(jī)多GPU卡上,這種做法是可以被改進(jìn)的。
圖5 單機(jī)多GPU和多機(jī)多GPU
采用虛擬化的方法進(jìn)行遠(yuǎn)程GPU調(diào)用,可以有效地將分布式環(huán)境中多機(jī)多GPU資源映射成單機(jī)多GPU的環(huán)境。在多機(jī)多GPU的分布式環(huán)境中,需要考慮的各種分布式通信問題可以放在虛擬化的過程中解決,同時(shí)利用虛擬化可以為用戶提供一個(gè)和單機(jī)多GPU相似的編程環(huán)境。這樣可以將2種不同的多GPU環(huán)境有效地結(jié)合在一起,進(jìn)行CUDA編程的程序員只需要考慮一種情況的編程模式,單機(jī)多GPU的CUDA代碼不需要進(jìn)行修改或者只需要進(jìn)行少量的修改就可以移植到多機(jī)多GPU上。傳統(tǒng)的虛擬化方法,如gVirtus、vCUDA、GVim只能支持一對(duì)一的虛擬化,而rCUDA源碼并不公開,不利于做分布式深度學(xué)習(xí)的進(jìn)一步改進(jìn)。
一個(gè)典型的分布式集群系統(tǒng)中存在多個(gè)有計(jì)算能力的分布式節(jié)點(diǎn),在每個(gè)分布式節(jié)點(diǎn)上部署不同計(jì)算能力的GPU資源,分布式節(jié)點(diǎn)之間采用一定的通信方式互相連接[11]。在虛擬化的過程中,將需要重定向轉(zhuǎn)發(fā)的API數(shù)據(jù)分別轉(zhuǎn)發(fā)到能夠使用網(wǎng)絡(luò)通信的所有其他機(jī)器上,在這些機(jī)器上執(zhí)行相應(yīng)的GPU計(jì)算并將結(jié)果返回給本地[12]。程序轉(zhuǎn)發(fā)流程如圖6所示。同時(shí)使用不同機(jī)器的IP地址,將機(jī)器的GPU節(jié)點(diǎn)唯一標(biāo)識(shí),強(qiáng)制命名為GPU0、GPU1、GPU2、……來區(qū)分不同的GPU。所有分布式通信需要解決的容錯(cuò)性、冗余性等問題都可以放在虛擬化中解決。
圖6 虛擬化GPU計(jì)算平臺(tái)軟件層次結(jié)構(gòu)
以gVirtus為例,這里的改進(jìn)主要包括2個(gè)方面:一方面是將gVirtus的一對(duì)一形式改成一對(duì)多的形式;另一方面是根據(jù)深度神經(jīng)網(wǎng)絡(luò)的訓(xùn)練,改進(jìn)虛擬化過程中的一些缺陷。
首先gVirtus實(shí)現(xiàn)的一對(duì)一的虛擬GPU只是真實(shí)GPU的邏輯映像,在虛擬機(jī)或者遠(yuǎn)程GPU調(diào)用的過程中并不能直接使用。改進(jìn)一對(duì)一到一對(duì)多的具體方法可以是利用MPI、MapReduce、多線程、Hadoop等[13]。
在本文中,當(dāng)一個(gè)本地上的CUDA需要調(diào)用多個(gè)遠(yuǎn)程GPU時(shí),采用多線程的方法進(jìn)行控制。每一個(gè)線程控制一個(gè)GPU虛擬化和數(shù)據(jù)傳輸?shù)倪^程,線程和線程之間以及多個(gè)GPU之間是互相獨(dú)立互補(bǔ)影響的。這也將和本文后面處理深度神經(jīng)網(wǎng)絡(luò)需要解決的問題相關(guān)。每一個(gè)多GPU程序在運(yùn)行的過程中,首先將數(shù)據(jù)分解到不同的線程上,由線程控制不同的GPU上的數(shù)據(jù)傳輸。同時(shí)可以根據(jù)不同GPU的計(jì)算能力實(shí)現(xiàn)數(shù)據(jù)分解上的負(fù)載均衡。數(shù)據(jù)計(jì)算過程中不同GPU之間是松耦合、互不相干的。計(jì)算的結(jié)果最終返回到主機(jī)CPU,CPU有時(shí)需要同步所有GPU的計(jì)算結(jié)果,這是緊耦合的[14]。這一部分和深度學(xué)習(xí)的多GPU訓(xùn)練是密切相關(guān)的,因此,在實(shí)驗(yàn)過程中仍然會(huì)著重闡述。
最終通過虛擬化的方法,可以將GPU集群中的所有GPU資源,集中虛擬化到一個(gè)GPU池中,同時(shí)集群中的每臺(tái)機(jī)器都可以訪問這個(gè)GPU池,充分利用網(wǎng)絡(luò)中的所有GPU資源,如圖7所示。
圖7 多機(jī)多GPU的邏輯配置
通過虛擬化的方法可以實(shí)現(xiàn)多GPU的遠(yuǎn)程調(diào)用,將分布式多機(jī)多GPU的環(huán)境映射成單機(jī)多GPU的環(huán)境,為上層程序員提供一個(gè)相同的CUDA編程環(huán)境,實(shí)現(xiàn)2個(gè)不同環(huán)境下編程模式的統(tǒng)一。
基于多GPU的深度神經(jīng)網(wǎng)絡(luò)的訓(xùn)練主要有數(shù)據(jù)并行和模型并行2種不同的方式。數(shù)據(jù)并行是在不同的GPU卡上部署相同的訓(xùn)練模型實(shí)例,然后將訓(xùn)練的數(shù)據(jù)有效切分到不同GPU卡上,對(duì)多GPU卡上的模型進(jìn)行并行訓(xùn)練,并在合理的時(shí)間進(jìn)行參數(shù)同步,保證最終只訓(xùn)練出一個(gè)模型。與之相對(duì)應(yīng)的是模型并行,模型并行并不劃分?jǐn)?shù)據(jù)塊,而是將大規(guī)模的網(wǎng)絡(luò)結(jié)構(gòu)進(jìn)行合理的劃分,劃分的子結(jié)構(gòu)由不同的GPU資源擁有,最后不同的GPU資源共同協(xié)作,完成一個(gè)完整網(wǎng)絡(luò)結(jié)構(gòu)的有效訓(xùn)練。數(shù)據(jù)并行的通信開銷來自于參數(shù)同步,而模型并行的通信開銷來自于不同GPU上神經(jīng)元的依賴關(guān)系。本文實(shí)驗(yàn)主要采用的是數(shù)據(jù)并行的方法,數(shù)據(jù)并行的內(nèi)容如圖8所示。
圖8 數(shù)據(jù)并行
在數(shù)據(jù)并行中,每一張GPU顯卡采用隨機(jī)梯度下降(SGD)的方法進(jìn)行訓(xùn)練,在每一張顯卡的一個(gè)mini-batch計(jì)算完成之后需要進(jìn)行一次不同GPU卡上的參數(shù)同步。每一塊GPU卡將每一個(gè)mini-batch計(jì)算得到梯度Δw同步到參數(shù)服務(wù)器W上,常用的梯度參數(shù)同步更新的公式為:
Wi+1=Wi-ε·Δw
其中,i是參數(shù)更新的次數(shù),W是同步后的梯度參數(shù),ε是有效的學(xué)習(xí)速率,Δw是每個(gè)mini-batch BP計(jì)算出的梯度[15]。如圖8所示,參數(shù)服務(wù)器即為更新W。
以數(shù)據(jù)并行為例,將多GPU深度神經(jīng)網(wǎng)絡(luò)的訓(xùn)練和虛擬化的遠(yuǎn)程GPU結(jié)合在一起,將在單機(jī)多GPU上執(zhí)行的訓(xùn)練程序,在不需要修改或者進(jìn)行少量修改的情況下直接移植到多機(jī)多GPU的環(huán)境下。一般情況下只需要修改單機(jī)多GPU程序的編譯方式,將libcudart.so的調(diào)用方式變成動(dòng)態(tài)鏈接庫(kù)而不需要修改原來的代碼。但因?yàn)樘摂M化出來的GPU畢竟不是真實(shí)的GPU,而且CPU-GPU的匹配隊(duì)并不在同一臺(tái)機(jī)器上,所以很多與CPU相關(guān)的特定內(nèi)存訪問模型并不支持。而且現(xiàn)在的GPU虛擬化不支持統(tǒng)一內(nèi)存管理、模塊管理等。最后因?yàn)榫W(wǎng)絡(luò)延時(shí)的問題,與事件管理功能的時(shí)序功能可能不正確。與出現(xiàn)上述幾種情況有關(guān)的GPU代碼進(jìn)行分布式擴(kuò)展時(shí),就會(huì)遇到問題,需要修改原來的代碼才能繼續(xù)操作。擴(kuò)展執(zhí)行的邏輯框圖如圖9所示。
圖9 基于遠(yuǎn)程GPU調(diào)用的數(shù)據(jù)并行訓(xùn)練框圖
與傳統(tǒng)的數(shù)據(jù)并行不同的是,本文的數(shù)據(jù)并行在參數(shù)同步的過程上稍有差別。這是由于基于虛擬化的遠(yuǎn)程GPU調(diào)用的方法部署分布式GPU的遺留問題。雖然多機(jī)多GPU可以通過這種方法映射成單機(jī)多GPU的形式,但是兩者還是有一些差異的。單機(jī)多GPU中不同的GPU卡可以通過PCI-e相連,同時(shí)在CUDA中支持P2P的方法來進(jìn)行不同GPU卡之間的數(shù)據(jù)交換[16]。然而,通過本文部署分布式GPU集群映射出來的單機(jī)多GPU卻不具備這種屬性。原因是通用網(wǎng)絡(luò)中不同節(jié)點(diǎn)的GPU本身不具備互連的性質(zhì),在虛擬化之后,映射出來的GPU仍然不能夠互連。與此相關(guān)的問題主要有2種解決方案:第1種是改變CUDA虛擬化中與P2P相關(guān)的服務(wù)器端執(zhí)行接口,取代原來接口一致性的實(shí)現(xiàn)方法;第2種則是改變數(shù)據(jù)并行的實(shí)現(xiàn)流程。本文采用第2種方法。
具體的不同是在于,傳統(tǒng)數(shù)據(jù)并行在不同GPU上訓(xùn)練的參數(shù)在同步時(shí)可以選擇一個(gè)GPU作為GPU server,其他GPU卡上的參數(shù)可以通過P2P拷貝到GPU server上進(jìn)行參數(shù)同步。本文的數(shù)據(jù)并行依賴于通用網(wǎng)絡(luò)且不同GPU之間并不能互連,因此,在參數(shù)同步的過程中,需要將所有GPU上的數(shù)據(jù)傳輸?shù)奖镜谻PU上執(zhí)行,執(zhí)行完后再將同步結(jié)果利用cudaMemcpy等方法再分發(fā)到不同GPU上。同理,基于通用網(wǎng)絡(luò)的分布式環(huán)境中的模型并行,也需要進(jìn)行這方面的改進(jìn)。
深度神經(jīng)網(wǎng)絡(luò)的數(shù)據(jù)并行在遠(yuǎn)程GPU上的執(zhí)行流程為:首先要對(duì)所有需要訓(xùn)練的數(shù)據(jù)進(jìn)行有效的、合理的劃分,劃分的依據(jù)為不同GPU設(shè)備的計(jì)算能力。數(shù)據(jù)并行根據(jù)不同GPU的計(jì)算能力,將數(shù)據(jù)合理劃分到不同的GPU顯卡設(shè)備上進(jìn)行計(jì)算。然后使用一個(gè)或者多個(gè)CPU線程分別控制不同的GPU卡,利用普通的顯存拷貝方式或者異步的數(shù)據(jù)拷貝方式將數(shù)據(jù)轉(zhuǎn)移到虛擬GPU上。接著虛擬GPU將需要執(zhí)行的API數(shù)據(jù)和訓(xùn)練數(shù)據(jù)轉(zhuǎn)發(fā)到多個(gè)遠(yuǎn)程GPU上,遠(yuǎn)程GPU完成執(zhí)行之后,將計(jì)算結(jié)果返回給客戶端的虛擬GPU。由于P2P的緣故,在迭代更新的過程中,上層用戶只可以在本地CPU上執(zhí)行不同GPU訓(xùn)練的參數(shù)同步。最后用戶可以接收到來自虛擬GPU返回的計(jì)算結(jié)果,進(jìn)行下一步計(jì)算,而不需要考慮底層虛擬化的遠(yuǎn)程GPU調(diào)用過程。
實(shí)驗(yàn)采用的環(huán)境是4臺(tái)Intel(R) Core(TM) i5-4590 CPU,7.8 GHz內(nèi)存,ubuntu14.04操作系統(tǒng),分別配置相同的一塊GeForce GTX 750的GPU卡。
在虛擬環(huán)境或者沒有GPU資源的環(huán)境中,采用ubuntu14.04的操作系統(tǒng),除了顯卡外其他資源相同。所有CUDA的版本為7.5,這里的GPU加速暫時(shí)沒有使用CUDNN,所以不涉及CUDNN的版本。
這里訓(xùn)練的深度神經(jīng)網(wǎng)絡(luò)和第3節(jié)中的模型相同,訓(xùn)練的數(shù)據(jù)集以mnist手寫數(shù)字識(shí)別為例,采用隨機(jī)梯度下降的訓(xùn)練方法。分別在虛擬環(huán)境或者沒有GPU資源環(huán)境外配置1個(gè)遠(yuǎn)程GPU、2個(gè)遠(yuǎn)程GPU、4個(gè)遠(yuǎn)程GPU。由于每個(gè)GPU都是相同的,因此每種情況下的每個(gè)GPU仍然采用相同的batch size,即為200。最后得到訓(xùn)練的結(jié)果。分別比較1個(gè)遠(yuǎn)程GPU、2個(gè)遠(yuǎn)程GPU和4個(gè)遠(yuǎn)程GPU的訓(xùn)練1 000個(gè)batch size所需要的平均時(shí)間和收斂速度。
由圖10和圖11中的訓(xùn)練時(shí)間和收斂速度可以發(fā)現(xiàn),相對(duì)于1個(gè)遠(yuǎn)程GPU,2個(gè)遠(yuǎn)程GPU和4個(gè)遠(yuǎn)程GPU可以分別達(dá)到1.6倍和2.2倍的加速比。同時(shí)和一個(gè)本地GPU相比,2個(gè)遠(yuǎn)程GPU和4個(gè)遠(yuǎn)程GPU也能分別達(dá)到0.6倍和1.0倍的加速比。也就是說,在mnist數(shù)據(jù)集上,4個(gè)遠(yuǎn)程GPU的加速性能基本上就可以覆蓋普通網(wǎng)絡(luò)通信帶來的延遲。分布式環(huán)境中的深度神經(jīng)網(wǎng)絡(luò)的平均訓(xùn)練時(shí)間是隨著GPU的增加而減小的,但并不能達(dá)到線性的加速比,甚至比線性的加速比效果還差很多。這是因?yàn)樵诙郍PU訓(xùn)練的過程中涉及到更多的數(shù)據(jù)交換。每個(gè)固定的時(shí)間或者迭代次數(shù)之后需要進(jìn)行參數(shù)同步,這是與單個(gè)GPU有區(qū)別的地方。頻繁的數(shù)據(jù)交換只能在通用網(wǎng)絡(luò)中進(jìn)行,這將會(huì)很大程度上影響到最終訓(xùn)練的時(shí)間。
圖10 不同個(gè)數(shù)GPU訓(xùn)練1 000個(gè)batch size的平均時(shí)間
圖11 不同個(gè)數(shù)GPU訓(xùn)練錯(cuò)誤率的收斂速度
圖11表明,隨著GPU數(shù)量的增加,訓(xùn)練錯(cuò)誤率的收斂速度加快。這一點(diǎn)從原理上并不難理解,但是由于mnist數(shù)據(jù)集偏小,因此訓(xùn)練過程中到達(dá)收斂值的時(shí)間較短,所以,圖11中看起來差距并不是特別明顯。在2個(gè)GPU和4個(gè)GPU的訓(xùn)練結(jié)果表明,錯(cuò)誤率收斂在1%左右。
基于虛擬化的多個(gè)遠(yuǎn)程GPU調(diào)用平臺(tái)的實(shí)現(xiàn),在解決深度神經(jīng)網(wǎng)絡(luò)的GPU加速問題上具有一定的先進(jìn)性。一方面在沒有GPU資源的節(jié)點(diǎn)上可以有效地調(diào)用分布式多機(jī)多GPU環(huán)境中的所有其他計(jì)算節(jié)點(diǎn)上的GPU資源,遠(yuǎn)程調(diào)用的GPU資源可以有效地提高本節(jié)點(diǎn)高性能計(jì)算的能力。另一方面,由于基于虛擬化的遠(yuǎn)程GPU調(diào)用采用的API重定向方法,重定向過程中涉及到很多的額外通信開銷,在一定程度上限制了多個(gè)遠(yuǎn)程GPU調(diào)用的分布式平臺(tái)的整體性能。但是在損失一點(diǎn)性能的基礎(chǔ)上,有效實(shí)現(xiàn)了單機(jī)多GPU和多機(jī)多GPU2種不同環(huán)境下編程模式的統(tǒng)一。
分布式環(huán)境中深度神經(jīng)網(wǎng)絡(luò)的加速訓(xùn)練可以采用基于虛擬化的遠(yuǎn)程GPU調(diào)用的方法來實(shí)現(xiàn),這種方法最大優(yōu)點(diǎn)是可以將分布式通信和多GPU的CUDA編程進(jìn)行隔離,實(shí)現(xiàn)CUDA并行接口的自然獨(dú)立。
利用基于虛擬化的遠(yuǎn)程GPU調(diào)用的方法布置通用網(wǎng)絡(luò)中的分布式GPU集群,不僅簡(jiǎn)單易行,同時(shí)提供的編程接口與傳統(tǒng)CUDA相比,具有一致性和先進(jìn)性。
本文提出基于虛擬化方法的多GPU遠(yuǎn)程調(diào)用的解決方案,并利用該解決方案搭建分布式深度神經(jīng)網(wǎng)絡(luò)的訓(xùn)練平臺(tái)。使用多線程的方法控制多個(gè)GPU,將單機(jī)多GPU的深度神經(jīng)網(wǎng)絡(luò)的訓(xùn)練代碼,無需進(jìn)行大幅度修改即可拓展到分布式環(huán)境中的多機(jī)多GPU上。在以較少通信性能為代價(jià)的基礎(chǔ)上,實(shí)現(xiàn)單機(jī)多GPU和多機(jī)多GPU在編程模式上的統(tǒng)一。最終通過實(shí)驗(yàn)驗(yàn)證了該方法的有效性和可行性。隨著現(xiàn)代技術(shù)的發(fā)展,普通網(wǎng)絡(luò)的通信方式得到進(jìn)一步改進(jìn),如InfiniBand網(wǎng)絡(luò)、GPU Direct RDMA等通信技術(shù)[13]。同時(shí)在深度神經(jīng)網(wǎng)絡(luò)的CUDA加速上,如CUDNN、Caffe、mxnet等都在加速性能上有很大程度上的提高。因此,把普通網(wǎng)絡(luò)的多GPU訓(xùn)練框架推廣到新的網(wǎng)絡(luò)模型和網(wǎng)絡(luò)結(jié)構(gòu)上,同時(shí)能將更多的訓(xùn)練框架移植到該平臺(tái)上將是下一步的目標(biāo)。
[1] 張玉潔,呂相文,張?jiān)浦?GPU虛擬化環(huán)境下的數(shù)據(jù)通信策略研究[J].計(jì)算機(jī)技術(shù)與發(fā)展,2015,25(8):24-28.
[2] SHI L,CHEN H,SUN J,et al.vCUDA:GPU-accelerated High-performance Computing in Virtual Machines[J].IEEE Transactions on Computers,2012,61(6):804-816.
[3] DUATO J,PENA A J,SILLA F,et al.rCUDA:Reducing the Number of GPU-based Accelerators in High Performance Clusters[C]//Proceedings of 2010 IEEE International Conference on High Performance Computing and Simulation.Washington D.C.,USA:IEEE Press,2010:224-231.
[4] 楊經(jīng)緯,馬 凱,龍 翔.面向集群環(huán)境的虛擬化GPU計(jì)算平臺(tái)[J].北京航空航天大學(xué)學(xué)報(bào),2016,42(11):2340-2348.
[5] 盛沖沖,胡新明,李佳佳,等.面向節(jié)點(diǎn)異構(gòu) GPU 集群的編程框架[J].計(jì)算機(jī)工程,2015,41(2):292-297.
[6] HINTON G E,SALAKHUTDINOV R R.Reducing the Dimensionality of Data with Neural Networks[J].Science,2006,313(5786):504-507.
[7] DEAN J,CORRADO G,MONGA R,et al.Large Scale Distributed Deep Networks[C]//Proceedings of IEEE ANIPS’12.Washington D.C.,USA:IEEE Press,2012:1223-1231.
[8] ZOU Y,JIN X,LI Y,et al.Mariana:Tencent Deep Learning Platform and Its Applications[J].Proceedings of the VLDB Endowment,2014,7(13):1772-1777.
[9] YADAN O,ADAMS K,TAIGMAN Y,et al.Multi-gpu Training of Convnets[EB/OL].(2013-05-23).https://wenku.baidu.com/view/c2121ee0aaea998fcd220e95.html.
[10] POVEY D,ZHANG X,KHUDANPUR S.Parallel Training of DNNs with Natural Gradient and Parameter Averaging[EB/OL].(2014-05-21).http://www.itsoc.org/publications/arxiv/arxiv-faq.
[11] SOUROURI M,GILLBERG T,BADEN S B,et al.Effective Multi-GPU Communication Using Multiple CUDA Streams and Threads[C]//Proceedings of the 20th IEEE International Conference on Parallel and Distributed Systems.Washington D.C.,USA:IEEE Press,2014:981-986.
[12] 王 剛,唐 杰,武港山.基于多 GPU 集群的編程框架[J].計(jì)算機(jī)技術(shù)與發(fā)展,2014,24(1):9-13.
[13] 閔 芳,張志先,張玉潔.虛擬化環(huán)境下多 GPU 并行計(jì)算研究[J].微電子學(xué)與計(jì)算機(jī),2016,33(3):69-75.
[14] 張玉潔.基于多 GPGPU 并行計(jì)算的虛擬化技術(shù)研究[D].南京:南京航空航天大學(xué),2015.
[15] ELLIOTT G A,WARD B C,ANDERSON J H.GPUSync:A Framework for Real-time GPU Management[C]//Proceed-ings of RTSS’13.Washington D.C.,USA:IEEE Press,2013:33-44.
[16] STUART J A,OWENS J D.Multi-GPU MapReduce on GPU Clusters[C]//Proceedings of IEEE International on Parallel & Distributed Processing Symposium.Washington D.C.,USA:IEEE Press,2011:1068-1079.