大規模機器學(xué)習框架的四重境界
1. 背景
本文引用地址:http://dyxdggzs.com/article/201711/371641.htm自從google發(fā)表著(zhù)名的GFS、MR、BigTable三篇paper以后,互聯(lián)網(wǎng)正式迎來(lái)了大數據時(shí)代。大數據的顯著(zhù)特點(diǎn)是大,哪里都大的大。本篇主要針對volume大的數據時(shí),使用機器學(xué)習來(lái)進(jìn)行數據處理過(guò)程中遇到的架構方面的問(wèn)題做一個(gè)系統的梳理。
有了GFS我們有能力積累海量的數據樣本,比如在線(xiàn)廣告的曝光和點(diǎn)擊數據,天然具有正負樣本的特性,累積一兩個(gè)月往往就能輕松獲得百億、千億級的訓練樣本。這樣海量的樣本如何存儲?用什么樣的模型可以學(xué)習海量樣本中有用的pattern?這些問(wèn)題不止是工程問(wèn)題,也值得每個(gè)做算法的同學(xué)去深入思考。
1.1簡(jiǎn)單模型or復雜模型
在深度學(xué)習概念提出之前,算法工程師手頭能用的工具其實(shí)并不多,就LR、SVM、感知機等聊聊可數、相對固定的若干個(gè)模型和算法,那時(shí)候要解決一個(gè)實(shí)際的問(wèn)題,算法工程師更多的工作主要是在特征工程方面。而特征工程本身并沒(méi)有很系統化的指導理論(至少目前沒(méi)有看到相關(guān)的系統介紹的書(shū)籍),所以很多時(shí)候特征的構造技法顯得光怪陸離,是否有用也取決于問(wèn)題本身、數據樣本、模型以及運氣。
在特征工程作為算法工程師主要工作內容的時(shí)候,構造新特征的嘗試往往很大部分都不能在實(shí)際工作中work。據我了解,國內幾家大公司在特征構造方面的成功率在后期一般不會(huì )超過(guò)20%。也就是80%的新構造特征往往并沒(méi)什么正向提升效果。如果給這種方式起一個(gè)名字的話(huà),大概是簡(jiǎn)單模型+復雜特征;簡(jiǎn)單模型說(shuō)的是算法比如LR、SVM本身并不服務(wù),參數和表達能力基本呈現一種線(xiàn)性關(guān)系,易于理解。復雜特征則是指特征工程方面不斷嘗試使用各種奇技淫巧構造的可能有用、可能沒(méi)用的特征,這部分特征的構造方式可能會(huì )有各種trick,比如窗口滑動(dòng)、離散化、歸一化、開(kāi)方、平方、笛卡爾積、多重笛卡爾積等等;順便提一句,因為特征工程本身并沒(méi)有特別系統的理論和總結,所以初入行的同學(xué)想要構造特征就需要多讀paper,特別是和自己業(yè)務(wù)場(chǎng)景一樣或類(lèi)似的場(chǎng)景的paper,從里面學(xué)習作者分析、理解數據的方法以及對應的構造特征的技法;久而久之,有望形成自己的知識體系。
深度學(xué)習概念提出以后,人們發(fā)現通過(guò)深度神經(jīng)網(wǎng)絡(luò )可以進(jìn)行一定程度的表現學(xué)習(representation learning),例如在圖像領(lǐng)域,通過(guò)CNN提取圖像feature并在此基礎上進(jìn)行分類(lèi)的方法,一舉打破了之前算法的天花板,而且是以極大的差距打破。這給所有算法工程師帶來(lái)了新的思路,既然深度學(xué)習本身有提取特征的能力,干嘛還要苦哈哈的自己去做人工特征設計呢?
深度學(xué)習雖然一定程度上緩解了特征工程的壓力,但這里要強調兩點(diǎn):1.緩解并不等于徹底解決,除了圖像這種特定領(lǐng)域,在個(gè)性化推薦等領(lǐng)域,深度學(xué)習目前還沒(méi)有完全取得絕對的優(yōu)勢;究其原因,可能還是數據自身內在結構的問(wèn)題,使得在其他領(lǐng)域目前還沒(méi)有發(fā)現類(lèi)似圖像+CNN這樣的完美CP。2.深度學(xué)習在緩解特征工程的同時(shí),也帶來(lái)了模型復雜、不可解釋的問(wèn)題。算法工程師在網(wǎng)絡(luò )結構設計方面一樣要花很多心思來(lái)提升效果。概括起來(lái),深度學(xué)習代表的簡(jiǎn)單特征+復雜模型是解決實(shí)際問(wèn)題的另一種方式。
兩種模式孰優(yōu)孰劣還難有定論,以點(diǎn)擊率預測為例,在計算廣告領(lǐng)域往往以海量特征+LR為主流,根據VC維理論,LR的表達能力和特征個(gè)數成正比,因此海量的feature也完全可以使LR擁有足夠的描述能力。而在個(gè)性化推薦領(lǐng)域,深度學(xué)習剛剛萌芽,目前google play采用了WDL的結構[1],youtube采用了雙重DNN的結構[2]。
不管是那種模式,當模型足夠龐大的時(shí)候,都會(huì )出現模型參數一臺機器無(wú)法存放的情況。比如百億級feature的LR對應的權重w有好幾十個(gè)G,這在很多單機上存儲都是困難的,大規模神經(jīng)網(wǎng)絡(luò )則更復雜,不僅難以單機存儲,而且參數和參數之間還有邏輯上的強依賴(lài);要對超大規模的模型進(jìn)行訓練勢必要借用分布式系統的技法,本文主要是系統總結這方面的一些思路。
1.2 數據并行vs模型并行
數據并行和模型并行是理解大規模機器學(xué)習框架的基礎概念,其緣起未深究,第一次看到是在姐夫(Jeff Dean)的blog里,當時(shí)匆匆一瞥,以為自己懂了。多年以后,再次開(kāi)始調研這個(gè)問(wèn)題的時(shí)候才想起長(cháng)者的教訓,年輕人啊,還是圖樣,圖森破。如果你和我一樣曾經(jīng)忽略過(guò)這個(gè)概念,今天不放復習一下。
這兩個(gè)概念在[3]中沐帥曾經(jīng)給出了一個(gè)非常直觀(guān)而經(jīng)典的解釋?zhuān)上Р恢朗裁丛?,當我想引用時(shí)卻發(fā)現已經(jīng)被刪除了。我在這里簡(jiǎn)單介紹下這個(gè)比喻:如果要修兩棟樓,有一個(gè)工程隊,怎么操作?第一個(gè)方案是將人分成兩組,分別蓋樓,改好了就裝修;第二種做法是一組人蓋樓,等第一棟樓蓋好,另一組裝修第一棟,然后第一組繼續蓋第二棟樓,改完以后等裝修隊裝修第二棟樓。咋一看,第二種方法似乎并行度并不高,但第一種方案需要每個(gè)工程人員都擁有“蓋樓”和“裝修”兩種能力,而第二個(gè)方案只需要每個(gè)人擁有其中一種能力即可。第一個(gè)方案和數據并行類(lèi)似,第二個(gè)方案則道出了模型并行的精髓。
數據并行理解起來(lái)比較簡(jiǎn)單,當樣本比較多的時(shí)候,為了使用所有樣本來(lái)訓練模型,我們不妨把數據分布到不同的機器上,然后每臺機器都來(lái)對模型參數進(jìn)行迭代,如下圖所示
圖片取材于tensorflow的paper[4],圖中ABC代表三臺不同的機器,上面存儲著(zhù)不同的樣本,模型P在各臺機器上計算對應的增量,然后在參數存儲的機器上進(jìn)行匯總和更新,這就是數據并行。先忽略synchronous,這是同步機制相關(guān)的概念,在第三節會(huì )有專(zhuān)門(mén)介紹。
數據并行概念簡(jiǎn)單,而且不依賴(lài)于具體的模型,因此數據并行機制可以作為框架的一種基礎功能,對所有算法都生效。與之不同的是,模型并行因為參數間存在依賴(lài)關(guān)系(其實(shí)數據并行參數更新也可能會(huì )依賴(lài)所有的參數,但區別在于往往是依賴(lài)于上一個(gè)迭代的全量參數。而模型并行往往是同一個(gè)迭代內的參數之間有強依賴(lài)關(guān)系,比如DNN網(wǎng)絡(luò )的不同層之間的參數依照BP算法形成的先后依賴(lài)),無(wú)法類(lèi)比數據并行這樣直接將模型參數分片而破壞其依賴(lài)關(guān)系,所以模型并行不僅要對模型分片,同時(shí)需要調度器來(lái)控制參數間的依賴(lài)關(guān)系。而每個(gè)模型的依賴(lài)關(guān)系往往并不同,所以模型并行的調度器因模型而異,較難做到完全通用。關(guān)于這個(gè)問(wèn)題,CMU的Erix Xing在[5]中有所介紹,感興趣的可以參考。
模型并行的問(wèn)題定義可以參考姐夫的[6],這篇paper也是tensorflow的前身相關(guān)的總結,其中圖

