Diffusers documentation

Reproductibilité

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

Reproductibilité

La diffusion est un processus aléatoire qui génère une sortie différente à chaque exécution. Pour des cas d’usage tels que les tests et la reproduction des résultats, vous souhaitez obtenir le même résultat à chaque fois, d’une version à l’autre et d’une plateforme à l’autre, dans une certaine plage de tolérance.

Ce guide vous montre comment contrôler les sources d'aléa et activer les algorithmes déterministes.

Générateur

Les pipelines s’appuient sur torch.randn, qui utilise une graine aléatoire différente à chaque fois, pour créer les tenseurs bruités initiaux. Pour générer la même sortie sur un CPU ou un GPU, utilisez un Generator pour gérer la génération des valeurs aléatoires.

Si la reproductibilité est importante, vous devriez utiliser un Generator CPU. La perte de performance est souvent négligeable et vous générerez des valeurs plus similaires.

GPU
CPU

Utilisez un Generator CPU lorsque vous accordez de l'importance à la reproductibilité. Le RNG CPU est plus stable d'une machine à l'autre.

Lorsque vous passez un Generator CPU, la fonction randn_tensor() de Diffusers effectue l'échantillonnage sur le CPU et déplace le tenseur vers le GPU à l'intérieur du pipeline. Vous n'appelez pas vous-même randn_tensor ou .to("cuda"). Un Generator GPU effectue l'échantillonnage directement sur l'appareil et peut produire des résultats différents de ceux du CPU.

Utilisez manual_seed pour définir une graine.

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]

Passez un objet Generator au pipeline au lieu d'une graine entière. Un Generator conserve un état aléatoire qui est consommé et mis à jour lors de son utilisation. Par la suite, le même objet produit des résultats différents lors des appels suivants, même à travers différents pipelines, car son état a changé. Réinitialisez sa graine ou créez un nouveau Generator avant chaque appel si vous avez besoin de la même graine à nouveau.

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]

Algorithmes déterministes

PyTorch prend en charge des algorithmes déterministes (lorsqu’ils sont disponibles) pour certaines opérations afin qu’elles produisent les mêmes résultats. Les algorithmes déterministes peuvent être plus lents et réduire les performances.

Utilisez enable_full_determinism() de Diffusers pour activer les algorithmes déterministes.

from diffusers.utils.torch_utils import enable_full_determinism

enable_full_determinism()

enable_full_determinism fonctionne en :

  • Définir la variable d'environnement CUDA_LAUNCH_BLOCKING sur 1
  • Définir la variable d’environnement CUBLAS_WORKSPACE_CONFIG sur :16:8 afin que cuBLAS utilise une disposition de zone de travail fixe à l’exécution
  • Appeler torch.use_deterministic_algorithms(True)
  • Définir torch.backends.cudnn.deterministic = True
  • Définir torch.backends.cudnn.benchmark = False afin que cuDNN ne sélectionne pas un algorithme de convolution différent à chaque exécution
  • Désactiver TensorFloat32 (TF32) avec torch.backends.cuda.matmul.allow_tf32 = False au profit d'un matmul de pleine précision plus précis

Étapes suivantes

Vous devriez lire les notes de développement de PyTorch sur la Reproductibilité. Vous pouvez essayer de limiter l’aléatoire, mais ce n’est pas garanti, même avec une graine identique.

Update on GitHub