大模型有什么用,從技術(shù)上看
目前為止,大模型主要是以NLP為主,因為NLP拋棄了RNN序列依賴(lài)的問(wèn)題,采用了Attention is All you need的Transformer結構,使得NLP能夠演變出更多大模型。圖像領(lǐng)域也不甘示弱,CNN大模型也開(kāi)始陸續涌現。
模型碎片化,大模型提供預訓練方案。目前AI面對行業(yè)、業(yè)務(wù)場(chǎng)景很多,人工智能需求正呈現出碎片化、多樣化的特點(diǎn)。從開(kāi)發(fā)、調參、優(yōu)化、迭代到應用,AI模型研發(fā)成本極高,且難以滿(mǎn)足市場(chǎng)定制化需求,所以網(wǎng)上有的人會(huì )說(shuō)現階段的AI模型研發(fā)處于手工作坊式?;旧弦粋€(gè)公司想要用AI賦能自身的業(yè)務(wù),多多少少也得招聘懂AI的研發(fā)人員。為了解決手工作坊式走向工廠(chǎng)模式,大模型提供了一種可行方案,也就是“預訓練大模型+下游任務(wù)微調”的方式。大規模預訓練可以有效地從大量標記和未標記的數據中捕獲知識,通過(guò)將知識存儲到大量的參數中并對特定任務(wù)進(jìn)行微調,極大地擴展了模型的泛化能力。例如,在NLP領(lǐng)域,預訓練大模型共享了預訓任務(wù)和部分下游任務(wù)的參數,在一定程度上解決了通用性的難題,可以被應用于翻譯,問(wèn)答,文本生成等自然語(yǔ)言任務(wù)。PS:手工作坊式 ==> 工廠(chǎng)模式,一個(gè)大模型替代之前幾十個(gè)專(zhuān)門(mén)小模型。
大模型具備自監督學(xué)習功能,降低訓練研發(fā)成本。大模型的自監督學(xué)習方法,可以減少數據標注,在一定程度上解決了人工標注成本高、周期長(cháng)、準確度不高的問(wèn)題。
大模型有望進(jìn)一步突破現有模型結構的精度局限。從深度學(xué)習發(fā)展前10年的歷程來(lái)看,模型精度提升,主要依賴(lài)網(wǎng)絡(luò )在結構上的變革。例如,從AlexNet到ResNet50,再到NAS搜索出來(lái)的EfficientNet,ImageNet Top-1 精度從58提升到了84。但是,隨著(zhù)神經(jīng)網(wǎng)絡(luò )結構設計技術(shù),逐漸成熟并趨于收斂,想要通過(guò)優(yōu)化神經(jīng)網(wǎng)絡(luò )結構從而打破精度局限非常困難。近年來(lái),隨著(zhù)數據規模和模型規模的不斷增大,模型精度也得到了進(jìn)一步提升,研究實(shí)驗表明,模型和數據規模的增大確實(shí)能突破現有精度的一個(gè)局限。
二、什么是大模型
TensorFlow在推薦系統中的分布式訓練優(yōu)化實(shí)踐隨著(zhù)美團業(yè)務(wù)的發(fā)展,推薦系統模型的規模和復雜度也在快速增長(cháng),具體表現如下:
訓練數據:訓練樣本從到百億增長(cháng)到千億,增長(cháng)了近10倍。
稀疏參數:個(gè)數從幾百到幾千,也增長(cháng)了近10倍;總參數量(也就是tf.Variable)從幾億增長(cháng)到百億,增長(cháng)了10~20倍。
模型復雜度:越來(lái)越復雜,模型單步計算時(shí)間增長(cháng)10倍以上。對于大流量業(yè)務(wù),一次訓練實(shí)驗,從幾個(gè)小時(shí)增長(cháng)到了幾天,而此場(chǎng)景一次實(shí)驗保持在1天之內是基本的需求。
深度學(xué)習分布式訓練的現狀及未來(lái)大模型主要分為兩類(lèi):
搜索、推薦、廣告類(lèi)任務(wù),它的特點(diǎn)是海量樣本及大規模稀疏參數(sparse embeddings),適合使用 CPU/GPU 參數服務(wù)器模式(PS);參數服務(wù)器模式從第一代 Alex Smola 在 2010 年提出的 LDA(文本挖掘領(lǐng)域的隱狄利克雷分配模型),到第二代 Jeff Dean 提出的 DistBelief,接著(zhù)到第三代李沐提出的相對成熟的現代 Parameter Server 架構,再到后來(lái)的百花齊放:Uber 的 Horvod,阿里的 XDL、PAI,Meta 的 DLRM,字節的 BytePs、美團基于 Tensorlow 做的各種適配等等。參數服務(wù)器的功能日趨完善,性能也越來(lái)越強,有純 CPU、純 GPU,也有異構模式。
CV、NLP 任務(wù),它的特點(diǎn)是常規樣本數據及大規模稠密參數,它適合用純 GPU 集合通信模式(Collective)?;诩?GPU 的集合通信模式的分布式訓練框架,伴隨著(zhù) Nvidia 的技術(shù)迭代,特別是 GPU 通信技術(shù)(GPU Direct RDMA)的進(jìn)步,性能也變得愈來(lái)愈強。
廣告推薦中大規模分布式模型 為啥一兩百類(lèi)的特征,我們卻總是聽(tīng)說(shuō)大規模特征?舉個(gè)例子,用戶(hù) userid 這一維特征,比如系統中用戶(hù)有1億個(gè),那么每個(gè) id 實(shí)際上也可以當做一個(gè)獨立的特征對待。這樣一算,特征規模就上去了。這里就要重新理解 embedding 的概念了。對于模型而言,id 查了embedding表后得到向量,輸入進(jìn)來(lái)進(jìn)行計算,是對數據進(jìn)行抽特征。如果類(lèi)比到圖像分類(lèi),抽取 rgb 特征來(lái)分類(lèi) (一個(gè)值變成 3個(gè)255)
參數量卷到一百萬(wàn)億!華人團隊開(kāi)源史上最大的推薦訓練系統Persia 一般來(lái)說(shuō),推薦系統模型首先需要將不同的ID特征(如用戶(hù)ID和session ID)映射到一個(gè)固定長(cháng)度的低維向量,而系統中的用戶(hù)ID、交叉特征數量都特別多,就需要更大規模的模型來(lái)捕獲特征和映射。但更大規模的embedding layer也需要更大的內存來(lái)載入,不得不說(shuō)大模型太費錢(qián)了!
有了embedding后,剩下的工作就簡(jiǎn)單了,設計后續layer來(lái)適配不同的任務(wù)。通常只占據整個(gè)模型的0.1%,無(wú)需大內存,主要是一些計算密集型的工作。
在實(shí)現上
推理服務(wù)在運行時(shí) 也會(huì )訪(fǎng)問(wèn)ps (distributed inference),根據 ID feature 查詢(xún)對應的 embedding 向量。當然,有的框架直接將 ps 組件的功能內嵌到各個(gè)worker 上了。
針對 大模型 包含 embedding layer的場(chǎng)景,input 層和 embedding 層之間不是全連接的,而是一個(gè) embedding_lookup 的Op
常規的dense 模型,input是一個(gè)一維向量。針對多個(gè)id feature,為了 確保與模型的input 層對齊,input 實(shí)際變成了一個(gè) map<string,tensor>,key 為id feature 名字,value 為id feature 值對應的 tensor。
內存墻。在計算過(guò)程中,神經(jīng)網(wǎng)絡(luò )模型每一層的卷積或者全連接計算,都會(huì )把權重W_m長(cháng)期保存下來(lái),用作網(wǎng)絡(luò )的權重參數更新(靜態(tài)內存)。另外針對諸如ADAM的優(yōu)化器,會(huì )存儲優(yōu)化器的動(dòng)量等信息,用于優(yōu)化器計算(動(dòng)態(tài)內存)。一塊有16G顯存的AI芯片,最大能塞滿(mǎn)20+億參數的模型,但是這時(shí)候已經(jīng)沒(méi)有額外空間,留給動(dòng)態(tài)內存進(jìn)行分配啦。靜態(tài)內存和動(dòng)態(tài)內存都可能造成內存墻的問(wèn)題。
通訊墻。大模型通過(guò)模型并行、流水線(xiàn)并行切分到AI集群后,通訊便成了主要的性能瓶頸。隨著(zhù)機器規模的擴大,基于同步的All Reduce通訊聚合方式,會(huì )因為大量的AI芯片和服務(wù)器之間頻繁進(jìn)行同步,出現水桶效應,也就是最慢的一路通訊,將會(huì )決定整個(gè)AI集群的通訊的高度。如果采用目前比較流行的Ring-AllReduce的通信聚合方式,當通訊的環(huán)越大,通訊的延長(cháng)將會(huì )不斷地被擴大。另外網(wǎng)絡(luò )協(xié)議的多次握手的方式,諸如此類(lèi)的開(kāi)銷(xiāo)會(huì )導致訓練無(wú)法有效利用帶寬。
性能墻。性能墻呢主要是指計算資源利用率的問(wèn)題。隨著(zhù)大模型的提出,對算力需求更加迫切,理論上在4K的集群上每塊卡快1分鐘,總體就快了68個(gè)小時(shí)。大模型會(huì )增加對算力的需求,但是隨著(zhù)大模型引入各項分布式并行技術(shù)的同時(shí),會(huì )降低計算資源的利用率。
算子層(Operator Level):小算子過(guò)多,可以通過(guò)算子融合進(jìn)行優(yōu)化;子實(shí)現不夠高效,類(lèi)似于卷積CONV算子針對2x2和3x3 Kernel大小的使用Winograd算法代替;內存局部性差,對算子和內存的開(kāi)銷(xiāo)進(jìn)行分析,可以對計算時(shí)算子輸出有相同的shape進(jìn)行復用。
圖層(Graph Level):如何搜索和切分處計算效率更高的子圖,分配到不同的機器上進(jìn)行計算;數據在通訊和內存之間如何增加overlay重疊部分,提高單卡整體的計算率。
任務(wù)層(Task Level):在任務(wù)層級,性能的瓶頸從計算轉移到了通信,如何降低通信量,縮減通信域規模,盡可能把通信時(shí)延隱藏在計算中,是大規模訓練的核心關(guān)注點(diǎn)。
調優(yōu)墻。所以在數千節點(diǎn)的集群上,需要考慮到提升算法工程師分布式調試調優(yōu)的效率,另外還要考慮降低工程師對大模型進(jìn)行并行切分的難度。除了對人的考慮,還要對硬件集群的管理,需要保證計算的正確性、性能、可用性。要是有一臺機器壞了,如何快速恢復訓練中的參數。
淺談工業(yè)界分布式訓練(一) 除了上述的數據量級大,不同場(chǎng)景下分布式訓練的痛點(diǎn) 對CV和NLP場(chǎng)景
CV和NLP場(chǎng)景模型復雜,單機性能要求高,比如卷積的計算時(shí)間在CPU上和 GPU上相差十倍到幾十倍。==> 業(yè)界主要使用高性能的GPU進(jìn)行計算,并采用All-reduce的通信拓撲進(jìn)行參數的同步更新。
模型大(DenseNet部分),比如NLP領(lǐng)域,GPT-3這樣的模型高達1750億參數,顯存占用高達2.8 TB,單機內存無(wú)法容納。而B(niǎo)ert-Large雖然只有3.4億參數規模,但由于各種內存占用,在16G V100上,訓練也僅能使用batch Size=8。==> 當面對GPT-3這種DenseNet部分大的模型,Allreduce 單卡內存無(wú)法容納,我們需要采用模型并行(model parallelism)的方式將計算圖劃分到不同的設備上構建有向無(wú)環(huán)圖(DAG)進(jìn)行分布式訓練,其中Gpipe, Megatron, Oneflow和Whale都提出模型并行的相關(guān)解決方案。相比于數據并行每個(gè)worker只有一部分數據,模型并行下每個(gè)node使用所有數據.
Intra-layer parallelism(Tensor Parallelism) 。主要是將一層Layer中的矩陣計算分別拆分到不同的機器上進(jìn)行運算,比如簡(jiǎn)單的Y_1=W_1 X_1這一次矩陣乘法中,我們將模型參數W_1或者輸入數據X_1,按某個(gè)維度分別拆分到不同設備上計算,比如1D Megatron。
Inter-layer parallelism(Pipeline Parallelism)。而Inter-Layer Parallism會(huì )將模型的layers拆分到不同的機器上,則一次forward就需要跨過(guò)不同的機器串行地進(jìn)行運算,而流行并行通過(guò)將batch size切分為更小的mirco batch,減少數據依賴(lài),從而將整個(gè)計算過(guò)程異步起來(lái),最大化資源利用率。舉例來(lái)說(shuō),在一個(gè)簡(jiǎn)單的三層MLP中(的Y_i = W_i X_i, i=1,2,3)會(huì )存在三次矩陣乘法 W_i X_i,流水線(xiàn)并行會(huì )把W_i X_i分別分配到三臺機器上進(jìn)行運算。
AI for Science的出現,讓高性能計算與AI融合成為剛需:
數據并行。假如整個(gè)模型設兩個(gè)節點(diǎn),一個(gè)模型節點(diǎn)0、另一個(gè)模型做的節點(diǎn)1,整個(gè)模型都做了數據并行,數據各一半要拿去訓練學(xué)習,但是要注意訓練完了以后不是最終的結果,因為只輸入了一半的數據。因此這中間要AII-Reduce
模型并行。將整個(gè)模型切成一半,一半模型節點(diǎn)0,一半模型節點(diǎn)1,數據是整個(gè)拿去訓練。訓練完了以后出來(lái)的結果也不是最終結果,因為只訓練了一半的模型,出來(lái)還有AII-Gather,也是做通信的。 究竟用哪種并行方法呢?實(shí)際上這跟計算機結構有關(guān)。如果每臺計算機之間通信都非???,那么用數據并行就可以;如果你的通信比較慢,就要考慮模型并行。因此,這些模型如何跟數據、機器實(shí)際情況匹配?這就涉及到軟硬件協(xié)
基于tensorflow做擴展支持大模型的做法
在模型比較小的時(shí)候,比如100G以下,模型還有可能單機存儲。這個(gè)時(shí)候的方案是tensorflow分布式訓練+savedmodel,分布式訓練可以用多個(gè)ps(tensorflow自帶的),資源管理可以用yarn。用分布式是由于樣本數大,同時(shí)多ps也能異步加速訓練。saved_model一般由chief worker保存,但存下來(lái)以后,會(huì )抹掉ps的痕跡,保存的模型跟單機訓練的一模一樣。
當模型比較大的時(shí)候,這個(gè)時(shí)候要求的樣本數也更大,訓練完dump出來(lái)的模型會(huì )很大,一個(gè)單機放不下,尤其是embedding table。這個(gè)時(shí)候怎么辦?一個(gè)自然的思路就是,把訓練時(shí)候的ps拷貝同步一份給serving ps,線(xiàn)上由該ps做serving。注意后面談到的serving ps,都是自己開(kāi)發(fā)或者根據某個(gè)開(kāi)源軟件修改而成(比如ps-lite)。如果是天級模型,可以用tensorflow原生的worker和train ps,但依然用saved model方式把模型存放到hdfs,然后從hdfs讀入另外一個(gè)serving ps。如果是實(shí)時(shí)訓練,則serving ps還得跟訓練ps進(jìn)行實(shí)時(shí)的網(wǎng)絡(luò )連接,在內存就解決掉weight同步的處理,這個(gè)時(shí)候就不能用tensorflow原生的ps了,因為原生的ps沒(méi)有實(shí)現同步接口。ps變了,worker也得跟著(zhù)變,worker大多數都是基于tensorflow的c++底層接口開(kāi)發(fā),底層用到tf的session接口。
針對上述的問(wèn)題,各個(gè)大廠(chǎng)的訓練框架進(jìn)行很多相關(guān)優(yōu)化,目前總結下來(lái),核心的兩點(diǎn),一個(gè)在于分布式通信拓撲的設計,還有一個(gè)在于Embedding Lookup的性能優(yōu)化。
只要單卡放的下,走數據并行,ps 或allreduce 都行,allreduce 通信成本小一些。若規模變大
稀疏模型,稀疏參數特殊處理
使用ps,加上一些稀疏tensor 的優(yōu)化,且將 embedding 存儲和更新 負擔轉嫁到 ps
稠密參數allreduce,想辦法解決 稀疏tensor 的存儲、通信成本。比如 HybridBackend架構中參數放在 worker 上:稠密參數 replication 存放,每個(gè) worker 都有副本,梯度更新時(shí)進(jìn)行 allreduce;稀疏參數 partition 存放,每個(gè) worker 只有部分分片,梯度更新時(shí)進(jìn)行 alltoall。allreduce 和 alltoall 都會(huì )使用 nccl 進(jìn)行同步通信,效率較高。hb 進(jìn)行 alltoall 時(shí),通信的是稀疏梯度,而不是完整的參數,通信量上和 ps 是一致的,但是通信效率會(huì )更高。
稠密模型,單卡無(wú)論如何也放不下了,就只能采取模型并行 及附屬的一些優(yōu)化方案
知乎高贊回答——為什么說(shuō)大模型訓練很難?
算子拆分 單個(gè)矩陣乘法可以分到兩個(gè)device上計算 Y = WX = [W1,W2]X = [W1X,W2X]。我們在工程上要做的就是:將切分到兩個(gè)device上,將復制到兩個(gè)device上,然后兩個(gè)device分別做矩陣乘法即可。有的時(shí)候,切分會(huì )帶來(lái)額外的通信,比如矩陣乘法切到了reduction維度上,為了保持語(yǔ)義正確,就必須再緊跟一個(gè)AllReduce通信。這里復雜之處在于,你不能無(wú)腦地將所有算子全部做拆分,因為拆分可能會(huì )引入一些額外通信,降低總體吞吐。所以你得做些分析,決定哪些算子被拆分,現在大部分框架都不支持這種全自動(dòng)化策略,要么是半自動(dòng)或純手工,要么是針對某種模型把它的拆分方案寫(xiě)死。所以只能造輪子解決這個(gè)事
流水并行 不切算子,而是將不同的Layer切分到不同的Device上,就可以形成Pipeline方案,GPipe就是這樣一種方案,提出了將一個(gè)batch拆分成若干個(gè)micro-batch,依次推入到Pipeline系統中,即可消除Bubble time。和算子拆分類(lèi)似,全自動(dòng)化方案工作量不小,比如Pipeline怎么切,才能讓通信量小,計算還能均勻,這需要一定的算法和工程量
搞定大模型訓練
我們的模型可能會(huì )很大,或者數據量會(huì )很大。僅僅用一塊GPU卡可能連模型都放不下,或者batch size只能設置的很小,但是我們知道有些情況下大的batch size往往會(huì )提供更好的效果。
假設我們只有一個(gè)GPU,我們的模型一次只能輸入batch size為8的數據,那么我們怎么樣實(shí)現batch size為32的更新呢?那就需要時(shí)間換空間了,即我們訓練32/8=4步才去更新模型,也就是所謂的梯度累積。
Gradient-Checkpointing, 那么如果你的GPU連batch size為1都跑不了怎么辦?我們在訓練深度學(xué)習模型的時(shí)候,需要先做前向傳播,然后將中間得到的激活值存儲在內存中,然后反向傳播的時(shí)候再根據loss和激活值計算梯度。也就是說(shuō)內存消耗其實(shí)跟模型的層數線(xiàn)性相關(guān)。那么怎么減少這個(gè)內存消耗呢?最簡(jiǎn)單的想法就是我不存這些中間信息,計算梯度的時(shí)候,到了某一層我重新計算它的激活值,這個(gè)方法雖然可以讓內存消耗是個(gè)常量,但是運行時(shí)間會(huì )是O(n^2),這是沒(méi)法接受的。那么就有一個(gè)折中的辦法,我不存全部的中間數據,只存部分,那么我們在計算梯度的時(shí)候不需要從頭計算了,只需要從最近的checkpoint點(diǎn)計算就好。
我們訓練模型一般都是用單精度(FP32)的參數,但是其實(shí)我們還使用半精度(FP16)。半精度可以降低內存消耗,從而訓練更大的模型或者使用更大的batch size;同時(shí)運算時(shí)間受內存和算術(shù)帶寬的限制,在有些gpu(Tensor cores)上可以為半精度提供更大的算術(shù)帶寬,從而提高訓練效率,減少inference用時(shí)。
轉自知乎《大模型有什么用,從技術(shù)上看》
*博客內容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀(guān)點(diǎn),如有侵權請聯(lián)系工作人員刪除。