解釋了模型并行的物理圖景,當一個(gè)超大神經(jīng)網(wǎng)絡(luò )無(wú)法存儲在一臺機器上時(shí),我們可以切割網(wǎng)絡(luò )存到不同的機器上,但是為了保持不同參數分片之間的一來(lái),如圖中粗黑線(xiàn)的部分,則需要在不同的機器之間進(jìn)行concurrent控制;同一個(gè)機器內部的參數依賴(lài),即途中細黑線(xiàn)部分在機器內即可完成控制。
黑線(xiàn)部分如何有效控制呢?如下圖所示

在將模型切分到不同機器以后,我們將參數和樣本一起在不同機器間流轉,途中ABC代表模型的不同部分的參數;假設C依賴(lài)B,B依賴(lài)A,機器1上得到A的一個(gè)迭代后,將A和必要的樣本信息一起傳到機器2,機器2根據A和樣本對P2更新得到,以此類(lèi)推;當機器2計算B的時(shí)候,機器1可以展開(kāi)A的第二個(gè)迭代的計算。熟悉CPU流水線(xiàn)操作的同學(xué)一定感到熟悉,是的,模型并行是通過(guò)數據流水線(xiàn)來(lái)實(shí)現并行的。想想那個(gè)蓋樓的第二種方案,就能理解模型并行的精髓了。

