Try   HackMD

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 →

  • Y=GeLU(XA)
  • Z=Dropout(YB)
  • X
    是輸入矩陣(batch size × hidden dimension)
  • A
    是權重矩陣(hidden dimension × MLP hidden size)
  • B
    是 第二個權重矩陣(MLP hidden size × hidden dimension)

前向傳播

方法 : 將
A
沿著列方向切割

  1. A
    沿著列方向劃分為兩個部分:
    A=[A1,A2]
    • 透過這樣切分,計算變成
      [Y1,Y2]=[GeLU(XA1),GeLU(XA2)]
    • 可以在每個 GPU 上獨立應用 GeLU ,避免了同步點的需求,使得計算更為高效
  2. 進行Dropout,我們經過剛剛那步已經得到
    [Y1,Y2]=[GeLU(XA1),GeLU(XA2)]
    ,代表第一個 GEMM 和 GeLU 的計算已經完成,接下來進行 第二個 GEMM 和 Dropout
    Z=Dropout(YB)
    • B
      沿行方向分割:
      B=[B1B2]
    • 計算變為:
      Z=Dropout(Y1B1+Y2B2)
    • 這種處理方式會需要同步點(透過 All Reduce),因為Dropout 不能作用在部分張量,必須先 All Reduce 相加兩張卡的數值,才能進行 Dropout

反向傳播

  1. Z
    進行微分

    δZ=LZ
    • 前向傳播時,已經進行了 All-Reduce,每張GPU 都有完整的數值,所以梯度也是完整的
    • 由於 Dropout 作用在整個
      YB
      之後,反向傳播時,應用 Dropout 反向操作
      δYB=δZM
    • M
      是 Dropout 的 mask
  2. B
    Y
    進行微分
  • B
    求梯度,因為是沿行方向分割
    B=[B1B2]
    • 在不同 GPU 上:
      LB1=Y1TδYB,LB2=Y2TδYB
    • 這些梯度可以在 各 GPU 上獨立計算,不需要 All-Reduce
  • Y
    求梯度
    Z=YB

    LY=δYBBT

    δY=δYBBT
    • 因為
      B
      是沿行方向分割
      δY1=δYBB1T,δY2=δYBB2T
    • 因為
      A
      是沿著列方向分割的:
      • Y1
        Y2
        沒有加總,所以反向傳播時梯度可以在各自的 GPU 上獨立計算,不需要 All-Reduce
  1. A
    X
    進行微分
  • A
    求梯度
    • 已知
      Y1=GeLU(XA1),Y2=GeLU(XA2)
    • 鏈式規則
      δXA1=δY1GeLU(XA1),δXA2=δY2GeLU(XA2)
    • A1,A2
      求梯度
      LA1=XTδXA1,LA2=XTδXA2
    • 這些梯度只涉及當前 GPU 上的
      A1,A2
      ,不用 All-Reduce
  • X
    求梯度
    δX=δXA1A1T+δXA2A2T
    • X
      是所有GPU 上是共享的
    • 因為
      A
      是沿列進行分割,
      δXA1
      δXA2
      是各自計算的,所以需要 All-Reduce 確保所有 GPU 都獲得完整的梯度
      δX

      δX=AllReduce(δXA1A1T+δXA2A2T)

多頭自注意力層

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 →

多頭注意力的張量並行

主要解決自注意力層中,查詢(

Q)、鍵(
K
)跟值(
V
)的大規模矩陣乘法,Megatron-LM 通過列方向(Column Parallel)分割來優化:

  • Q,K,V
    矩陣乘法沿列方向劃分
  • 每張 GPU 只負責計算部分注意力頭
  • 注意力頭與頭之間在部分計算是無關的,不需要立即進行 GPU 間的通訊
    • GPU 間不用交換
      Q,K,V
      的部分結果,減少通訊開銷

自注意力後的線性變換並行

算完自注意力後,最後有一個線性變換層,Megatron-LM 透過將輸出線性層的矩陣乘法沿行方向(Row Parallel)分割

  • 輸出線性層的矩陣沿行方向劃分(Row Parallel),接收前一層平行化的注意力輸出

範例 : GPU 數 : 2

  • 輸入向量
    X
    ,形狀為
    (B,S,D)
  • 自注意力頭數為 8
  • 每張 GPU 負責 4 個注意力頭計算(Megatron-LM 通過列方向分割來優化)

