パイプライン並列(パイプラインヘイレツ)
深層学習モデルのレイヤー群を複数のステージに分割し、各ステージを異なるGPU/デバイスに配置して、マイクロバッチをパイプライン的に処理する分散学習手法。モデル並列の一形態で、単一GPUメモリに収まらない大規模モデルの学習を可能にする。
パイプライン並列とは
パイプライン並列(Pipeline Parallelism, PP)は、ニューラルネットワークのレイヤーを複数のステージに分割し、各ステージを異なるGPUに配置する分散学習手法である。CPUのパイプライン実行と同様の原理で、マイクロバッチを連続的に投入することでGPUの稼働率を高める。
テンソル並列がレイヤー内の演算を分割するのに対し、パイプライン並列はレイヤー間で分割する。通信パターンが隣接ステージ間のPoint-to-Pointに限定されるため、InfiniBandなどのノード間ネットワークでも効率的に動作する。
パイプラインバブルの本質
パイプライン並列の最大の課題は「バブル」(パイプラインの空き時間)である。Forward計算が全ステージを通過するまで、最終ステージは待機状態となり、Backward計算が先頭ステージに戻るまで先頭ステージは待機する。
P個のステージ、Mマイクロバッチの場合、バブル時間の比率は:
バブル比率 = (P - 1) / M
例えばP=4ステージでM=16マイクロバッチの場合、バブル比率は3/16 ≈ 18.75%となる。これはGPU計算能力の約19%が無駄になることを意味する。バブルを削減するにはMを増やす(バッチサイズ拡大)かPを減らす(ステージ数削減)が必要だが、いずれもトレードオフがある。
主要スケジューリングアルゴリズム
パイプライン並列の効率はスケジューリングアルゴリズムに大きく依存する。主要なアルゴリズムを比較する。
| アルゴリズム | バブル比率 | 活性値メモリ | 通信回数 | 年 | 提案者 |
|---|---|---|---|---|---|
| GPipe | (P-1)/M | M個分 | 2M | 2019 | |
| PipeDream-Flush | (P-1)/M | P個分 | 2M | 2020 | Microsoft |
| 1F1B | (P-1)/M | P個分 | 2M | 2021 | NVIDIA |
| Interleaved 1F1B | (P-1)/(M×V) | P×V個分 | 2M×V | 2021 | NVIDIA |
| Zero Bubble PP | ≈0 | P+1個分 | 2M+2P | 2024 | Sea AI Lab |
| Breadth-First PP | (P-1)/M | 1個分 | 2M | 2024 |
GPipe
Google Brainが2019年に提案した最初期のパイプライン並列手法。ミニバッチをM個のマイクロバッチに分割し、全マイクロバッチのForwardを完了後、全マイクロバッチのBackwardを実行する。全マイクロバッチの活性値をメモリに保持するため、メモリ消費が大きい。
PipeDream-FlushとOne Forward One Backward(1F1B)
1F1Bスケジューリングは、ウォームアップフェーズの後、ForwardとBackwardを交互に実行する。各ステージが同時にアクティブなマイクロバッチ数がP個に制限されるため、活性値メモリがGPipeのM個分からP個分に削減される。
ステージ0: F0 F1 F2 F3 | B0 F4 | B1 F5 | B2 F6 | B3 F7 | B4 B5 B6 B7
ステージ1: F0 F1 F2 | B0 F3 | B1 F4 | B2 F5 | B3 F6 | B4 F7 | B5 B6 B7
ステージ2: F0 F1 | B0 F2 | B1 F3 | B2 F4 | B3 F5 | B4 F6 | B5 F7 | B6 B7
ステージ3: F0 | B0 F1 | B1 F2 | B2 F3 | B3 F4 | B4 F5 | B5 F6 | B6 F7 B7
ウォームアップ(先頭のForward列)後、「1つForward → 1つBackward」を繰り返す定常状態に入り、最後にクールダウン(残りのBackward)を実行する。
Interleaved 1F1B
各GPUに1つではなくV個の仮想ステージを割り当て、パイプラインの粒度を細かくする。バブル比率が(P-1)/(M×V)に改善される。たとえばV=4であればバブルが1/4になる。ただし、非連続ステージ間の通信が必要となり、ノード間通信回数が増加する。
Zero Bubble Pipeline Parallelism
2024年にSea AI Labが提案した画期的な手法。Backward計算を入力活性値に対するBackward(B)と重みに対するBackward(W)に分離し、WをForwardと重複実行することでバブルをほぼゼロにする。
ステージ分割の最適化
レイヤーの計算量が均一でない場合、均等分割ではステージ間で負荷バランスが崩れる。特に以下のケースで不均衡が生じやすい。
| 不均衡要因 | 影響 | 対策 |
|---|---|---|
| Embedding層の重み共有 | 先頭・最終ステージに追加計算 | 先頭ステージのレイヤー数を削減 |
| MoEレイヤー | エキスパート数でFLOPs変動 | MoE層を独立ステージに分離 |
| 層ごとの計算量差 | Attention層 vs FFN層 | プロファイリングベースの自動分割 |
| メモリ不均衡 | 活性値サイズの層間差 | メモリ考慮の動的分割 |
Megatron-LMではレイヤー数Lをステージ数Pで均等分割(L/Pレイヤー/ステージ)が基本だが、先頭ステージにEmbedding層・最終ステージにLM Head層が加わるため、先頭・最終ステージのレイヤー数を1〜2層減らす調整が一般的である。
パイプライン並列のメモリ分析
パイプライン並列でのGPUメモリ使用量を分析する。L層モデルをP ステージに分割した場合:
パラメータメモリ: 2 × (L/P) × params_per_layer バイト(BF16)
勾配メモリ: 2 × (L/P) × params_per_layer バイト
オプティマイザメモリ: 12 × (L/P) × params_per_layer バイト(Adam FP32)
活性値メモリ: min(P, M) × activation_per_layer × (L/P) バイト(1F1B時)
70Bモデル(80層)をP=8ステージに分割すると、各ステージは10層分のパラメータ(約17.5B)を保持する。BF16でパラメータ35GB + 勾配35GB + Adam状態105GB ≈ 175GB/ステージとなり、A100 80GBではZeROとの併用が不可欠である。
テンソル並列との組み合わせ
実用的なLLM学習では、パイプライン並列単体ではなく、テンソル並列(TP)と組み合わせて使用する。典型的な構成は:
- TP: ノード内8GPU(NVLink帯域を活用)
- PP: ノード間数ステージ(InfiniBand通信を最小化)
- DP/ZeRO: 残りのGPUでデータ並列
この「3D並列」により、各並列化戦略の長所を活かしつつ短所を補う。TPはノード内高速通信を前提とし、PPはノード間のPoint-to-Point通信で帯域要求を抑え、DPで学習スループットをスケールさせる。
よくある質問(FAQ)
Q1: パイプライン並列のステージ数はいくつが最適ですか?
バブル比率(P-1)/Mから、マイクロバッチ数Mに対してPを十分小さくする必要がある。一般的にはP≤8を推奨し、M≥4Pでバブル比率を25%以下に抑える。70Bモデルの場合、TP=8×PP=4の構成が一般的である。ステージ数を増やしすぎると、バブル損失が学習効率を大幅に低下させる。
Q2: パイプライン並列は推論にも使えますか?
バッチ推論では使用可能だが、単一リクエストのレイテンシは改善しない(パイプラインを満たすバッチが必要)。推論ではテンソル並列が主流で、パイプライン並列はスループット重視のバッチ推論サーバーで補助的に使われる。
Q3: Zero Bubble PPはなぜ普及していないのですか?
Zero Bubble PPはBackward計算をB(入力勾配)とW(重み勾配)に分離するため、学習フレームワーク側の大幅な改修が必要である。2024年時点でMegatron-LMやDeepSpeedへの正式統合は進行中だが、本番環境での安定性検証が十分ではない。バブル比率が0に近づくメリットは大きいが、実装複雑度とのトレードオフで採用に慎重な組織が多い。