上圖則是對控制模型參數依賴(lài)的調度器的一個(gè)示意圖,實(shí)際框架中一般都會(huì )用DAG(有向無(wú)環(huán)圖)調度技術(shù)來(lái)實(shí)現類(lèi)似功能,未深入研究,以后有機會(huì )再補充說(shuō)明。
理解了數據并行和模型并行對后面參數服務(wù)器的理解至關(guān)重要,但現在讓我先蕩開(kāi)一筆,簡(jiǎn)單介紹下并行計算框架的一些背景信息。
2. 并行算法演進(jìn)2.1MapReduce路線(xiàn)
從函數式編程中的受到啟發(fā),google發(fā)布了MapReduce[7]的分布式計算方
式;通過(guò)將任務(wù)切分成多個(gè)疊加的Map+Reduce任務(wù),來(lái)完成復雜的計算任務(wù),示意圖如下

MapReduce的主要問(wèn)題有兩個(gè),一是原語(yǔ)的語(yǔ)義過(guò)于低級,直接使用其來(lái)寫(xiě)復雜算法,開(kāi)發(fā)量比較大;另一個(gè)問(wèn)題是依賴(lài)于磁盤(pán)進(jìn)行數據傳遞,性能跟不上業(yè)務(wù)需求。
為了解決MapReduce的兩個(gè)問(wèn)題,Matei在[8]中提出了一種新的數據結構RDD,并構建了Spark框架。Spark框架在MR語(yǔ)義之上封裝了DAG調度器,極大降低了算法使用的門(mén)檻。較長(cháng)時(shí)間內spark幾乎可以說(shuō)是大規模機器學(xué)習的代表,直至后來(lái)沐帥的參數服務(wù)器進(jìn)一步開(kāi)拓了大規模機器學(xué)習的領(lǐng)域以后,spark才暴露出一點(diǎn)點(diǎn)不足。如下圖