張量並行

  1. 列方向分割
  • Q,K,V
    沿列方向劃分
    • GPU-0:計算前 4 個注意力頭的
      Q,K,V
    • GPU-1:計算後 4 個注意力頭的
      Q,K,V

      每張 GPU,只需計算:
      Qlocal=XWQlocal,Klocal=XWKlocal,Vlocal=XWVlocal
  1. 各自計算局部注意力(跟原本一致)
    GPU 間不需要通信
    Attentionlocal=softmax(QlocalKlocalTdk)Vlocal
  2. 行方向分割輸出線性層(Row Parallelism)
    假設有輸出線性層的權重矩陣
    WO
    1. 前面假設 2 張 GPU,把
      WO
      沿 行方向(Row Parallel) 劃分成 2 部分:
      WO=[WO1WO2]
    2. 每張 GPU 計算自己的部分輸出
      • GPU-0 計算
        Z1=AttentionWO1
      • GPU-1 計算
        Z2=AttentionWO2
  3. 合併結果
    每張 GPU 只計算了一部分
    Z
    ,需要一個 All-Reduce 操作來合併
    Z1
    Z2
    • 讓 所有 GPU 共享
      Z1
      Z2
    • 每張 GPU 都可以獲得完整
      Z

Input embedding層

  1. 並行化輸入嵌入
    將輸入的 Token(詞彙索引)轉換為向量表示
    • 透過嵌入矩陣(Embedding Matrix),嵌入矩陣的形狀為:
      WERV×H
    • ORV×BS
      是 one-hot 編碼的輸入 Token
    • 進行行方向分割
      WE=[WE1WE2],WEiRV2×H
      • GPU 0 負責查找詞表範圍
        0V2
      • GPU 1 負責查找詞表範圍
        V2V
    • 嵌入主要是查找操作,可視為一個 矩陣乘法
      X=WETO
    • 在每張 GPU 上計算局部嵌入
      Xi=WEiTOi,XiRH×BS
    • 因為每張 GPU 只負責一部份向量查找,所以需要透過 All Reduce 聚合結果
      X=i=1NXi,XRH×BS

Output embedding層

一般並行做法

一般輸出輸出嵌入層(Output Embedding Layer) 的維度通常是 Hidden Size(

H) × Vocabulary Size(
V
)
Output EmbeddingRH×V

在 Megatron-LM 中,對其進行並行化處理,再者,因為 Transformer語言模型中輸入嵌入與輸出嵌入共用權重,因此都會修改計算方式

  • 原本Output embedding層的形狀(與Input embedding層共享權重)
    WORH×V
  • 輸出層的矩陣運算為:
    Y=XWO

    其中:
    • XRB×S×H
      (Transformer 最後一層的 hidden state)
    • WORH×V
    • YRB×S×V
      (最終 logits,對應詞彙表中的每個詞的預測分數)
  • 將Output embedding層進行列方向切分
    • WO
      沿著詞表維度
      V
      進行列方向切分
      WO=[WO1,WO2],WOiRH×V/2
    • 每張 GPU 只對自己負責的詞表進行 logits 計算
      Yi=XWOi,YiRB×S×V/2
    • 每張 GPU 的輸出大小
      (B,S,V/2)
      ,比完整的
      (B,S,V)
      2
  • 最終的 logits
    Yi
    要完整的
    V
    才可以計算交叉熵損失,因此要 All Gather 來合併計算結果
    Y=All-Gather([Y1,Y2])

進一步優化(減少通信開銷) - Megatron-LM : 交叉熵融合(Loss Fusion)

避免 All-Gather,讓每張 GPU 直接計算部分 logits 的交叉熵,只通信標量損失值,而不是完整 logits
交叉熵計算公式:

L=j=1Vtjlogpj

  • tj
    是目標 Token 的 one-hot 編碼
    ,如果正確的詞是
    j
    ,則
    tj=1
    ,其餘為 0
  • pj
    是 softmax 後的機率分布

    pj=eYjk=1VeYk

直接在每張 GPU 上計算部分 logits 的交叉熵

  • 每張 GPU 只存
    WO
    的一部分,並計算對應的 logits
    Yi

    Y1=XWO1,Y2=XWO2,Y1,Y2RB×S×V/2
    1. 每張 GPU 先找出他自己負責部分的最大值
      Ymax,i

      Ymax,i=maxYi,Ymax,iRB×S
    2. All-Reduce 操作獲得全局最大值
      Ymax=All-Reduce(max(Y1,Y2))
    3. 計算局部 softmax 分子(穩定數值修正,避免數值溢出)
      Y~i=YiYmax
      • 這邊還是 partial logits
    4. 計算 softmax 分母
      Zi=j=1V/2eY~i,j
    5. All-Reduce,獲得完整的歸一化因子
      Z=All-Reduce(Z1+Z2)
    6. 計算部分 softmax 機率
      pi=eY~iZ
    7. 計算交叉熵損失
      Li=j=1V/2tjlogpj
    8. All-Reduce,獲得總損失
      L=All-Reduce(L1+L2)

總結

步驟 計算內容 All-Reduce?
計算局部 logits
Yi=XWOi
計算最大值
Ymax,i=max(Yi)
計算 softmax 分母
Zi=exp(Y~i)
計算 softmax 機率
Pi=exp(Y~i)Z
計算局部交叉熵
Li=logP(y)
最終合併損失
L=Li