# DDIMScheduler

[Denoising Diffusion Implicit Models](https://huggingface.co/papers/2010.02502) (DDIM) от Jiaming Song, Chenlin Meng и Stefano Ermon.

Аннотация из статьи:

*Модели вероятностного диффузионного шумоподавления (DDPM) обеспечивают генерацию изображений высокого качества без использования противоречивого обучения, однако для получения одного образца им необходимо симулировать цепь Маркова на протяжении множества шагов. Для ускорения процесса выборки мы предлагаем модели неявного диффузионного шумоподавления (DDIM) — более эффективный класс итеративных неявных вероятностных моделей, использующих ту же процедуру обучения, что и DDPM. В DDPM генеративный процесс определяется как обратный процессу марковской диффузии. Мы конструируем класс немарковских процессов диффузии, которые приводят к той же целевой функции обучения, но обратный процесс которых позволяет выполнять выборку значительно быстрее. На практике мы показываем, что DDIM способны генерировать образцы высокого качества в 10–50 раз быстрее по фактическому времени выполнения по сравнению с DDPM, позволяют находить баланс между вычислительными затратами и качеством образцов, а также выполняют семантически осмысленную интерполяцию изображений непосредственно в латентном пространстве.*

Исходная кодовая база этой статьи доступна по адресу [ermongroup/ddim](https://github.com/ermongroup/ddim), а связаться с автором можно через [tsong.me](https://tsong.me/).

## Советы

The paper [Common Diffusion Noise Schedules and Sample Steps are Flawed](https://huggingface.co/papers/2305.08891) claims that a mismatch between the training and inference settings leads to suboptimal inference generation results for Stable Diffusion. To fix this, the authors propose:

> [!WARNING]
> 🧪 Это экспериментальная функция!

1. масштабировать расписание шума для обеспечения нулевого отношения сигнал/шум (SNR) на конечном шаге

```py
pipe.scheduler = DDIMScheduler.from_config(pipe.scheduler.config, rescale_betas_zero_snr=True)
```

2. train a model with `v_prediction` (add the following argument to the [train_text_to_image.py](https://github.com/huggingface/diffusers/blob/main/examples/text_to_image/train_text_to_image.py) or [train_text_to_image_lora.py](https://github.com/huggingface/diffusers/blob/main/examples/text_to_image/train_text_to_image_lora.py) scripts)

```bash
--prediction_type="v_prediction"
```

3. измените сэмплер так, чтобы он всегда начинал с последнего шага

```py
pipe.scheduler = DDIMScheduler.from_config(pipe.scheduler.config, timestep_spacing="trailing")
```

4. масштабирование classifier-free guidance для предотвращения переэкспозиции

```py
image = pipe(prompt, guidance_rescale=0.7).images[0]
```

Например:

```py
from diffusers import DiffusionPipeline, DDIMScheduler
import torch

pipe = DiffusionPipeline.from_pretrained("ptx0/pseudo-journey-v2", dtype=torch.float16)
pipe.scheduler = DDIMScheduler.from_config(
    pipe.scheduler.config, rescale_betas_zero_snr=True, timestep_spacing="trailing"
)
pipe.to("cuda")  # or "mps", "xpu", "cpu"

prompt = "A lion in galaxies, spirals, nebulae, stars, smoke, iridescent, intricate detail, octane render, 8k"
image = pipe(prompt, guidance_rescale=0.7).images[0]
image
```

## DDIMScheduler[[diffusers.DDIMScheduler]]

#### diffusers.DDIMScheduler[[diffusers.DDIMScheduler]]

```python
diffusers.DDIMScheduler(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, clip_sample: bool = True, set_alpha_to_one: bool = True, steps_offset: int = 0, prediction_type: typing.Literal['epsilon', 'sample', 'v_prediction'] = 'epsilon', thresholding: bool = False, dynamic_thresholding_ratio: float = 0.995, clip_sample_range: float = 1.0, sample_max_value: float = 1.0, timestep_spacing: typing.Literal['leading', 'trailing', 'linspace'] = 'leading', rescale_betas_zero_snr: bool = False)
```

[Источник](https://github.com/huggingface/diffusers/blob/main/src/diffusers/schedulers/scheduling_ddim.py#L139)

**Параметры:**

num_train_timesteps (`int`, по умолчанию 1000) : Количество шагов диффузии для обучения модели.

beta_start (`float`, по умолчанию 0.0001) : начальное значение `beta` для инференса.

beta_end (`float`, по умолчанию 0.02) : Итоговое значение `beta`.

beta_schedule (`Literal["linear", "scaled_linear", "squaredcos_cap_v2"]`, по умолчанию `"linear"`) : Расписание бета, отображение диапазона бета в последовательность значений бета для шагов модели. Должно быть одним из `"linear"`, `"scaled_linear"` или `"squaredcos_cap_v2"`.

trained_betas (`np.ndarray`, *необязательный*) : Передайте массив бета непосредственно в конструктор, чтобы обойти `beta_start` и `beta_end`.

clip_sample (`bool`, по умолчанию `True`) : Обрезает предсказанную выборку для обеспечения численной стабильности.

clip_sample_range (`float`, по умолчанию 1.0) : Максимальная величина для обрезки выборок. Действительно только при `clip_sample=True`.

set_alpha_to_one (`bool`, по умолчанию `True`) : Каждый шаг диффузии использует значение произведения альф на этом шаге и на предыдущем. Для последнего шага предыдущего альфа не существует. Если этот параметр установлен в `True`, произведение предыдущего альфа фиксируется в `1`, в противном случае используется значение альфа на шаге 0.

steps_offset (`int`, по умолчанию 0) : Смещение, добавляемое к шагам инференса, как требуется некоторыми семействами моделей.

prediction_type (`Literal["epsilon", "sample", "v_prediction"]`, по умолчанию `"epsilon"`) : Тип предсказания функции планировщика. Должен быть одним из `"epsilon"` (предсказывает шум диффузионного процесса), `"sample"` (напрямую предсказывает зашумленный образец) или `"v_prediction"` (см. раздел 2.4 статьи [Imagen Video](https://huggingface.co/papers/2210.02303)).

thresholding (`bool`, по умолчанию `False`) : Использовать ли метод «динамического порога». Этот метод не подходит для моделей диффузии в латентном пространстве, таких как Stable Diffusion.

dynamic_thresholding_ratio (`float`, по умолчанию 0.995) : Коэффициент для метода динамического порогового значения. Действительно только при `thresholding=True`.

sample_max_value (`float`, по умолчанию 1.0) : Пороговое значение для динамического порогового отсечения. Действительно только при `thresholding=True`.

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

rescale_betas_zero_snr (`bool`, по умолчанию `False`) : Нужно ли перемасштабировать беты для нулевого конечного SNR. Это позволяет модели генерировать очень яркие и тёмные образцы, а не ограничиваться образцами со средней яркостью. Непосредственно связано с [`--offset_noise`](https://github.com/huggingface/diffusers/blob/74fd735eb073eb1d774b1ab4154a0876eb82f055/examples/dreambooth/train_dreambooth.py#L506).

`DDIMScheduler` расширяет процедуру денойзинга, предложенную в вероятностных моделях диффузионного денойзинга (DDPM), с помощью немарковского управления.

Эта модель наследуется от [SchedulerMixin](/docs/diffusers/main/ru/api/schedulers/overview#diffusers.SchedulerMixin) и [ConfigMixin](/docs/diffusers/main/ru/api/configuration#diffusers.ConfigMixin). Общие методы, которые библиотека реализует для всех планировщиков, такие как загрузка и сохранение, описаны в документации суперкласса.

#### add_noise[[diffusers.DDIMScheduler.add_noise]]

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

[Источник](https://github.com/huggingface/diffusers/blob/main/src/diffusers/schedulers/scheduling_ddim.py#L517)

**Параметры:**

original_samples (`torch.Tensor`) : исходные образцы, к которым будет добавлен шум.

noise (`torch.Tensor`) : Шум, который нужно добавить к образцам.

timesteps (`torch.IntTensor`) : Шаги, указывающие уровень шума для каждого примера.

**Возвращает:** `torch.Tensor`

Шумные образцы.

Добавьте шум к исходным образцам в соответствии с величиной шума на каждом шаге (это процесс прямой диффузии).

#### get_velocity[[diffusers.DDIMScheduler.get_velocity]]

```python
get_velocity(sample: Tensor, noise: Tensor, timesteps: IntTensor)
```

[Источник](https://github.com/huggingface/diffusers/blob/main/src/diffusers/schedulers/scheduling_ddim.py#L560)

**Параметры:**

sample (`torch.Tensor`) : Входной образец.

noise (`torch.Tensor`) : Тензор шума.

timesteps (`torch.IntTensor`) : Шаги для вычисления скорости.

**Возвращает:** `torch.Tensor`

Вычисленная скорость.

Вычислите предсказание скорости из выборки и шума согласно формуле скорости.

#### scale_model_input[[diffusers.DDIMScheduler.scale_model_input]]

```python
scale_model_input(sample: Tensor, timestep: int = None)
```

[Источник](https://github.com/huggingface/diffusers/blob/main/src/diffusers/schedulers/scheduling_ddim.py#L245)

**Параметры:**

sample (`torch.Tensor`) : Входной образец.

timestep (`int`, *необязательный*) : Текущий шаг в цепочке диффузии.

**Возвращает:** `torch.Tensor`

Масштабированный входной образец.

Обеспечивает совместимость с планировщиками, которым необходимо масштабировать входную модель денуазинга в зависимости от текущего шага.

#### set_timesteps[[diffusers.DDIMScheduler.set_timesteps]]

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

[Источник](https://github.com/huggingface/diffusers/blob/main/src/diffusers/schedulers/scheduling_ddim.py#L334)

**Параметры:**

num_inference_steps (`int`) : Количество шагов диффузии, используемое при генерации образцов с помощью предобученной модели.

device (`str | torch.device`, *необязательный*) : Устройство, используемое для шагов времени.

**Исключения:** ``ValueError``

- ``ValueError`` -- если `num_inference_steps` больше, чем `self.config.num_train_timesteps`.

Устанавливает дискретные временные шаги, используемые для цепочки диффузии (выполняется перед инференсом).

#### шаг[[diffusers.DDIMScheduler.step]]

```python
step(model_output: Tensor, timestep: int, sample: Tensor, eta: float = 0.0, use_clipped_model_output: bool = False, generator: typing.Optional[torch.Generator] = None, variance_noise: typing.Optional[torch.Tensor] = None, return_dict: bool = True)
```

[Источник](https://github.com/huggingface/diffusers/blob/main/src/diffusers/schedulers/scheduling_ddim.py#L384)

**Параметры:**

model_output (`torch.Tensor`) : Прямой вывод из обученной диффузионной модели.

timestep (`int`) : Текущий дискретный шаг времени в цепочке диффузии.

sample (`torch.Tensor`) : Текущая инстанция сэмпла, созданная процессом диффузии.

eta (`float`, *optional*, по умолчанию 0.0) : Вес шума для добавляемого шума на шаге диффузии. Значение 0 соответствует DDIM (детерминированный), а 1 — DDPM (полностью стохастический).

use_clipped_model_output (`bool`, *необязательный*, по умолчанию `False`) : Если `True`, вычисляет «скорректированный» `model_output` из обрезанного предсказанного исходного образца. Это необходимо, так как предсказанный исходный образец обрезается до [-1, 1], когда `self.config.clip_sample` равно `True`. Если обрезка не выполнялась, «скорректированный» `model_output` совпадал бы с переданным на вход, и `use_clipped_model_output` не оказывает влияния.

generator (`torch.Generator`, *необязательный*) : генератор случайных чисел для воспроизводимой выборки.

variance_noise (`torch.Tensor`, *необязательный*) : Альтернатива генерации шума с помощью `generator` путём прямого предоставления шума для дисперсии. Полезно для методов, таких как `CycleDiffusion`.

return_dict (`bool`, *необязательный*, по умолчанию `True`) : Возвращать ли [DDIMSchedulerOutput](/docs/diffusers/main/ru/api/schedulers/ddim#diffusers.schedulers.scheduling_ddim.DDIMSchedulerOutput) или `tuple`.

**Возвращает:** [DDIMSchedulerOutput](/docs/diffusers/main/ru/api/schedulers/ddim#diffusers.schedulers.scheduling_ddim.DDIMSchedulerOutput) или `tuple`

If return_dict is `True`, [DDIMSchedulerOutput](/docs/diffusers/main/ru/api/schedulers/ddim#diffusers.schedulers.scheduling_ddim.DDIMSchedulerOutput) is returned, otherwise a tuple is returned where the first element is the sample tensor.

Предскажите образец из предыдущего шага времени, обращая SDE. Эта функция распространяет процесс диффузии от выходов обученной модели (чаще всего — предсказанного шума).

## DDIMSchedulerOutput[[diffusers.schedulers.scheduling_ddim.DDIMSchedulerOutput]]

#### diffusers.schedulers.scheduling_ddim.DDIMSchedulerOutput[[diffusers.schedulers.scheduling_ddim.DDIMSchedulerOutput]]

```python
diffusers.schedulers.scheduling_ddim.DDIMSchedulerOutput(prev_sample: Tensor, pred_original_sample: typing.Optional[torch.Tensor] = None)
```

[Источник](https://github.com/huggingface/diffusers/blob/main/src/diffusers/schedulers/scheduling_ddim.py#L33)

**Параметры:**

prev_sample (`torch.Tensor` формы `(batch_size, num_channels, height, width)` для изображений) : Вычисленная выборка `(x_{t-1})` для предыдущего шага. `prev_sample` следует использовать как следующий вход модели в цикле шумоподавления.

pred_original_sample (`torch.Tensor` формы `(batch_size, num_channels, height, width)` для изображений) : Предсказанный денойзированный образец `(x_{0})` на основе вывода модели из текущего шага. `pred_original_sample` можно использовать для предпросмотра прогресса или для guidance.

Класс результата для вывода функции `step` планировщика.

