# FlowMapEulerDiscreteScheduler

`FlowMapEulerDiscreteScheduler`는 flow-map-distilled diffusion 모델을 위한 Euler 스타일의 샘플러입니다. Flow-map 모델은 consistency 모델의 고정된 $\mathbf{z}_t \to \mathbf{z}_0$ 매핑이 아닌, 임의의 간격을 가진 전이 $\mathbf{z}_t \to \mathbf{z}_r$를 학습합니다. 스텝의 양쪽 끝점은 모두 호출자가 제공하며, 이를 통해 any-step 샘플링이 가능합니다. 단일 distilled checkpoint를 재학습 없이 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-distilled 체크포인트라면 모두 사용할 수 있습니다.

## 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/main/src/diffusers/schedulers/scheduling_flow_map_euler_discrete.py#L42)

**매개변수:**

num_train_timesteps (*int*, 기본값 1000) : 기반 flow-map 모델을 학습하는 데 사용되는 diffusion step 수입니다.

shift (*float*, 기본값 1.0) : 추론 스케줄에 적용되는 곱셈 시간 단계 시프트입니다. `shift=1.0`은 항등 변환이며, 1.0보다 큰 값은 스케줄을 후속 단계에서 더 많은 노이즈 제거 방향으로 이동시킵니다(예: `shift=5`는 Wan2.1 기본값과 일치합니다).

flow-map-distilled diffusion 모델용 Euler 스타일 샘플러.

Flow-map 모델은 consistency 모델의 고정된 \\(z_t \to z_0\\) 매핑이 아닌, 임의의 간격 전이 \\(z_t \to z_r\\)를 학습하므로, 재학습 없이 단일 distilled checkpoint를 1, 2, 4, 8, ... NFE에서 평가할 수 있습니다. *step* 메서드는 예측된 속도를 따라 샘플을 *timestep*에서 *r_timestep*으로 진행시킵니다.

