第一部分為看清:大模型的訓練及推理過程是如何的,以及內部邏輯 第二部分為理解:大模型的訓練及推理和算力的關係 第三部分為推演:用簡單的公式量化大模型算力的需求 第四部分為優化:我們如何提高算力利用率 ...
閱讀幫助
第一部分為看清:大模型的訓練及推理過程是如何的,以及內部邏輯
第二部分為理解:大模型的訓練及推理和算力的關係
第三部分為推演:用簡單的公式量化大模型算力的需求
第四部分為優化:我們如何提高算力利用率
一、看清
1.1 大模型訓練
我們以投籃訓練為例,來嘗試理解大模型的訓練過程。
假設你正在練習投籃,目標是投進籃筐。已知的是投籃和你的出手點高度、投籃角度、手腕力度大小有關,作為一個小白你並不知道出手點高度、投籃角度、手腕力度大小該控制多少,那麼你的第一次出手就是一個隨機控制,至於籃球進不進籃筐就交給上帝吧。
有一種可能是你進了,那麼恭喜你,天才選手;但現實往往很骨感,你不但沒有中而且距離籃筐還很遠。聰明的你就開始分析你觀察箭偏離籃筐的方向和距離,然後找出如何調整你的出手點高度、投籃角度、手腕力度大小等因素,以便下次投籃更接近籃筐。
第二次投籃就根據第一次的分析結果,調整了出手點、高度等,你發現這次距離籃筐更近了,但是還有優化的空間,以此類推直到第 N 次,你發現幾乎可以百發百中了。

我們來看大模型訓練包含哪幾部分,以及和投籃訓練的過程類比:
1、前向傳播(forward pass):在前向傳播過程中,輸入數據(例如圖像、文本等)通過神經網路的各層進行傳遞,直到得到輸出結果。這個過程包括了將輸入數據與權重矩陣相乘、應用激活函數等操作。前向傳播的目的是計算網路的預測輸出,並將其與實際目標值進行比較,從而計算損失函數(loss function)的值。
以上述投籃類比:根據你目前的技能(神經網路的權重)來投籃,然後觀察籃球距離籃筐的位置(神經網路的輸出)。這個過程告訴你,根據你現有的技能,你的投籃表現如何。
2、反向傳播(backward pass):反向傳播是一種高效計算梯度的演算法。在這個過程中,損失函數關於每個權重的梯度(偏導數)被計算出來。從輸出層開始,沿著網路的層次結構向輸入層反向傳播,計算每個權重的梯度。這些梯度表示了權重對損失函數的貢獻大小,因此可以用於指導權重更新。
以上述投籃類比:這就像你分析籃球距離籃筐的位置,並找出如何改進你的投籃技巧。你觀察籃球偏離籃筐的方向和距離(損失函數),然後找出如何調整你的投籃姿勢、力量等因素(權重梯度),以便下次投籃更接近籃筐。這個過程涉及到計算梯度(找出如何調整技巧)。
3、權重更新(weight update):在計算出所有權重的梯度後,我們使用優化演算法(如隨機梯度下降(SGD)、Adam 等)來更新權重。這個過程中,權重會根據它們的梯度值進行調整,以減小損失函數的值。這樣,模型就能逐漸學習到從輸入數據中預測目標值的能力。
以上述投籃類比:你經過分析找出如何調整你的投籃姿勢、力量等因素(權重梯度),以便下次投籃更接近籃筐。這個過程涉及到更新權重(實際調整技巧)。
下麵舉例一個簡單三層神經網路模型的推導過程
神經網路介紹見下圖,包含三層:輸入層、隱含層、輸出層,以及每層的神經元及相互之間權重,目標是使得輸入數據 x1,x2(0.05 和 0.05),使輸出儘可能與原始輸出 y1,y2(0.25 和 0.15)接近。

第一步:前向傳播
1、輸入層-->>隱含層
計算神經元 h1 的加權和:

神經元 h1 的輸出 out_h1:

同理,可計算出:out_h2 = 0.63064853
2、隱含層-->>輸出層

一次前向傳播就完成了,我們得到輸出結果[0.78438045,0.82385737] 與目標值[0.25,0.15]相差還很遠,下麵進行反向傳播,更新權重值
第二步:反向傳播
1、計算損失函數(Loss)

分別計算 y1 和 y2 的誤差,總誤差為兩者之和。


2、隱含層 -->> 輸出層權值(w4-w7)更新
w4 對整體誤差產生的影響,可以由偏導求出:

基於鏈式法則我們推出偏導可以拆分為三個子公式得到
第一部分

第二部分


第三部分


最後可以得出我們需要的偏導:

有了偏導數據,我們就可以更新 w4 的值:

同理可以計算 w5-w7 的更新值:
w5'=0.57150144
w6'=0.66939351
w7'=0.76916515
3、隱含層 -->> 隱含層權值(w0-w3)更新
方法和上面類似,我們先推算下 w0 的更新值:

第一部分


根據之前的計算結果:

同理可以計算出:

這樣就可以得出:

第二部分


