# データ並列性

[データ並列性](https://huggingface.co/spaces/nanotron/ultrascale-playbook?section=data_parallelism)では、同じモデルを各GPUに複製し、各GPUに異なるプロンプトを割り当てます。モデルがすでに1つのGPUに収まる場合、スループットを向上させ、単一プロンプトのレイテンシは変わりません。まだ試していない場合は、まず1つのGPUで[バッチ推論](../using-diffusers/batched_inference)を試してください。他の戦略との比較については、[分散推論](../training/distributed_inference)を参照してください。

[Accelerate](https://huggingface.co/docs/accelerate/index) または [PyTorch Distributed](https://pytorch.org/tutorials/beginner/dist_overview.html) を直接使用して、データ並列性を設定できます。

## Accelerate

Accelerate はプロセスを設定し、それぞれに GPU を割り当てます。

次のコマンドでAccelerateをインストールします。

```bash
uv pip install accelerate
```

`run_distributed.py` というファイルを作成し、[PartialState](https://huggingface.co/docs/accelerate/main/en/package_reference/state#accelerate.PartialState) を作成して分散環境を設定します。[DiffusionPipeline](/docs/diffusers/main/ja/api/pipelines/overview#diffusers.DiffusionPipeline) を `PartialState.device` に移動して、各プロセスに GPU を割り当てます。

```py
import torch
from accelerate import PartialState
from diffusers import DiffusionPipeline

pipeline = DiffusionPipeline.from_pretrained(
    "Qwen/Qwen-Image", dtype=torch.bfloat16
)
distributed_state = PartialState()
pipeline.to(distributed_state.device)
```

同じファイル内で、[split_between_processes](https://huggingface.co/docs/accelerate/main/en/package_reference/state#accelerate.PartialState.split_between_processes) をコンテキストマネージャーとして使用し、プロンプトをプロセス間で分割します。

```py
with distributed_state.split_between_processes(["a dog", "a cat"]) as prompt:
    result = pipeline(prompt).images[0]
    result.save(f"result_{distributed_state.process_index}.png")
```

`accelerate launch`でスクリプトを実行し、`--num_processes`をGPUの数に設定します。

```bash
accelerate launch --num_processes=2 run_distributed.py
```

> [!TIP]
> 完全な例については、この[最小限のマルチGPU推論スクリプト](https://gist.github.com/sayakpaul/cfaebd221820d7b43fae638b4dfa01ba)を参照してください。詳細については、[Accelerateによる分散推論](https://huggingface.co/docs/accelerate/en/usage_guides/distributed_inference#distributed-inference-with-accelerate)ガイドを参照してください。

## PyTorch Distributed

Accelerate を使わずに、`torch.distributed` を直接使用してデータ並列性を設定することもできます。

分散環境を作成するには、[init_process_group](https://pytorch.org/docs/stable/distributed.html#torch.distributed.init_process_group)を呼び出します。`torchrun`は環境変数を通じて各プロセスのランクとプロセスの総数（ワールドサイズ）を設定するため、これらを自分で渡す必要はありません。

各プロセスには、それぞれ専用のGPUとプロンプトが必要です。`torchrun`は、`LOCAL_RANK`環境変数をそのノード上でのプロセスのGPUインデックスに設定するため、GPUの選択にはこれを使用します。プロンプトの選択には、すべてのノードにまたがってプロセスを数える`get_rank`を使用します。

```py
import os
import torch
import torch.distributed as dist
from diffusers import DiffusionPipeline

def main():
    dist.init_process_group("nccl")
    rank = dist.get_rank()
    local_rank = int(os.environ["LOCAL_RANK"])
    device = torch.device(f"cuda:{local_rank}")

    pipeline = DiffusionPipeline.from_pretrained(
        "Qwen/Qwen-Image", dtype=torch.bfloat16,
    ).to(device)

    prompts = ["a dog", "a cat"]
    prompt = prompts[rank]

    image = pipeline(prompt).images[0]
    image.save(f"{prompt.replace(' ', '_')}.png")

    dist.destroy_process_group()

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

スクリプトを`run_distributed.py`として保存し、`torchrun`で実行します。`--nproc-per-node`にはGPUの数を指定します。`prompts`リストにはプロセスごとに1つのプロンプトが含まれるため、使用するGPUごとにプロンプトを追加してください。

```bash
torchrun --nproc-per-node 2 run_distributed.py
```

