> ## Documentation Index
> Fetch the complete documentation index at: https://wb-21fd5541-sdk-testing-latest.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> 複数のGPUを使用した分散トレーニング実験をW&Bでログします。

# 分散トレーニング実験をログする

分散トレーニング実験では、複数のマシンまたはクライアントを並列に使用してモデルをトレーニングします。W\&Bは、分散トレーニング実験のトラッキングに役立ちます。ユースケースに応じて、次のいずれかの方法で分散トレーニング実験をトラッキングします。

* **単一のプロセスをトラッキングする**: rank 0 のプロセス ("leader" または "coordinator" とも呼ばれます) をW\&Bでトラッキングします。これは、[PyTorch Distributed Data Parallel](https://pytorch.org/docs/stable/generated/torch.nn.parallel.DistributedDataParallel.html#torch.nn.parallel.DistributedDataParallel) (DDP) Class を使用した分散トレーニング実験のログで一般的な方法です。
* **複数のプロセスをトラッキングする**: 複数のプロセスをトラッキングする場合は、次のいずれかの方法を使用できます。
  * 各プロセスを、プロセスごとに1つの run を使って個別にトラッキングします。必要に応じて、W\&B App UI でまとめてグループ化することもできます。
  * すべてのプロセスを単一の run にトラッキングします。

<Tip>
  **同時接続**

  同時接続ごとに、コンピュート、メモリ、ネットワークのリソースが必要になります。メトリクスを定期的にログしない空のクライアント接続でもシステムメトリクスの更新は送信されるため、チャートの読み込み時のパフォーマンス低下につながります。

  W\&Bでは、ワークロードに応じて同時クライアント接続の最大数を適切に制限し、時間の経過に伴うリソース使用量を監視することを推奨しています。W\&Bは、**専用クラウド** で同時クライアント接続数 300 のハード制限までテストしています。

  **Multi-tenant Cloud** の組織では、分散トレーニング用のクライアント接続には、通常のトレーニング run と同じ [rate limits](/ja/models/track/limits#rate-limits) が適用されます。[Teams and Enterprise plans](https://wandb.ai/site/pricing) のUsersは、Free プランのUsersよりも高い rate limits を利用できます。
</Tip>

<div id="track-a-single-process">
  ## 単一プロセスをトラッキングする
</div>

このセクションでは、rank 0 プロセスで利用可能な値やメトリクスをトラッキングする方法について説明します。このアプローチは、単一のプロセスからしか取得できないメトリクスをトラッキングする場合に使用します。代表的なメトリクスには、GPU/CPU 使用率、共有の検証セットでの挙動、勾配やパラメーター、代表的なデータサンプルに対する損失値などがあります。

rank 0 プロセス内で、[`wandb.init()`](/ja/models/ref/python/functions/init) を使用して W\&B run を初期化し、その run に実験データをログします ([`wandb.Run.log()`](/ja/models/ref/python/experiments/run/#method-runlog)) 。

次の [Python サンプルスクリプト (`log-ddp.py`) ](https://github.com/wandb/examples/blob/master/examples/pytorch/pytorch-ddp/log-ddp.py) は、PyTorch DDP を使用して 1 台のマシン上の 2 つの GPU でメトリクスをトラッキングする方法の一例を示しています。[PyTorch DDP](https://pytorch.org/tutorials/intermediate/ddp_tutorial.html) (`torch.nn` の `DistributedDataParallel`) は、分散トレーニングで広く使われているライブラリです。基本的な考え方はどの分散トレーニング構成にも当てはまりますが、実装は異なる場合があります。

この Python スクリプトでは、次のことを行います。

1. `torch.distributed.launch` を使用して複数のプロセスを起動します。
2. `--local_rank` コマンドライン引数で rank を確認します。
3. rank が 0 に設定されている場合、[`train()`](https://github.com/wandb/examples/blob/master/examples/pytorch/pytorch-ddp/log-ddp.py#L24) 関数内で条件付きで `wandb` をログする設定します。

```python theme={null}
if __name__ == "__main__":
    # 引数を取得する
    args = parse_args()

    if args.local_rank == 0:  # メインプロセスのみ
        # wandb run を初期化する
        run = wandb.init(
            entity=args.entity,
            project=args.project,
        )
        # DDP でモデルをトレーニングする
        train(args, run)
    else:
        train(args)
```

単一プロセスでトラッキングされたメトリクスを示す[ダッシュボードの例](https://wandb.ai/ayush-thakur/DDP/runs/1s56u3hc/system)を確認してください。

このダッシュボードには、温度や利用率など、2基のGPUそれぞれのシステムメトリクスが表示されます。

<Frame>
  <img src="https://mintcdn.com/wb-21fd5541-sdk-testing-latest/H06KgVKW2CsyczDM/images/track/distributed_training_method1.png?fit=max&auto=format&n=H06KgVKW2CsyczDM&q=85&s=60df69791f11756d5d235ba1107e24a5" alt="GPUメトリクスのダッシュボード" width="1822" height="733" data-path="images/track/distributed_training_method1.png" />
</Frame>

ただし、エポックとバッチサイズに対する損失値は、1基のGPUからのみログされていました。

<Frame>
  <img src="https://mintcdn.com/wb-21fd5541-sdk-testing-latest/_BDoNoao0FSZz-dv/images/experiments/loss_function_single_gpu.png?fit=max&auto=format&n=_BDoNoao0FSZz-dv&q=85&s=40a308c85c630fb805edd0114f1faef0" alt="損失関数のプロット" width="1207" height="391" data-path="images/experiments/loss_function_single_gpu.png" />
</Frame>

<div id="track-multiple-processes">
  ## 複数のプロセスをトラッキングする
</div>

W\&B で複数のプロセスをトラッキングするには、次のいずれかの方法を使用します。

* 各プロセスごとに run を作成して、[各プロセスを個別にトラッキングする](/ja/models/track/log/distributed-training/#track-each-process-separately)。
* [すべてのプロセスを 1 つの run にトラッキングする](/ja/models/track/log/distributed-training/#track-all-processes-to-a-single-run)。

<div id="track-each-process-separately">
  ### 各プロセスを個別にトラッキングする
</div>

このセクションでは、各プロセスごとに run を作成して、各プロセスを個別にトラッキングする方法を説明します。各 run では、それぞれの run にメトリクスや Artifacts などをログします。すべてのプロセスが正常に終了するよう、トレーニングの最後に `wandb.Run.finish()` を呼び出して、run が完了したことを示します。

複数の実験にまたがる run の管理は難しいことがあります。これを軽減するには、W\&B の初期化時に `group` パラメーターに値を指定し (`wandb.init(group='group-name')`) 、どの run がどの実験に属するかを追跡できるようにします。実験内でトレーニングおよび評価の W\&B Runs を追跡する方法の詳細については、[Group Runs](/ja/models/runs/grouping/)を参照してください。

<Note>
  **個々のプロセスからのメトリクスをトラッキングしたい場合は、この方法を使用してください**。代表的な例としては、各ノード上のデータと予測 (データ分散のデバッグ用) や、メインノード以外での個々のバッチのメトリクスがあります。なお、この方法は、すべてのノードからシステムメトリクスを取得したり、メインノードで利用可能な要約統計を取得したりするためには必要ありません。
</Note>

次の Python コードスニペット は、W\&B の初期化時に `group` パラメーターを設定する方法を示しています。

```python theme={null}
if __name__ == "__main__":
    # 引数を取得する
    args = parse_args()
    # run を初期化する
    run = wandb.init(
        entity=args.entity,
        project=args.project,
        group="DDP",  # 実験のすべての runs を 1 つのグループにまとめる
    )
    # DDP でモデルをトレーニングする
    train(args, run)

    run.finish()  # run を完了としてマークする
```

W\&B App UI で、複数のプロセスからトラッキングされたメトリクスの[ダッシュボード例](https://wandb.ai/ayush-thakur/DDP?workspace=user-noahluna)を確認してください。左サイドバーでは、2 つの W\&B Runs が 1 つのグループにまとめられていることに注目してください。グループをクリックすると、その実験専用のグループページを表示できます。専用のグループページでは、各プロセスのメトリクスが個別に表示されます。

<Frame>
  <img src="https://mintcdn.com/wb-21fd5541-sdk-testing-latest/_BDoNoao0FSZz-dv/images/experiments/dashboard_grouped_runs.png?fit=max&auto=format&n=_BDoNoao0FSZz-dv&q=85&s=b55e3f86eb95fec14a74e3c39da1dfd1" alt="グループ化された分散 runs" width="3730" height="1722" data-path="images/experiments/dashboard_grouped_runs.png" />
</Frame>

上の画像は、W\&B App UI のダッシュボードを示しています。サイドバーには 2 つの実験が表示されています。1 つは 'null' というラベルで、もう 1 つは 'DPP' です (黄色の枠で囲まれています) 。グループを展開すると (Group ドロップダウンを選択) 、その実験に関連付けられた W\&B Runs を確認できます。

<div id="organize-distributed-runs">
  ### 分散 run を整理する
</div>

W\&B の初期化時に `job_type` パラメーター (`wandb.init(job_type='type-name')`) を設定すると、各ノードをその役割に応じて分類できます。たとえば、全体を制御するメインノードと、結果を報告する複数のワーカーノードで構成される場合があります。メインノードでは `job_type` を `main` に、結果を報告するワーカーノードでは `worker` に設定できます。

```python theme={null}
   # メインの制御ノード
   with wandb.init(project="<project>", job_type="main", group="experiment_1") as run:
        # トレーニングコード

   # 結果を報告するワーカーノード
   with wandb.init(project="<project>", job_type="worker", group="experiment_1") as run:
        # トレーニングコード
```

ノードに `job_type` を設定したら、Workspace で [保存済みビュー](/ja/models/track/workspaces/#create-a-new-saved-workspace-view) を作成して runs を整理できます。右上の **action (<Icon icon="ellipsis" iconType="solid" />)** メニューをクリックし、**Save as new view** をクリックします。

たとえば、次のような保存済みビューを作成できます。

* **Default view**: worker ノードを除外してノイズを減らす
  * **フィルター** をクリックし、**Job Type** を `worker` に設定します。

  * レポート用ノードのみが表示されます

  * **Debug view**: トラブルシューティングのために worker ノードに絞り込む
    * **フィルター** をクリックし、**Job Type** を `==` `worker` に設定し、**State** を `IN` `crashed` に設定します。
    * クラッシュした worker ノード、またはエラー状態の worker ノードのみが表示されます

  * **All nodes view**: すべてをまとめて表示する
    * フィルターなし
    * 全体を監視する際に便利です

保存済みビューを開くには、プロジェクトのサイドバーで **Workspaces** をクリックし、次にメニューをクリックします。Workspaces はリストの上部に、保存済みビューは下部に表示されます。

<div id="track-all-processes-to-a-single-run">
  ### すべてのプロセスを単一の run にトラッキングする
</div>

<Warning>
  `x_` 接頭辞が付いたパラメーター (`x_label` など) はパブリックプレビューです。フィードバックを提供するには、[W\&B リポジトリの GitHub issue](https://github.com/wandb/wandb) を作成してください。
</Warning>

<Note>
  **要件**

  複数のプロセスを単一の run にトラッキングするには、以下が必要です。

  * W\&B Python SDK バージョン `v0.19.9` 以降

  * W\&B Server v0.68 以降
</Note>

この方法では、プライマリノードと 1 つ以上のワーカーノードを使用します。プライマリノード内で W\&B run を初期化します。各ワーカーノードでは、プライマリノードで使用している run ID を使って run を初期化します。トレーニング中、各ワーカーノードはプライマリノードと同じ run ID にログします。W\&B はすべてのノードのメトリクスを集約し、W\&B App UI に表示します。

プライマリノードでは、[`wandb.init()`](/ja/models/ref/python/functions/init) を使って W\&B run を初期化します。`settings` パラメーターに `wandb.Settings` オブジェクト (`wandb.init(settings=wandb.Settings()`) を渡し、以下を設定します。

1. 共有モードを有効にするため、`mode` パラメーターを `"shared"` に設定します。
2. [`x_label`](https://github.com/wandb/wandb/blob/main/wandb/sdk/wandb_settings.py#L638) に一意のラベルを設定します。`x_label` に指定した値は、ログおよび W\&B App UI のシステムメトリクスで、データがどのノードから送られてきたかを識別するために使用されます。指定しない場合、W\&B はホスト名とランダムなハッシュを使ってラベルを作成します。
3. これがプライマリノードであることを示すため、[`x_primary`](https://github.com/wandb/wandb/blob/main/wandb/sdk/wandb_settings.py#L660) パラメーターを `True` に設定します。
4. 必要に応じて、W\&B がどの GPU のメトリクスをトラッキングするかを指定するため、GPU インデックスのリスト (\[0,1,2]) を `x_stats_gpu_device_ids` に指定します。リストを指定しない場合、W\&B はそのマシン上のすべての GPU のメトリクスをトラッキングします。

プライマリノードの run ID を控えておいてください。各ワーカーノードで、プライマリノードの run ID が必要になります。

<Note>
  `x_primary=True` は、プライマリノードとワーカーノードを区別するための設定です。設定ファイルやテレメトリーなど、ノード間で共有されるファイルを upload できるのはプライマリノードだけです。ワーカーノードはこれらのファイルを upload しません。
</Note>

各ワーカーノードでは、[`wandb.init()`](/ja/models/ref/python/functions/init) で W\&B run を初期化し、以下を指定します。

1. `settings` パラメーターに `wandb.Settings` オブジェクト (`wandb.init(settings=wandb.Settings()`) を渡し、次を設定します。
   * 共有モードを有効にするため、`mode` パラメーターを `"shared"` に設定します。
   * `x_label` に一意のラベルを設定します。`x_label` に指定した値は、ログおよび W\&B App UI のシステムメトリクスで、データがどのノードから送られてきたかを識別するために使用されます。指定しない場合、W\&B はホスト名とランダムなハッシュを使ってラベルを作成します。
   * これがワーカーノードであることを示すため、`x_primary` パラメーターを `False` に設定します。
2. プライマリノードで使用している run ID を `id` パラメーターに渡します。
3. 必要に応じて、[`x_update_finish_state`](https://github.com/wandb/wandb/blob/main/wandb/sdk/wandb_settings.py#L772) を `False` に設定します。これにより、非プライマリノードが [run の状態](/ja/models/runs/run-states#run-states) を早い段階で `finished` に更新してしまうのを防ぎ、run の状態を一貫してプライマリノードで管理できます。

<Note>
  * すべてのノードで同じ entity とプロジェクトを使用してください。これにより、正しい run ID を確実に見つけやすくなります。
  * プライマリノードの run ID を設定するために、各ワーカーノードで環境変数を定義することを検討してください。
</Note>

以下のサンプルコードは、複数のプロセスを単一の run にトラッキングするための大まかな要件を示しています。

```python theme={null}
import wandb

entity = "<team_entity>"
project = "<project_name>"

# プライマリノードで run を初期化する
run = wandb.init(
    entity=entity,
    project=project,
	settings=wandb.Settings(
        x_label="rank_0",
        mode="shared",
        x_primary=True,
        x_stats_gpu_device_ids=[0, 1],  # (オプション) GPU 0 と 1 のメトリクスのみをトラッキングする
        )
)

# プライマリノードの run ID を記録する。
# 各ワーカーノードにはこの run ID が必要。
run_id = run.id

# プライマリノードの run ID を使用してワーカーノードで run を初期化する
run = wandb.init(
    entity=entity, # プライマリノードと同じ entity を使用する
    project=project, # プライマリノードと同じ project を使用する
	settings=wandb.Settings(x_label="rank_1", mode="shared", x_primary=False),
	id=run_id,
)

# プライマリノードの run ID を使用してワーカーノードで run を初期化する
run = wandb.init(
    entity=entity, # プライマリノードと同じ entity を使用する
    project=project, # プライマリノードと同じ project を使用する
	settings=wandb.Settings(x_label="rank_2", mode="shared", x_primary=False),
	id=run_id,
)
```

実際の環境では、各ワーカーノードがそれぞれ別のマシン上にある場合があります。

<Note>
  GKE 上のマルチノードかつマルチ GPU の Kubernetes クラスターでモデルを
  トレーニングする方法をエンドツーエンドで示した例については、[Distributed Training with Shared Mode](https://wandb.ai/dimaduev/simple-cnn-ddp/reports/Distributed-Training-with-Shared-Mode--VmlldzoxMTI0NTE1NA) report を参照してください。
</Note>

run がログを送信する project で、マルチノードプロセスのコンソールログを表示するには、次の手順に従います。

1. run を含む project にアクセスします。
2. プロジェクトのサイドバーで **Runs** タブをクリックします。
3. 表示したい run をクリックします。
4. プロジェクトのサイドバーで **Logs** タブをクリックします。

コンソールログページ上部にある UI の検索バーでは、`x_label` に指定したラベルに基づいてコンソールログをフィルターできます。たとえば、次の画像は、`rank0`、`rank1`、`rank2`、`rank3`、`rank4`、`rank5`、`rank6` の各値を `x_label` に指定した場合に、コンソールログのフィルターに使用できるオプションを示しています。\`

<Frame>
  <img src="https://mintcdn.com/wb-21fd5541-sdk-testing-latest/BwrnEjaj-2zjRpjo/images/track/multi_node_console_logs.png?fit=max&auto=format&n=BwrnEjaj-2zjRpjo&q=85&s=12974c0c3a94fb9658b4f577fa3dd3ef" alt="マルチノードのコンソールログ" width="3446" height="1976" data-path="images/track/multi_node_console_logs.png" />
</Frame>

詳細は [Console logs](/ja/models/app/console-logs/) を参照してください。

W\&B はすべてのノードのシステムメトリクスを集約し、W\&B App UI に表示します。たとえば、次の画像は、複数ノードのシステムメトリクスを含むサンプルダッシュボードを示しています。各ノードには、`x_label` パラメーターで指定する一意のラベル (`rank_0`、`rank_1`、`rank_2`) があります。

<Frame>
  <img src="https://mintcdn.com/wb-21fd5541-sdk-testing-latest/BwrnEjaj-2zjRpjo/images/track/multi_node_system_metrics.png?fit=max&auto=format&n=BwrnEjaj-2zjRpjo&q=85&s=fb16c5d22253ec665c5a65ae0bba077b" alt="マルチノードのシステムメトリクス" width="2450" height="1972" data-path="images/track/multi_node_system_metrics.png" />
</Frame>

ラインプロットパネルをカスタマイズする方法については、[Line plots](/ja/models/app/features/panels/line-plot/) を参照してください。

<div id="example-use-cases">
  ## 使用例
</div>

以下のコードスニペットは、高度な分散処理の利用でよくあるシナリオを示しています。

<div id="spawn-process">
  ### プロセスの生成
</div>

spawn されたプロセスで run を開始する場合は、メイン関数内で `wandb.setup()` method を使用します。

```python theme={null}
import multiprocessing as mp

def do_work(n):
    with wandb.init(config=dict(n=n)) as run:
        run.log(dict(this=n * n))

def main():
    wandb.setup()
    pool = mp.Pool(processes=4)
    pool.map(do_work, range(4))


if __name__ == "__main__":
    main()
```

<div id="share-a-run">
  ### run を共有する
</div>

プロセス間で run を共有するには、run オブジェクトを引数として渡します。

```python theme={null}
def do_work(run):
    with wandb.init() as run:
        run.log(dict(this=1))

def main():
    run = wandb.init()
    p = mp.Process(target=do_work, kwargs=dict(run=run))
    p.start()
    p.join()
    run.finish()  # run を完了としてマークする


if __name__ == "__main__":
    main()
```

W\&B ではログの順序は保証されません。同期はスクリプトの作成者側で行ってください。

<div id="troubleshooting">
  ## トラブルシューティング
</div>

W\&B と分散トレーニングを使用する際に発生しやすい一般的な問題は、主に 2 つあります。

1. **トレーニング開始時にハングする** - 分散トレーニングのマルチプロセッシングと `wandb` のマルチプロセッシングが干渉すると、`wandb` プロセスがハングすることがあります。
2. **トレーニング終了時にハングする** - `wandb` プロセスがいつ終了すべきかを認識できない場合、トレーニング ジョブがハングすることがあります。Python スクリプトの最後で `wandb.Run.finish()` API を呼び出して、run が終了したことを W\&B に通知してください。`wandb.Run.finish()` API はデータのアップロードを完了し、W\&B を終了させます。
   W\&B では、分散ジョブの信頼性を向上させるために `wandb service` コマンドを使用することを推奨しています。前述の 2 つのトレーニングの問題は、wandb service を利用できないバージョンの W\&B SDK でよく見られます。

<div id="enable-wb-service">
  ### W\&B Service を有効にする
</div>

使用している W\&B SDK のバージョンによっては、W\&B Service はデフォルトで既に有効になっている場合があります。

<div id="wb-sdk-0130-and-above">
  #### W\&B SDK 0.13.0 以降
</div>

W\&B SDK `0.13.0` 以降では、W\&B Service はデフォルトで有効です。

<div id="wb-sdk-0125-and-above">
  #### W\&B SDK 0.12.5 以降
</div>

W\&B SDK バージョン 0.12.5 以降で W\&B Service を有効にするには、Python スクリプトを修正します。メイン関数内で `wandb.require()` method を使用し、文字列 `"service"` を渡してください。

```python theme={null}
if __name__ == "__main__":
    main()


def main():
    wandb.require("service")
    # 残りのスクリプトをここに記述
```

快適に利用するため、最新バージョンへのアップグレードをお勧めします。

**W\&B SDK 0.12.4 以下**

W\&B SDK バージョン 0.12.4 以下を使用している場合は、代わりにマルチスレッドを使用できるよう、`WANDB_START_METHOD` 環境変数を `"thread"` に設定します。