第三部分


綜上三部分,我們可以計算出:

最後,通過偏導來更新 w0 的值:

同理可以計算 w1-w3 的更新值:
w1'=0.19933483
w2'=0.29922866
w3'=0.39922866
這樣一次反向傳播就完成了,我們再把更新的權重重新計算,不停的進行迭代,迭代一次 Loss 值由 0.36982311 -> 0.36277389,以此類推,當迭代次數足夠大,Loss 值不斷變小。

1000 次迭代後,Loss 值已經很小了:

1.2 大模型推理
有了一個訓練好的模型,我們就可以進行推理上線了,推理過程主要包括五個步驟:

第一步:分詞(Tokenize)將輸入的文本分解為更小的 token,這些部分可以是單個單詞,字元等,簡單理解為類似一種編碼演算法,把字元映射到 ID。比如下麵這句 [Write a story about number 1234567.]就可以映射到一串數字[16594, 257, 1621, 546, 1271, 17031, 2231, 3134, 13]

第二步:嵌入(Embedding)將高維度的數據(例如文字、圖片、音頻)映射到低維度空間的過程,最終以多維度向量表示每一個 object(大模型就是指的每一個 token)。

第三步:位置編碼(Positional Encoding)將 token 在句子中的位置信息進行編碼,使得輸入 Input = Input_Embedding + Positional_Enbedding 增加位置信息。

至於為何要增加位置編碼,互聯網上有很多大佬解釋,這裡不贅述,簡單歸因兩點:
1、神經網路 RNN 本身是按照序列順序處理句子的,Transformer 模型用 Attention 取代了 RNN ,它對數據的處理是同時並行處理,不包含時序信息
2、時序不同的句子含義會有很大不同

第四步:Transformer 層 將處理後的 Input 輸入神經網路 +attention 註意力模型進行處理:

第五步:Softmax 將多個神經元的輸出映射到(0,1)區間,進而轉換為一組概率分佈(加和為 1)(convert the decoder output to predicted next-token probabilities)

示例一次計算過程如下:

二、理解
2.1 訓練過程
第一章節第一小節講述了大模型的通用過程,包括前向傳播(forward pass)和反向傳播(backward pass),我們以單位計算 unit 來計數,一次前向傳播為 1 unit,一次反向傳播為 2 unit(因為這裡需要計算一份輸出的梯度+參數的梯度),那麼一次完整的訓練包含了 1+2 = 3 unit,也就是對於每個 token、每個模型參數,需要3 unit 的計算。
每一個 unit 的計算都是矩陣運算,我們知道對於一次矩陣運算需要進行一次乘法及加法,共計 2 次浮點運算。

綜上兩部分,我們可以得出對於每個 token、每個模型參數,需要進行 3 unit × 2 flops = 6 次浮點運算。
補充:訓練還有一個可選流程激活重計算技術(本質上是時間換空間),使用激活重計算技術來減少中間激活顯存需要進行 1 次額外的前向傳播,如果使用重計算技術,那麼對於每個 token、每個模型參數,需要進行 4 unit × 2 flops = 8 次浮點運算。
2.2 推理過程
第一章節第一小節講述了大模型的推理過程,主要計算量在 Transformer 解碼層,這一層對於每個 token、每個模型參數是一個單位 unit 的計算量,所以推理過程每個 token、每個模型參數,需要進行 1 unit × 2 flops = 2 次浮點運算。
三、推演
有瞭如上的兩個章節的分析,我們可以得出一個比較通用的算力評估,所需的 FLOPs 浮點運算量:

3.1 算力底座
得到通用的計算量評估,我們需要進一步細化到我們熟知的 GPU 卡算力上,為此我們需要一些算力底座的相關信息,一些常用 GPU 卡對比的信息如下:

3.2 算力評估
有了通用的 GPU 卡的算力信息,我們就有了可以評估所需 GPU 卡數量的依據,在上述通用算力評估的基礎上,我們就有了基於 GPU 卡的算力評估:

其中 FLOPS utilization 以目前業界能達到的最大值來進行推測:

感興趣可查閱 PaLM: Scaling Language Modeling with Pathways
3.3 算力驗證
以業界開源大模型為例,我們通過公式計算算力基本和公開數據一致,以下兩個維度來推算:
3.3.1、需要的算力
例如 GPT3 參數規模 175B,訓練 token300B,採用的是稠密(Dense)模型,按照公式計算 6 × 175B × 300B = 3.15e23 FLOPs 公開的 GPT3 運算量 3.1e23 FLOPs,二者基本一致。
除此之外,該算力模型對於公司內部的一些大模型評估也是適用的,業務敏感信息這裡不展示具體數據了。

