Pipeline Parallelism
パイプライン並列化では、モデルの連続するレイヤーを複数のGPUに配置し、マイクロバッチを順次処理します。これにより、1台のGPUに収まらない大きさのモデルも学習できます。
パイプライン並列化は、分散トレーニングの手法の1つです。ニューラルネットワークを深さ方向に分割して、ステージと呼ばれる連続したレイヤー群にし、各ステージを個別のGPUに配置して、アクティベーションを次のステージへ渡します。すべてのGPUを稼働させ続けるため、各バッチを小さなマイクロバッチに分割し、組み立てライン上の部品のようにステージ間を流します。レイヤー間モデル並列化とも呼ばれます。Yanping Huang率いるGoogleの研究者たちは、2018年11月にGPipeでマイクロバッチ方式を広め、5億5,700万パラメーターのAmoebaNetをImageNetでトップ1精度84.4%まで学習させたほか、60億パラメーター、128レイヤーの多言語翻訳Transformerも学習させました。
マイクロバッチとパイプラインバブル#
一度に1つのバッチだけを処理する場合、1つのステージだけが稼働し、ほかのステージは待機します。ステージ2はステージ1が完了するまで開始できず、バックプロパゲーションでは順序が逆になります。マイクロバッチを使うと、ステージ1は最初のマイクロバッチをステージ2に渡した時点で、2つ目の処理を開始できます。パイプラインの充填中と排出中に残るアイドル時間はバブルと呼ばれます。4ステージ、6マイクロバッチのGPipe形式のフォワードスケジュールを出力すると、次のようになります。
stages, micro_batches = 4, 6
steps = micro_batches + stages - 1 # time steps until the last micro-batch leaves the last stage
for stage in range(stages):
row = ""
for t in range(steps):
m = t - stage # stage s starts micro-batch m once stage s-1 hands it over
row += f" F{m}" if 0 <= m < micro_batches else " ."
print(f"GPU {stage}:{row}")
# Every stage idles for stages - 1 of the steps, in the forward and again in the backward pass
bubble = (stages - 1) / steps
print(f"Idle fraction: {bubble:.0%}")出力は階段状になります。GPU 0は最初の9ステップのうち6ステップでF0からF5までのフォワードパスを実行し、その後は待機します。GPU 3は3ステップ待機してからF0を開始し、最後の行はIdle fraction: 33%です。バブルの割合は(ステージ数 − 1)/(マイクロバッチ数 + ステージ数 − 1)なので、同じ4ステージで24マイクロバッチを処理すると11%まで低下します。すべてのマイクロバッチの勾配を合算してからオプティマイザーステップを1回実行するため、勾配蓄積と同じ計算になり、フルバッチで学習した場合と同じ更新になります。GPipeは各ステージ内のアクティベーションを破棄し、バックワードパス中に再計算します。これは勾配チェックポイントの一種です。
パイプラインスケジュール#
後続のスケジュールでは、メモリを節約したりバブルを縮小したりするため、同じ処理の順序を変更しています。
- 1F1B: 2018年にPipeDreamシステムが導入した方式で、パイプラインが満杯になると、各ステージで1つのフォワードマイクロバッチと1つのバックワードマイクロバッチを交互に処理します。これにより、各ステージが保持するアクティベーションはすべてのマイクロバッチ分ではなく、最大でもステージ数と同じ数になります。
- インターリーブ1F1B: 各GPUに、互いに隣接しない小さなステージを複数割り当てます。NVIDIAのMegatron-LMチームは、この方式でスループットが10%を超えて向上したと報告し、3,072基のGPUで1兆パラメーターのモデルを502 petaFLOP/s、ピーク性能の52%で学習させました。
- ゼロバブル: バックワードパスを、前のステージが待ち受けているステージ入力の勾配と、後からアイドル時間を埋めるのに利用できる重みの勾配に分割します。同程度のメモリ予算で、1F1Bよりスループットを最大23%向上させます。
PyTorchのパイプライン化APIでは、モデルをステージに分割する機能とともに、ScheduleGPipe、Schedule1F1B、ScheduleInterleaved1F1B、ScheduleInterleavedZeroBubble、ScheduleDualPipeVとしてこれらの方式を提供しています。DualPipeはDeepSeek-V3に由来し、チームは16段のパイプラインステージを実行して、計算と通信を重ね合わせ、バブルを縮小しました。
パイプライン並列化の位置付け#
ステージ間でやり取りするのは、マイクロバッチごとに一度だけ境界のアクティベーションです。そのため、すべてのレイヤー内で通信するテンソル並列化よりも、サーバー間の接続が遅い環境に適しています。大規模な学習では、これらの手法を組み合わせます。MetaはLlama 3 405Bの学習で、各8 GPUサーバー内に8分割のテンソル並列化、サーバー間に16段のパイプライン、64~128レプリカにわたるデータ並列化を採用しました。また、大規模言語モデル(LLM)に複数ノードが必要な場合、vLLMなどのサービングエンジンも同じ分割方式を使います。最も遅いステージがパイプライン全体の速度を決めます。また、言語モデルの最初と最後のステージは埋め込みテーブルと出力レイヤーも担うため、Llama 3ではそれぞれのステージのTransformerレイヤーを1つ減らしました。
関連する手法では、異なる方法で処理を分割します。
- テンソル並列化: 各レイヤー内の重み行列を分割するため、すべてのGPUがすべてのレイヤーに参加します。
- コンテキスト並列化: 長い入力シーケンスを複数のGPUに分割します。
- 分割学習: ネットワークを深さ方向に分割する点は同じですが、組織間で分割するため、データ所有者が後続レイヤーを実行するサーバーに生データを送信する必要がありません。
データ並列化では、すべてのGPUにすべてのレイヤーを配置し、代わりにバッチを分割します。これは、モデルが1台のデバイスに収まる場合に必要な方式です。Ultralytics YOLO26はこの方法で複数のGPUを使って学習します。トレーニングモードでdevice=[0, 1, 2, 3]とbatch=64を使用すると、各GPUが16枚の画像で完全な物体検出モデルを実行し、PyTorch DistributedDataParallelが各バックワードパスの後にGPU間の勾配を平均化します。










