Diffusers documentation
Reproductibilité
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
GeneratorCPU. La perte de performance est souvent négligeable et vous générerez des valeurs plus similaires.
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]Créez un Generator CPU et définissez une graine avec 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]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_BLOCKINGsur1 - Définir la variable d’environnement CUBLAS_WORKSPACE_CONFIG sur
:16:8afin 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 = Falseafin 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 = Falseau 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