Yuchao Gu, Guian Fang 외 다수가 [AnyFlow: Any-Step Video Diffusion Model with On-Policy Flow Map Distillation](https://huggingface.co/papers/2605.13724)에서 소개했습니다.

이 스케줄러는 [*SchedulerMixin*]과 [*ConfigMixin*]을 상속합니다. 모든 스케줄러에 대해 구현된 일반 메서드(로드, 저장 등)에 대해서는 상위 클래스 문서를 확인하세요.

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

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

[소스](https://github.com/huggingface/diffusers/blob/main/src/diffusers/schedulers/scheduling_flow_map_euler_discrete.py#L117)

sigma 텐서에 구성된 시프트 변환을 적용합니다.

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

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

[소스](https://github.com/huggingface/diffusers/blob/main/src/diffusers/schedulers/scheduling_flow_map_euler_discrete.py#L207)

현재 스케줄에서 `timestep`의 인덱스를 반환하며, 스케줄에 없으면 `None`을 반환합니다.

`self.timesteps`를 기준으로 작은 fp 허용 오차 내에서 조회가 수행됩니다. `timesteps = sigmas * num_train_timesteps`의 선형 관계를 가정하지 않고 대응하는 sigma를 복원하는 데 사용됩니다. 이를 통해 커스텀 스케줄(예: 비선형 시프트, 수동으로 설정된 timesteps)도 올바르게 해석됩니다.

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

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

[소스](https://github.com/huggingface/diffusers/blob/main/src/diffusers/schedulers/scheduling_flow_map_euler_discrete.py#L99)

No-op identity scaling. 다른 Diffusers 스케줄러와의 API 호환성을 위해 제공됩니다.

#### 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/main/src/diffusers/schedulers/scheduling_flow_map_euler_discrete.py#L103)

`timestep`의 정규화된 값에 따라 `sample`을 `noise` 방향으로 선형 보간합니다.

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

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

[소스](https://github.com/huggingface/diffusers/blob/main/src/diffusers/schedulers/scheduling_flow_map_euler_discrete.py#L94)

스케줄러의 시작 인덱스를 설정합니다. 일정 중간에 시작하는 파이프라인(예: 이미지-투-이미지)은 `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/main/src/diffusers/schedulers/scheduling_flow_map_euler_discrete.py#L123)

**매개변수:**

num_inference_steps (*int*, *optional*) : 추론 단계 수. `None`인 경우 `sigmas` 또는 `timesteps`를 전달해야 합니다.

device (*str* 또는 *torch.device*, *선택 사항*) : `self.sigmas` / `self.timesteps`의 대상 디바이스.

sigmas (*List[float]*, *선택 사항*) : 길이가 `num_inference_steps`인 사용자 지정 sigma 스케줄입니다. 마지막 `0` sigma는 자동으로 추가됩니다. 설정된 `shift`가 이 위에 적용됩니다.

timesteps (*List[float]*, *선택 사항*) : `num_inference_steps` 길이의 사용자 지정 timestep 스케줄입니다. `self.timesteps`와 동일한 단위(즉, `num_train_timesteps`로 스케일된 값)를 사용합니다. 내부적으로 sigmas로 변환됩니다. `sigmas`와 `timesteps`가 모두 전달되면, 두 값의 길이가 일치해야 합니다.

추론 timestep 스케줄을 구성합니다.

`self.sigmas`를 내부적으로 추적하며, 길이는 `num_inference_steps + 1`입니다(기본적으로 `1.0`에서 `0.0`까지의 linspace에 구성된 shift가 적용됨). `self.timesteps`는 `num_train_timesteps`으로 스케일링된 첫 번째 `num_inference_steps`개의 sigmas를 노출합니다. 즉, 추론 단계마다 하나의 timestep을 가지며 [FlowMatchEulerDiscreteScheduler](/docs/diffusers/main/ko/api/schedulers/flow_match_euler_discrete#diffusers.FlowMatchEulerDiscreteScheduler)와 일치합니다. 마지막 sigma(`0`)는 마지막 단계의 암시적인 r-endpoint이며, `sigmas` / `timesteps`가 사용자에 의해 제공될 경우 자동으로 추가됩니다.

#### step[[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/main/src/diffusers/schedulers/scheduling_flow_map_euler_discrete.py#L223)

**매개변수:**

model_output (*torch.Tensor*) : flow-map 모델의 직접 출력(예측된 평균 속도).

timestep (*float* 또는 *torch.Tensor*) : `self.timesteps`와 동일한 단위의 소스 타임스텝 `t`.

sample (*torch.Tensor*) : 현재 샘플 \\(z_t\\).

r_timestep (*float* 또는 *torch.Tensor*, *optional*) : 대상 timestep `r`. `None`인 경우 기본값은 스케줄의 다음 timestep입니다. any-step sampling을 위해 명시적인 값을 전달하십시오. `r_timestep == timestep`이면 아무 동작도 수행하지 않습니다.

return_dict (*bool*, 기본값 *True*) : [*FlowMapEulerDiscreteSchedulerOutput*] (기본값) 또는 일반 튜플을 반환할지 여부.

**반환값:** [*FlowMapEulerDiscreteSchedulerOutput*] 또는 *tuple*

`return_dict=True`인 경우, `prev_sample`가 \\(z_r\\)인 [*FlowMapEulerDiscreteSchedulerOutput*]을 반환합니다. 그렇지 않으면 1-튜플 `(prev_sample,)`을 반환합니다.

모델이 예측한 속도를 사용하여 `timestep`에서 `r_timestep`까지 `sample`을 진행합니다.

표준 Euler 스케줄러와 달리, 구간의 양 끝점은 호출자가 지정할 수 있어 임의의 단계 샘플링이 가능합니다. 단일 모델 호출로 *t*에서 선택한 임의의 목표 *r*(원샷 생성을 위한 *r=0* 포함)까지 한 단계 이동할 수 있습니다. `r_timestep`이 생략되면 스케줄의 다음 타임스텝이 기본값으로 사용되며(`FlowMatchEulerDiscreteScheduler`의 의미론과 일치합니다).

내부적으로 소스 및 타깃 시그마는 입력 타임스텝을 `num_train_timesteps`로 나누는 방식이 아니라, `index_for_timestep`을 통해 `self.sigmas`를 인덱싱하여 복원됩니다. 따라서 타임스텝과 시그마의 관계가 비선형인 모든 스케줄(예: 커스텀 시프트)도 정확성을 유지합니다. 스케줄에 없는 `r_timestep`의 경우, 스케줄 외부의 any-step 샘플링이 계속 지원되도록 `r_timestep / num_train_timesteps`로 폴백합니다.