從圖中可以看出,spark框架以Driver為核心,任務(wù)調度和參數匯總都在driver,而driver是單機結構,所以spark的瓶頸非常明顯,就在Driver這里。當模型規模大到一臺機器存不下的時(shí)候,Spark就無(wú)法正常運行了。所以從今天的眼光來(lái)看,Spark只能稱(chēng)為一個(gè)中等規模的機器學(xué)習框架。劇透一句,公司開(kāi)源的Angel通過(guò)修改Driver的底層協(xié)議將Spark擴展到了一個(gè)高一層的境界。后面還會(huì )再詳細介紹這部分。
MapReduce不僅是一個(gè)框架,還是一種思想,google開(kāi)創(chuàng )性的工作為我們找到了大數據分析的一個(gè)可行方向,時(shí)至今日,仍不過(guò)時(shí)。只是逐漸從業(yè)務(wù)層下沉到底層語(yǔ)義應該處于的框架下層。
2.2MPI技術(shù)
沐帥在[9]中對MPI的前景做了簡(jiǎn)要介紹;和Spark不同,MPI是類(lèi)似socket
的一種系統同學(xué)API,只是支持了消息廣播等功能。因為對MPI研究不深入,這里簡(jiǎn)單介紹下有點(diǎn)和缺點(diǎn)吧;有點(diǎn)是系統支持,性能剛剛;缺點(diǎn)也比較多,一是和MR一樣因為原語(yǔ)過(guò)于低級,用MPI寫(xiě)算法,往往代碼量比較大。另一方面是基于MPI的集群,如果某個(gè)任務(wù)失敗,往往需要重啟整個(gè)集群,而MPI集群的任務(wù)成功率并不高。阿里在[10]中給出了下圖:

從圖中可以看出,MPI作業(yè)失敗的幾率接近五成。MPI也并不是完全沒(méi)有可取之處,正如沐帥所說(shuō),在超算集群上還是有場(chǎng)景的。對于工業(yè)屆依賴(lài)于云計算、依賴(lài)于commodity計算機來(lái)說(shuō),則顯得性?xún)r(jià)比不夠高。當然如果在參數服務(wù)器的框架下,對單組worker再使用MPI未嘗不是個(gè)好的嘗試,[10]的鯤鵬系統正式這么設計的。
3. 參數服務(wù)器演進(jìn)
3.1歷史演進(jìn)
沐帥在[12]中將參數服務(wù)器的歷史劃分為三個(gè)階段,第一代參數服務(wù)器萌芽
于沐帥的導師Smola的[11],如下圖所示:

這個(gè)工作中僅僅引入memcached來(lái)存放key-value數據,不同的處理進(jìn)程并行對其進(jìn)行處理。[13]中也有類(lèi)似的想法,第二代參數服務(wù)器叫application-specific參數服務(wù)器,主要針對特定應用而開(kāi)發(fā),其中最典型的代表應該是tensorflow的前身[6]。
第三代參數服務(wù)器,也即是通用參數服務(wù)器框架是由百度少帥李沐正式提出的,和前兩代不同,第三代參數服務(wù)器從設計上就是作為一個(gè)通用大規模機器學(xué)習框架來(lái)定位的。要擺脫具體應用、算法的束縛,做一個(gè)通用的大規模機器學(xué)習框架,首先就要定義好框架的功能;而所謂框架,往往就是把大量重復的、瑣碎的、做了一次就不想再來(lái)第二次的臟活、累活進(jìn)行良好而優(yōu)雅的封裝,讓使用框架的人可以只關(guān)注與自己的核心邏輯。第三代參數服務(wù)器要對那些功能進(jìn)行封裝呢?沐帥總結了這幾點(diǎn),我照搬如下:
1)高效的網(wǎng)絡(luò )通信:因為不管是模型還是樣本都十分巨大,因此對網(wǎng)絡(luò )通信的高效支持以及高配的網(wǎng)絡(luò )設備都是大規模機器學(xué)習系統不可缺少的;
2)靈活的一致性模型:不同的一致性模型其實(shí)是在模型收斂速度和集群計算量之間做tradeoff;要理解這個(gè)概念需要對模型性能的評價(jià)做些分析,暫且留到下節再介紹。
3)彈性可擴展:顯而易見(jiàn)
4)容災容錯:大規模集群協(xié)作進(jìn)行計算任務(wù)的時(shí)候,出現Straggler或者機器故障是非常常見(jiàn)的事,因此系統設計本身就要考慮到應對;沒(méi)有故障的時(shí)候,也可能因為對任務(wù)時(shí)效性要求的變化而隨時(shí)更改集群的機器配置。這也需要框架能在不影響任務(wù)的情況下能做到機器的熱插拔。
5)易用性:主要針對使用框架進(jìn)行算法調優(yōu)的工程師而言,顯然,一個(gè)難用的框架是沒(méi)有生命力的。
在正式介紹第三代參數服務(wù)器的主要技術(shù)之前,先從另一個(gè)角度來(lái)看下大規模機器學(xué)習框架的演進(jìn)

