Diffusers documentation
Воспроизводимость
Воспроизводимость
Diffusion — это случайный процесс, который каждый раз генерирует разный результат. Для таких сценариев использования, как тестирование и воспроизведение результатов, вам нужно получать одинаковый результат при каждом запуске, в пределах допустимого диапазона отклонений, независимо от версии и платформы.
В этом руководстве показано, как управлять источниками случайности и включать детерминированные алгоритмы.
Генератор
Pipelines используют torch.randn, который каждый раз применяет другое случайное зерно, для создания начальных шумовых тензоров. Чтобы получить одинаковый вывод на CPU или GPU, используйте Generator для управления генерацией случайных значений.
Если важна воспроизводимость, следует использовать генератор
Generatorна CPU. Потеря производительности часто незначительна, а генерируемые значения будут более похожи.
Используйте Generator на CPU, если важна воспроизводимость. Генератор случайных чисел на CPU более стабилен на разных машинах.
Если вы передаёте CPU Generator, функция randn_tensor() в Diffusers выполняет выборку на CPU и перемещает тензор на GPU внутри пайплайна. Вам не нужно самостоятельно вызывать randn_tensor или .to("cuda"). GPU Generator выполняет выборку непосредственно на устройстве, поэтому результаты могут отличаться от CPU.
Используйте manual_seed, чтобы задать сид.
import torch
from diffusers import DiffusionPipeline
pipeline = DiffusionPipeline.from_pretrained(
"Qwen/Qwen-Image", dtype=torch.bfloat16, device_map="cuda" # or "mps", "xpu", "cpu"
)
generator = torch.manual_seed(0)
image = pipeline(
prompt="a red apple on a wooden table",
generator=generator,
num_inference_steps=4,
).images[0]Создайте CPU-генератор Generator и задайте сид с помощью Generator.manual_seed.
import torch
from diffusers import DiffusionPipeline
pipeline = DiffusionPipeline.from_pretrained(
"Qwen/Qwen-Image", dtype=torch.bfloat16, device_map="cpu"
)
generator = torch.Generator(device="cpu").manual_seed(0)
image = pipeline(
prompt="a red apple on a wooden table",
generator=generator,
num_inference_steps=4,
).images[0]Передавайте в пайплайн объект Generator вместо целочисленного seed. Объект Generator хранит случайное состояние, которое потребляется и обновляется при каждом использовании. После этого тот же объект будет выдавать разные результаты при последующих вызовах, даже в разных пайплайнах, поскольку его состояние изменилось. Если вам снова нужен тот же seed, сбрасывайте состояние или создавайте новый Generator перед каждым вызовом.
import torch
prompt = "a red apple on a wooden table"
for _ in range(5):
generator = torch.manual_seed(0)
image = pipeline(prompt, generator=generator, num_inference_steps=4).images[0]Детерминированные алгоритмы
PyTorch поддерживает детерминированные алгоритмы (если они доступны) для определённых операций, чтобы они давали одинаковые результаты. Детерминированные алгоритмы могут работать медленнее и снижать производительность.
Используйте enable_full_determinism() в Diffusers, чтобы включить детерминированные алгоритмы.
from diffusers.utils.torch_utils import enable_full_determinism
enable_full_determinism()enable_full_determinism работает следующим образом:
- Установка переменной окружения
CUDA_LAUNCH_BLOCKINGв значение1 - Установка переменной окружения CUBLAS_WORKSPACE_CONFIG в значение
:16:8, чтобы cuBLAS использовал фиксированную структуру рабочего пространства во время выполнения - Вызов
torch.use_deterministic_algorithms(True) - Установка
torch.backends.cudnn.deterministic = True - Установка
torch.backends.cudnn.benchmark = False, чтобы cuDNN не выбирал другой алгоритм свёртки при каждом запуске - Отключение TensorFloat32 (TF32) с помощью
torch.backends.cuda.matmul.allow_tf32 = Falseв пользу более точного матричного умножения с полной точностью
Дальнейшие шаги
Вам следует ознакомиться с заметками разработчиков PyTorch о воспроизводимости. Вы можете попытаться ограничить случайность, но она не гарантирована даже при использовании одинакового семени.
Update on GitHub