调度器功能
调度器是任何扩散模型的重要组成部分,因为它控制着整个去噪(或采样)过程。调度器有很多类型,有些针对速度优化,有些针对质量优化。使用 Diffusers,你可以修改调度器配置以使用自定义噪声调度、sigma 和重新缩放噪声调度。更改这些参数会对推理质量和速度产生深远的影响。
本指南将演示如何使用这些功能来提高推理质量。
TIP
Diffusers 目前仅支持 timesteps
和 sigmas
参数,适用于选定的调度器和管道列表。如果你想将这些参数扩展到当前不支持它们的调度器和管道,请随时打开一个 功能请求!
时间步长调度
时间步长或噪声调度决定了每个采样步骤的噪声量。调度器使用它来生成在每个步骤具有相应噪声量的图像。时间步长调度是从调度器的默认配置生成的,但你可以自定义调度器以使用尚未在 Diffusers 中的新的优化采样调度。
例如,Align Your Steps (AYS) 是一种优化采样调度以在少至 10 步内生成高质量图像的方法。Stable Diffusion XL 的最佳 10 步调度 为:
from diffusers.schedulers import AysSchedules
sampling_schedule = AysSchedules["StableDiffusionXLTimesteps"]
print(sampling_schedule)
"[999, 845, 730, 587, 443, 310, 193, 116, 53, 13]"
时间步间隔
在调度中选择采样步骤的方式会影响生成图像的质量,尤其是在重新缩放噪声调度方面,这可以使模型生成更亮或更暗的图像。Diffusers 提供三种时间步间隔方法:
leading
创建均匀间隔的步骤linspace
包含第一个和最后一个步骤,并均匀地选择剩余的中间步骤trailing
只包含最后一个步骤,并从末尾开始均匀地选择剩余的中间步骤
建议使用 trailing
间隔方法,因为它在采样步骤较少时会生成更高质量的图像,并包含更多细节。但对于更标准的采样步骤值,质量差异并不明显。
pipeline = StableDiffusionXLPipeline.from_pretrained(
"SG161222/RealVisXL_V4.0",
torch_dtype=torch.float16,
variant="fp16",
).to("cuda")
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"
generator = torch.Generator(device="cpu").manual_seed(2487854446)
image = pipeline(
prompt=prompt,
negative_prompt="",
generator=generator,
timesteps=sampling_schedule,
).images[0]



import torch
from diffusers import StableDiffusionXLPipeline, DPMSolverMultistepScheduler
pipeline = StableDiffusionXLPipeline.from_pretrained(
"SG161222/RealVisXL_V4.0",
torch_dtype=torch.float16,
variant="fp16",
).to("cuda")
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"
generator = torch.Generator(device="cpu").manual_seed(2487854446)
image = pipeline(
prompt=prompt,
negative_prompt="",
generator=generator,
num_inference_steps=5,
).images[0]
image


西格玛
sigmas
参数是在每个时间步根据时间步调度添加的噪声量。与 timesteps
参数类似,你可以自定义 sigmas
参数来控制在每个步骤中添加多少噪声。当你使用自定义 sigmas
值时,timesteps
将根据自定义 sigmas
值计算,默认调度程序配置将被忽略。
例如,你可以手动将 sigmas 传递给管道,例如之前提到的 10 步 AYS 调度。
import torch
from diffusers import DiffusionPipeline, EulerDiscreteScheduler
model_id = "stabilityai/stable-diffusion-xl-base-1.0"
pipeline = DiffusionPipeline.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
torch_dtype=torch.float16,
variant="fp16",
).to("cuda")
pipeline.scheduler = EulerDiscreteScheduler.from_config(pipeline.scheduler.config)
sigmas = [14.615, 6.315, 3.771, 2.181, 1.342, 0.862, 0.555, 0.380, 0.234, 0.113, 0.0]
prompt = "anthropomorphic capybara wearing a suit and working with a computer"
generator = torch.Generator(device='cuda').manual_seed(123)
image = pipeline(
prompt=prompt,
num_inference_steps=10,
sigmas=sigmas,
generator=generator
).images[0]
当你查看调度程序的 timesteps
参数时,你会发现它与 AYS 时间步调度相同,因为 timestep
调度是根据 sigmas
计算的。
print(f" timesteps: {pipe.scheduler.timesteps}")
"timesteps: tensor([999., 845., 730., 587., 443., 310., 193., 116., 53., 13.], device='cuda:0')"
Karras 标准差
TIP
请参考调度器 API 概述 以获取支持 Karras 标准差的调度器列表。
Karras 标准差不应用于未用其训练的模型。例如,基础 Stable Diffusion XL 模型不应使用 Karras 标准差,但 DreamShaperXL 模型可以使用,因为它们是用 Karras 标准差训练的。
Karras 调度器使用 阐明基于扩散的生成模型的设计空间 论文中的时间步长计划和标准差。与其他调度器相比,这种调度器变体在采样过程结束时每步应用的噪声更少,可以提高生成图像的细节水平。
通过在调度器中设置 use_karras_sigmas=True
来启用 Karras 标准差。
import torch
from diffusers import StableDiffusionXLPipeline, DPMSolverMultistepScheduler
pipeline = StableDiffusionXLPipeline.from_pretrained(
"SG161222/RealVisXL_V4.0",
torch_dtype=torch.float16,
variant="fp16",
).to("cuda")
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"
generator = torch.Generator(device="cpu").manual_seed(2487854446)
image = pipeline(
prompt=prompt,
negative_prompt="",
generator=generator,
).images[0]


重塑噪声调度
在 Common Diffusion Noise Schedules and Sample Steps are Flawed 这篇论文中,作者发现常见的噪声调度允许一些信号泄漏到最后一个时间步。这种推理时的信号泄漏会导致模型只生成中等亮度的图像。通过对时间步调度强制执行零信噪比 (SNR) 并从最后一个时间步采样,可以改进模型以生成非常明亮或黑暗的图像。
TIP
对于推理,你需要一个使用 v_prediction 训练的模型。要使用 v_prediction 训练你自己的模型,请在 train_text_to_image.py 或 train_text_to_image_lora.py 脚本中添加以下标志。
> --prediction_type="v_prediction"
> ```
例如,加载 [ptx0/pseudo-journey-v2](https://hf.co/ptx0/pseudo-journey-v2) 检查点,该检查点使用 `v_prediction` 和 [`DDIMScheduler`] 进行训练。在 [`DDIMScheduler`] 中配置以下参数:
* `rescale_betas_zero_snr=True` 将噪声调度重新缩放到零 SNR
* `timestep_spacing="trailing"` 从最后一个时间步开始采样
在管道中设置 `guidance_rescale` 以防止过度曝光。较低的值会增加亮度,但某些细节可能会显得褪色。
```py
from diffusers import DiffusionPipeline, DDIMScheduler
pipeline = DiffusionPipeline.from_pretrained("ptx0/pseudo-journey-v2", use_safetensors=True)
pipeline.scheduler = DDIMScheduler.from_config(
pipeline.scheduler.config, rescale_betas_zero_snr=True, timestep_spacing="trailing"
)
pipeline.to("cuda")
prompt = "cinematic photo of a snowy mountain at night with the northern lights aurora borealis overhead, 35mm photograph, film, professional, 4k, highly detailed"
generator = torch.Generator(device="cpu").manual_seed(23)
image = pipeline(prompt, guidance_rescale=0.7, generator=generator).images[0]
image

