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.42.1).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

可复现性

Diffusion 是一个随机过程,每次都会生成不同的输出。对于测试和复现结果等用例,你希望在一定的容差范围内,跨版本和平台每次都能生成相同的结果。

本指南将向您展示如何控制随机性来源并启用确定性算法。

生成器

Pipelines 依赖 torch.randn 来创建初始噪声张量,而该函数每次都会使用不同的随机种子。若要在 CPU 或 GPU 上生成相同的输出,请使用 Generator 来管理随机值的生成方式。

如果可复现性很重要,你应该使用 CPU 上的 Generator。性能损失通常可以忽略不计,并且你会生成更相似的数值。

GPU
CPU

如果您关注可复现性,请使用 CPU Generator。CPU 随机数生成器在不同机器上更加稳定。

当传入 CPU Generator 时,Diffusers 的 randn_tensor() 会在 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]

向 pipeline 传入一个 Generator 对象,而不是整数种子。Generator 会维护一个随机状态,每次使用它时该状态都会被消耗并更新。因此,即使跨 pipeline,后续调用同一对象也会产生不同的结果,因为其状态已经改变。如果需要再次使用相同的种子,请在每次调用前重新设置种子或创建一个新的 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 支持针对某些操作使用确定性算法(在可用的情况下),以确保它们产生相同的结果。确定性算法可能会更慢并降低性能。

使用 Diffusers 的 enable_full_determinism() 来启用确定性算法。

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 不会在每次运行时选择不同的卷积算法
  • 通过torch.backends.cuda.matmul.allow_tf32 = False禁用 TensorFloat32 (TF32),转而使用精度更高的全精度矩阵乘法

后续步骤

建议阅读 PyTorch 关于 可复现性 的开发者说明。你可以尝试限制随机性,但即使使用相同的随机种子,也无法保证结果完全一致。

Update on GitHub