- Published on
マルチGPU・マルチノード学習プラットフォーム総まとめ — フレームワークの地図からSlurm・Kubeflow実践ガイドまで
- Authors

- Name
- Youngju Kim
- @fjvbn20031
- はじめに — GPUが増えた瞬間、問題はソフトウェアになる
- 第1部 — AIライブラリ・フレームワークのエコシステム地図
- 第2部 — 並列化戦略:「何が載らないか」からまず問う
- 第3部 — torchrun:すべての共通分母
- 第4部 — Slurm使い方ガイド:HPCの王
- 第5部 — Kubeflow使い方ガイド:Kubernetes陣営の答え
- 第6部 — 選択基準:Slurm vs Kubeflow vs Ray
- おわりに
- 参考資料
はじめに — GPUが増えた瞬間、問題はソフトウェアになる
GPU 1枚での学習はフレームワークが面倒を見てくれます。GPU 8枚、ノード4台になった瞬間から、インフラの問題が始まります — プロセスをどう起動し、互いをどう見つけさせ、失敗したらどう再起動するのか。本記事はその地形の全体を扱います — どんなライブラリがあるのか(エコシステム地図)、モデルをどう分割するのか(並列化戦略)、そしてジョブをどこに投げるのか(Slurm vs Kubeflow vs Ray)。AIモデル開発ライフサイクルの「分散学習スタック」の節を実践レベルに拡張した記事です。
第1部 — AIライブラリ・フレームワークのエコシステム地図
まずは登場人物から。層で分けると地形がはっきりします。
層 代表プレイヤー 一言まとめ
────────────────────── ──────────────────────────── ─────────────────────────────
基盤フレームワーク PyTorch 2.x 事実上の標準。torch.compileでコンパイル加速
JAX 関数型+XLA。TPU・Google系研究の中心
モデル・データハブ HuggingFace Transformers モデル定義の共通語
Datasets / Tokenizers データロード・トークナイズの標準
ファインチューニング層 PEFT (LoRA), TRL (SFT/DPO) 少ないリソースでチューニング・アラインメント
Accelerate 単一↔分散のコードを同じにする抽象化
分散学習エンジン PyTorch DDP/FSDP フレームワーク内蔵の並列化
DeepSpeed (ZeRO) メモリ最適化の代名詞
Megatron-LM TP/PP込み、超大規模事前学習の標準
オーケストレーション Slurm HPCクラスタの王
Kubeflow / Ray Kubernetes・Pythonネイティブ陣営
サービング(参考) vLLM / SGLang / TensorRT-LLM 学習が終わったらこちら — サービング編を参照
選び方の感覚としては、研究・ファインチューニングはPyTorch + HFスタック、TPUや大規模並列研究はJAX、超大規模事前学習はMegatron系、そしてその中間のあらゆる場所にDeepSpeedとFSDPがあります。
第2部 — 並列化戦略:「何が載らないか」からまず問う
並列化の選択は「何がGPUに載らないか」で決まります。
- DDP(Data Parallel) — モデルは載るが、もっと速く 学習させたい。モデルを各GPUに複製してバッチを分割し、逆伝播の後に勾配をall-reduceで同期します。最も単純でスケール効率も良いため、可能なら常にDDPが第一候補です。
- ZeRO / FSDP(Fully Sharded Data Parallel) — モデル(正確にはパラメータ+勾配+オプティマイザ状態)が 載らない。その3つをGPU群にシャーディングしておき、必要な瞬間だけ集めて使います。DeepSpeed ZeROのステージ(1: オプティマイザ、2: +勾配、3: +パラメータ)とPyTorch FSDPは、同じアイデアの2つの実装です。7B〜70Bファインチューニングの主力です。
- TP(Tensor Parallel) — 1層すら載らない、あるいはレイテンシが重要。行列積そのものをGPU群に分割します。通信が頻繁なため、ノード内(NVLink)での使用が原則です。
- PP(Pipeline Parallel) — 層をGPUグループに分けて、組み立てラインのように流します。マイクロバッチでパイプラインのバブルを減らします。ノード境界をまたぐ分割に向いています。
- 実際の超大規模学習ではこれらを 3D並列(DP × TP × PP)として組み合わせ、MoEモデルならEP(Expert Parallel)が加わります。
暗記用の公式:載るならDDP → 載らないならFSDP/ZeRO → それでも無理ならTP・PPを追加。そしてどの組み合わせでも、混合精度(bf16)と勾配チェックポインティングは標準装備です。
第3部 — torchrun:すべての共通分母
SlurmであれKubeflowであれ、足元では多くの場合 torchrun(PyTorchの分散ランチャー)が動いています。概念は3つだけです — 全体のプロセス数(world size)、自分の順番(rank)、待ち合わせ場所(rendezvous)。
# 単一ノード 8 GPU
torchrun --nproc_per_node=8 train.py
# マルチノード(例:2ノード × 8GPU = world size 16)
# すべてのノードで同じコマンドを実行し、node_rankだけ変える
torchrun \
--nnodes=2 --nproc_per_node=8 --node_rank=0 \
--rdzv_backend=c10d --rdzv_endpoint=10.0.0.1:29500 \
train.py
学習コードは torch.distributed.init_process_group() を呼んだ後、LOCAL_RANK 環境変数で自分のGPUを掴めば十分です。HF AccelerateやLightningを使えば、この配線はライブラリが肩代わりしてくれます。マルチノードの性能の前提条件を1つ — ノード間はEthernetではなく RDMA(InfiniBand/RoCE)でなければall-reduceがボトルネックになります。NCCLはその上で通信を担当します。
第4部 — Slurm使い方ガイド:HPCの王
Slurm は、数十年のHPCの歴史の中で磨かれてきたバッチスケジューラで、GPUクラスタ学習の事実上の標準です。バージョンは 年.月 方式(24.11、25.05 …)で、SchedMDが管理しています。概念は4つで十分です:ノード(機械) — パーティション(ノードの束、キュー) — ジョブ(リソース要求+スクリプト) — GRES(GPUのような汎用リソース)。
# クラスタの状態をざっと見る
sinfo # パーティション・ノードの状態
squeue --me # 自分のジョブキュー
scontrol show node node01 # ノードの詳細
# ジョブ投入の3兄弟
sbatch job.sh # バッチ投入(標準)
srun --pty bash # インタラクティブシェル(デバッグ用)
salloc --gres=gpu:2 # リソースを先取りして手動実行
マルチノード学習の核心はsbatchスクリプトです。2ノード × 8GPUのtorchrun例:
#!/bin/bash
#SBATCH --job-name=llm-train
#SBATCH --partition=gpu
#SBATCH --nodes=2 # ノード2台
#SBATCH --ntasks-per-node=1 # ノードあたりtorchrun 1つ(プロセスはtorchrunが8つ生成)
#SBATCH --gres=gpu:8 # ノードあたりGPU 8枚
#SBATCH --cpus-per-task=64
#SBATCH --time=48:00:00
#SBATCH --output=logs/%x-%j.out # %x=ジョブ名 %j=ジョブID
# ランデブーのアドレス = 最初のノード
export MASTER_ADDR=$(scontrol show hostnames "$SLURM_JOB_NODELIST" | head -n 1)
export MASTER_PORT=29500
# 各ノードでtorchrunを実行 — SLURM変数で配線を自動化
srun torchrun \
--nnodes=$SLURM_JOB_NUM_NODES \
--nproc_per_node=8 \
--node_rank=$SLURM_NODEID \
--rdzv_backend=c10d \
--rdzv_endpoint=$MASTER_ADDR:$MASTER_PORT \
train.py --config config.yaml
読み方:srun がジョブに割り当てられた 各ノードで1回ずつ torchrunを実行し、SLURM_NODEID がノードの順番を、scontrol show hostnames がマスターのアドレスを自動で埋めてくれます。このパターン1つがSlurmマルチノード学習の80%を占めます。残りの20%は運用のコツです — チェックポイントは --time 制限より頻繁に書く(プリエンプション・タイムアウト対策)、--signal=SIGUSR1@120 で終了2分前にシグナルを受け取って最後のチェックポイントを残す、アレイジョブ(--array)でハイパーパラメータスイープを回す、といったところです。
第5部 — Kubeflow使い方ガイド:Kubernetes陣営の答え
GPUクラスタがすでにKubernetesなら(GPU Operator でセットアップしたあのクラスタなら)、学習ジョブもKubernetesリソースとして投げるのが自然です。Kubeflow はその陣営の総合プラットフォームです。
コンポーネントの地図 — すべてを使う必要はありません:
コンポーネント 役割 必須か?
───────────────── ───────────────────────────────────────── ────────────────────────
Training Operator 分散学習ジョブのCRD(核心!) ★ これだけで始められる
Pipelines MLワークフローのDAGオーケストレーション パイプライン化の段階で
Katib ハイパーパラメータチューニング・AutoML 必要になったら
Notebooks クラスタ内のJupyter環境 便利機能
KServe モデルサービング(別プロジェクト化) サービング段階で
核心は Training Operator です。PyTorchJob CRD 1つで、マルチノード学習が宣言できます:
apiVersion: kubeflow.org/v1
kind: PyTorchJob
metadata:
name: llm-train
spec:
nprocPerNode: "8" # ノード(Pod)あたりのプロセス数 = GPU枚数
pytorchReplicaSpecs:
Master:
replicas: 1
template:
spec:
containers:
- name: pytorch
image: my-registry/train:latest
command: ["torchrun", "train.py"]
resources:
limits:
nvidia.com/gpu: 8
Worker:
replicas: 3 # マスター1 + ワーカー3 = 4ノード
template:
spec:
containers:
- name: pytorch
image: my-registry/train:latest
command: ["torchrun", "train.py"]
resources:
limits:
nvidia.com/gpu: 8
Training Operatorがポッドを作り、MASTER_ADDR・WORLD_SIZE・RANK 環境変数を 自動注入 してくれるので、Slurmで手作業だった配線が消えます。ジョブの状態は kubectl get pytorchjobs で確認します。なお、次世代の Kubeflow Trainer(v2) は、フレームワークごとのCRDを1つのTrainJobへ統合する方向に進化中です — 新規導入なら、ドキュメントでv2のサポート状況を確認してから始めてください。ギャングスケジューリング(全ノードが同時に確保されて初めて開始する方式)は、Volcano/Kueueのようなスケジューラを組み合わせて解決します。
第6部 — 選択基準:Slurm vs Kubeflow vs Ray
状況 おすすめ
────────────────────────────────────────── ─────────────────────────
HPCの伝統がある組織、ベアメタルGPUファーム Slurm
すでにKubernetesですべてを運用 Kubeflow (Training Operator)
Pythonコード内で柔軟に分散・サービング統合 Ray (Train/Serve)
研究室の小規模、ノード2〜4台 素のtorchrun + pdsh/tmuxで十分
クラウドマネージド志向 SageMaker/Vertexなど(概念は同じ)
本質を1つだけ残すなら — どのプラットフォームでも足元は同じ です:torchrun(またはその等価物)がプロセスを起動し、NCCLがGPU間の通信を担い、チェックポイントが障害に耐えます。プラットフォームの違いは「誰がノードを貸してくれて、誰が環境変数を埋めてくれるか」だけです。だから、1つのプラットフォームでマルチノードをきちんと理解すれば、残りは翻訳の問題になります。
おわりに
GPUが1枚から複数枚・複数ノードへと増えるときに直面する決定を順に並べると:並列化戦略(載るならDDP、載らないならFSDP/ZeRO、それでも無理ならTP・PP)→ ランチャー(torchrun)→ オーケストレーター(SlurmまたはKubeflow)→ 運用(チェックポイント・RDMA・ギャングスケジューリング)。このスタックの上で学習が回り始めたら、次のボトルネックはデータです — その話は LLM学習データ前処理編 に続きます。