祝佳怡
(西南民族大學(xué)計(jì)算機(jī)科學(xué)與工程學(xué)院,成都 610225)
人工智能(artificial intelligence,AI)這一概念的出現(xiàn)最早可以追溯到20世紀(jì)50年代。隨著Marvin Minsky和John McCarthy于1956年共同主持的達(dá)特矛斯會(huì)議(dartmouth summer research project on artificial intelligence,DSRPAI)的舉辦,“人工智能”這一概念被正式定義。該會(huì)議的舉辦標(biāo)志著人工智能進(jìn)入了第一次發(fā)展期。在當(dāng)今時(shí)代,因機(jī)器學(xué)習(xí)(machine learning,ML)和深度學(xué)習(xí)(deep learning,DL)方法和大數(shù)據(jù)技術(shù)的不斷發(fā)展,人工智能已經(jīng)成為必不可少的科學(xué)技術(shù)之一。如今人工智能模型的效果越來(lái)越好,這離不開(kāi)高性能模型的設(shè)計(jì),而無(wú)論是在工業(yè)界還是學(xué)術(shù)界,機(jī)器學(xué)習(xí)方法及深度學(xué)習(xí)模型都越來(lái)越傾向于向更復(fù)雜的方向發(fā)展。這一發(fā)展趨勢(shì)使得模型的訓(xùn)練成本越來(lái)越大,再加上數(shù)據(jù)量的龐大,訓(xùn)練一個(gè)效果優(yōu)秀的深度學(xué)習(xí)模型往往需要數(shù)月的時(shí)間。
在一般的計(jì)算機(jī)程序中,解決問(wèn)題的算法通常是以指令序列流的形式執(zhí)行,這些指令通過(guò)中央處理器(central processing unit,CPU)來(lái)進(jìn)行計(jì)算,這種方法被稱為串行計(jì)算(serial computing)。與之相對(duì)的并行計(jì)算(parallel computing)則將一個(gè)任務(wù)劃分為互不相關(guān)的多個(gè)計(jì)算部分,并使用多個(gè)計(jì)算單元對(duì)這些計(jì)算部分并行地分別進(jìn)行計(jì)算,最終將結(jié)果匯總起來(lái),實(shí)現(xiàn)了性能的提升。在理想的情況下,并行化所帶來(lái)的性能提升是指數(shù)級(jí)別的,即把問(wèn)題規(guī)模劃分為一半,性能提升兩倍,以此類推。但是在更一般的情況下,并行計(jì)算的性能提升遵循Gustafson法則。消息傳遞接口(message passing interface,MPI)是實(shí)現(xiàn)并行計(jì)算的一種主流方式,各個(gè)進(jìn)程間通過(guò)這一接口來(lái)進(jìn)行任務(wù)的分配、消息的接收發(fā)送等機(jī)制,實(shí)現(xiàn)并行的目的。隨著目前云服務(wù)器和大數(shù)據(jù)的普及,并行計(jì)算將是解決大規(guī)模方法的最有效優(yōu)化手段之一。
傳統(tǒng)的ML、DL模型的訓(xùn)練方法是對(duì)訓(xùn)練樣本一個(gè)一個(gè)地進(jìn)行計(jì)算,并根據(jù)所有樣本的結(jié)果對(duì)模型進(jìn)行調(diào)整。這是一種非常典型的串行的實(shí)現(xiàn)思路。通過(guò)對(duì)該問(wèn)題進(jìn)行簡(jiǎn)要分析可知,每個(gè)訓(xùn)練樣本之間的計(jì)算都是獨(dú)立的計(jì)算單元,這些樣本自身的計(jì)算之間互不相干,因此可以使用并行化的思想來(lái)解決該問(wèn)題,從而大幅縮減模型的訓(xùn)練時(shí)間。多個(gè)節(jié)點(diǎn)并行地計(jì)算各自的樣本子集結(jié)果,并將這些結(jié)果匯總到主節(jié)點(diǎn)中,對(duì)模型的參數(shù)進(jìn)行更新,完成了一輪的訓(xùn)練流程。在本實(shí)驗(yàn)中嘗試將這一思想應(yīng)用于最簡(jiǎn)單的機(jī)器學(xué)習(xí)模型訓(xùn)練當(dāng)中。理想情況下,隨著計(jì)算節(jié)點(diǎn)數(shù)量的增加,訓(xùn)練所消耗的時(shí)間應(yīng)逐漸減少。實(shí)驗(yàn)結(jié)果表明,在模型的規(guī)模較小時(shí),使用MPI技術(shù)實(shí)現(xiàn)并行化方法的訓(xùn)練時(shí)間會(huì)隨著節(jié)點(diǎn)數(shù)的增加而增加。通過(guò)分析可知,在各節(jié)點(diǎn)的消息接收和發(fā)送階段也會(huì)存在一定的時(shí)間消耗。如果一個(gè)樣本計(jì)算所消耗的時(shí)間小于進(jìn)程間消息接收發(fā)送的時(shí)間,則會(huì)導(dǎo)致這一與理想情況相悖的現(xiàn)象發(fā)生。本實(shí)驗(yàn)中的模型是最簡(jiǎn)單的線性回歸模型。在實(shí)際中,深度學(xué)習(xí)模型是非常龐大且復(fù)雜的。在這種常規(guī)的情況下,一個(gè)樣本計(jì)算所消耗的時(shí)間會(huì)大幅度多于進(jìn)程間的通訊時(shí)間,這時(shí)并行化所帶來(lái)的計(jì)算效率的收益是巨大的。
本文以回歸任務(wù)作為示例,并使用其中最基礎(chǔ)的線性回歸來(lái)解釋本文闡述的ML、DL并行訓(xùn)練思想。所使用的數(shù)據(jù)集是隨機(jī)生成的用于線性回歸的數(shù)據(jù)。數(shù)據(jù)集的生成使用基于Python語(yǔ)言的Sci-kit Learn工具包中的make_regression()函數(shù)來(lái)實(shí)現(xiàn),代碼段如下:
其中指定了樣本數(shù)量為500,特征數(shù)量為1。生成的是一個(gè)長(zhǎng)度為500的向量,也是一個(gè)長(zhǎng)度為500的向量,中的每一個(gè)元素都通過(guò)一個(gè)參數(shù)與中的對(duì)應(yīng)值進(jìn)行匹配。該數(shù)據(jù)集的可視化如圖1所示。需要注意的是該可視化雖然在視覺(jué)上是一條直線的形式,但實(shí)際上是由500個(gè)數(shù)據(jù)點(diǎn)構(gòu)成的。
圖1 隨機(jī)生成線性回歸數(shù)據(jù)集的可視化
機(jī)器學(xué)習(xí)及深度學(xué)習(xí)模型的目標(biāo)就是找到最好的擬合數(shù)據(jù)的參數(shù),實(shí)現(xiàn)對(duì)訓(xùn)練集的特征學(xué)習(xí)。圖2很好地展示了不同的模型或不同的模型參數(shù)的擬合情況。
圖2 對(duì)數(shù)據(jù)集不同的擬合情況(長(zhǎng)線段表示原始的數(shù)據(jù)集,點(diǎn)線表示擬合情況)
從圖2可知,(a)和(b)均沒(méi)有很好地?cái)M合數(shù)據(jù)集;而(c)是一個(gè)擬合較好的情況,因此本文要盡可能使我們的模型達(dá)到如圖2(c)所示的效果。
為了更好地闡述以上的問(wèn)題,在這里給出一些數(shù)學(xué)符號(hào)來(lái)對(duì)問(wèn)題進(jìn)行定義。設(shè)訓(xùn)練集的樣本總?cè)萘繛?,每個(gè)樣本含有個(gè)特征,則給定訓(xùn)練集∈R,其對(duì)應(yīng)的標(biāo)簽∈R。在上述的數(shù)據(jù)集中,每個(gè)樣本只有一個(gè)特征,即=1;且保證了本實(shí)驗(yàn)中的數(shù)據(jù)集中所有樣本的平均值為0,因此可以用一條=的直線來(lái)對(duì)數(shù)據(jù)進(jìn)行擬合。
值越小,證明模型對(duì)該樣本的預(yù)測(cè)效果越好。對(duì)所有樣本都進(jìn)行該運(yùn)算,最后將所有樣本的值進(jìn)行累加,得到模型總的損失??倱p失也被稱為模型的代價(jià)(cost value)。
一種通用的求解的方法被稱為梯度下降法。根據(jù)模型的代價(jià),對(duì)參數(shù)求偏導(dǎo),可以使用該值對(duì)模型的參數(shù)不斷進(jìn)行更新迭代,數(shù)學(xué)定義如下:
其中為學(xué)習(xí)率,可以用來(lái)調(diào)節(jié)更新迭代的步長(zhǎng)大小。合適的學(xué)習(xí)率可以使模型的損失更快速地收斂到局部或全局最小值。迭代更新多次后,模型的損失逐漸收斂,不再減小,這時(shí)可以認(rèn)為模型已經(jīng)訓(xùn)練完畢,此時(shí)的參數(shù)為模型訓(xùn)練的最終結(jié)果。
上述的步驟中,對(duì)所有的訓(xùn)練樣本是一個(gè)一個(gè)地進(jìn)行計(jì)算損失,并進(jìn)行累加作為模型的代價(jià),最終使用梯度下降法進(jìn)行更新。對(duì)訓(xùn)練樣本分別進(jìn)行計(jì)算是一個(gè)典型的串行思維方式。該思路的偽代碼實(shí)現(xiàn)如下:
串行的梯度下降算法
假設(shè)計(jì)算每個(gè)樣本的預(yù)測(cè)和計(jì)算梯度的時(shí)間復(fù)雜度為(),則訓(xùn)練一輪需要的時(shí)間復(fù)雜度為(×),其中是訓(xùn)練樣本的數(shù)量。通常情況下()的規(guī)模是十分巨大的,又由于訓(xùn)練樣本數(shù)量通常也有很大的規(guī)模(>10),采用這種串行的計(jì)算方式會(huì)導(dǎo)致訓(xùn)練大型深度學(xué)習(xí)模型的時(shí)間開(kāi)銷過(guò)于龐大。
通過(guò)上述的訓(xùn)練過(guò)程可以知道,模型的代價(jià)計(jì)算是一個(gè)求和的過(guò)程,是對(duì)所有樣本的損失值進(jìn)行累加,進(jìn)而進(jìn)行更新迭代。在該求和的過(guò)程中,每一項(xiàng)(樣本的損失值)的計(jì)算并不會(huì)相互影響,因此每個(gè)樣本計(jì)算損失的過(guò)程可以被多個(gè)進(jìn)程或多個(gè)計(jì)算節(jié)點(diǎn)并行化。因此模型的訓(xùn)練過(guò)程與最簡(jiǎn)單的數(shù)列求和背后的邏輯是一致的。由于進(jìn)程之間沒(méi)有相互依賴,該問(wèn)題可以很好地被并行化。
根據(jù)這一思想,本實(shí)驗(yàn)提出的并行訓(xùn)練方法與簡(jiǎn)單的數(shù)列求和思想非常相近。考慮一個(gè)數(shù)列求和的并行化問(wèn)題:1+2+…+100,假設(shè)由四個(gè)節(jié)點(diǎn)來(lái)計(jì)算,一種巧妙的方法是令:
可以看到四個(gè)節(jié)點(diǎn)分別計(jì)算各自的和,并且能夠覆蓋1…100的所有值?;氐侥P偷挠?xùn)練問(wèn)題,模型訓(xùn)練中的關(guān)鍵是進(jìn)行模型的代價(jià),而代價(jià)是所有樣本的損失值的累加和。因此:
用與數(shù)列求和相似的思路可以很好地解決該問(wèn)題的求解。本實(shí)驗(yàn)的機(jī)器學(xué)習(xí)及深度學(xué)習(xí)模型梯度下降的并行訓(xùn)練算法的偽代碼如下所示:
并行的梯度下降算法
本節(jié)闡述了上述方法的具體代碼實(shí)現(xiàn)過(guò)程。首先是MPI的初始化部分:
初始化后進(jìn)行數(shù)據(jù)的讀入部分。在這里已經(jīng)將數(shù)據(jù)集分別存入X.in和y.in文件中,讀入數(shù)據(jù)的代碼如下所示:
指定一些其余的參數(shù),如訓(xùn)練樣本數(shù)量等,如下所示:
接下來(lái)是訓(xùn)練環(huán)節(jié)。判斷當(dāng)前節(jié)點(diǎn)是否為主節(jié)點(diǎn),如果不是主節(jié)點(diǎn)則計(jì)算后傳給主節(jié)點(diǎn),如下所示:
上面的代碼中,變量predict為預(yù)測(cè)結(jié)果,loss為損失值,node_derivative為梯度信息。計(jì)算完畢后使用MPI_Send()將梯度信息和損失分別用不同的標(biāo)識(shí)符發(fā)送給主節(jié)點(diǎn)。主節(jié)點(diǎn)部分的代碼如下所示:
主節(jié)點(diǎn)在計(jì)算完自己的部分后,接收來(lái)自其他節(jié)點(diǎn)的梯度信息和損失信息,并進(jìn)行累加。累加后求得總損失和總梯度,然后使用weight=weight-alpha*derivative進(jìn)行梯度更新。上述過(guò)程循環(huán)epoch次,循環(huán)結(jié)束后訓(xùn)練終止。在最后主節(jié)點(diǎn)對(duì)訓(xùn)練的結(jié)果進(jìn)行輸出:
需要注意的是,在第一輪循環(huán)結(jié)束后,主節(jié)點(diǎn)要把更新后的weight傳給其他節(jié)點(diǎn),其他節(jié)點(diǎn)接收更新后的weight后再進(jìn)行下一輪的計(jì)算。主節(jié)點(diǎn)發(fā)送weight的代碼如下:
其他節(jié)點(diǎn)接收weight的代碼如下:
其他節(jié)點(diǎn)在第一輪的訓(xùn)練中,使用0作為參數(shù)進(jìn)行計(jì)算,后續(xù)的迭代過(guò)程中,使用主節(jié)點(diǎn)發(fā)送的weight來(lái)進(jìn)行計(jì)算。以上便是并行訓(xùn)練的核心代碼部分。
在本節(jié)中,為了分析并行方法在線性回歸模型中所帶來(lái)的性能提高程度,分別設(shè)置了節(jié)點(diǎn)數(shù)為1,2,4,8,16,32。為了得到可靠的結(jié)果,每個(gè)節(jié)點(diǎn)數(shù)量都分別運(yùn)行了五次。對(duì)方法的性能評(píng)估主要是用以下三個(gè)指標(biāo):運(yùn)行時(shí)間、計(jì)算所得的參數(shù)值、訓(xùn)練300輪后的損失值。將五次的運(yùn)行結(jié)果取平均值和方差,作為最終結(jié)果。實(shí)驗(yàn)結(jié)果如表1所示。
表1 不同節(jié)點(diǎn)數(shù)量的各個(gè)指標(biāo)統(tǒng)計(jì)結(jié)果
將模型的參數(shù)進(jìn)行可視化,得到如圖3所示的結(jié)果。從圖中可以看出,預(yù)測(cè)結(jié)果很好地?cái)M合了數(shù)據(jù)集(點(diǎn)線表示的預(yù)測(cè)結(jié)果與數(shù)據(jù)集完全重合)。
圖3 訓(xùn)練的參數(shù)可視化結(jié)果
根據(jù)表1的結(jié)果可以了解到,不同的節(jié)點(diǎn)數(shù)量訓(xùn)練后最終的參數(shù)和最終的損失都保持基本一致。訓(xùn)練的最終效果是一致的,都能擬合到最優(yōu)的情況。但是訓(xùn)練的時(shí)間卻出現(xiàn)了與理想情況相悖的現(xiàn)象:隨著節(jié)點(diǎn)數(shù)量的增加,模型所需要的訓(xùn)練時(shí)間越來(lái)越多。然而理想情況應(yīng)該是隨著節(jié)點(diǎn)數(shù)量的增加,訓(xùn)練時(shí)間越來(lái)越少。
這一現(xiàn)象的產(chǎn)生可以從并行方法的時(shí)間復(fù)雜度進(jìn)行考慮。在第二節(jié)中提到過(guò),并行訓(xùn)練的時(shí)間復(fù)雜度形式為
在本實(shí)驗(yàn)中針對(duì)機(jī)器學(xué)習(xí)和深度學(xué)習(xí)模型的訓(xùn)練過(guò)程提出了一種并行化的策略,用于解決大規(guī)模的數(shù)據(jù)和大量的計(jì)算所帶來(lái)的時(shí)間消耗問(wèn)題。本實(shí)驗(yàn)以最基礎(chǔ)的線性回歸作為示例,展示了并行訓(xùn)練的一種思路。對(duì)實(shí)驗(yàn)結(jié)果進(jìn)行分析,說(shuō)明基于MPI技術(shù)的并行化方法有它的適用場(chǎng)景,也存在不適用的情況。本實(shí)驗(yàn)提出的并行化方法適用于大規(guī)模的數(shù)據(jù)集和大規(guī)模的網(wǎng)絡(luò)框架,隨著節(jié)點(diǎn)數(shù)量的增加,訓(xùn)練耗時(shí)將大大減少;而對(duì)于小規(guī)模數(shù)據(jù)和小規(guī)模模型的情景,隨著節(jié)點(diǎn)數(shù)量的增加,訓(xùn)練時(shí)間將逐漸增加,因此該并行化方法不適用于此場(chǎng)景。