這張圖可以看出,在參數服務(wù)器出來(lái)之前,人們已經(jīng)做了多方面的并行嘗試,不過(guò)往往只是針對某個(gè)特定算法或特定領(lǐng)域,比如YahooLDA是針對LDA算法的。當模型參數突破十億以后,則可以看出參數服務(wù)器一統江湖,再無(wú)敵手。
首先我們看看第三代參數服務(wù)器的基本架構

上圖的resourcemanager可以先放一放,因為實(shí)際系統中這部分往往是復用現有的資源管理系統,比如yarn或者mesos;底下的training data毋庸置疑的需要類(lèi)似GFS的分布式文件系統的支持;剩下的部分就是參數服務(wù)器的核心組件了。
圖中畫(huà)了一個(gè)servergroup和三個(gè)worker group;實(shí)際應用中往往也是類(lèi)似,server group用一個(gè),而worker group按需配置;server manager是server group中的管理節點(diǎn),一般不會(huì )有什么邏輯,只有當有server node加入或退出的時(shí)候,為了維持一致性哈希而做一些調整。
Worker group中的task schedule則是一個(gè)簡(jiǎn)單的任務(wù)協(xié)調器,一個(gè)具體任務(wù)運行的時(shí)候,task schedule負責通知每個(gè)worker加載自己對應的數據,然后去server node上拉取一個(gè)要更新的參數分片,用本地數據樣本計算參數分片對應的變化量,然后同步給server node;server node在收到本機負責的參數分片對應的所有worker的更新后,對參數分片做一次update。

如圖所示,不同的worker同時(shí)并行運算的時(shí)候,可能因為網(wǎng)絡(luò )、機器配置等外界原因,導致不同的worker的進(jìn)度是不一樣的,如何控制worker的同步機制是一個(gè)比較重要的課題。詳見(jiàn)下節分解。
3.2同步協(xié)議
本節假設讀者已經(jīng)對隨機梯度優(yōu)化算法比較熟悉,如果不熟悉的同學(xué)請參考吳恩達經(jīng)典課程機器學(xué)習中對SGD的介紹,或者我之前多次推薦過(guò)的書(shū)籍《最優(yōu)化導論》。
我們先看一個(gè)單機算法的運行過(guò)程,假設一個(gè)模型的參數切分成三個(gè)分片k1,k2,k3;比如你可以假設是一個(gè)邏輯回歸算法的權重向量被分成三段。我們將訓練樣本集合也切分成三個(gè)分片s1,s2,s3;在單機運行的情況下,我們假設運行的序列是(k1,s1)、(k2,s1)、(k3、s1)、(k1、s2)、(k2、s2)、(k3、s2)。。??疵靼琢藛?就是假設先用s1中的樣本一次對參數分片k1、k2、k3進(jìn)行訓練,然后換s2;這就是典型的單機運行的情況,而我們知道這樣的運行序列最后算法會(huì )收斂。
現在我們開(kāi)始并行化,假設k1、k2、k3分布在三個(gè)servernode上,s1、s2、s3分布在三個(gè)worker上,這時(shí)候如果我們還要保持之前的計算順序,則會(huì )變成怎樣?work1計算的時(shí)候,work2和worker3只能等待,同樣worker2計算的時(shí)候,worker1和work3都得等待,以此類(lèi)推;可以看出這樣的并行化并沒(méi)有提升性能;但是也算簡(jiǎn)單解決了超大規模模型的存儲問(wèn)題。
為了解決性能的問(wèn)題,業(yè)界開(kāi)始探索這里的一致性模型,最先出來(lái)的版本是前面提到的[11]中的ASP模式,就是完全不顧worker之間的順序,每個(gè)worker按照自己的節奏走,跑完一個(gè)迭代就update,然后繼續,這應該是大規模機器學(xué)習中的freestyle了,如圖所示

