# FlowMapEulerDiscreteScheduler

`FlowMapEulerDiscreteScheduler` — это сэмплер в стиле Эйлера, разработанный для дистиллированных диффузионных моделей flow-map. Модели flow-map обучаются переходам на произвольные интервалы $\mathbf{z}_t \to \mathbf{z}_r$, а не фиксированному отображению $\mathbf{z}_t \to \mathbf{z}_0$, как в моделях consistency. Обе точки шага задаются вызывающим кодом, что и обеспечивает сэмплирование с любым числом шагов: одна дистиллированная контрольная точка может быть оценена при 1, 2, 4, 8, 16... NFE без повторного обучения.

Планировщик был представлен в [AnyFlow: Any-Step Video Diffusion Model with On-Policy Flow Map Distillation](https://huggingface.co/papers/2605.13724) и поставляется с интеграциями `AnyFlowPipeline` и `AnyFlowFARPipeline`, но не является специфичным для AnyFlow — его можно использовать с любым чекпоинтом, обученным с помощью дистилляции flow-map.

## FlowMapEulerDiscreteScheduler[[diffusers.FlowMapEulerDiscreteScheduler]]

#### diffusers.FlowMapEulerDiscreteScheduler[[diffusers.FlowMapEulerDiscreteScheduler]]

```python
diffusers.FlowMapEulerDiscreteScheduler(num_train_timesteps: int = 1000, shift: float = 1.0)
```

[Источник](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/schedulers/scheduling_flow_map_euler_discrete.py#L42)

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

num_train_timesteps (*int*, по умолчанию 1000) : Количество шагов диффузии, используемых для обучения базовой модели flow-map.

shift (*float*, по умолчанию 1.0) : Множитель сдвига временных шагов, применяемый к расписанию вывода. `shift=1.0` — это тождественное преобразование; значения больше 1.0 смещают расписание в сторону более сильного шумоподавления на поздних шагах (например, `shift=5` соответствует значению по умолчанию для Wan2.1).

Сэмплер в стиле Эйлера для дистиллированных диффузионных моделей с картой потока.

Модели flow-map обучаются переходам на произвольные интервалы \\(z_t \to z_r\\), а не фиксированному отображению \\(z_t \to z_0\\) моделей consistency, поэтому одну дистиллированную контрольную точку можно оценивать при 1, 2, 4, 8, ... NFE без повторного обучения. Метод *step* перемещает образец из *timestep* в *r_timestep* вдоль предсказанной скорости.

Представлено в [AnyFlow: Any-Step Video Diffusion Model with On-Policy Flow Map Distillation](https://huggingface.co/papers/2605.13724) от Yuchao Gu, Guian Fang и др.

Этот планировщик наследуется от [*SchedulerMixin*] и [*ConfigMixin*]. Общие методы, реализованные для всех планировщиков (загрузка, сохранение и т. д.), описаны в документации суперкласса.

#### apply_shift[[diffusers.FlowMapEulerDiscreteScheduler.apply_shift]]

```python
apply_shift(sigmas: Tensor)
```

[Источник](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/schedulers/scheduling_flow_map_euler_discrete.py#L117)

Примените настроенное преобразование сдвига к тензору сигмы.

#### index_for_timestep[[diffusers.FlowMapEulerDiscreteScheduler.index_for_timestep]]

```python
index_for_timestep(timestep: typing.Union[float, torch.FloatTensor])
```

[Источник](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/schedulers/scheduling_flow_map_euler_discrete.py#L207)

Возвращает индекс `timestep` в текущем расписании или `None`, если шаг не входит в расписание.

Поиск выполняется по `self.timesteps` с небольшим допуском для fp. Используется для восстановления соответствующего sigma без предположения о линейной связи `timesteps = sigmas * num_train_timesteps` — таким образом, пользовательское расписание (например, нелинейный сдвиг, вручную заданные timesteps) также корректно разрешается.

#### scale_model_input[[diffusers.FlowMapEulerDiscreteScheduler.scale_model_input]]

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

[Источник](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/schedulers/scheduling_flow_map_euler_discrete.py#L99)

Масштабирование тождественного преобразования без действия. Предоставлено для обеспечения совместимости API с другими планировщиками Diffusers.

#### scale_noise[[diffusers.FlowMapEulerDiscreteScheduler.scale_noise]]

```python
scale_noise(sample: FloatTensor, timestep: typing.Union[float, torch.FloatTensor], noise: typing.Optional[torch.FloatTensor] = None)
```

[Источник](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/schedulers/scheduling_flow_map_euler_discrete.py#L103)

Линейно интерполируйте `sample` в сторону `noise` в соответствии с нормализованным `timestep`.

#### set_begin_index[[diffusers.FlowMapEulerDiscreteScheduler.set_begin_index]]

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

[Источник](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/schedulers/scheduling_flow_map_euler_discrete.py#L94)

Устанавливает начальный индекс для планировщика. Конвейеры, которые начинают работу с середины расписания (например, image-to-image), вызывают этот метод между `set_timesteps` и первым `step`, чтобы зафиксировать точку начала развертывания.

#### set_timesteps[[diffusers.FlowMapEulerDiscreteScheduler.set_timesteps]]

```python
set_timesteps(num_inference_steps: typing.Optional[int] = None, device: typing.Union[str, torch.device] = None, sigmas: typing.Optional[typing.List[float]] = None, timesteps: typing.Optional[typing.List[float]] = None)
```

[Источник](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/schedulers/scheduling_flow_map_euler_discrete.py#L123)

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

num_inference_steps (*int*, *optional*) : Количество шагов инференса. Если `None`, необходимо передать `sigmas` или `timesteps`.

device (*str* или *torch.device*, *optional*) : Целевое устройство для `self.sigmas` / `self.timesteps`.

sigmas (*List[float]*, *optional*) : Пользовательское расписание сигм длиной `num_inference_steps`. Конечное значение сигмы `0` добавляется автоматически. На него накладывается настроенное значение `shift`.

timesteps (*List[float]*, *optional*) : Пользовательское расписание временных шагов длины `num_inference_steps` в тех же единицах, что и `self.timesteps` (т. е. масштабированное на `num_train_timesteps`). Внутренне преобразуется в сигмы. Если переданы и `sigmas`, и `timesteps`, их длины должны совпадать.

Сформируйте расписание шагов времени для инференса.

Внутренне отслеживает `self.sigmas` длины `num_inference_steps + 1` (по умолчанию применяется настроенный сдвиг к линейной последовательности от `1.0` до `0.0`); `self.timesteps` предоставляет первые `num_inference_steps` сигм, масштабированные на `num_train_timesteps` — то есть один временной шаг на каждый шаг инференса, что соответствует [FlowMatchEulerDiscreteScheduler](/docs/diffusers/v0.43.0/ru/api/schedulers/flow_match_euler_discrete#diffusers.FlowMatchEulerDiscreteScheduler). Последняя сигма (`0`) является неявной правой границей последнего шага и добавляется автоматически, если `sigmas` / `timesteps` заданы пользователем.

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

```python
step(model_output: FloatTensor, timestep: typing.Union[float, torch.FloatTensor], sample: FloatTensor, r_timestep: typing.Union[float, torch.FloatTensor, NoneType] = None, return_dict: bool = True)
```

[Источник](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/schedulers/scheduling_flow_map_euler_discrete.py#L223)

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

model_output (*torch.Tensor*) : Прямой вывод модели flow-map (предсказанная средняя скорость).

timestep (*float* или *torch.Tensor*) : Исходный шаг времени `t` в тех же единицах, что и `self.timesteps`.

sample (*torch.Tensor*) : Текущая выборка \\(z_t\\).

r_timestep (*float* или *torch.Tensor*, *необязательный*) : Целевой шаг `r`. По умолчанию используется следующий шаг в расписании, если передано `None`; для any-step sampling передайте явное значение. `r_timestep == timestep` не выполняет никаких действий.

return_dict (*bool*, по умолчанию *True*) : Возвращать ли [*FlowMapEulerDiscreteSchedulerOutput*] (по умолчанию) или обычный кортеж.

**Возвращает:** [*FlowMapEulerDiscreteSchedulerOutput*] или *tuple*

При `return_dict=True` возвращает [*FlowMapEulerDiscreteSchedulerOutput*], у которого `prev_sample` равно \\(z_r\\). В противном случае возвращает 1-кортеж `(prev_sample,)`.

Выполните шаг `sample` от `timestep` до `r_timestep` с использованием скорости, предсказанной моделью.

В отличие от стандартного планировщика Эйлера, обе границы интервала могут быть заданы вызывающей стороной, что позволяет выполнять сэмплирование за любое число шагов: один вызов модели может сделать шаг от *t* к любой выбранной цели *r* (включая *r=0* для генерации за один шаг). Если `r_timestep` не указан, по умолчанию используется следующий шаг расписания (соответствует семантике `FlowMatchEulerDiscreteScheduler`).

Внутренне сигмы источника и цели восстанавливаются путём индексирования `self.sigmas` через `index_for_timestep`, а не делением входных временных шагов на `num_train_timesteps`, поэтому любая раскладка, в которой связь между временным шагом и сигмой нелинейна (например, с пользовательским сдвигом), остаётся корректной. Для `r_timestep` вне раскладки планировщик использует запасной вариант `r_timestep / num_train_timesteps`, что позволяет поддерживать выборку на произвольных шагах вне раскладки.