標記紅色的為 7 月 11 號最新公開的 GPT-4 的核心數據,大家可能會註意到,GPT-4 好像並不符合算力公式,這是不是說我們的公式存在一些邏輯錯誤呢?那麼我們就深入探討下 GPT-4 的訓練過程:
GPT-4 採用了混合專家(MoE)模型
專家混合模型(Mixture-of-Experts,MoE):MoE 模型是一種深度學習架構,該架構,通常由多個專家(Experts)組成,每個專家負責處理輸入數據的不同方面,並擁有自己的參數集(也有一些參數,例如 embedding,可以被所有專家共用,即共用參數)。在模型的推理過程中,根據輸入數據的不同特征,模型會將輸入路由到不同的專家,每個專家根據其參數集處理對應分配到的輸入後完成輸出,最終輸出則是各個專家輸出的集成。

如上圖,簡單理解 MoE 類比:我把百度拆分為了,醫學知識百度+歷史知識百度+地理知識百度等等,實際我請求百度的時候,百度路由到對應的 XX 知識百度上,然後回答我的問題。
實際上 GPT-4 採用了 16 個專家,每個專家的 MLP 參數約為 1110 億,每次前向傳遞有 2 個專家進行路由,還有 550 億共用參數用於註意力機制,如上圖每次調用實際走到了其中 16 個專家中的 2 個,大大減少了所需的訓練以及推理計算量。
最後我們再回過頭看下之前根據公式計算不匹配的問題,這裡就會有一個問題就是實際執行的參數規模變化了:1.8T -> 1110 億 * 2 + 550 億,重新計算得到計算量為 6×2770 億 ×13T=2.16e25 與公開 2.15e25 基本一致。

^^註:1T = 1000B = 10000 億^^
3.3.2、需要的 GPU 卡/時
例如 GPT3 參數規模 175B,訓練 token300B,採用的是稠密(Dense)模型,按照下圖公式計算:
分子為訓練所需要的浮點運算量:1750 億(參數規模) × 6 × 3000 億(token 量);
分母為 312TFLOPS(一張 A100 FP16 精度下的算力) × 46.2%(利用率)× 3600 (1 小時對應的秒)
得到的結果就是60.67 萬 A100/小時 = 2.53 萬 A100/天,如果是 1000 張 A100,需要的訓練時間約為一個月,和公開的數據也基本一致

再說到 GPT4 參數規模 1.8T,訓練 token 13T,採用的是稀疏(MoE)模型,按照下圖公式計算:
53433642 A100/小時 = 2226402 A100/天,如果用 25000 張 A100 訓練,需要 89 天;與公開數據使用了約 25000 個 A100 進行了 90-100 天的訓練基本一致

3.3.3、業界模型推演
有瞭如上的驗證,我們推演下業界一些公開模型的算力數據:

四、優化
至此,所有的算力推演部分結束,下麵我們來簡單看一組數據

由上圖可以看到,不論是訓練還是推理,利用率都不是特別高,這其實對於大規模的模型推廣是一大阻礙:
1、成本阻礙
我們第三章公式,採用 AWS 最具成本效益的 GPU 選擇,擁有 8 個 A100 實例的有效時薪 19.22 美元;估計其成本約為 0.0035 美元/1000 token,OpenAI 的 API 定價為 0.02 美元/1000 token, 其毛利率約為 80%;假如利用率提升 10%,單位成本就可以降低 30%以上
2、算力阻礙
目前已知的各大互聯網公司都在囤卡,尋求抓住大模型的機遇,所以能得到多少張 GPU 卡也存在一定的不確定性;如何能夠高效利用 GPU 也可以反向推動項目的進展,從另一個角度破除算力瓶頸'卡脖子'
優化分析的一些現狀:
1、基礎工具
英偉達提供了 Nsight System(nsys)工具查看模型運行時的 CPU/GPU 執行情況,可以幫助發現 GPU 運行時的一些問題

2、訓練過程
大模型訓練中存在幾種經典的分散式並行範式,分別為數據並行(Data Parallelism),流水線並行(Pipeline Parallelism)和張量並行(Tensor Parallesim)。
2.1 數據並行:ZeRO 優化器
ZeRO(Zero Redundancy Optimizer)思想就是拆分 參數、梯度及優化器狀態,使得節點保存部分參數、梯度及優化器狀態

2.2 模型並行:張量並行和流水線並行
-
張量並行 :將模型中的線性層切分到多個顯卡上,並插入適當的 All-reduce 運算元實現數據同步(通信量大)

-
流水線並行 :將模型分為多個 stage,放置在不同的顯卡上計算

3、推理過程
像一些公司進行了模型的 CPU 和 GPU 運算部分拆分,單獨部署成 CPU/GPU 微服務,減少 CPU 和 GPU 之間的相互干擾,以此提升性能。

目前對於這部分還是知之甚少,後續會對於這部分再單獨展開,歡迎有興趣的小伙伴一起探討。
結束語
隨著混元的落地,LLama2 的開源,會有更多的預訓練模型和推理模型的資源利用優化、評估的事情,這也是我們下階段工作(算力評估、性能優化)的一個開端,歡迎對大模型算力及優化感興趣的同學一起交流溝通!
作者:zhenfei
本文來自博客園,作者:古道輕風,轉載請註明原文鏈接:https://www.cnblogs.com/88223100/p/Large-model-computing-power-deduction-and-optimization-in-practice.html