Diffusers documentation
Reproducibility
Reproducibility
Diffusion is a random process that generates a different output every time. For use cases like testing and replicating results, you want to generate the same result each time, across releases and platforms within a certain tolerance range.
This guide will show you how to control sources of randomness and enable deterministic algorithms.
Generator
Pipelines rely on torch.randn, which uses a different random seed each time, to create the initial noisy tensors. To generate the same output on a CPU or GPU, use a Generator to manage how random values are generated.
If reproducibility is important, you should use a CPU
Generator. The performance loss is often negligible and you’ll generate more similar values.
Use a CPU Generator when you care about reproducibility. CPU RNG is more stable across machines.
When you pass a CPU Generator, Diffusers’ randn_tensor() samples on the CPU and moves the tensor to the GPU inside the pipeline. You do not call randn_tensor or .to("cuda") yourself. A GPU Generator samples on-device instead and can diverge from CPU results.
Use manual_seed to set a 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]Pass a Generator object to the pipeline instead of an integer seed. A Generator keeps a random state that is consumed and updated when you use it. After that, the same object produces different results on later calls, even across pipelines, because its state has changed. Reseed it or create a new Generator before each call when you need the same seed again.
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]Deterministic algorithms
PyTorch supports deterministic algorithms (where available) for certain operations so they produce the same results. Deterministic algorithms may be slower and decrease performance.
Use Diffusers’ enable_full_determinism() to enable deterministic algorithms.
from diffusers.utils.torch_utils import enable_full_determinism
enable_full_determinism()enable_full_determinism works by:
- Setting the environment variable
CUDA_LAUNCH_BLOCKINGto1 - Setting the environment variable CUBLAS_WORKSPACE_CONFIG to
:16:8so cuBLAS uses a fixed workspace layout at runtime - Calling
torch.use_deterministic_algorithms(True) - Setting
torch.backends.cudnn.deterministic = True - Setting
torch.backends.cudnn.benchmark = Falseso cuDNN does not pick a different convolution algorithm each run - Disabling TensorFloat32 (TF32) with
torch.backends.cuda.matmul.allow_tf32 = Falsein favor of more precise full-precision matmul
Next steps
You should read PyTorch’s developer notes about Reproducibility. You can try to limit randomness, but it is not guaranteed even with an identical seed.
Update on GitHub