ASP的優(yōu)勢是最大限度利用了集群的計算能力,所有的worker所在的機器都不用等待,但缺點(diǎn)也顯而易見(jiàn),除了少數幾個(gè)模型,比如LDA,ASP協(xié)議可能導致模型無(wú)法收斂。也就是SGD徹底跑飛了,梯度不知道飛到哪里去了。
在A(yíng)SP之后提出了另一種相對極端的同步協(xié)議BSP,spark用的就是這種方式,如圖所示

每個(gè)worker都必須在同一個(gè)迭代運行,只有一個(gè)迭代任務(wù)所有的worker都完成了,才會(huì )進(jìn)行一次worker和serve人之間的同步和分片更新。這個(gè)算法和嚴格一直的算法非常類(lèi)似,區別僅僅在于單機版本的batch size在BSP的時(shí)候變成了有所有worker的單個(gè)batch size求和得到的總的butch size替換。毫無(wú)疑問(wèn),BSP的模式和單機串行因為僅僅是batch size的區別,所以在模型收斂性上是完全一樣的。同時(shí),因為每個(gè)worker在一個(gè)周期內是可以并行計算的,所以有了一定的并行能力。
以此協(xié)議為基礎的spark在很長(cháng)時(shí)間內成為機器學(xué)習領(lǐng)域實(shí)際的霸主,不是沒(méi)有理由的。此種協(xié)議的缺陷之處在于,整個(gè)worker group的性能由其中最慢的worker決定;這個(gè)worker一般成為straggler。讀過(guò)GFS文章的同學(xué)應該都知道straggler的存在是非常普遍的現象。
能否將ASP和BSP做一下折中呢?答案當然是可以的,這就是目前我認為最好的同步協(xié)議SSP;SSP的思路其實(shí)很簡(jiǎn)單,既然ASP是允許不同worker之間的迭代次數間隔任意大,而B(niǎo)SP則只允許為0,那我是否可以取一個(gè)常數s?如圖所示

不同的worker之間允許有迭代的間隔,但這個(gè)間隔數不允許超出一個(gè)指定的數值s,圖中s=3.
SSP協(xié)議的詳細介紹參見(jiàn)[14],CMU的大拿Eric Xing在其中詳細介紹了SSP的定義,以及其收斂性的保證。理論推導證明常數s不等于無(wú)窮大的情況下,算法一定可以在若干次迭代以后進(jìn)入收斂狀態(tài)。
順便提一句,考察分布式算法的性能,一般會(huì )分為statistical performance和hard performance來(lái)看。前者指不同的同步協(xié)議導致算法收斂需要的迭代次數的多少,后者是單次迭代所對應的耗時(shí)。兩者的關(guān)系和precisionrecall關(guān)系類(lèi)似,就不贅述了。有了SSP,BSP就可以通過(guò)指定s=0而得到。而ASP同樣可以通過(guò)制定s=∞來(lái)達到。
3.3核心技術(shù)
除了參數服務(wù)器的架構、同步協(xié)議之外,本節再對其他技術(shù)做一個(gè)簡(jiǎn)要的介紹,詳細的了解請直接閱讀沐帥的博士論文和相關(guān)發(fā)表的論文。
熱備、冷備技術(shù):為了防止servernode掛掉,導致任務(wù)中斷,可以采用兩個(gè)技術(shù),一個(gè)是對參數分片進(jìn)行熱備,每個(gè)分片存儲在三個(gè)不同的server node中,以master-slave的形式存活。如果master掛掉,可以快速從slave獲取并重啟相關(guān)task。
除了熱備,還可以定時(shí)寫(xiě)入checkpoint文件到分布式文件系統來(lái)對參數分片及其狀態(tài)進(jìn)行備份。進(jìn)一步保證其安全性。
Servernode管理:可以使用一致性哈希技術(shù)來(lái)解決server node的加入和退出問(wèn)題,如圖所示

