Diffusers documentation

Параллелизм данных

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v0.43.0).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Параллелизм данных

Параллелизм данных дублирует одну и ту же модель на каждом GPU и передаёт каждому GPU разные промпты. Это повышает пропускную способность, когда модель уже помещается на одном GPU, и не изменяет задержку для одного промпта. Если вы ещё этого не делали, сначала попробуйте Пакетный вывод на одном GPU. Чтобы сравнить с другими стратегиями, обратитесь к разделу Распределённый вывод.

Вы можете настроить параллелизм данных с помощью Accelerate или напрямую с помощью PyTorch Distributed.

Accelerate

Accelerate настраивает процессы и назначает каждому из них GPU.

Установите Accelerate с помощью следующей команды.

uv pip install accelerate

Создайте PartialState в файле run_distributed.py, чтобы настроить распределённую среду. Переместите DiffusionPipeline на PartialState.device, чтобы назначить GPU каждому процессу.

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 в качестве контекстного менеджера для распределения промптов между процессами.

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.

accelerate launch --num_processes=2 run_distributed.py

Полный пример приведён в этом минимальном скрипте инференса на нескольких GPU. Подробнее — в руководстве Распределённый инференс с Accelerate.

PyTorch Distributed

Вы также можете настроить параллелизм данных с помощью torch.distributed напрямую, без Accelerate.

Вызовите init_process_group, чтобы создать распределённую среду. torchrun задаёт ранг каждого процесса и общее количество процессов (размер мира) через переменные окружения, поэтому передавать их вручную не нужно.

Каждому процессу требуется собственный GPU и собственный промпт. torchrun устанавливает переменную окружения LOCAL_RANK в значение индекса GPU процесса на его узле, поэтому используйте её для выбора GPU. Используйте get_rank, который считает процессы по всем узлам, для выбора промпта.

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 содержится один промпт на процесс, поэтому добавьте промпт для каждого используемого GPU.

torchrun --nproc-per-node 2 run_distributed.py
Update on GitHub