對應原題(Common ‧ Inference, Serving and GPU Performance)

  • Compare tensor, pipeline, data, sequence and expert parallelism. When do you combine them?
    — Asked at: Google DeepMind, Meta, Amazon, NVIDIA

🎯 什麼情境該想到我

當你「模型一張卡裝不下,要決定怎麼切」的時候。選錯切法的代價不是慢一點,是慢好幾倍——因為每種切法的通訊量差了兩三個數量級。

⚙️ 怎麼用(五種切法)

一張表先看全貌

策略切什麼每層通訊通訊頻率省模型記憶體適合的互連
Data (DP)batch梯度 all-reduce每步一次❌(除非 ZeRO)跨節點可
Tensor (TP)層內的矩陣activation all-reduce每層 2 次 🔥✅必須 NVLink
Pipeline (PP)層邊界 activation每 stage 一次✅跨節點可
Sequence / Context (SP/CP)序列長度ring / all-gather每層✅ activation視實作
Expert (EP)MoE 專家all-to-all每 MoE 層 2 次✅高頻寬佳

1. Data Parallelism(DP)

每張卡一份完整模型,各吃不同的資料,反向後 all-reduce 梯度。

  • 最簡單,但不省模型記憶體——每張卡都要裝得下完整的權重 + 梯度 + 優化器狀態
  • 通訊量 = 模型大小,但每步只一次,可以和反向計算重疊

ZeRO / FSDP 是 DP 的記憶體優化版,把「冗餘的複本」分片:

階段分片什麼記憶體省
ZeRO-1優化器狀態~4×
ZeRO-2+ 梯度~8×
ZeRO-3 / FSDP+ 參數本身與卡數成正比

ZeRO-3 在用到某層前 all-gather 那層的參數,用完立刻丟。通訊換記憶體——效果接近 TP 但通訊模式更友善,是今天多數團隊的起手式。

2. Tensor Parallelism(TP)—— Megatron 風格

把單一層的矩陣乘法切到多張卡上。

FFN 的經典切法(這個要會畫):

Y = GeLU(X · A) · B

A 按「行方向」切(column-parallel):A = [A₁ | A₂]
  → Y₁ = GeLU(X·A₁),Y₂ = GeLU(X·A₂)     ★ 不需通訊!
     (因為 GeLU 是 elementwise,可以在切開的狀態下直接做)

B 按「列方向」切(row-parallel):B = [B₁ ; B₂]
  → Z = Y₁·B₁ + Y₂·B₂                     ★ 需要 all-reduce

巧妙之處:第一個矩陣 column-split、第二個 row-split,中間的非線性不需要任何通訊,整個 FFN 只要一次 all-reduce。

Attention 更自然:按 head 切。每張卡管幾個完整的 head,最後 用 row-parallel 收一次。

代價:每個 transformer 層前向 2 次 all-reduce(attention 一次、FFN 一次),反向再 2 次。80 層就是每步 320 次集體通訊。

★ 所以 TP 幾乎只能在單節點內用。 NVLink 約 900 GB/s,跨節點 InfiniBand 約 50–100 GB/s——差一個數量級。
TP size ≤ 單機 GPU 數(通常 8) 是硬性的實務規則。

3. Pipeline Parallelism(PP)

按層切:卡 0 放 1–20 層,卡 1 放 21–40 層……activation 往後傳、梯度往前傳。

通訊量極小(只有 stage 邊界的 activation),所以可以跨節點。

問題:氣泡(bubble)

naive(一個 batch 走完才進下一個)

GPU0: [F1]                          [B1]
GPU1:      [F2]                [B2]
GPU2:           [F3]     [B3]
GPU3:                [F4][B4]
       ↑ 大量閒置

解法:把 batch 切成 個 microbatch,讓它們接力。

( = stage 數、 = microbatch 數)

氣泡
4443%
41616%
4644.5%
86410%

經驗法則:,能到 更好。

