# VQDiffusionScheduler

`VQDiffusionScheduler` 将 transformer 模型的输出转换为上一个扩散时间步的无噪图像样本。它由 Shuyang Gu、Dong Chen、Jianmin Bao、Fang Wen、Bo Zhang、Dongdong Chen、Lu Yuan 和 Baining Guo 在 [Vector Quantized Diffusion Model for Text-to-Image Synthesis](https://huggingface.co/papers/2111.14822) 中提出。

该论文的摘要如下：

*我们提出了用于文本到图像生成的向量量化扩散（VQ-Diffusion）模型。该方法基于向量量化变分自编码器（VQ-VAE），其潜在空间由近期开发的去噪扩散概率模型（DDPM）的条件变体进行建模。我们发现，这种潜在空间方法非常适合文本到图像生成任务，因为它不仅消除了现有方法中的单向偏差，还允许我们引入掩码与替换扩散策略来避免误差累积，而误差累积是现有方法的一个严重问题。实验表明，与具有相似参数量的传统自回归（AR）模型相比，VQ-Diffusion 能产生显著更好的文本到图像生成结果。与之前的基于 GAN 的文本到图像方法相比，我们的 VQ-Diffusion 能够处理更复杂的场景，并大幅提升合成图像的质量。最后，我们表明，通过重参数化，我们方法中的图像生成计算可以变得非常高效。使用传统的 AR 方法，文本到图像生成的时间会随着输出图像分辨率的增加而线性增长，因此即使是普通尺寸的图像也会非常耗时。VQ-Diffusion 使我们能够在质量和速度之间实现更好的权衡。我们的实验表明，采用重参数化的 VQ-Diffusion 模型比传统 AR 方法快十五倍，同时实现了更好的图像质量。*

## VQDiffusionScheduler[[diffusers.VQDiffusionScheduler]]

#### diffusers.VQDiffusionScheduler[[diffusers.VQDiffusionScheduler]]

```python
diffusers.VQDiffusionScheduler(num_vec_classes: int, num_train_timesteps: int = 100, alpha_cum_start: float = 0.99999, alpha_cum_end: float = 9e-06, gamma_cum_start: float = 9e-06, gamma_cum_end: float = 0.99999)
```

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

**参数：**

num_vec_classes (`int`) : 潜在像素向量嵌入的类别数。包括被掩码的潜在像素的类别。

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

alpha_cum_start (`float`，默认值为 `0.99999`)：起始累积 alpha 值。

alpha_cum_end (`float`，默认为 `0.000009`)：结束时的累积 alpha 值。

gamma_cum_start (`float`，默认为 `0.000009`)：初始累积 gamma 值。

gamma_cum_end (`float`，默认为 `0.99999`)：结束时的累积 gamma 值。

用于向量量化扩散的调度器。

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

#### apply_cumulative_transitions[[diffusers.VQDiffusionScheduler.apply_cumulative_transitions]]

```python
apply_cumulative_transitions(q: Tensor, t: typing.Union[int, torch.Tensor])
```

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

**参数：**

q (`torch.Tensor`，形状为 `(batch size, num classes - 1, num latent pixels)`)：非掩码潜在像素类别的对数概率。

t (`int` 或 `torch.Tensor`)：用于确定使用哪个累积转移矩阵的时间步。

**返回：** `torch.Tensor`，形状为 `(batch size, num classes, num latent pixels)`

附加了掩码类别概率的转换后对数概率。

在某个时间步应用累积转移矩阵，以计算非掩码类别上的对数概率。

#### log_Q_t_transitioning_to_known_class[[diffusers.VQDiffusionScheduler.log_Q_t_transitioning_to_known_class]]

```python
log_Q_t_transitioning_to_known_class(t: typing.Union[int, torch.Tensor], x_t: LongTensor, log_onehot_x_t: Tensor, cumulative: bool)
```

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

**参数：**

t (`int` 或 `torch.Tensor`)：用于确定使用哪个转移矩阵的时间步。

x_t (`torch.LongTensor`，形状为 `(batch size, num latent pixels)`)：时间步 `t` 时每个潜在像素的类别。

log_onehot_x_t (`torch.Tensor`，形状为 `(batch size, num classes, num latent pixels)`)：`x_t` 的对数 one-hot 向量。

cumulative (`bool`) : 如果 cumulative 为 `False`，则使用单步转移矩阵 `t-1`->`t`。如果 cumulative 为 `True`，则使用累积转移矩阵 `0`->`t`。

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

返回矩阵的每个 _列_ 都是完整概率转移矩阵的对数概率的 _行_。当 `cumulative` 为 `True` 时，张量的形状为 `(batch size, num classes - 1, num latent pixels)`；否则，其形状为 `(batch size, num classes, num latent pixels)`。

在累积模式下，由于初始潜在像素无法被掩码，张量会少一行。

其中：
- `q_n` 是第 `n` 个潜在像素前向过程的概率分布。
- C_0 是潜在像素嵌入的一个类别
- C_k 是被掩码的潜在像素的类别

非累积结果（省略对数）：
```
q_0(x_t | x_{t-1} = C_0) ... q_n(x_t | x_{t-1} = C_0)
          .      .                     .
          .               .            .
          .                      .     .
q_0(x_t | x_{t-1} = C_k) ... q_n(x_t | x_{t-1} = C_k)
```

累积结果（省略对数）：
```
q_0_cumulative(x_t | x_0 = C_0)    ...  q_n_cumulative(x_t | x_0 = C_0)
          .               .                          .
          .                        .                 .
          .                               .          .
q_0_cumulative(x_t | x_0 = C_{k-1}) ... q_n_cumulative(x_t | x_0 = C_{k-1})
```

计算 `x_t` 中每个潜在像素从（累积或非累积）转移矩阵的行中得到的对数概率。

#### q_posterior[[diffusers.VQDiffusionScheduler.q_posterior]]

```python
q_posterior(log_p_x_0: Tensor, x_t: LongTensor, t: typing.Union[int, torch.Tensor])
```

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

**参数：**

log_p_x_0 (`torch.Tensor`，形状为 `(batch size, num classes - 1, num latent pixels)`)：初始潜在像素的预测类别的对数概率。由于初始未加噪图像无法被掩码，因此不包含对掩码类别的预测。

x_t (`torch.LongTensor`，形状为 `(batch size, num latent pixels)`)：时间步 `t` 时每个潜在像素的类别。

t (`int` 或 `torch.Tensor`)：用于确定使用哪个转移矩阵的时间步。

**返回：** `torch.Tensor`，形状为 `(batch size, num classes, num latent pixels)`

在时间步 `t-1` 时，图像预测类别的对数概率。

计算图像在时间步 `t-1` 的预测类别的对数概率：

```
p(x_{t-1} | x_t) = sum( q(x_t | x_{t-1}) * q(x_{t-1} | x_0) * p(x_0) / q(x_t | x_0) )
```

#### set_timesteps[[diffusers.VQDiffusionScheduler.set_timesteps]]

```python
set_timesteps(num_inference_steps: int, device: typing.Union[str, torch.device, NoneType] = None)
```

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

**参数：**

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

device (`str` 或 `torch.device`，*可选*)：时间步和扩散过程参数（alpha、beta、gamma）应移动到的设备。

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

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

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

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

**参数：**

model_output (`torch.Tensor`，形状为 `(batch size, num classes - 1, num latent pixels)`)：初始潜在像素的预测类别的对数概率。由于初始未加噪图像无法被掩码，因此不包含对掩码类别的预测。

timestep （`int` 或 `torch.Tensor`）：决定使用哪些转移矩阵的时间步。

sample (`torch.LongTensor`，形状为 `(batch size, num latent pixels)`)：当前时间步下每个潜在像素的类别。

generator (`torch.Generator`, *可选*) : 用于在从 `p(x_{t-1} | x_t)` 中采样之前，对施加于该分布的噪声进行随机数生成的生成器。

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

**返回：** [VQDiffusionSchedulerOutput](/docs/diffusers/v0.43.0/zh/api/schedulers/vq_diffusion#diffusers.schedulers.scheduling_vq_diffusion.VQDiffusionSchedulerOutput) 或 `tuple[torch.LongTensor]`

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

通过反向转移分布预测上一时间步的样本。有关该分布计算方式的更多详细信息，请参阅 [q_posterior()](/docs/diffusers/v0.43.0/zh/api/schedulers/vq_diffusion#diffusers.VQDiffusionScheduler.q_posterior)。

## VQDiffusionSchedulerOutput[[diffusers.schedulers.scheduling_vq_diffusion.VQDiffusionSchedulerOutput]]

#### diffusers.schedulers.scheduling_vq_diffusion.VQDiffusionSchedulerOutput[[diffusers.schedulers.scheduling_vq_diffusion.VQDiffusionSchedulerOutput]]

```python
diffusers.schedulers.scheduling_vq_diffusion.VQDiffusionSchedulerOutput(prev_sample: LongTensor)
```

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

**参数：**

prev_sample (`torch.LongTensor`，形状为 `(batch size, num latent pixels)`)：在上一个时间步计算得到的样本。`prev_sample` 应作为去噪循环中下一个模型输入。

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

