# DDIMScheduler

[Denoising Diffusion Implicit Models](https://huggingface.co/papers/2010.02502) (DDIM) của Jiaming Song, Chenlin Meng và Stefano Ermon.

Tóm tắt từ bài báo là:

*Các mô hình xác suất khuếch tán khử nhiễu (DDPM) đã đạt được chất lượng tạo ảnh cao mà không cần huấn luyện đối kháng, nhưng chúng yêu cầu mô phỏng một chuỗi Markov qua nhiều bước để tạo ra một mẫu. Để tăng tốc quá trình lấy mẫu, chúng tôi giới thiệu các mô hình xác suất ẩn khử nhiễu (DDIM), một lớp mô hình xác suất ẩn lặp hiệu quả hơn với cùng quy trình huấn luyện như DDPM. Trong DDPM, quá trình sinh được định nghĩa là quá trình ngược của một quá trình khuếch tán Markov. Chúng tôi xây dựng một lớp các quá trình khuếch tán phi Markov dẫn đến cùng mục tiêu huấn luyện, nhưng quá trình ngược của chúng có thể lấy mẫu nhanh hơn nhiều. Chúng tôi chứng minh thực nghiệm rằng DDIM có thể tạo ra các mẫu chất lượng cao nhanh hơn 10 lần đến 50 lần về thời gian thực so với DDPM, cho phép chúng tôi đánh đổi giữa tính toán và chất lượng mẫu, và có thể thực hiện nội suy ảnh có ý nghĩa ngữ nghĩa trực tiếp trong không gian ẩn.*

Mã nguồn gốc của bài báo này có thể được tìm thấy tại [ermongroup/ddim](https://github.com/ermongroup/ddim), và bạn có thể liên hệ với tác giả qua [tsong.me](https://tsong.me/).

## Mẹo

Bài báo [Common Diffusion Noise Schedules and Sample Steps are Flawed](https://huggingface.co/papers/2305.08891) cho rằng sự không khớp giữa các cài đặt huấn luyện và suy luận dẫn đến kết quả sinh suy luận không tối ưu cho Stable Diffusion. Để khắc phục điều này, các tác giả đề xuất:

> [!WARNING]
> 🧪 Đây là một tính năng thử nghiệm!

1. tái chuẩn hóa lịch nhiễu để đảm bảo tỷ số tín hiệu trên nhiễu (SNR) cuối cùng bằng không

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

2. huấn luyện một mô hình với `v_prediction` (thêm đối số sau vào các script [train_text_to_image.py](https://github.com/huggingface/diffusers/blob/main/examples/text_to_image/train_text_to_image.py) hoặc [train_text_to_image_lora.py](https://github.com/huggingface/diffusers/blob/main/examples/text_to_image/train_text_to_image_lora.py))

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

3. thay đổi trình lấy mẫu để luôn bắt đầu từ bước thời gian cuối

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

4. tái chuẩn hóa hướng dẫn không phân loại để ngăn ngừa phơi sáng quá mức

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

Ví dụ:

```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)
```

[Nguồn](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/schedulers/scheduling_ddim.py#L139)

**Tham số:**

num_train_timesteps (`int`, mặc định là 1000) : Số bước khuếch tán để huấn luyện mô hình.

beta_start (`float`, mặc định là 0.0001) : Giá trị `beta` ban đầu của suy luận.

beta_end (`float`, mặc định là 0.02) : Giá trị `beta` cuối cùng.

beta_schedule (`Literal["linear", "scaled_linear", "squaredcos_cap_v2"]`, mặc định là `"linear"`) : Lịch beta, một ánh xạ từ một khoảng beta sang một chuỗi các beta để bước qua mô hình. Phải là một trong `"linear"`, `"scaled_linear"`, hoặc `"squaredcos_cap_v2"`.

trained_betas (`np.ndarray`, *tùy chọn*) : Truyền một mảng betas trực tiếp vào constructor để bỏ qua `beta_start` và `beta_end`.

clip_sample (`bool`, mặc định là `True`) : Cắt mẫu dự đoán để đảm bảo ổn định về mặt số học.

clip_sample_range (`float`, mặc định là 1.0) : Độ lớn tối đa cho việc cắt mẫu. Chỉ có hiệu lực khi `clip_sample=True`.

set_alpha_to_one (`bool`, mặc định là `True`) : Mỗi bước khuếch tán sử dụng giá trị tích alpha tại bước đó và tại bước trước đó. Đối với bước cuối cùng, không có alpha trước đó. Khi tùy chọn này là `True`, tích alpha trước đó được cố định là `1`, ngược lại nó sử dụng giá trị alpha tại bước 0.

steps_offset (`int`, mặc định là 0) : Một giá trị bù được cộng vào các bước suy luận, theo yêu cầu của một số họ mô hình.

prediction_type (`Literal["epsilon", "sample", "v_prediction"]`, mặc định là `"epsilon"`) : Kiểu dự đoán của hàm scheduler. Phải là một trong `"epsilon"` (dự đoán nhiễu của quá trình khuếch tán), `"sample"` (dự đoán trực tiếp mẫu nhiễu), hoặc `"v_prediction"` (xem mục 2.4 của bài báo [Imagen Video](https://huggingface.co/papers/2210.02303)).

thresholding (`bool`, mặc định là `False`) : Có sử dụng phương pháp "dynamic thresholding" hay không. Phương pháp này không phù hợp với các mô hình khuếch tán trong không gian ẩn như Stable Diffusion.

dynamic_thresholding_ratio (`float`, mặc định là 0.995) : Tỷ lệ cho phương pháp ngưỡng động. Chỉ hợp lệ khi `thresholding=True`.

sample_max_value (`float`, mặc định là 1.0) : Giá trị ngưỡng cho ngưỡng động. Chỉ hợp lệ khi `thresholding=True`.

timestep_spacing (`Literal["leading", "trailing", "linspace"]`, mặc định là `"leading"`) : Cách các bước thời gian (timesteps) nên được quy đổi. Phải là một trong `"leading"`, `"trailing"`, hoặc `"linspace"`. Xem Bảng 2 trong [Common Diffusion Noise Schedules and Sample Steps are Flawed](https://huggingface.co/papers/2305.08891) để biết thêm thông tin.

rescale_betas_zero_snr (`bool`, mặc định là `False`) : Có nên điều chỉnh lại các hệ số beta để có SNR cuối bằng không hay không. Điều này cho phép mô hình tạo ra các mẫu rất sáng và rất tối thay vì giới hạn ở các mẫu có độ sáng trung bình. Liên quan lỏng lẻo đến [`--offset_noise`](https://github.com/huggingface/diffusers/blob/74fd735eb073eb1d774b1ab4154a0876eb82f055/examples/dreambooth/train_dreambooth.py#L506).

`DDIMScheduler` mở rộng quy trình khử nhiễu được giới thiệu trong các mô hình xác suất khuếch tán khử nhiễu (DDPM) bằng cách sử dụng hướng dẫn phi Markov.

Mô hình này kế thừa từ [SchedulerMixin](/docs/diffusers/v0.43.0/vi/api/schedulers/overview#diffusers.SchedulerMixin) và [ConfigMixin](/docs/diffusers/v0.43.0/vi/api/configuration#diffusers.ConfigMixin). Xem tài liệu của lớp cha để biết các phương thức chung mà thư viện triển khai cho tất cả các scheduler, chẳng hạn như tải và lưu.

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

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

[Nguồn](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/schedulers/scheduling_ddim.py#L517)

**Tham số:**

original_samples (`torch.Tensor`) : Các mẫu gốc mà nhiễu sẽ được thêm vào.

noise (`torch.Tensor`) : Nhiễu cần thêm vào các mẫu.

timesteps (`torch.IntTensor`) : Các bước thời gian (timesteps) chỉ ra mức độ nhiễu cho từng mẫu.

**Trả về:** `torch.Tensor`

Các mẫu nhiễu.

Thêm nhiễu vào các mẫu gốc theo mức độ nhiễu tại mỗi bước thời gian (đây là quá trình khuếch tán thuận).

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

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

[Nguồn](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/schedulers/scheduling_ddim.py#L560)

**Tham số:**

sample (`torch.Tensor`) : Mẫu đầu vào.

noise (`torch.Tensor`) : Tensor nhiễu.

timesteps (`torch.IntTensor`) : Các bước thời gian (timesteps) cho việc tính toán vận tốc.

**Trả về:** `torch.Tensor`

Tốc độ đã được tính toán.

Tính dự đoán vận tốc từ mẫu và nhiễu theo công thức vận tốc.

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

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

[Nguồn](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/schedulers/scheduling_ddim.py#L245)

**Tham số:**

sample (`torch.Tensor`) : Mẫu đầu vào.

timestep (`int`, *tùy chọn*) : Bước thời gian hiện tại trong chuỗi khuếch tán.

**Trả về:** `torch.Tensor`

Một mẫu đầu vào đã được chuẩn hóa.

Đảm bảo khả năng hoán đổi với các trình lập lịch cần mở rộng đầu vào của mô hình khử nhiễu tùy thuộc vào bước thời gian hiện tại.

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

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

[Nguồn](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/schedulers/scheduling_ddim.py#L334)

**Tham số:**

num_inference_steps (`int`) : Số bước khuếch tán được sử dụng khi tạo mẫu bằng một mô hình đã được huấn luyện trước.

device (`str | torch.device`, *tùy chọn*) : Thiết bị (device) để sử dụng cho các bước thời gian (timesteps).

**Lỗi:** ``ValueError``

- ``ValueError`` -- Nếu `num_inference_steps` lớn hơn `self.config.num_train_timesteps`.

Đặt các bước thời gian rời rạc được sử dụng cho chuỗi khuếch tán (cần chạy trước khi suy luận).

#### bước[[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)
```

[Nguồn](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/schedulers/scheduling_ddim.py#L384)

**Tham số:**

model_output (`torch.Tensor`) : Đầu ra trực tiếp từ mô hình khuếch tán đã học.

timestep (`int`) : Bước thời gian rời rạc hiện tại trong chuỗi khuếch tán.

sample (`torch.Tensor`) : Một bản sao mẫu hiện tại được tạo ra bởi quá trình khuếch tán.

eta (`float`, *optional*, mặc định là 0.0) : Trọng số của nhiễu cho nhiễu được thêm vào trong bước khuếch tán. Giá trị 0 tương ứng với DDIM (xác định) và 1 tương ứng với DDPM (ngẫu nhiên hoàn toàn).

use_clipped_model_output (`bool`, *tùy chọn*, mặc định là `False`) : Nếu `True`, sẽ tính toán `model_output` đã "điều chỉnh" từ mẫu gốc dự đoán đã bị cắt. Điều này là cần thiết vì mẫu gốc dự đoán sẽ bị cắt về [-1, 1] khi `self.config.clip_sample` là `True`. Nếu không có sự cắt nào xảy ra, `model_output` "đã điều chỉnh" sẽ trùng khớp với giá trị được cung cấp làm đầu vào và `use_clipped_model_output` sẽ không có tác dụng.

generator (`torch.Generator`, *tùy chọn*) : Bộ tạo số ngẫu nhiên để lấy mẫu có thể tái lập.

variance_noise (`torch.Tensor`, *tùy chọn*) : Cách thay thế cho việc tạo nhiễu bằng `generator` bằng cách cung cấp trực tiếp nhiễu cho phương sai. Hữu ích cho các phương pháp như `CycleDiffusion`.

return_dict (`bool`, *tuỳ chọn*, mặc định là `True`) : Có trả về [DDIMSchedulerOutput](/docs/diffusers/v0.43.0/vi/api/schedulers/ddim#diffusers.schedulers.scheduling_ddim.DDIMSchedulerOutput) hay `tuple` hay không.

**Trả về:** [DDIMSchedulerOutput](/docs/diffusers/v0.43.0/vi/api/schedulers/ddim#diffusers.schedulers.scheduling_ddim.DDIMSchedulerOutput) hoặc `tuple`

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

Dự đoán mẫu từ bước thời gian trước đó bằng cách đảo ngược SDE. Hàm này lan truyền quá trình khuếch tán từ các đầu ra của mô hình đã học (thường nhất là nhiễu được dự đoán).

## 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)
```

[Nguồn](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/schedulers/scheduling_ddim.py#L33)

**Tham số:**

prev_sample (`torch.Tensor` có shape `(batch_size, num_channels, height, width)` đối với ảnh) : Mẫu `(x_{t-1})` đã tính của bước thời gian trước đó. `prev_sample` nên được dùng làm đầu vào mô hình tiếp theo trong vòng lặp khử nhiễu.

pred_original_sample (`torch.Tensor` có shape `(batch_size, num_channels, height, width)` đối với ảnh) : Mẫu khử nhiễu dự đoán `(x_{0})` dựa trên đầu ra của mô hình tại bước thời gian hiện tại. `pred_original_sample` có thể được dùng để xem trước tiến độ hoặc cho guidance.

Lớp đầu ra cho kết quả của hàm `step` của trình lập lịch.

