飛槳面向異構(gòu)場(chǎng)景下的自動(dòng)并行設(shè)計(jì)與實(shí)踐
一、背景介紹
在介紹自動(dòng)并行之前,我們思考一下為什么需要自動(dòng)并行?一方面現(xiàn)在有著不同的模型結(jié)構(gòu),另一方面還有各種各樣的并行策略,兩者之間一般是多對(duì)多的映射關(guān)系。假設(shè)我們能實(shí)現(xiàn)一個(gè)統(tǒng)一的模型結(jié)構(gòu)滿足各種任務(wù)需求,那么我們的并行策略是不是在這種統(tǒng)一的模型結(jié)構(gòu)上實(shí)現(xiàn)收斂?
答案是否定的,因?yàn)椴⑿胁呗圆粌H僅跟模型結(jié)構(gòu)相關(guān),還跟模型的規(guī)模以及實(shí)際使用的機(jī)器資源息息相關(guān)。這就體現(xiàn)出自動(dòng)并行的價(jià)值,它的目標(biāo)是:用戶給定一個(gè)模型和所使用的機(jī)器資源后,能夠自動(dòng)地幫用戶選擇一個(gè)比較好或者最優(yōu)的并行策略來(lái)高效執(zhí)行。
這里羅列了個(gè)人感興趣的一些工作,不一定完整,想跟大家討論一下自動(dòng)并行的現(xiàn)狀和歷史。大概分了幾個(gè)維度:第一個(gè)維度是自動(dòng)并行的程度,分為全自動(dòng)和半自動(dòng);第二個(gè)維度是并行粒度,分別是針對(duì)每個(gè) Layer 來(lái)提供并行策略,或者是針對(duì)每一個(gè)算子或者張量來(lái)提供并行策略;第三個(gè)是表示能力,這里簡(jiǎn)化為 SPMD(Single Program Multiple Data)并行和 Pipeline 并行兩大類;第四個(gè)是特色,這里列出了個(gè)人覺(jué)得相關(guān)工作比較有特色的地方;第五個(gè)是支持硬件,主要寫出相關(guān)工作所支持最大規(guī)模的硬件類型和數(shù)量。其中,標(biāo)紅部分主要是對(duì)飛槳自動(dòng)并行研發(fā)有啟發(fā)性的點(diǎn)。
對(duì)于全自動(dòng)并行來(lái)說(shuō),我們可以看到并行粒度,是由粗粒度到細(xì)粒度的發(fā)展過(guò)程;表示能力是從比較簡(jiǎn)單的 SPMD 到非常通用的 SPMD 與 Pipeline 的方式;支持的模型是從簡(jiǎn)單的 CNN 到 RNN 再到比較復(fù)雜的 GPT;雖然支持多機(jī)多卡,但整體規(guī)模不是特別大。
對(duì)于半自動(dòng)并行來(lái)說(shuō),并行粒度基本上都是以算子為粒度的,而表示能力從簡(jiǎn)單的 SPMD 到完備的 SPMD 加上 Pipeline 的并行策略,模型支持規(guī)模達(dá)到千億和萬(wàn)億量級(jí),所使用的硬件數(shù)量達(dá)到千卡量級(jí)。
再?gòu)目蚣芙嵌葋?lái)看,我們可以看到現(xiàn)有的框架基本上已經(jīng)支持或計(jì)劃支持半自動(dòng)這種模式,而并行粒度也發(fā)展到算子粒度,表示能力基本上都采用 SPMD 加上 Pipeline 的完備表示,都面向各種各樣模型和各種各樣硬件。
這里總結(jié)一下個(gè)人的一些思考:
① 第一點(diǎn),分布式策略在底層表示上逐漸統(tǒng)一。
② 第二點(diǎn),半自動(dòng)會(huì)逐漸成為框架的一種分布式編程范式,而全自動(dòng)會(huì)結(jié)合特定的場(chǎng)景和經(jīng)驗(yàn)規(guī)則去探索落地。
③ 第三點(diǎn),實(shí)現(xiàn)一個(gè)極致端到端性能,需要采用并行策略與優(yōu)化策略聯(lián)合調(diào)優(yōu)來(lái)實(shí)現(xiàn)。
二、架構(gòu)設(shè)計(jì)
一般完整分布式訓(xùn)練包括 4 個(gè)具體的流程。首先是模型切分,無(wú)論是手動(dòng)并行還是自動(dòng)并行都需要將模型切分為多個(gè)可以并行的任務(wù);其次是資源獲取,可以通過(guò)自己搭建或者從平臺(tái)申請(qǐng)來(lái)準(zhǔn)備好我們訓(xùn)練所需要的設(shè)備資源;然后是任務(wù)放置(或者任務(wù)映射),也就是將切分后的任務(wù)放置到對(duì)應(yīng)資源上;最后是分布式執(zhí)行,就是各個(gè)設(shè)備上的任務(wù)并行執(zhí)行,并通過(guò)消息通信來(lái)進(jìn)行同步和交互。
現(xiàn)在一些主流的解決方案存在一些問(wèn)題:一方面可能只考慮分布式訓(xùn)練中的部分流程,或者只側(cè)重部分流程;第二個(gè)就是過(guò)于依賴專家的經(jīng)驗(yàn)規(guī)則,比如模型切分和資源分配;最后是在整個(gè)訓(xùn)練的過(guò)程中,缺乏對(duì)任務(wù)和資源的感知能力。
而飛槳所設(shè)計(jì)的端到端自適應(yīng)分布式訓(xùn)練架構(gòu),在全面考慮 4 個(gè)流程基礎(chǔ)上,又加入第五個(gè)流程,即彈性調(diào)度。我們核心設(shè)計(jì)理念主要包括這 3 點(diǎn):
第一,計(jì)算和資源統(tǒng)一表示,并且計(jì)算和資源同等重要。往往大家比較關(guān)心怎么切分模型,但是對(duì)資源關(guān)注度比較少。我們一方面用統(tǒng)一的分布式計(jì)算圖來(lái)表示各種各樣的并行策略;另一方面,我們用統(tǒng)一的分布式資源圖來(lái)建模各種各樣的機(jī)器資源,既能表示同構(gòu)的,又能表示異構(gòu)的資源連接關(guān)系,還包括資源本身的計(jì)算和存儲(chǔ)能力。
第二,最大化解耦,除了模塊之間解耦外,我們還將邏輯切分跟物理放置以及分布式執(zhí)行等進(jìn)行解耦,這樣能夠更好地實(shí)現(xiàn)不同模型在不同集群資源高效執(zhí)行。
第三,端到端自適應(yīng),涵蓋分布式訓(xùn)練所涉及的全面流程,并采用一個(gè)全局的代表模型來(lái)驅(qū)動(dòng)并行策略或者資源放置的自適應(yīng)決策,來(lái)盡可能代替人工定制化決策。上圖淺藍(lán)色框住的部分就是本次報(bào)告所介紹的自動(dòng)并行相關(guān)工作。
1、統(tǒng)一分布式計(jì)算圖
首先是統(tǒng)一的分布式計(jì)算圖。統(tǒng)一目的是便于我們采用統(tǒng)一方式來(lái)表示現(xiàn)有的各種各樣的并行策略,這樣利于做自動(dòng)化處理。眾所周知,串行計(jì)算圖能表示各種各樣的模型,類似地,我們?cè)诖杏?jì)算圖的基礎(chǔ)上,對(duì)每個(gè)算子和張量加上分布式屬性來(lái)作為分布式計(jì)算圖,這種細(xì)粒度方式能表示現(xiàn)有并行策略,而且語(yǔ)義會(huì)更豐富和通用,還能表示新的并行策略。分布式計(jì)算圖中的分布式屬性主要包括三個(gè)方面信息:1)需要表示張量怎么切分或者算子怎么切分;2)需要表示在哪些資源進(jìn)行分布式計(jì)算;3)如何將切分后的張量或算子映射到資源上。對(duì)比串行計(jì)算圖,分布式計(jì)算圖有 3 個(gè)基礎(chǔ)組成概念:分布式張量,類似于串行的張量;分布式算子,類似于串行的算子;分布式重排,分布式計(jì)算圖獨(dú)有。
(1)分布式張量
首先,介紹分布式張量所包括的三個(gè)方面信息:
① 串行張量信息:主要包含張量 shape、dtype 等一些元信息,一般實(shí)際計(jì)算不需要對(duì)串行張量進(jìn)行實(shí)例化。
② ProcessMesh:進(jìn)程的 cartesion topology 表示,有別于 DeviceMesh,我們之所以采用 ProcessMesh,主要希望邏輯的進(jìn)程跟物理設(shè)備進(jìn)行一個(gè)解耦,這樣便于做更高效任務(wù)映射。
③ ShardSpec:用來(lái)表示串行張量每個(gè)維度用 ProcessMesh 哪個(gè)維度進(jìn)行切分,具體可看下圖示例。
假如有一個(gè)二維的 6*12 張量和一個(gè) 3*2 的 ProcessMesh(第一維是 x,第二維是 y,元素是進(jìn)程 ID)。如果 ShardSpec 是 [None,None],就表示張量第 0 維和第 2 維都不切分,每個(gè)進(jìn)程上都有一個(gè)全量張量。如果 ShardSpec是 ['x’, ‘y’],表示用 ProcessMesh 的 x 軸去切張量第 0 維,用 ProcessMesh 的 y 軸去切張量第 1 維,這樣每個(gè)進(jìn)程都有一個(gè) 2*6 大小的 Local 張量??傊?,通過(guò) ProcessMesh 和 ShardSpec 以及張量未切分前的串行信息,就能夠表示一個(gè)張量在相關(guān)進(jìn)程上切分情況。
(2)分布式算子
分布式算子表示是基于分布式張量的,包括串行算子信息,輸入和輸出張量的分布式屬性。類似一個(gè)分布式張量可能會(huì)對(duì)應(yīng)多種切分方式,分布式算子里面的分布式屬性不一樣,對(duì)應(yīng)著不同切分。以矩形乘 Y=X*W 算子為例,如果輸入和輸出分布式屬性不同,就對(duì)應(yīng)不同的分布式算子實(shí)現(xiàn)(分布屬性包括 ProcessMesh 和 ShardSpec)。對(duì)于分布式算子來(lái)說(shuō),其輸入和輸出張量的 ProcessMesh 相同。
(3)分布式重排
最后一個(gè)是分布式重排,這是分布式計(jì)算圖所必須具有的概念,用來(lái)處理源張量和目的張量分布式屬性不同的情況。比如有 2 個(gè)算子的計(jì)算,上一個(gè)算子產(chǎn)生 y,跟下一個(gè)算子使用 y 分布式屬性不同(圖中用不同顏色表示),這時(shí)我們需要插入額外的一個(gè) Reshard 操作來(lái)通過(guò)通信進(jìn)行張量分布式重排,本質(zhì)就是處理生產(chǎn)和消費(fèi)不匹配問(wèn)題。
導(dǎo)致不匹配的原因主要有三個(gè)方面:1)支持支持?jǐn)?shù)據(jù)和計(jì)算分離,所以對(duì)張量和使用它的算子有不同的分布式屬性;2)支持用戶自定義標(biāo)記分布式屬性,用戶可能對(duì)張量和使用它的算子標(biāo)記不同的分布式屬性;3)分布式算子底層實(shí)現(xiàn)有限,如果出現(xiàn)了輸入或者輸出分布式屬性不支持的情況,也需要通過(guò)分布式重排。
2、統(tǒng)一分布式資源圖
介紹完統(tǒng)一的分布計(jì)算圖三個(gè)基本概念后,再看統(tǒng)一的分布式資源圖,主要設(shè)計(jì)的考量:1)支持異構(gòu)集群,異構(gòu)集群就是集群中可能有 CPU、GPU、XPU 資源;2)表示拓?fù)溥B接,這里面涵蓋了集群的層次結(jié)構(gòu)連接關(guān)系,包括對(duì)連接能力的量化,比如帶寬或者延遲;3)設(shè)備本身建模,包括一個(gè)設(shè)備的存儲(chǔ)和計(jì)算能力。為了滿足上面設(shè)計(jì)需求,我們用Cluster來(lái)表示分布式資源,它包含多個(gè)同構(gòu) DeviceMesh。每個(gè) DeviceMesh 內(nèi)會(huì)隱含一個(gè)由 Device 鏈接組成的 Graph。
這里舉個(gè)例子,上圖可以看到有 4 臺(tái)機(jī)器,包括 2 個(gè) GPU 機(jī)器和 2 個(gè) XPU 機(jī)器。對(duì)于 2 臺(tái) GPU 機(jī)器,會(huì)用一個(gè)同構(gòu)的 DeviceMesh 表示,而對(duì)于 2 臺(tái) XPU 機(jī)器,會(huì)用另一個(gè)同構(gòu)的 DeviceMesh 表示。對(duì)于一個(gè)固定集群來(lái)說(shuō),它的 DeviceMesh 是固定不變的,而用戶操作的是 ProcessMesh,可以理解是 DeviceMesh 的抽象,用戶可以隨意 Reshape 和 Slice,最后會(huì)統(tǒng)一地將 ProcessMesh 進(jìn)程映射到 DeviceMesh 設(shè)備上。
采用前面基于張量和算子細(xì)粒度的分布式計(jì)算圖表示,能涵蓋現(xiàn)有并行策略以及未來(lái)可能會(huì)出現(xiàn)新的并行策略。數(shù)據(jù)并行就是對(duì)數(shù)據(jù)張量的 Batch 維度進(jìn)行切分。模型并行對(duì)權(quán)重相關(guān)維度進(jìn)行切分。流水線并行使用不同 ProcessMesh 來(lái)表示,它可以表示為更靈活 Pipeline 并行,比如一個(gè) Pipeline Stage 可以連接多個(gè) Pipeline Stage,而且不同 Stage 使用 ProcessMesh 的 shape 可以不同。其他有些框架的流水線并行是通過(guò) Stage Number 或者 Placement 實(shí)現(xiàn),不夠靈活通用?;旌喜⑿芯褪菙?shù)據(jù)并行,張量模型并行和流水線并行三者混合。
三、關(guān)鍵實(shí)現(xiàn)
前面是飛槳自動(dòng)并行架構(gòu)設(shè)計(jì)和一些抽象概念介紹?;谇懊娴幕A(chǔ),下面我們通過(guò) 2 層 FC 網(wǎng)絡(luò)例子,來(lái)介紹飛槳自動(dòng)并行內(nèi)部實(shí)現(xiàn)流程。
上圖是飛槳整個(gè)自動(dòng)并行的流程圖。首先我們會(huì)基于一個(gè)串行前向計(jì)算圖,進(jìn)行反向生成,獲得包括前向、后向和更新子圖的完整計(jì)算圖。然后,需要明確組網(wǎng)中每個(gè)張量和每個(gè)算子的分布式屬性。既可以采用半自動(dòng)的推導(dǎo)方式,也可以采用全自動(dòng)搜索方式。本報(bào)告主要講解半自動(dòng)推導(dǎo)方式,即基于用戶少量標(biāo)記來(lái)推導(dǎo)其他未標(biāo)記張量和算子的分布式屬性。通過(guò)分布式屬性推導(dǎo)后,串行計(jì)算圖中每個(gè)張量和每個(gè)算子都有自己的分布式屬性?;诜植际綄傩?,先通過(guò)自動(dòng)切分模塊,將串行計(jì)算圖變成支持 SPMD 并行的邏輯分布式計(jì)算圖,再通過(guò)分布式重排,實(shí)現(xiàn)支持 Pipeline 并行的邏輯分布式計(jì)算圖。生成的邏輯分布式計(jì)算圖會(huì)通過(guò)物理映射,變成物理分布式計(jì)算圖,目前只支持一個(gè)進(jìn)程和一個(gè)設(shè)備的一一映射。最后,將物理分布式計(jì)算圖變成一個(gè)實(shí)際任務(wù)依賴圖交給異步執(zhí)行器進(jìn)行實(shí)際執(zhí)行。
1、分布式屬性推導(dǎo)
分布式屬性推導(dǎo)就是給定計(jì)算圖中部分張量和算子的分布式屬性,自動(dòng)補(bǔ)全其他所有的張量和算子的分布式屬性。例子是兩個(gè) Matmul 計(jì)算,用戶只標(biāo)記了兩個(gè)參數(shù)分布式屬性,表示 W1 在 0,1 進(jìn)程上進(jìn)行列切,W2 是在 2,3 進(jìn)程上進(jìn)行行切,這里有兩個(gè)不同 ProcessMesh,用不同的顏色表示。
分布式屬性推導(dǎo)分為兩個(gè)步驟:1)先進(jìn)行 ProcessMesh 傳導(dǎo),實(shí)現(xiàn) Pipeline 切分;2)再進(jìn)行 ShardSpec 傳導(dǎo),實(shí)現(xiàn)一個(gè) Stage 內(nèi)的 SPMD 切分。ProcessMesh 推導(dǎo)利用了飛槳線性 Program lR, 按靜態(tài) Program Order 采用就近選擇策略進(jìn)行推導(dǎo),支持包含計(jì)算,即如果兩個(gè) ProcessMesh,一個(gè)大一個(gè)小,就選較大作為最終 ProcessMesh。而 ShardSpec 推導(dǎo)利用飛槳 SSA Graph IR 進(jìn)行前向和后向數(shù)據(jù)流分析進(jìn)行推導(dǎo),之所以可以用數(shù)據(jù)流分析,是因?yàn)?ShardSpec 語(yǔ)義,滿足數(shù)據(jù)流分析的 Semilattice 性質(zhì)。數(shù)流分析理論上能保證收斂,通過(guò)結(jié)合前向和后向分析,能夠?qū)⒂?jì)算圖任何一個(gè)位置標(biāo)記信息傳播到整張計(jì)算圖,而不是只能單方向傳播。
基于分布式屬性推導(dǎo),串行計(jì)算圖中的每個(gè)張量和算子都擁有自己的分布式屬性,這樣就可以基于分布式屬性進(jìn)行計(jì)算圖的自動(dòng)切分。按照例子來(lái)說(shuō),就是把單機(jī)串行計(jì)算圖,變成 Rank0、Rank1,Rank2、Rank3 四個(gè)計(jì)算圖。
簡(jiǎn)單來(lái)說(shuō),會(huì)遍歷每個(gè)算子,先對(duì)算子輸入和輸出進(jìn)行張量切分,然后再對(duì)每個(gè)算子進(jìn)行計(jì)算切分。張量切分會(huì)通過(guò) Distributed Tensor 對(duì)象來(lái)構(gòu)造 Local Tensor 對(duì)象,而算子切分會(huì)通過(guò) Distributed Operator 對(duì)象來(lái)基于實(shí)際輸入和輸出的分布屬性來(lái)選擇對(duì)應(yīng)分布式實(shí)現(xiàn),類似于單機(jī)框架的算子到 Kernel 的分發(fā)過(guò)程。
通過(guò)前面自動(dòng)切分,只能獲得支持 SPMD 并行的分布式計(jì)算圖。為了支持 Pipeline 并行,還需要通過(guò)分布式重排來(lái)處理,這樣通過(guò)插入一個(gè)合適的 Reshard 操作,例子中每個(gè) Rank 擁有自己真正獨(dú)立計(jì)算圖。雖然左圖 Rank0 的 Y 跟 Rank2 的 Y,切分一樣,但是由于他們?cè)诓煌?ProcessMesh 上,導(dǎo)致了生產(chǎn)消費(fèi)分布式屬性不匹配,所以也需要插入 Reshard。
飛槳目前支持兩類分布式重排。第一類,是比較常見(jiàn)源張量分布跟目標(biāo)張量分布都在同一個(gè) ProcessMesh 上,但是源張量分布和目標(biāo)張量分布所使用切分方式不一樣(即 ShardSpec 不一樣)。第二類,是源張量分布和目標(biāo)張量分布在不同的 ProcessMesh 上,而且 ProcessMesh 大小可以不一樣,比如圖中情形 2 中的 0-5 進(jìn)程和 6-9 進(jìn)程。為了盡可能減少通信,飛槳也對(duì) Reshard 操作進(jìn)行相關(guān)優(yōu)化。
經(jīng)過(guò)分布式重排后,得到一個(gè)邏輯上的分布式計(jì)算圖,這個(gè)時(shí)候還沒(méi)有決定進(jìn)程和具體設(shè)備映射?;谶壿嫷姆植际接?jì)算圖和前面統(tǒng)一的資源表示圖,會(huì)進(jìn)行物理映射操作,也就是 Rank Mapping,就是從多種映射方案(一個(gè)進(jìn)程具體跟哪個(gè)設(shè)備進(jìn)行映射)中找到一個(gè)最優(yōu)的映射方案。
這里介紹一個(gè)比較簡(jiǎn)單基于貪心規(guī)則的實(shí)現(xiàn)。先構(gòu)建進(jìn)程和進(jìn)程間通信量的鄰接表,邊表示通信量,節(jié)點(diǎn)表示設(shè)備需求,再構(gòu)建設(shè)備與設(shè)備之間的鄰接表,邊表示通信帶寬,節(jié)點(diǎn)表示設(shè)備計(jì)算和內(nèi)存。我們會(huì)任選一個(gè)進(jìn)程 R 放置到滿足需求的設(shè)備 D 上,放置后,選擇與 R 通信量最大的進(jìn)程放到 D 所在機(jī)器其他設(shè)備上,按照這種方式直到完成所有進(jìn)程映射。在映射過(guò)程中,需要判斷所選擇的設(shè)備與進(jìn)程圖所需求的設(shè)備類型以及所需要計(jì)算量和內(nèi)存是否匹配。
通過(guò)物理映射后,我們會(huì)根據(jù)所獲得的物理分布式組網(wǎng)構(gòu)建實(shí)際任務(wù)依賴圖。圖中示例是基于計(jì)算圖的前向、后向和更新角色來(lái)構(gòu)建任務(wù)依賴圖,相同角色的算子會(huì)組成一個(gè)任務(wù)。為了支持 Micro-batching 優(yōu)化,一個(gè)任務(wù)依賴圖會(huì)生成多個(gè)任務(wù)實(shí)例依賴圖,每個(gè)示例雖然計(jì)算邏輯一樣,但是使用不同內(nèi)存。目前飛槳會(huì)自動(dòng)地根據(jù)計(jì)算圖角色去構(gòu)建任務(wù)圖,但是用戶可以根據(jù)合適粒度自定義任務(wù)構(gòu)建。每個(gè)進(jìn)程有了任務(wù)多實(shí)例依賴圖后就會(huì)基于 Actor 模式進(jìn)行異步執(zhí)行,通過(guò)消息驅(qū)動(dòng)方式就可以自動(dòng)地實(shí)現(xiàn) 1F1B 執(zhí)行調(diào)度。
基于上面整個(gè)流程,我們已經(jīng)實(shí)現(xiàn)一個(gè)功能比較完備的自動(dòng)并行。但只有并行策略還無(wú)法獲得一個(gè)比較好的端到端性能,所以我們還需要加入相應(yīng)的優(yōu)化策略。對(duì)飛槳自動(dòng)并行,我們會(huì)在一個(gè)自動(dòng)切分之前和組網(wǎng)切分之后加一些優(yōu)化策略,這是因?yàn)橐恍﹥?yōu)化在串行邏輯上實(shí)現(xiàn)比較自然,有一些優(yōu)化在切分后比較容易實(shí)現(xiàn),通過(guò)統(tǒng)一的優(yōu)化 Pass 管理機(jī)制,我們能夠保證飛槳自動(dòng)并行中并行策略與優(yōu)化策略自由結(jié)合。
四、應(yīng)用實(shí)踐
下面介紹應(yīng)用實(shí)踐。
首先是接口,不管如何實(shí)現(xiàn),用戶最終還是通過(guò)接口來(lái)使用我們所提供的自動(dòng)并行能力。如果對(duì)用戶分布式需求進(jìn)行拆解,包括模型組網(wǎng)切分,資源表示,數(shù)據(jù)分布式加載,分布式執(zhí)行過(guò)程控制和分布式保存和恢復(fù)等。為了滿足這些需求,我們提供了一個(gè) Engine 類,它同時(shí)兼顧易用性和靈活性。易用性方面,它提供了高階 API,能支持自定義 Callback,分布式過(guò)程對(duì)用戶透明。靈活性方面,它提供了低階 API,包括分布式 dataloader 構(gòu)建,自動(dòng)并行切圖和執(zhí)行等接口,用戶可以進(jìn)行更細(xì)粒度控制。兩者會(huì)共享 shard_tensor、shard_op 以及 save 和 load 等接口。
這里有兩個(gè)標(biāo)記接口 shard_op 和 shard_tensor。其中,shard_op 既可以標(biāo)記單個(gè)算子,也可以對(duì)整個(gè) Module 進(jìn)行標(biāo)記,是函數(shù)式。上圖是一個(gè)非常簡(jiǎn)單的使用示例。首先,使用飛槳已有 API 進(jìn)行一個(gè)串行組網(wǎng),在其中,我們會(huì)使用 shard_tensor 或者 shard_op 進(jìn)行非侵入式分布式屬性標(biāo)記。然后,構(gòu)建一個(gè)自動(dòng)并行 Engine,傳入模型相關(guān)信息和配置。這個(gè)時(shí)候用戶有兩個(gè)選擇,一個(gè)選擇是直接使用 fit /evaluate/predict 高階接口,另一種選擇是使用 dataloader+prepare+run 接口。如果選擇 fit 接口,用戶只需要傳 Dataset,框架會(huì)自動(dòng)進(jìn)行分布式數(shù)據(jù)集加載,自動(dòng)并行過(guò)程編譯和分布式訓(xùn)練執(zhí)行。如果選擇 dataloader+prepare+run 接口,用戶可以將分布式數(shù)據(jù)加載、自動(dòng)并行編譯和分布式執(zhí)行進(jìn)行解耦,能更好進(jìn)行單步調(diào)試。
PaddleFleetX 是具備易用性和高性能的一個(gè)端到端的一站式大模型套件,支持自動(dòng)并行功能。用戶要想調(diào)用飛槳自動(dòng)并行端到端功能,只需要提供串行動(dòng)態(tài)圖模型組網(wǎng)即可。在獲得用戶動(dòng)態(tài)圖串行組網(wǎng)后,內(nèi)部實(shí)現(xiàn)會(huì)利用飛槳?jiǎng)愚D(zhuǎn)靜模塊,將動(dòng)態(tài)圖單卡組網(wǎng)變成靜態(tài)圖單卡組網(wǎng),然后通過(guò)自動(dòng)并行編譯,最后再進(jìn)行分布式訓(xùn)練。在推理生成時(shí)候,使用的機(jī)器資源可能與訓(xùn)練時(shí)使用的資源不太一樣,內(nèi)部實(shí)現(xiàn)還會(huì)進(jìn)行參數(shù)和組網(wǎng)的自適應(yīng)參數(shù)切分。目前 PaddleFleetX 中的自動(dòng)并行涵蓋了大家常用的并行策略和優(yōu)化策略,并支持兩者任意組合,而且對(duì)生成任務(wù)來(lái)說(shuō),還支持 While 控制流的自動(dòng)切分。
五、總結(jié)展望
飛槳自動(dòng)并行還有很多工作在開(kāi)展中,目前的特色可以總結(jié)為以下幾方面:
首先,統(tǒng)一的分布式計(jì)算圖,能夠支持完備的 SPMD 和 Pipeline 的分布式策略,能夠支持存儲(chǔ)和計(jì)算的分離式表示;
第二,統(tǒng)一的分布式資源圖,能夠支持異構(gòu)資源的建模和表示;
第三,支持并行策略和優(yōu)化策略的有機(jī)結(jié)合;
第四,提供了比較完備的接口體系;
最后,作為關(guān)鍵組成,支撐飛槳端到端的自適應(yīng)分布式架構(gòu)。
并行一般可以分為兩個(gè)領(lǐng)域(沒(méi)有明確分界),一個(gè)是傳統(tǒng)的分布式計(jì)算,一個(gè)是傳統(tǒng)高性能計(jì)算,兩者各有優(yōu)劣?;趥鹘y(tǒng)分布式計(jì)算的框架代表是 TensorFlow,它側(cè)重 MPMD(Multiple Program-Multiple Data)并行模式,能夠很好支持彈性和容錯(cuò),分布式計(jì)算的用戶體驗(yàn)會(huì)好一些,編程較簡(jiǎn)單,用戶一般是以一個(gè)串行全局視角進(jìn)行編程;基于傳統(tǒng)高性能的計(jì)算的框架代表是 PyTorch,更側(cè)重 SPMD(Single Program-Multiple Data)模式,追求極致性能,用戶需要直接面臨物理集群進(jìn)行編程,自己負(fù)責(zé)切分模型和插入合適通信,對(duì)用戶要求較高。而自動(dòng)并行或者自適應(yīng)分布式計(jì)算,可以看作兩者結(jié)合。當(dāng)然不同架構(gòu)設(shè)計(jì)側(cè)重點(diǎn)不一樣,需要根據(jù)實(shí)際需求進(jìn)行權(quán)衡,我們希望飛槳自適應(yīng)架構(gòu)能夠兼顧兩個(gè)領(lǐng)域的優(yōu)勢(shì)。