當有server node加入或退出的時(shí)候,servermanager負責對參數進(jìn)行重新分片或者合并。注意在對參數進(jìn)行分片管理的情況下,一個(gè)分片只需要一把鎖,這大大提升了系統的性能,也是參數服務(wù)器可以實(shí)用的一個(gè)關(guān)鍵點(diǎn)。
4. 大規模機器學(xué)習的四重境界
到這里可以回到我們的標題了,大規模機器學(xué)習的四重境界到底是什么呢?
這四重境界的劃分是作者個(gè)人閱讀總結的一種想法,并不是業(yè)界標準,僅供大家參考。
境界1:參數可單機存儲和更新
此種境界較為簡(jiǎn)單,但仍可以使用參數服務(wù)器,通過(guò)數據并行來(lái)加速模型的訓練。
境界2:參數不可單機存儲,可以單機更新
此種情況對應的是一些簡(jiǎn)單模型,比如sparse logistic regression;當feature的數量突破百億的時(shí)候,LR的權重參數不太可能在一臺機器上完全存下,此時(shí)必須使用參數服務(wù)器架構對模型參數進(jìn)行分片。但是注意一點(diǎn),SGD的更新公式
w’=w-α,其中可以分開(kāi)到單個(gè)維度進(jìn)行計算,但是單個(gè)維度的wi=f(w)xi
這里的f(w)表示是全部參數w的一個(gè)函數,具體推倒比較簡(jiǎn)單,這里篇幅所限就不贅述了。只是想說(shuō)明worker在計算梯度的時(shí)候可能需要使用到上一輪迭代的所有參數。
而我們之所以對參數進(jìn)行分片就是因為我們無(wú)法將所有參數存放到一臺機器,現在單個(gè)worker有需要使用所有的參數才能計算某個(gè)參數分片的梯度,這不是矛盾嗎?可能嗎?
答案是可能的,因為單個(gè)樣本的feature具有很高的稀疏性(sparseness)。例如一個(gè)百億feature的模型,單個(gè)訓練樣本往往只在其中很小一部分feature上有取值,其他都為0(假設feature取值都已經(jīng)離散化了)。因此計算f(w)的時(shí)候可以只拉取不為0的feature對應的那部分w即可。有文章統計一般這個(gè)級別的系統,稀疏性往往在0.1%(or 0.01%,記得不是很準,大致這樣)一下。這樣的系數性,可以讓單機沒(méi)有任何阻礙的計算f(w)。
目前公司開(kāi)源的angel等系統都處于這個(gè)境界。而原生spark還沒(méi)有達到這個(gè)境界,只能在中小規模的圈子里廝混。
境界3:參數不可單機存儲,不可單機更新,但無(wú)需模型并行
境界3順延境界2二來(lái),當百億級feature且feature比較稠密的時(shí)候,就需要計算框架進(jìn)入到這層境界了,此時(shí)單個(gè)worker的能力有限,無(wú)法完整加載一個(gè)樣本,也無(wú)法完整計算f(w)。怎么辦呢?其實(shí)很簡(jiǎn)單,學(xué)過(guò)線(xiàn)性代數的都知道,矩陣可以分塊。向量是最簡(jiǎn)單的矩陣,自然可以切成一段一段的來(lái)計算。只是調度器需要支持算符分段而已了。
境界4:參數不可單機存儲,不可單機更新,需要模型并行
進(jìn)入到這個(gè)層次的計算框架,可以算是世界一流了??梢蕴幚沓笠幠5纳窠?jīng)網(wǎng)絡(luò )。這也是最典型的應用場(chǎng)景。此時(shí)不僅模型的參數不能單機存儲,而且同一個(gè)迭代內,模型參數之間還有強的依賴(lài)關(guān)系,可以參見(jiàn)姐夫對distbelief的介紹里的模型切分。
此時(shí)首先需要增加一個(gè)coordinator組件來(lái)進(jìn)行模型并行的concurrent控制。而一般參數間的一來(lái)關(guān)系因模型而已,所以較難抽象出通用的coordinator來(lái),而必須以某種形式通過(guò)腳本parser來(lái)生產(chǎn)整個(gè)計算任務(wù)的DAG圖,然后通過(guò)DAG調度器來(lái)完成。對這個(gè)問(wèn)題的介紹可以參考Erix Xing的分享[5]。
Tensorflow
目前業(yè)界比較知名的深度學(xué)習框架有Caffee、MXNet、Torch、Keras、Theano等,但目前最炙手可熱的應該是google發(fā)布的Tensorflow。這里單獨拿出來(lái)稍微分解下。
前面不少圖片引自此文,從TF的論文來(lái)看,TF框架本身是支持模型并行和數據并行的,內置了一個(gè)參數服務(wù)器模塊,但從開(kāi)源版本所曝光的API來(lái)看,TF無(wú)法用來(lái)10B級別feature的稀疏LR模型。原因是已經(jīng)曝光的API只支持在神經(jīng)網(wǎng)絡(luò )的不同層和層間進(jìn)行參數切分,而超大規模LR可以看做一個(gè)神經(jīng)單元,TF不支持單個(gè)神經(jīng)單元參數切分到多個(gè)參數服務(wù)器node上。
當然,以google的實(shí)力,絕對是可以做到第四重境界的,之所以沒(méi)有曝光,可能是基于其他商業(yè)目的的考量,比如使用他們的云計算服務(wù)。
5. 其他
5.1資源管理
本文沒(méi)有涉及到的部分是資源管理,大規模機器學(xué)習框架部署的集群往往
資源消耗也比較大,需要專(zhuān)門(mén)的資源管理工具來(lái)維護。這方面yarn和mesos都是佼佼者,細節這里也就不介紹了。
5.2設備
除了資源管理工具,本身部署大規模機器學(xué)習集群本身對硬件也還是有些要
求的,雖然理論上來(lái)說(shuō),所有commodity機器都可以用來(lái)搭建這類(lèi)集群,但是考慮到性能,我們建議盡量用高內存的機器+萬(wàn)兆及以上的網(wǎng)卡。沒(méi)有超快速的網(wǎng)卡,玩參數傳遞和樣本加載估計會(huì )比較苦逼。
6. 結語(yǔ)
從后臺轉算法以來(lái),長(cháng)期沉浸于算法推理的論文無(wú)法自拔,對自己之前的后
臺工程能力漸漸輕視起來(lái),覺(jué)得工程對算法的幫助不大。直到最近一個(gè)契機,需要做一個(gè)這方面的調研,才豁然發(fā)現,之前的工程經(jīng)驗對我理解大規模機器學(xué)習框架非常有用,果然如李宗盛所說(shuō),人生每一步路,都不是白走的。
在一個(gè)月左右的調研中,腦子每天都充斥這各種疑問(wèn)和困惑,曾經(jīng)半夜4點(diǎn)醒來(lái),思考同步機制而再也睡不著(zhù),干脆起來(lái)躲衛生間看書(shū),而那天我一點(diǎn)多才睡。當腦子里有放不下的問(wèn)題的時(shí)候,整個(gè)人會(huì )處于一種非??簥^的狀態(tài),除非徹底想清楚這個(gè)問(wèn)題,否則失眠是必然的,上一次這種狀態(tài)已經(jīng)是很多年前了。好在最后我總算理清了這方面的所有關(guān)鍵細節。以此,記之。Carbonzhang于2017年8月26日凌晨!
致謝
感謝wills、janwang、joey、roberty、suzi等同學(xué)一起討論,特別感謝burness在TF方面的深厚造詣和調研。因為本人水平所限,錯漏難免,另外還有相當多的細節因為篇幅限制并未一一展開(kāi),僅僅是從較高抽象層面上簡(jiǎn)述了下大規模機器學(xué)習框架的關(guān)鍵思路,其他如分片向量鎖、通信協(xié)議、時(shí)鐘邏輯、DAG調度器、資源調度模塊等均為展開(kāi)來(lái)講,希望以后有機會(huì )能補上。
評論