Diffusers documentation
Planificateurs
Planificateurs
Un planificateur indique à la boucle de débruitage la quantité de bruit à éliminer à chaque étape. Les différents planificateurs offrent un compromis entre la vitesse et la qualité.
Ce guide montre comment charger un planificateur et personnaliser son calendrier de pas de temps, son espacement et ses sigmas.
Choisir un planificateur
Commencez à partir du point de contrôle par défaut. N’effectuez un remplacement que si vous avez besoin d’un compromis différent entre vitesse et qualité.
- DPM++ 2M SDE Karras est une option polyvalente et performante pour de nombreux points de contrôle de diffusion latente.
- TCDScheduler fonctionne bien pour les modèles distillés.
- Utilisez FlowMatchEulerDiscreteScheduler ou FlowMatchHeunDiscreteScheduler pour les modèles FlowMatch (Qwen-Image, Flux et similaires).
- EulerDiscreteScheduler ou EulerAncestralDiscreteScheduler fonctionnent souvent bien pour les images de style anime.
- LCMScheduler avec un UNet LCM ou un LoRA pour une génération en peu d'étapes lorsque le checkpoint le prend en charge.
Chargement des planificateurs
Les modèles de flow-matching tels que Qwen-Image et Flux livrent FlowMatchEulerDiscreteScheduler par défaut. Conservez ce planificateur à moins d’expérimenter délibérément. Remplacez-le via from_config() uniquement si le substitut est compatible avec le point de contrôle.
Les planificateurs ne contiennent que des configurations et ne fournissent pas de tenseurs de poids. Accédez à l'attribut .scheduler d'un pipeline pour inspecter la configuration chargée.
import torch
from diffusers import DiffusionPipeline
pipeline = DiffusionPipeline.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0", dtype=torch.float16, device_map="cuda" # or "mps", "xpu", "cpu"
)
pipeline.schedulerPour remplacer les planificateurs d'un pipeline chargé, utilisez from_config() avec la configuration du planificateur existant afin que num_train_timesteps et les champs associés restent alignés. Pour les points de contrôle FlowMatch (Qwen-Image, Flux et similaires), conservez FlowMatchEulerDiscreteScheduler à moins d'expérimenter délibérément avec un remplacement compatible.
from diffusers import DPMSolverMultistepScheduler
pipeline.scheduler = DPMSolverMultistepScheduler.from_config(pipeline.scheduler.config)Vous pouvez également charger une configuration de planificateur depuis le Hub avec from_pretrained() et la transmettre à from_pretrained() via scheduler.
from diffusers import DiffusionPipeline, DPMSolverMultistepScheduler
dpm = DPMSolverMultistepScheduler.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0", subfolder="scheduler"
)
pipeline = DiffusionPipeline.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
scheduler=dpm,
dtype=torch.float16,
device_map="cuda", # or "mps", "xpu", "cpu"
)
pipeline.schedulerPlans de pas de temps
Le timestep ou le plan de bruit détermine la manière dont le bruit est réparti au cours du processus de débruitage. Le plan peut être linéaire ou plus concentré vers le début ou la fin. Il s’agit d’une séquence précalculée de niveaux de bruit générée à partir de la configuration par défaut du scheduler, mais elle peut être personnalisée pour utiliser d’autres plans.
linear (even steps) AYS (denser where it matters) noise noise ^ ^ | * | * | * | * | * | ** | * | *** | * | ** | * | * | * | * +-----------------> step +-----------------> step
Les
timestepspersonnalisés ne fonctionnent que si la méthodeset_timestepsde ce planificateur accepte cet argument (les pipelines vérifient la signature viaretrieve_timestepset lèvent uneValueErrordans le cas contraire). Consultez la page API du planificateur ou la signature deset_timestepsavant de les transmettre.
L'exemple ci-dessous utilise le planning Align Your Steps (AYS), qui peut générer une image de haute qualité en 10 étapes, accélérant considérablement la génération et réduisant le temps de calcul.
Importez le planning et passez-le à l'argument timesteps dans le pipeline.
import torch
from diffusers import DiffusionPipeline, DPMSolverMultistepScheduler
from diffusers.schedulers import AysSchedules
sampling_schedule = AysSchedules["StableDiffusionXLTimesteps"]
print(sampling_schedule)
# [999, 845, 730, 587, 443, 310, 193, 116, 53, 13]
pipeline = DiffusionPipeline.from_pretrained(
"SG161222/RealVisXL_V4.0",
dtype=torch.float16,
device_map="cuda" # or "mps", "xpu", "cpu"
)
pipeline.scheduler = DPMSolverMultistepScheduler.from_config(
pipeline.scheduler.config, algorithm_type="sde-dpmsolver++"
)
prompt = "A cinematic shot of a cute little rabbit wearing a jacket and doing a thumbs up"
image = pipeline(
prompt=prompt,
negative_prompt="",
timesteps=sampling_schedule,
).images[0]
Pour le rééchelonnement v-prediction/zero-SNR sur les anciens points de contrôle, voir Points de contrôle legacy.
Espacement des pas de temps
L'espacement des timesteps désigne les étapes spécifiques t à échantillonner à partir du planning. Diffusers propose trois types d'espacement, présentés ci-dessous.
| stratégie d'espacement | calcul de l'espacement | étapes de temps d'exemple |
|---|---|---|
leading | étapes régulièrement espacées | [900, 800, 700, ..., 100, 0] |
linspace | inclure les étapes première et dernière et répartir uniformément les étapes intermédiaires restantes | [1000, 888.89, 777.78, ..., 111.11, 0] |
trailing | inclure la dernière étape et répartir uniformément les étapes intermédiaires restantes en partant de la fin | [999, 899, 799, 699, 599, 499, 399, 299, 199, 99] |
Transmettez la stratégie d'espacement à l'argument timestep_spacing dans le planificateur.
La stratégie
trailingproduit généralement des images de meilleure qualité, avec plus de détails, en moins d'étapes, mais la différence de qualité n'est pas aussi évidente pour des valeurs d'étapes plus standard.
import torch
from diffusers import DiffusionPipeline, DPMSolverMultistepScheduler
pipeline = DiffusionPipeline.from_pretrained(
"SG161222/RealVisXL_V4.0",
dtype=torch.float16,
device_map="cuda" # or "mps", "xpu", "cpu"
)
pipeline.scheduler = DPMSolverMultistepScheduler.from_config(
pipeline.scheduler.config, timestep_spacing="trailing"
)
prompt = "A cinematic shot of a cute little black cat sitting on a pumpkin at night"
image = pipeline(
prompt=prompt,
negative_prompt="",
num_inference_steps=5,
).images[0]
image
Sigmas
Sigmas est une mesure du niveau de bruit d'un échantillon à une étape donnée, telle que définie par le planning. Lors de l'utilisation de sigmas personnalisés, les timesteps sont calculés à partir de ces valeurs au lieu de la configuration par défaut du planificateur.
step: 0 1 2 3 4
sigma: σ0 > σ1 > σ2 > σ3 > σ4 ≈ 0
high noise ---> clean sampleLes
sigmaspersonnalisés ne fonctionnent que si la méthodeset_timestepsde ce planificateur accepte cet argument (les pipelines vérifient la signature viaretrieve_timestepset lèvent uneValueErrordans le cas contraire). Consultez la page API du planificateur ou la signature deset_timestepsavant de les transmettre.
Passez les sigmas personnalisés à l'argument sigmas du pipeline. L'exemple ci-dessous utilise les sigmas de l'agenda AYS en 10 étapes.
import torch
from diffusers import DiffusionPipeline, EulerDiscreteScheduler
from diffusers.schedulers import AysSchedules
pipeline = DiffusionPipeline.from_pretrained(
"SG161222/RealVisXL_V4.0",
dtype=torch.float16,
device_map="cuda", # or "mps", "xpu", "cpu"
)
pipeline.scheduler = EulerDiscreteScheduler.from_config(pipeline.scheduler.config)
sigmas = AysSchedules["StableDiffusionXLSigmas"]
prompt = "A cinematic shot of a cute little rabbit wearing a jacket and doing a thumbs up"
image = pipeline(
prompt=prompt,
negative_prompt="",
sigmas=sigmas,
).images[0]Sigmas de Karras
Karras sigmas rééchantillonne le plan de bruit pour un échantillonnage plus efficace en regroupant les sigmas plus densément au milieu de la séquence, là où la reconstruction de la structure est cruciale, tout en utilisant moins de sigmas au début et à la fin, où les variations de bruit ont moins d’impact. Cela peut augmenter le niveau de détails d’une image générée.
default σ: * * * * * * * * even-ish
Karras σ: * * * * * * * denser mid, sparser ends
|---structure---|Définissez use_karras_sigmas=True dans le planificateur pour l'activer.
import torch
from diffusers import DiffusionPipeline, DPMSolverMultistepScheduler
pipeline = DiffusionPipeline.from_pretrained(
"SG161222/RealVisXL_V4.0",
dtype=torch.float16,
device_map="cuda" # or "mps", "xpu", "cpu"
)
pipeline.scheduler = DPMSolverMultistepScheduler.from_config(
pipeline.scheduler.config,
algorithm_type="sde-dpmsolver++",
use_karras_sigmas=True,
)
prompt = "A cinematic shot of a cute little rabbit wearing a jacket and doing a thumbs up"
image = pipeline(
prompt=prompt,
negative_prompt="",
num_inference_steps=20,
).images[0]
Reportez-vous à l’aperçu de l’API du planificateur pour obtenir la liste des planificateurs prenant en charge les sigmas de Karras. Il ne doit être utilisé que pour les modèles entraînés avec des sigmas de Karras.
Étapes suivantes
- Lisez l'article Common Diffusion Noise Schedules and Sample Steps are Flawed pour plus de détails sur le rééchelonnement du bruit pour imposer un SNR nul.