排程演進:

  • GPipe:全部前向 → 全部反向。氣泡如上,但要存所有 microbatch 的 activation,記憶體大
  • 1F1B(PipeDream):一個前向接一個反向。氣泡相同,但activation 記憶體大幅降低(同時只有 ~ 份)→ 現在的預設
  • Interleaved 1F1B:每張卡放不連續的多段層(如卡 0 放 1–10 和 41–50),氣泡再降,但通訊變多

4. Sequence / Context Parallelism

兩種不同的東西,常被混談:

Megatron 的 Sequence Parallelism(SP):TP 只切了矩陣乘法,LayerNorm、Dropout、殘差這些 elementwise 操作在每張卡上都是完整複本——白白浪費 activation 記憶體。SP 把這些也按序列維度切開。通常和 TP 綁在一起用,純粹是記憶體優化。

Context Parallelism / Ring Attention:把序列本身切到不同卡上,每張卡只持有一段的 Q/K/V。Attention 需要跨段計算,所以用 ring 方式輪流傳遞 K/V 區塊,邊傳邊用 online softmax 累積(原理同 FlashAttention,只是把 tiling 從 SRAM 層搬到了 GPU 之間)。

這是訓練百萬級上下文的關鍵技術。 通訊可以和計算重疊,所以擴展性不錯。

5. Expert Parallelism(EP)

MoE 專用(見 混合專家 MoE)。不同專家放不同卡上,每個 MoE 層要做:

  1. all-to-all:把每個 token 送去它被路由到的專家所在的卡
  2. 計算
  3. all-to-all:把結果送回原來的卡

all-to-all 是最貴的集體通訊模式,而且負載不均時會有等待。這是 MoE 訓練最大的工程難點。

★ 怎麼組合(3D / 4D / 5D parallelism)

標準配置順序(由內而外):

┌─ DP / FSDP ────────────────────────────────┐  最外層,跨很多節點
│  ┌─ PP ──────────────────────────────┐    │  跨節點(通訊少)
│  │  ┌─ TP (+SP) ─────────────┐       │    │  節點內(NVLink)
│  │  │  GPU 0..7 (同一台機器)  │       │    │
│  │  └────────────────────────┘       │    │
│  └───────────────────────────────────┘    │
└────────────────────────────────────────────┘

總 GPU 數 = TP × PP × DP

決策順序:

  1. 先用 TP 填滿一個節點(TP = 8),因為它最省記憶體又有 NVLink 撐著
  2. 還裝不下 → 加 PP 跨節點,
  3. 裝得下了 → 剩下的卡全給 DP/FSDP 放大 batch
  4. 序列超長 → 加 CP
  5. MoE → 加 EP(通常取代部分 TP)

★ 推論的平行化不一樣

  • 沒有梯度 → 不需要 DP(要橫向擴展就是多開幾份服務,各自獨立)
  • TP 是主力:它能同時降低單請求延遲(多卡分擔)與提供容量
  • PP 在推論上很不討喜:會直接加到 TTFT 與 TPOT 上,而且氣泡在 batch 小時很難填滿。只在 TP 不夠裝時才用
  • EP 在 MoE 推論很常見

⚠️ 注意 / 什麼時候不適用

  • TP 跨節點是最常見的災難級配置錯誤。把 TP=16 跨兩台機器,通訊會吃掉大部分時間。寧可 TP=8 + PP=2。
  • PP 的 stage 要平衡。層數平均分不等於計算量平均分——第一個 stage 多了 embedding、最後一個多了 LM head,常需要手動微調層的分配。
  • 氣泡不會消失,只會變小。 越大氣泡越大,所以 PP 的擴展性本質上比 TP、DP 差。
  • ZeRO-3 的通訊可能比想像中貴。它在每層前後都要 all-gather / reduce-scatter,小模型上可能得不償失。
  • 不要一開始就上 5D。從最簡單的配置開始(能塞就 DP、塞不下加 TP),量到瓶頸再加維度。組合越多,除錯越痛苦。
  • 推論和訓練的最佳配置不同,別直接沿用訓練的 mesh。
  • 通訊與計算的重疊要確認真的發生了。很多設定下它靜默地沒重疊,profile 一次才知道。

🧪 我實際套用的紀錄

  • 2026-09-20:從面試題庫展開,尚未實際套用。

🔗 相關