Buckets:

mishig's picture
|
download
raw
10.6 kB
# 调度器
调度器(scheduler)告诉去噪循环在每个步骤中应去除多少噪声。不同的调度器在速度与质量之间进行权衡。
本指南介绍如何加载调度器,并自定义其时间步调度、间隔和 sigmas。
## 选择调度器
从默认检查点开始。只有在需要不同的速度或质量权衡时,才进行替换。
- DPM++ 2M SDE Karras 是许多潜在扩散检查点的强大通用选项。
- [TCDScheduler](/docs/diffusers/v0.43.0/zh/api/schedulers/tcd#diffusers.TCDScheduler) 适用于蒸馏模型。
- 对于 FlowMatch 模型(如 Qwen-Image、Flux 及类似模型),请使用 [FlowMatchEulerDiscreteScheduler](/docs/diffusers/v0.43.0/zh/api/schedulers/flow_match_euler_discrete#diffusers.FlowMatchEulerDiscreteScheduler) 或 [FlowMatchHeunDiscreteScheduler](/docs/diffusers/v0.43.0/zh/api/schedulers/flow_match_heun_discrete#diffusers.FlowMatchHeunDiscreteScheduler)。
- [EulerDiscreteScheduler](/docs/diffusers/v0.43.0/zh/api/schedulers/euler#diffusers.EulerDiscreteScheduler) 或 [EulerAncestralDiscreteScheduler](/docs/diffusers/v0.43.0/zh/api/schedulers/euler_ancestral#diffusers.EulerAncestralDiscreteScheduler) 通常适用于动漫风格的图像。
- 如果检查点支持,使用 [LCMScheduler](/docs/diffusers/v0.43.0/zh/api/schedulers/lcm#diffusers.LCMScheduler) 搭配 LCM UNet 或 LoRA 进行少步生成。
## 加载调度器
> [!TIP]
> 像 Qwen-Image 和 Flux 这样的 Flow-matching 模型默认使用 [FlowMatchEulerDiscreteScheduler](/docs/diffusers/v0.43.0/zh/api/schedulers/flow_match_euler_discrete#diffusers.FlowMatchEulerDiscreteScheduler)。除非您有意进行实验,否则请保留该调度器。仅当替换项与检查点兼容时,才使用 [from_config()](/docs/diffusers/v0.43.0/zh/api/configuration#diffusers.ConfigMixin.from_config) 进行替换。
调度器仅包含配置,不包含权重张量。可以通过访问 pipeline 的 `.scheduler` 属性来查看已加载的配置。
```py
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.scheduler
```
要在已加载的 pipeline 中更换调度器,请使用 [from_config()](/docs/diffusers/v0.43.0/zh/api/configuration#diffusers.ConfigMixin.from_config) 并传入现有的调度器配置,以确保 `num_train_timesteps` 及相关字段保持一致。对于 FlowMatch 检查点(Qwen-Image、Flux 及类似模型),除非您有意尝试使用兼容的替代方案,否则请保留 [FlowMatchEulerDiscreteScheduler](/docs/diffusers/v0.43.0/zh/api/schedulers/flow_match_euler_discrete#diffusers.FlowMatchEulerDiscreteScheduler)。
```py
from diffusers import DPMSolverMultistepScheduler
pipeline.scheduler = DPMSolverMultistepScheduler.from_config(pipeline.scheduler.config)
```
您还可以通过 [from_pretrained()](/docs/diffusers/v0.43.0/zh/api/schedulers/overview#diffusers.SchedulerMixin.from_pretrained) 从 Hub 加载调度器配置,并通过 `scheduler` 将其传入 [from_pretrained()](/docs/diffusers/v0.43.0/zh/api/pipelines/overview#diffusers.DiffusionPipeline.from_pretrained)。
```py
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.scheduler
```
## 时间步调度
时间步或噪声调度决定了噪声在去噪过程中的分布方式。该调度可以是线性的,也可以更集中于过程的开始或结束阶段。它是由调度器的默认配置生成的预计算噪声水平序列,但也可以进行自定义以使用其他调度方案。
```text
linear (even steps) AYS (denser where it matters)
noise noise
^ ^
| * | *
| * | *
| * | **
| * | ***
| * | **
| * | *
| * | *
+-----------------> step +-----------------> step
```
> [!TIP]
> 自定义的 `timesteps` 仅在该调度器的 `set_timesteps` 接受此参数时有效(流水线会通过 `retrieve_timesteps` 检查函数签名,否则将抛出 `ValueError`)。在传入之前,请查阅该调度器的 API 页面或 `set_timesteps` 的函数签名。
以下示例使用 [Align Your Steps (AYS)](https://research.nvidia.com/labs/toronto-ai/AlignYourSteps/) 调度器,该调度器可在 10 步内生成高质量图像,从而显著加快生成速度并减少计算时间。
导入该 schedule,并将其传递给 pipeline 中的 `timesteps` 参数。
```py
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]
```
AYS 时间步调度 10 步
线性间隔的时间步调度 10 步
线性间隔的时间步调度 25 步
对于旧检查点的 v-prediction/zero-SNR 重缩放,请参阅 [Legacy checkpoints](./legacy_checkpoints#rescaling-schedules)。
## 时间步间隔
时间步间距指的是从调度方案中采样的特定步骤 *t*。Diffusers 提供了以下三种间距类型。
| 间距策略 | 间距计算 | 示例时间步 |
|---|---|---|
| `leading` | 均匀间隔的步骤 | `[900, 800, 700, ..., 100, 0]` |
| `linspace` | 包含首尾步骤,并均匀划分其余中间步骤 | `[1000, 888.89, 777.78, ..., 111.11, 0]` |
| `trailing` | 包含最后一步,并从末尾开始均匀分配剩余的中间步骤 | `[999, 899, 799, 699, 599, 499, 399, 299, 199, 99]` |
将间距策略传递给调度器中的 `timestep_spacing` 参数。
> [!TIP]
> `trailing` 策略通常能在更少的步数下生成质量更高、细节更丰富的图像,但对于更标准的步数值,质量差异并不明显。
```py
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
```
5 步后的尾部间距
5 步后的前导间距
## Sigmas
Sigmas 是衡量在调度器定义的某个步骤中样本噪声程度的指标。当使用自定义的 `sigmas` 时,`timesteps` 将根据这些值进行计算,而不是使用默认的调度器配置。
```text
step: 0 1 2 3 4
sigma: σ0 > σ1 > σ2 > σ3 > σ4 ≈ 0
high noise ---> clean sample
```
> [!TIP]
> 自定义的 `sigmas` 仅在该调度器的 `set_timesteps` 接受此参数时才有效(流水线会通过 `retrieve_timesteps` 检查函数签名,否则将抛出 `ValueError`)。在传入之前,请查阅该调度器的 API 页面或 `set_timesteps` 的函数签名。
将自定义 sigmas 传入 pipeline 中的 `sigmas` 参数。下面的示例使用了 10 步 AYS 调度中的 [sigmas](https://github.com/huggingface/diffusers/blob/main/src/diffusers/schedulers/scheduling_utils.py)。
```py
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]
```
### Karras sigmas
[Karras sigmas](https://huggingface.co/papers/2206.00364) 通过重新采样噪声调度来实现更高效的采样:它在序列中部(结构重建至关重要的区域)将 sigmas 分布得更密集,而在噪声变化影响较小的开头和结尾使用更少的 sigmas。这可以提高生成图像的精细程度。
```text
default σ: * * * * * * * * even-ish
Karras σ: * * * * * * * denser mid, sparser ends
|---structure---|
```
在调度器中设置 `use_karras_sigmas=True` 即可启用该功能。
```py
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]
```
已启用 Karras sigmas
Karras sigmas 已禁用
有关支持 Karras sigmas 的调度器列表,请参阅调度器 API [概览](../api/schedulers/overview)。它仅应用于使用 Karras sigmas 训练的模型。
## 后续步骤
- Read the [Common Diffusion Noise Schedules and Sample Steps are Flawed](https://huggingface.co/papers/2305.08891) paper for more details about rescaling the noise schedule to enforce zero SNR.

Xet Storage Details

Size:
10.6 kB
·
Xet hash:
6aab6513d511d500255ef1423d6cf89907ab668b602d2e16171f1334761d5a95

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.