# UniPCMultistepScheduler

`UniPCMultistepScheduler` 是一个专为扩散模型快速采样而设计的免训练框架。它由 Wenliang Zhao、Lujia Bai、Yongming Rao、Jie Zhou 和 Jiwen Lu 在 [UniPC: A Unified Predictor-Corrector Framework for Fast Sampling of Diffusion Models](https://huggingface.co/papers/2302.04867) 中提出。

它由校正器（UniC）和预测器（UniP）组成，二者共享统一的解析形式并支持任意阶数。UniPC 在设计上是模型无关的，支持像素空间/潜空间 DPM 在无条件/条件采样中的应用。它同样适用于噪声预测模型和数据预测模型。校正器 UniC 也可以应用于任何现成的求解器之后，以提高精度阶数。

该论文的摘要如下：

*扩散概率模型（DPMs）在高分辨率图像合成方面展现了极具前景的能力。然而，由于需要对去噪网络进行多次评估，从预训练 DPM 中采样非常耗时，因此加速 DPM 的采样变得越来越重要。尽管在快速采样器设计方面取得了最新进展，但在许多偏好更少步数（例如 <10）的应用场景中，现有方法仍无法生成令人满意的图像。在本文中，我们开发了一种统一校正器（UniC），它可以应用于任何现有的 DPM 采样器之后，在不进行额外模型评估的情况下提高精度阶数，并作为副产品推导出了一个支持任意阶数的统一预测器（UniP）。结合 UniP 和 UniC，我们提出了一个用于 DPM 快速采样的统一预测器-校正器框架，称为 UniPC，它对任意阶数都具有统一的解析形式，并能显著地提高采样质量，尤其是在极少步数的情况下。我们通过大量实验评估了我们的方法，包括使用像素空间和潜在空间 DPM 的无条件采样和有条件采样。我们的 UniPC 仅需 10 次函数评估，即可在 CIFAR10（无条件）上实现 3.87 FID，在 ImageNet 256×256（有条件）上实现 7.51 FID。代码可在 [this https URL](https://github.com/wl-zhao/UniPC) 获取。*

## 提示

建议将 `solver_order` 设置为 2 用于引导采样，将 `solver_order=3` 用于无条件采样。

支持来自 [Imagen](https://huggingface.co/papers/2205.11487) 的动态阈值处理。对于像素空间扩散模型，您可以同时设置 `predict_x0=True` 和 `thresholding=True` 以使用动态阈值处理。此阈值处理方法不适用于 Stable Diffusion 等潜在空间扩散模型。

## UniPCMultistepScheduler[[diffusers.UniPCMultistepScheduler]]

#### diffusers.UniPCMultistepScheduler[[diffusers.UniPCMultistepScheduler]]

```python
diffusers.UniPCMultistepScheduler(num_train_timesteps: int = 1000, beta_start: float = 0.0001, beta_end: float = 0.02, beta_schedule: str = 'linear', trained_betas: numpy.ndarray | list[float] | None = None, solver_order: int = 2, prediction_type: typing.Literal['epsilon', 'sample', 'v_prediction', 'flow_prediction'] = 'epsilon', thresholding: bool = False, dynamic_thresholding_ratio: float = 0.995, sample_max_value: float = 1.0, predict_x0: bool = True, solver_type: typing.Literal['bh1', 'bh2'] = 'bh2', lower_order_final: bool = True, disable_corrector: list[int] = [], solver_p: SchedulerMixin = None, use_karras_sigmas: bool = False, use_exponential_sigmas: bool = False, use_beta_sigmas: bool = False, use_flow_sigmas: bool = False, flow_shift: float = 1.0, timestep_spacing: typing.Literal['linspace', 'leading', 'trailing'] = 'linspace', steps_offset: int = 0, final_sigmas_type: typing.Literal['zero', 'sigma_min'] = 'zero', rescale_betas_zero_snr: bool = False, use_dynamic_shifting: bool = False, time_shift_type: typing.Literal['exponential'] = 'exponential', sigma_min: float | None = None, sigma_max: bool | None = None, shift_terminal: bool | None = None)
```

[源代码](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/schedulers/scheduling_unipc_multistep.py#L123)

**参数：**

num_train_timesteps (`int`，默认为 1000)：用于训练模型的扩散步数。

beta_start (`float`，默认值为 0.0001)：推理的初始 `beta` 值。

beta_end (`float`，默认值为 0.02)：最终的 `beta` 值。

beta_schedule (`"linear"`、`"scaled_linear"` 或 `"squaredcos_cap_v2"`，默认为 `"linear"`)：beta 调度，即将 beta 范围映射为用于模型步进的一系列 beta 值。可选 `linear`、`scaled_linear` 或 `squaredcos_cap_v2`。

trained_betas (`np.ndarray`，*可选*)：将 beta 数组直接传递给构造函数，以绕过 `beta_start` 和 `beta_end`。

solver_order (`int`，默认为 `2`)：UniPC 的阶数，可以是任意正整数。由于 UniC 的存在，有效精度阶数为 `solver_order + 1`。建议在有引导采样时使用 `solver_order=2`，在无引导采样时使用 `solver_order=3`。

prediction_type (`"epsilon"`, `"sample"`, `"v_prediction"`, or `"flow_prediction"`, defaults to `"epsilon"`, *optional*) : Prediction type of the scheduler function; can be `epsilon` (predicts the noise of the diffusion process), `sample` (directly predicts the noisy sample`), `v_prediction` (see section 2.4 of [Imagen Video](https://huggingface.co/papers/2210.02303) paper), or `flow_prediction`.

thresholding (`bool`，默认为 `False`)：是否使用“动态阈值”方法。此方法不适用于 Stable Diffusion 等潜在空间扩散模型。

dynamic_thresholding_ratio (`float`，默认值为 0.995)：动态阈值化方法的比例。仅在 `thresholding=True` 时有效。

sample_max_value (`float`，默认值为 1.0)：动态阈值化的阈值。仅在 `thresholding=True` 且 `predict_x0=True` 时有效。

predict_x0 (`bool`，默认为 `True`)：是否对预测的 x0 使用更新算法。

solver_type (`"bh1"` 或 `"bh2"`，默认为 `"bh2"`)：UniPC 的求解器类型。建议当步数 < 10 时，无条件采样使用 `bh1`，其他情况使用 `bh2`。

lower_order_final (`bool`，默认值为 `True`) : 是否在最后几步中使用低阶求解器。仅适用于推理步数 < 15 的情况。这可以稳定 DPMSolver 在步数 < 15 时的采样，尤其是在步数 <= 10 时。

disable_corrector (`list`，默认值为 `[]`)：决定在哪些步骤禁用校正器，以缓解 `epsilon_theta(x_t, c)` 与 `epsilon_theta(x_t^c, c)` 之间的错位，这种错位可能会影响较大引导尺度下的收敛性。通常在前几步中会禁用校正器。

solver_p (`SchedulerMixin`，默认值为 `None`)：如果指定了其他调度器，算法将变为 `solver_p + UniC`。

use_karras_sigmas (`bool`，*可选*，默认为 `False`)：是否在采样过程的噪声调度中使用 Karras sigmas 作为步长。如果为 `True`，则 sigmas 将根据噪声水平序列 {σi} 确定。

use_exponential_sigmas (`bool`，*可选*，默认为 `False`)：在采样过程中，噪声调度是否使用指数 sigma 作为步长。

use_beta_sigmas (`bool`, *optional*, defaults to `False`) : Whether to use beta sigmas for step sizes in the noise schedule during the sampling process. Refer to [Beta Sampling is All You Need](https://huggingface.co/papers/2407.12173) for more information.

use_flow_sigmas (`bool`，*可选*，默认为 `False`)：是否在采样过程的噪声调度中使用 flow sigmas 作为步长。

timestep_spacing (`"linspace"`, `"leading"`, or `"trailing"`, defaults to `"linspace"`) : The way the timesteps should be scaled. Refer to Table 2 of the [Common Diffusion Noise Schedules and Sample Steps are Flawed](https://huggingface.co/papers/2305.08891) for more information.

steps_offset (`int`，默认为 0)：根据某些模型系列的要求，添加到推理步数中的偏移量。

final_sigmas_type (`"zero"` 或 `"sigma_min"`，默认为 `"zero"`)：采样过程中噪声调度的最终 `sigma` 值。如果为 `"sigma_min"`，则最终 sigma 与训练调度中的最后一个 sigma 相同。如果为 `zero`，则最终 sigma 设为 0。

rescale_betas_zero_snr (`bool`，默认为 `False`)：是否将 betas 重新缩放，使其具有零终端 SNR。这使模型能够生成非常明亮和非常暗的样本，而不是将其限制在中等亮度的样本上。与 [`--offset_noise`](https://github.com/huggingface/diffusers/blob/74fd735eb073eb1d774b1ab4154a0876eb82f055/examples/dreambooth/train_dreambooth.py#L506) 大致相关。

`UniPCMultistepScheduler` 是一个无需训练的框架，专为扩散模型的高效采样而设计。

该模型继承自 [SchedulerMixin](/docs/diffusers/v0.43.0/zh/api/schedulers/overview#diffusers.SchedulerMixin) 和 [ConfigMixin](/docs/diffusers/v0.43.0/zh/api/configuration#diffusers.ConfigMixin)。有关该库为所有调度器实现的通用方法（例如加载和保存），请参阅父类文档。

#### add_noise[[diffusers.UniPCMultistepScheduler.add_noise]]

```python
add_noise(original_samples: Tensor, noise: Tensor, timesteps: IntTensor)
```

[源代码](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/schedulers/scheduling_unipc_multistep.py#L1250)

**参数：**

original_samples (`torch.Tensor`) : 未添加噪声的原始样本。

noise (`torch.Tensor`) : 要添加到样本中的噪声。

timesteps (`torch.IntTensor`) : 向样本添加噪声的时间步。

**返回：** `torch.Tensor`

带噪声的样本。

根据指定时间步的噪声调度，向原始样本添加噪声。

#### convert_model_output[[diffusers.UniPCMultistepScheduler.convert_model_output]]

```python
convert_model_output(model_output: Tensor, *args, sample: Tensor = None, **kwargs)
```

[源代码](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/schedulers/scheduling_unipc_multistep.py#L760)

**参数：**

model_output (`torch.Tensor`)：学习到的扩散模型的直接输出。

timestep (`int`)：扩散链中当前的离散时间步。

sample (`torch.Tensor`)：扩散过程生成的当前样本实例。

**返回：** `torch.Tensor`

转换后的模型输出。

将模型输出转换为 UniPC 算法所需的对应类型。

#### index_for_timestep[[diffusers.UniPCMultistepScheduler.index_for_timestep]]

```python
index_for_timestep(timestep: typing.Union[int, torch.Tensor], schedule_timesteps: typing.Optional[torch.Tensor] = None)
```

[源代码](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/schedulers/scheduling_unipc_multistep.py#L1100)

**参数：**

timestep (`int` 或 `torch.Tensor`)：用于查找索引的时间步。

schedule_timesteps (`torch.Tensor`, *可选*) : 要搜索的时间步调度。如果为 `None`，则使用 `self.timesteps`。

**返回值：** `int`

时间步在调度器中的索引。

查找给定时间步在调度器中的索引。

#### multistep_uni_c_bh_update[[diffusers.UniPCMultistepScheduler.multistep_uni_c_bh_update]]

```python
multistep_uni_c_bh_update(this_model_output: Tensor, *args, last_sample: Tensor = None, this_sample: Tensor = None, order: int = None, **kwargs)
```

[源代码](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/schedulers/scheduling_unipc_multistep.py#L962)

**参数：**

this_model_output (`torch.Tensor`) : 模型在 `x_t` 处的输出。

this_timestep (`int`) : 当前时间步 `t`。

last_sample (`torch.Tensor`) : 最后一个预测器之前的生成样本 `x_{t-1}`。

this_sample (`torch.Tensor`) : 最后一个预测器 `x_{t}` 之后生成的样本。

order (`int`) : 此步骤中 UniC-p 的 `p`。有效精度阶数应为 `order + 1`。

**返回：** `torch.Tensor`

当前时间步的修正后样本张量。

UniC (B(h) 版本) 的一步。

#### multistep_uni_p_bh_update[[diffusers.UniPCMultistepScheduler.multistep_uni_p_bh_update]]

```python
multistep_uni_p_bh_update(model_output: Tensor, *args, sample: Tensor = None, order: int = None, **kwargs)
```

[源代码](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/schedulers/scheduling_unipc_multistep.py#L833)

**参数：**

model_output (`torch.Tensor`) : 学习到的扩散模型在当前时间步的直接输出。

prev_timestep (`int`) : 扩散链中的上一个离散时间步。

sample (`torch.Tensor`)：扩散过程生成的当前样本实例。

order (`int`) : 当前时间步的 UniP 阶数（对应于 UniPC-p 中的 *p*）。

**返回：** `torch.Tensor`

上一步时间步的样本张量。

UniP（B(h) 版本）的单步。或者，如果指定了，则使用 `self.solver_p`。

#### scale_model_input[[diffusers.UniPCMultistepScheduler.scale_model_input]]

```python
scale_model_input(sample: Tensor, *args, **kwargs)
```

[源代码](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/schedulers/scheduling_unipc_multistep.py#L1234)

**参数：**

sample (`torch.Tensor`)：输入样本。

**返回：** `torch.Tensor`

经过缩放的输入样本。

确保与那些需要根据当前时间步对去噪模型输入进行缩放的调度器保持可互换性。

#### set_begin_index[[diffusers.UniPCMultistepScheduler.set_begin_index]]

```python
set_begin_index(begin_index: int = 0)
```

[源代码](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/schedulers/scheduling_unipc_multistep.py#L308)

**参数：**

begin_index (`int`，默认为 `0`)：调度器的起始索引。

设置调度器的起始索引。此函数应在推理之前从流水线中运行。

#### set_timesteps[[diffusers.UniPCMultistepScheduler.set_timesteps]]

```python
set_timesteps(num_inference_steps: int | None = None, device: typing.Union[str, torch.device] = None, sigmas: list[float] | None = None, mu: bool | None = None)
```

[源代码](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/schedulers/scheduling_unipc_multistep.py#L318)

**参数：**

num_inference_steps (`int`) : 使用预训练模型生成样本时所用的扩散步数。

device (`str` 或 `torch.device`，*可选*)：时间步应移动到的设备。如果为 `None`，则不移动时间步。

sigmas (`List[float]`, *可选*) : 用于每个扩散步骤的自定义 sigma 值。如果为 `None`，则自动计算 sigma。

mu (`float`, *可选*) : 使用指数时间偏移类型时，用于动态偏移的可选 mu 参数。

设置扩散链所使用的离散时间步（需在推理之前运行）。

#### 步骤[[diffusers.UniPCMultistepScheduler.step]]

```python
step(model_output: Tensor, timestep: typing.Union[int, torch.Tensor], sample: Tensor, return_dict: bool = True)
```

[源代码](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/schedulers/scheduling_unipc_multistep.py#L1153)

**参数：**

model_output (`torch.Tensor`)：学习到的扩散模型的直接输出。

timestep (`int` 或 `torch.Tensor`)：扩散链中当前的离散时间步。

sample (`torch.Tensor`)：扩散过程生成的当前样本实例。

return_dict (`bool`，默认为 `True`)：是否返回 [SchedulerOutput](/docs/diffusers/v0.43.0/zh/api/schedulers/ipndm#diffusers.schedulers.scheduling_utils.SchedulerOutput) 或 `tuple`。

**返回：** [SchedulerOutput](/docs/diffusers/v0.43.0/zh/api/schedulers/ipndm#diffusers.schedulers.scheduling_utils.SchedulerOutput) 或 `tuple`

If return_dict is `True`, [SchedulerOutput](/docs/diffusers/v0.43.0/zh/api/schedulers/ipndm#diffusers.schedulers.scheduling_utils.SchedulerOutput) is returned, otherwise a tuple is returned where the first element is the sample tensor.

通过反转 SDE 来预测上一步时间步的样本。此函数使用多步 UniPC 传播样本。

#### stretch_shift_to_terminal[[diffusers.UniPCMultistepScheduler.stretch_shift_to_terminal]]

```python
stretch_shift_to_terminal(t: Tensor)
```

[源代码](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/schedulers/scheduling_unipc_multistep.py#L506)

**参数：**

t (`torch.Tensor`) : 一个待拉伸和偏移的时间步张量。

**返回：** `torch.Tensor`

一个经过调整的 timesteps 张量，其最终值等于 `self.config.shift_terminal`。

拉伸并平移时间步调度，以确保其在配置的 `shift_terminal` 配置值处终止。

参考：https://github.com/Lightricks/LTX-Video/blob/a01a171f8fe3d99dce2728d60a73fecf4d4238ae/ltx_video/schedulers/rf.py#L51

#### time_shift[[diffusers.UniPCMultistepScheduler.time_shift]]

```python
time_shift(mu: float, sigma: float, t: Tensor)
```

[源代码](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/schedulers/scheduling_unipc_multistep.py#L484)

**参数：**

mu (`float`) : 时间偏移的 mu 参数。

sigma (`float`) : 时间偏移的 sigma 参数。

t (`torch.Tensor`) : 输入的时间步。

**返回：** `torch.Tensor`

时间偏移的时间步。

对 sigmas 应用时间偏移。

## SchedulerOutput[[diffusers.schedulers.scheduling_utils.SchedulerOutput]]

#### diffusers.schedulers.scheduling_utils.SchedulerOutput[[diffusers.schedulers.scheduling_utils.SchedulerOutput]]

```python
diffusers.schedulers.scheduling_utils.SchedulerOutput(prev_sample: Tensor)
```

[源代码](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/schedulers/scheduling_utils.py#L66)

**参数：**

prev_sample （对于图像，形状为 `(batch_size, num_channels, height, width)` 的 `torch.Tensor`）：计算得到的前一时间步的样本 `(x_{t-1})`。在去噪循环中，应将 `prev_sample` 用作下一个模型输入。

调度器 `step` 函数输出的基类。

