Tensor-Parallel-Training
論文參考
張量並行
Megatron-LM 這篇論文主要貢獻是模型並行化(Model Parallelism)技術,用於在 多個 GPU 之間拆分 Transformer 層,主要用於訓練超大語言模型
Image Not Showing
Possible Reasons
- The image was uploaded to a note which you don't have access to
- The note which the image was originally uploaded to has been deleted
Learn More →
張量並行主要透過切分 FFN(MLP)層 和 多頭自注意力層來實現張量並行
FFN(MLP)層
Image Not Showing
Possible Reasons
- The image was uploaded to a note which you don't have access to
- The note which the image was originally uploaded to has been deleted
Learn More →
- 是輸入矩陣(batch size × hidden dimension)
- 是權重矩陣(hidden dimension × MLP hidden size)
- 是 第二個權重矩陣(MLP hidden size × hidden dimension)
前向傳播
方法 : 將 沿著列方向切割
- 將 沿著列方向劃分為兩個部分:
- 透過這樣切分,計算變成
- 可以在每個 GPU 上獨立應用 GeLU ,避免了同步點的需求,使得計算更為高效
- 進行Dropout,我們經過剛剛那步已經得到,代表第一個 GEMM 和 GeLU 的計算已經完成,接下來進行 第二個 GEMM 和 Dropout
- 沿行方向分割:
- 計算變為:
- 這種處理方式會需要同步點(透過 All Reduce),因為Dropout 不能作用在部分張量,必須先 All Reduce 相加兩張卡的數值,才能進行 Dropout
反向傳播
- 對 進行微分
- 前向傳播時,已經進行了 All-Reduce,每張GPU 都有完整的數值,所以梯度也是完整的
- 由於 Dropout 作用在整個 之後,反向傳播時,應用 Dropout 反向操作
- 是 Dropout 的 mask
- 對 和 進行微分
- 對 求梯度,因為是沿行方向分割
- 在不同 GPU 上:
- 這些梯度可以在 各 GPU 上獨立計算,不需要 All-Reduce
- 對 求梯度
- 因為 是沿行方向分割
- 因為 是沿著列方向分割的:
- 和 沒有加總,所以反向傳播時梯度可以在各自的 GPU 上獨立計算,不需要 All-Reduce
- 對 和 進行微分
- 對 求梯度
- 已知
- 鏈式規則
- 對求梯度
- 這些梯度只涉及當前 GPU 上的 ,不用 All-Reduce
- 對 求梯度
- 是所有GPU 上是共享的
- 因為 是沿列進行分割, 和 是各自計算的,所以需要 All-Reduce 確保所有 GPU 都獲得完整的梯度
多頭自注意力層
Image Not Showing
Possible Reasons
- The image was uploaded to a note which you don't have access to
- The note which the image was originally uploaded to has been deleted
Learn More →
多頭注意力的張量並行
主要解決自注意力層中,查詢()、鍵()跟值()的大規模矩陣乘法,Megatron-LM 通過列方向(Column Parallel)分割來優化:
- 將 矩陣乘法沿列方向劃分
- 每張 GPU 只負責計算部分注意力頭
- 注意力頭與頭之間在部分計算是無關的,不需要立即進行 GPU 間的通訊
自注意力後的線性變換並行
算完自注意力後,最後有一個線性變換層,Megatron-LM 透過將輸出線性層的矩陣乘法沿行方向(Row Parallel)分割
- 輸出線性層的矩陣沿行方向劃分(Row Parallel),接收前一層平行化的注意力輸出
範例 : GPU 數 : 2
- 輸入向量 ,形狀為
- 自注意力頭數為 8
- 每張 GPU 負責 4 個注意力頭計算(Megatron-LM 通過列方向分割來優化)
張量並行
- 列方向分割
- 將 沿列方向劃分
- GPU-0:計算前 4 個注意力頭的
- GPU-1:計算後 4 個注意力頭的
每張 GPU,只需計算:
- 各自計算局部注意力(跟原本一致)
GPU 間不需要通信
- 行方向分割輸出線性層(Row Parallelism)
假設有輸出線性層的權重矩陣
- 前面假設 2 張 GPU,把 沿 行方向(Row Parallel) 劃分成 2 部分:
- 每張 GPU 計算自己的部分輸出
- 合併結果
每張 GPU 只計算了一部分 ,需要一個 All-Reduce 操作來合併 和
- 讓 所有 GPU 共享 和
- 每張 GPU 都可以獲得完整
- 並行化輸入嵌入
將輸入的 Token(詞彙索引)轉換為向量表示
- 透過嵌入矩陣(Embedding Matrix),嵌入矩陣的形狀為:
- 是 one-hot 編碼的輸入 Token
- 進行行方向分割
- GPU 0 負責查找詞表範圍
- GPU 1 負責查找詞表範圍
- 嵌入主要是查找操作,可視為一個 矩陣乘法
- 在每張 GPU 上計算局部嵌入
- 因為每張 GPU 只負責一部份向量查找,所以需要透過 All Reduce 聚合結果
Output embedding層
一般並行做法
一般輸出輸出嵌入層(Output Embedding Layer) 的維度通常是 Hidden Size() × Vocabulary Size()
在 Megatron-LM 中,對其進行並行化處理,再者,因為 Transformer語言模型中輸入嵌入與輸出嵌入共用權重,因此都會修改計算方式
- 原本Output embedding層的形狀(與Input embedding層共享權重)
- 輸出層的矩陣運算為:
其中:
- (Transformer 最後一層的 hidden state)
- (最終 logits,對應詞彙表中的每個詞的預測分數)
- 將Output embedding層進行列方向切分
- 將 沿著詞表維度 進行列方向切分
- 每張 GPU 只對自己負責的詞表進行 logits 計算
- 每張 GPU 的輸出大小 ,比完整的 小 倍
- 最終的 logits 要完整的 才可以計算交叉熵損失,因此要 All Gather 來合併計算結果
進一步優化(減少通信開銷) - Megatron-LM : 交叉熵融合(Loss Fusion)
避免 All-Gather,讓每張 GPU 直接計算部分 logits 的交叉熵,只通信標量損失值,而不是完整 logits
交叉熵計算公式:
- 是目標 Token 的 one-hot 編碼,如果正確的詞是 ,則 ,其餘為 0
- 是 softmax 後的機率分布
直接在每張 GPU 上計算部分 logits 的交叉熵
- 每張 GPU 只存 的一部分,並計算對應的 logits
- 每張 GPU 先找出他自己負責部分的最大值
- All-Reduce 操作獲得全局最大值
- 計算局部 softmax 分子(穩定數值修正,避免數值溢出)
- 計算 softmax 分母
- All-Reduce,獲得完整的歸一化因子
- 計算部分 softmax 機率
- 計算交叉熵損失
- All-Reduce,獲得總損失
總結
步驟 |
計算內容 |
All-Reduce? |
計算局部 logits |
|
否 |
計算最大值 |
|
是 |
計算 softmax 分母 |
|
是 |
計算 softmax 機率 |
|
否 |
計算局部交叉熵 |
|
否 |
最終合併損失 |
|
是 |