pytorch-fsdp2 について
このスキルは、分散学習スクリプトにPyTorch FSDP2を導入するコーディングエージェント向けの手順をまとめています。適切なシャーディング順序、オプティマイザー設定、混合精度やオフロード、分散チェックポイントを扱います。
主な機能
- 01ボトムアップでのモジュールシャーディング
- 02分散プロセスとデバイスの初期化
- 03混合精度とCPUオフロードの設定
- 04DTensor対応オプティマイザーの設定
- 05分散チェックポイントの保存と読み込み
活用シーン
- 01複数GPUにモデルを分散して学習
- 02既存の学習ループにFSDP2を追加
- 03シャードされた学習状態の保存と復元
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ kalarislabs/ research-agent-skills --skill pytorch-fsdp2インストール後、Claude Code で/pytorch-fsdp2を入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/pytorch_dcp_async_recipe.mdpytorch_dcp_overview.mdpytorch_dcp_recipe.mdpytorch_ddp_notes.mdpytorch_device_mesh_tutorial.mdpytorch_examples_fsdp2.mdpytorch_fsdp1_api.mdpytorch_fsdp2_tutorial.mdpytorch_fully_shard_api.mdpytorch_tp_tutorial.mdray_train_fsdp2_example.mdtorchtitan_fsdp_notes.md詳細
スキル:トレーニングスクリプトで PyTorch FSDP2(fully_shard)を正しく使用する
このスキルでは、初期化、シャーディング、混合精度/オフロードの設定、チェックポイント処理を正しく行いながら、コーディングエージェントがトレーニングループに PyTorch FSDP2 を追加する方法を説明します。
PyTorch の FSDP2 は、主に
torch.distributed.fsdp.fully_shardと、それによってモジュールにインプレースで追加されるFSDPModuleメソッドを通じて提供されます。参照先:references/pytorch_fully_shard_api.md、references/pytorch_fsdp2_tutorial.md。
このスキルを使用する場面
次の場合は FSDP2 を使用します。
- モデルが 1 台の GPU に収まらない場合(パラメーター+勾配+オプティマイザーの状態)。
- FSDP1 よりも、eager モードでのシャーディング方式として パラメーターごとの DTensor ベースのシャーディング(より調査しやすく、シャーディングされた state dict もシンプル)を使用したい場合。
- 後から DeviceMesh を使って、DP と Tensor Parallel を組み合わせる可能性がある場合。
次の場合は使用を避けるか、慎重に扱ってください。
- PyTorch のバージョンをまたいで厳密な後方互換性のあるチェックポイントが必要な場合(DCP はこれを推奨していません)。
- FSDP2 スタックに対応していない古い PyTorch バージョンを使用せざるを得ない場合。
代替手段(FSDP2 が最適ではない場合)
- DistributedDataParallel(DDP):標準的なデータ並列ラッパーを使った、従来型の分散データ並列トレーニングが必要な場合に使用します。
- FullyShardedDataParallel(FSDP1):データ並列ワーカー間でパラメーターをシャーディングする、従来の FSDP ラッパーを使用します。
参照先:references/pytorch_ddp_notes.md、references/pytorch_fsdp1_api.md。
エージェントが守るべき契約
torchrunで起動し、プロセスごとに CUDA デバイスを設定します(通常はLOCAL_RANKを使用します)。fully_shard()はボトムアップで適用します。つまり、ルートモジュールより先にサブモジュール(Transformer ブロックなど)をシャーディングします。- FSDP2 のフックを実行するため、
model.forward(input)ではなくmodel(input)を呼び出します(明示的にunshard()を呼び出すか、forward メソッドを登録する場合を除きます)。 - シャーディング後にオプティマイザーを作成し、DTensor パラメーター(
fully_shardの適用後)を対象として構築されていることを確認します。 - 分散チェックポイント(DCP)または分散 state dict ヘルパーを使ってチェックポイントを保存します。全テンソルに意図的に集約する場合を除き、単純な
torch.save(model.state_dict())は使用しないでください。
(これらのルールはすべて、公式 API ドキュメント/チュートリアルで直接説明されています。参照先を確認してください。)
手順
0)バージョンと環境の確認
- FSDP2 と DCP のドキュメントが最近更新されている、比較的新しい安定版 PyTorch を推奨します。
torchrun --nproc_per_node <gpus_per_node> ...を使い、RANK、WORLD_SIZE、LOCAL_RANKが参照可能であることを確認します。
参照先:references/pytorch_fsdp2_tutorial.md(起動コマンドとセットアップ)、references/pytorch_fully_shard_api.md(ユーザー契約)。
1)分散環境を初期化してデバイスを設定する
最小限で正しいパターン:
dist.init_process_group(backend="nccl")torch.cuda.set_device(int(os.environ["LOCAL_RANK"]))- 必要に応じて、データ並列グループを記述する
DeviceMeshを作成します。
参照先:references/pytorch_device_mesh_tutorial.md(DeviceMesh が必要な理由と、プロセスグループの管理方法)。
2)meta デバイス上でモデルを構築する(非常に大きなモデルに推奨)
大規模モデルの場合は、meta 上で初期化し、シャーディングを適用してから GPU 上に重みを実体化します。
with torch.device("meta"): model = ...- サブモジュールに
fully_shard(...)を適用し、その後fully_shard(model)を適用します。 model.to_empty(device="cuda")model.reset_parameters()(または独自の初期化ルーチン)
参照先:references/pytorch_fsdp2_tutorial.md(移行ガイドにこの手順が明示されています)。
3) fully_shard() をボトムアップで適用する(ラップ方針=「必要な箇所に適用」)
最上位のモジュールだけに fully_shard を呼び出すのは避けてください。
Transformer のようなモデルに推奨されるシャーディングパターン:
- モジュールを反復処理し、
if isinstance(m, TransformerBlock): fully_shard(m, ...)を実行する - その後、
fully_shard(model, ...)を実行する
理由:
fully_shardは集合通信の効率化のために「パラメーターグループ」を作成し、先行する呼び出しですでにグループ化されたパラメーターは除外します。ボトムアップで適用すると、オーバーラップが向上し、ピークメモリ使用量が低下します。
参考:references/pytorch_fully_shard_api.md(ボトムアップで適用する要件とその理由)。
4) メモリとパフォーマンスのトレードオフに応じて reshard_after_forward を設定する
デフォルトの動作:
Noneは、ルート以外のモジュールではTrue、ルートモジュールではFalseを意味します(適切なデフォルト値です)。
目安:
- メモリがボトルネックの場合:デフォルトを維持するか、多くのブロックで
Trueを明示的に設定します。 - スループットがボトルネックで、メモリに余裕がある場合:シャーディングされていないパラメーターをより長く保持することを検討します(ルートでは通常
Falseです)。 - 高度な設定:意味のある除数であれば、
intを使って forward 後により小さなメッシュ(例:ノード内)に再シャーディングできます。
参考:references/pytorch_fully_shard_api.md(動作の詳細)。
5) 混合精度とオフロード(任意ですが、よく使用されます)
FSDP2 では以下を使用します:
mp_policy=MixedPrecisionPolicy(param_dtype=..., reduce_dtype=..., output_dtype=..., cast_forward_inputs=...)- CPU オフロードを行う場合は
offload_policy=CPUOffloadPolicy()
経験則:
- H100/A100 クラスの GPU では、モデルの数値安定性を確認したうえで、パラメーターとリダクションに BF16 を使用するところから始めます。
reduce_dtypeは、勾配のリダクションに関する想定に合わせます。- CPU オフロードを使用する場合は、PCIe/NVLink の通信量と実行時のオーバーヘッドを考慮してください。
参考:references/pytorch_fully_shard_api.md(MixedPrecisionPolicy / OffloadPolicy クラス)。
6) オプティマイザー、勾配クリッピング、勾配蓄積
- シャーディング後にオプティマイザーを作成し、DTensor パラメーターを保持するようにします。
- 勾配蓄積や no_sync が必要な場合:
- FSDP1 の
no_sync()ではなく、FSDP2 の仕組み(set_requires_gradient_sync)を使用します。
- FSDP1 の
勾配クリッピング:
- パラメーターと勾配は DTensor であるため、FSDP2 チュートリアルの「Gradient Clipping and Optimizer with DTensor」で示されている方法を使用します。
参考:references/pytorch_fsdp2_tutorial.md。
7) チェックポイント:DCP または分散状態辞書ヘルパーを推奨
推奨される方法は次の 2 つです。
A) Distributed Checkpoint(DCP)— 最適なデフォルト
- DCP は複数のランクから並列に保存・読み込みを行い、読み込み時の再シャーディングをサポートします。
- DCP は複数のファイル(多くの場合、少なくともランクごとに 1 つ)を生成し、「インプレース」で処理します。
B) 分散状態辞書ヘルパー
StateDictOptions(full_state_dict=True, cpu_offload=True, broadcast_from_rank0=True, ...)とともにget_model_state_dict/set_model_state_dictを使用します。- オプティマイザーには
get_optimizer_state_dict/set_optimizer_state_dictを使用します。
避けること:
DTensor.full_tensor()を使って意図的に変換し、メモリを慎重に管理する場合を除き、DTensor の状態辞書を通常のtorch.saveで保存しないでください。
参考:
references/pytorch_dcp_overview.md(DCP の動作と注意事項)references/pytorch_dcp_recipe.mdおよびreferences/pytorch_dcp_async_recipe.md(エンドツーエンドの使用方法)references/pytorch_fsdp2_tutorial.md(DTensor と DCP の状態辞書の処理フロー)references/pytorch_examples_fsdp2.md(動作するチェックポイントスクリプト)
ワークフローのチェックリスト(コピーしてすぐに使えます)
ワークフロー A:既存のトレーニングスクリプトに FSDP2 を導入する
-
torchrunで起動し、プロセスグループを初期化します。 -
LOCAL_RANKから CUDA デバイスを設定します。多次元並列処理が必要な場合は、DeviceMeshを作成します。 - モデルを構築し(必要に応じて
metaを使用)、fully_shardをボトムアップで適用してから、fully_shard(model)を適用します。 - シャーディング後にオプティマイザーを作成し、DTensor パラメーターを認識させます。
-
model(inputs)を使用してフックを実行します。勾配累積にはset_requires_gradient_syncを使用します。 -
torch.distributed.checkpointのヘルパーを使って DCP の保存/読み込みを追加します。
参考資料:references/pytorch_fsdp2_tutorial.md、references/pytorch_fully_shard_api.md、references/pytorch_device_mesh_tutorial.md、references/pytorch_dcp_recipe.md。
ワークフロー B:DCP の保存/読み込みを追加する(最小パターン)
- 状態を
Statefulでラップするか、get_state_dictを使って状態を組み立てます。 - すべてのランクから、共有パスに対して
dcp.save(...)を呼び出します。 -
dcp.load(...)を呼び出し、set_state_dictで復元します。 - 異なるメッシュに読み込む場合は、リシャーディングに関する前提を検証します。
参考資料:references/pytorch_dcp_recipe.md。
デバッグチェックリスト(エージェントが最初に確認すべき項目)
- すべてのランクが別々の GPU を使用していますか?
そうでない場合は、torch.cuda.set_device(LOCAL_RANK)とtorchrunのフラグを確認してください。 - 誤って
forward()を直接呼び出していませんか?
model(input)を使用するか、明示的にunshard()を呼び出すか、フォワードを登録してください。 fully_shard()はボトムアップで適用されていますか?
ルートのみがシャーディングされている場合、メモリーやパフォーマンスが悪化し、混乱を招く可能性があります。- 適切なタイミングでオプティマイザーを作成していますか?
シャーディング後に、DTensor パラメーターを使って作成する必要があります。 - チェックポイントのパスに一貫性がありますか?
- DCP を使用する場合、変換方法を理解していない限り、その場しのぎの
torch.saveと混在させないでください。 - DCP の PyTorch バージョン互換性に関する警告に注意してください。
- DCP を使用する場合、変換方法を理解していない限り、その場しのぎの
よくある問題と解決策
- フォワードフックが実行されない →
model.forward(...)ではなく、model(inputs)を呼び出すか、明示的にunshard()を呼び出します。 - オプティマイザーが非 DTensor パラメーターを認識する → すべての
fully_shard呼び出しの後にオプティマイザーを作成します。 - ルートモジュールのみがシャーディングされる → ルートの前に、サブモジュールに対してボトムアップで
fully_shardを適用します。 - フォワード後にメモリー使用量が急増する → より多くのモジュールで
reshard_after_forward=Trueを設定します。 - 勾配累積の同期がずれる → FSDP1 の
no_sync()ではなく、set_requires_gradient_syncを使用します。
参考資料:references/pytorch_fully_shard_api.md、references/pytorch_fsdp2_tutorial.md。
最小限のリファレンス実装の概要(エージェント向け)
コーディングエージェントは、次のラベル付きブロックを含むスクリプトを実装してください。
init_distributed(): プロセスグループを初期化し、デバイスを設定しますbuild_model_meta(): meta 上にモデルを作成し、fully_shardを適用して、重みを実体化しますbuild_optimizer(): シャーディング後にオプティマイザーを作成しますtrain_step():model(inputs)と DTensor 対応のパターンを使用して、フォワード/バックワード/ステップを実行しますcheckpoint_save/load(): DCP または分散状態辞書ヘルパーを使用します
具体的な例は references/pytorch_examples_fsdp2.md と公式チュートリアルのリファレンスにあります。
参考資料
references/pytorch_fsdp2_tutorial.mdreferences/pytorch_fully_shard_api.mdreferences/pytorch_ddp_notes.mdreferences/pytorch_fsdp1_api.mdreferences/pytorch_device_mesh_tutorial.mdreferences/pytorch_tp_tutorial.mdreferences/pytorch_dcp_overview.mdreferences/pytorch_dcp_recipe.mdreferences/pytorch_dcp_async_recipe.mdreferences/pytorch_examples_fsdp2.mdreferences/torchtitan_fsdp_notes.md(任意、本番環境向けの注意事項)references/ray_train_fsdp2_example.md(任意、統合例)
関連スキル
huggingface-accelerate: HuggingFace Accelerate(Accelerator クラス、accelerate config、accelerate launch)で既存の PyTorch トレーニングスクリプトをラップし、同じ c…distributed-llm-pretraining-torchtitan: 4D 並列処理(FSDP2、TP、PP、CP)を使用した、PyTorch ネイティブの分散 LLM 事前学習を torchtitan で提供します。