#
# Được cấp phép theo Giấy phép Apache, Phiên bản 2.0 (gọi là "Giấy phép");
# bạn có thể không sử dụng tệp này ngoại trừ tuân thủ theo Giấy phép.
# Bạn có thể nhận được một bản sao của Giấy phép tại
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Trừ khi được yêu cầu bởi luật pháp có hiệu lực hoặc được thỏa thuận bằng văn bản, phần mềm
# được phân phối theo Giấy phép được phân phối trên cơ sở
# KHÔNG CÓ BẢO HÀNH HOẶC ĐIỀU KIỆN DƯỚI BẤT KỲ HÌNH THỨC NÀO, dù được nêu rõ hay ngụ ý.
# Xem Giấy phép để biết ngôn ngữ cụ thể điều chỉnh các quyền và
# giới hạn theo Giấy phép. -->

# Latte

![latte text-to-video](https://github.com/Vchitect/Latte/blob/52bc0029899babbd6e9250384c83d8ed2670ff7a/visuals/latte.gif?raw=true)

[Latte: Latent Diffusion Transformer for Video Generation](https://huggingface.co/papers/2401.03048) từ Đại học Monash, Shanghai AI Lab, Đại học Nam Kinh và Đại học Công nghệ Nanyang.

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

*Chúng tôi đề xuất một Latent Diffusion Transformer mới, có tên là Latte, cho việc tạo video. Latte trước tiên trích xuất các token không gian-thời gian từ video đầu vào, sau đó áp dụng một loạt các khối Transformer để mô hình hóa phân phối video trong không gian ẩn. Để mô hình hóa một số lượng lớn token được trích xuất từ video, bốn biến thể hiệu quả được giới thiệu từ góc nhìn phân rã các chiều không gian và thời gian của video đầu vào. Để nâng cao chất lượng video được tạo ra, chúng tôi xác định các thực hành tốt nhất của Latte thông qua phân tích thực nghiệm nghiêm ngặt, bao gồm nhúng patch cho đoạn video, các biến thể mô hình, tiêm thông tin lớp theo bước thời gian, nhúng vị trí thời gian và các chiến lược học. Đánh giá toàn diện của chúng tôi cho thấy Latte đạt hiệu suất tiên tiến trên bốn bộ dữ liệu tạo video tiêu chuẩn, cụ thể là FaceForensics, SkyTimelapse, UCF101 và Taichi-HD. Ngoài ra, chúng tôi mở rộng Latte sang nhiệm vụ tạo video từ văn bản (T2V), trong đó Latte đạt kết quả tương đương so với các mô hình T2V gần đây. Chúng tôi tin chắc rằng Latte cung cấp những hiểu biết quý giá cho nghiên cứu tương lai về việc tích hợp Transformer vào các mô hình khuếch tán cho việc tạo video.*

**Những điểm nổi bật**: Latte là một latent diffusion transformer được đề xuất làm backbone để mô hình hóa các modalities khác nhau (được huấn luyện cho việc tạo video từ văn bản ở đây). Nó đạt hiệu suất state-of-the-art trên bốn benchmark video tiêu chuẩn - [FaceForensics](https://huggingface.co/papers/1803.09179), [SkyTimelapse](https://huggingface.co/papers/1709.07592), [UCF101](https://huggingface.co/papers/1212.0402) và [Taichi-HD](https://huggingface.co/papers/2003.00196). Để chuẩn bị và tải xuống các dataset phục vụ đánh giá, vui lòng tham khảo [đường dẫn này](https://github.com/Vchitect/Latte/blob/main/docs/datasets_evaluation.md).

Pipeline này được đóng góp bởi [maxin-cn](https://github.com/maxin-cn). Mã nguồn gốc có thể được tìm thấy [tại đây](https://github.com/Vchitect/Latte). Trọng số gốc có thể được tìm thấy tại [hf.co/maxin-cn](https://huggingface.co/maxin-cn).

> [!TIP]
> Hãy chắc chắn xem qua [hướng dẫn](../../using-diffusers/schedulers) về Schedulers để tìm hiểu cách khám phá sự đánh đổi giữa tốc độ và chất lượng của scheduler, và xem phần [tái sử dụng các thành phần giữa các pipeline](../../using-diffusers/loading#reusing-models-in-multiple-pipelines) để tìm hiểu cách nạp các thành phần giống nhau vào nhiều pipeline một cách hiệu quả.

### Suy luận

Sử dụng [`torch.compile`](https://huggingface.co/docs/diffusers/main/en/tutorials/fast_diffusion#torchcompile) để giảm độ trễ suy luận.

Đầu tiên, tải pipeline:

```python
import torch
from diffusers import LattePipeline

pipeline = LattePipeline.from_pretrained(
	"maxin-cn/Latte-1", dtype=torch.float16
).to("cuda")  # or "mps", "xpu", "cpu"
```

Sau đó, thay đổi bố trí bộ nhớ của các thành phần `transformer` và `vae` trong pipeline thành `torch.channels-last`:

```python
pipeline.transformer.to(memory_format=torch.channels_last)
pipeline.vae.to(memory_format=torch.channels_last)
```

Cuối cùng, biên dịch các thành phần và chạy suy luận:

```python
pipeline.transformer = torch.compile(pipeline.transformer)
pipeline.vae.decode = torch.compile(pipeline.vae.decode)

video = pipeline(prompt="A dog wearing sunglasses floating in space, surreal, nebulae in background").frames[0]
```

Kết quả [benchmark](https://gist.github.com/a-r-r-o-w/4e1694ca46374793c0361d740a99ff19) trên máy A100 80GB là:

```
Without torch.compile(): Average inference time: 16.246 seconds.
With torch.compile(): Average inference time: 14.573 seconds.
```

## Lượng tử hóa

Quantization giúp giảm yêu cầu về bộ nhớ của các mô hình rất lớn bằng cách lưu trữ trọng số mô hình trong kiểu dữ liệu có độ chính xác thấp hơn. Tuy nhiên, lượng tử hóa có thể ảnh hưởng khác nhau đến chất lượng video tùy thuộc vào mô hình video.

Tham khảo phần tổng quan [Lượng tử hóa](../../quantization/overview) để tìm hiểu thêm về các backend lượng tử hóa được hỗ trợ và cách chọn một backend lượng tử hóa phù hợp với trường hợp sử dụng của bạn. Ví dụ bên dưới minh họa cách tải một [LattePipeline](/docs/diffusers/v0.43.0/vi/api/pipelines/latte#diffusers.LattePipeline) đã được lượng tử hóa để suy luận bằng bitsandbytes.

```py
import torch
from diffusers import BitsAndBytesConfig as DiffusersBitsAndBytesConfig, LatteTransformer3DModel, LattePipeline
from diffusers.utils import export_to_gif
from transformers import BitsAndBytesConfig as BitsAndBytesConfig, T5EncoderModel

quant_config = BitsAndBytesConfig(load_in_8bit=True)
text_encoder_8bit = T5EncoderModel.from_pretrained(
    "maxin-cn/Latte-1",
    subfolder="text_encoder",
    quantization_config=quant_config,
    dtype=torch.float16,
)

quant_config = DiffusersBitsAndBytesConfig(load_in_8bit=True)
transformer_8bit = LatteTransformer3DModel.from_pretrained(
    "maxin-cn/Latte-1",
    subfolder="transformer",
    quantization_config=quant_config,
    dtype=torch.float16,
)

pipeline = LattePipeline.from_pretrained(
    "maxin-cn/Latte-1",
    text_encoder=text_encoder_8bit,
    transformer=transformer_8bit,
    dtype=torch.float16,
    device_map="balanced",
)

prompt = "A small cactus with a happy face in the Sahara desert."
video = pipeline(prompt).frames[0]
export_to_gif(video, "latte.gif")
```

## LattePipeline[[diffusers.LattePipeline]]

#### diffusers.LattePipeline[[diffusers.LattePipeline]]

```python
diffusers.LattePipeline(tokenizer: T5Tokenizer, text_encoder: T5EncoderModel, vae: AutoencoderKL, transformer: LatteTransformer3DModel, scheduler: KarrasDiffusionSchedulers)
```

[Nguồn](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/pipelines/latte/pipeline_latte.py#L145)

**Tham số:**

vae ([AutoencoderKL](/docs/diffusers/v0.43.0/vi/api/models/autoencoderkl#diffusers.AutoencoderKL)) : Mô hình Variational Auto-Encoder (VAE) để mã hóa và giải mã video sang và từ các biểu diễn ẩn.

text_encoder (`T5EncoderModel`) : Bộ mã hóa văn bản đóng băng. Latte sử dụng [T5](https://huggingface.co/docs/transformers/model_doc/t5#transformers.T5EncoderModel), cụ thể là biến thể [t5-v1_1-xxl](https://huggingface.co/PixArt-alpha/PixArt-alpha/tree/main/t5-v1_1-xxl).

tokenizer (`T5Tokenizer`) : Tokenizer của lớp [T5Tokenizer](https://huggingface.co/docs/transformers/model_doc/t5#transformers.T5Tokenizer).

transformer ([LatteTransformer3DModel](/docs/diffusers/v0.43.0/vi/api/models/latte_transformer3d#diffusers.LatteTransformer3DModel)) : Một `LatteTransformer3DModel` có điều kiện văn bản để khử nhiễu các latents video đã mã hóa.

scheduler ([SchedulerMixin](/docs/diffusers/v0.43.0/vi/api/schedulers/overview#diffusers.SchedulerMixin)) : Một scheduler được sử dụng kết hợp với `transformer` để khử nhiễu các latents video đã được mã hóa.

Pipeline để tạo video từ văn bản sử dụng Latte.

Mô hình này kế thừa từ [DiffusionPipeline](/docs/diffusers/v0.43.0/vi/api/pipelines/overview#diffusers.DiffusionPipeline). 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 pipeline (chẳng hạn như tải xuống hoặc lưu, chạy trên một thiết bị cụ thể, v.v.)

#### __call__[[diffusers.LattePipeline.__call__]]

```python
__call__(prompt: str | list[str] = None, negative_prompt: str = '', num_inference_steps: int = 50, timesteps: list[int] | None = None, guidance_scale: float = 7.5, num_images_per_prompt: int = 1, video_length: int = 16, height: int = 512, width: int = 512, eta: float = 0.0, generator: typing.Union[torch.Generator, list[torch.Generator], NoneType] = None, latents: typing.Optional[torch.FloatTensor] = None, prompt_embeds: typing.Optional[torch.FloatTensor] = None, negative_prompt_embeds: typing.Optional[torch.FloatTensor] = None, output_type: str = 'pil', return_dict: bool = True, callback_on_step_end: typing.Union[typing.Callable[[int, int], NoneType], diffusers.callbacks.PipelineCallback, diffusers.callbacks.MultiPipelineCallbacks, NoneType] = None, callback_on_step_end_tensor_inputs: list[str] = ['latents'], clean_caption: bool = True, mask_feature: bool = True, enable_temporal_attentions: bool = True, decode_chunk_size: int = 14)
```

[Nguồn](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/pipelines/latte/pipeline_latte.py#L613)

**Tham số:**

prompt (`str` hoặc `list[str]`, *tùy chọn*) : Prompt hoặc các prompt để định hướng việc tạo video. Nếu không được định nghĩa, bạn phải truyền `prompt_embeds` thay thế.

negative_prompt (`str` hoặc `list[str]`, *tùy chọn*) : Prompt hoặc các prompt không được dùng để định hướng việc tạo video. Nếu không được định nghĩa, bạn phải truyền `negative_prompt_embeds` thay thế. Bỏ qua khi không sử dụng guidance (tức là bị bỏ qua nếu `guidance_scale` nhỏ hơn `1`).

num_inference_steps (`int`, *optional*, mặc định là 100) : Số bước khử nhiễu. Số bước khử nhiễu nhiều hơn thường dẫn đến video có chất lượng cao hơn, đổi lại là suy luận chậm hơn.

timesteps (`list[int]`, *optional*) : Các bước thời gian tùy chỉnh để sử dụng cho quá trình khử nhiễu. Nếu không được định nghĩa, các bước thời gian `num_inference_steps` cách đều sẽ được sử dụng. Phải được sắp xếp theo thứ tự giảm dần.

guidance_scale (`float`, *optional*, mặc định là 7.0) : Thang độ dẫn hướng như được định nghĩa trong [Classifier-Free Diffusion Guidance](https://huggingface.co/papers/2207.12598). `guidance_scale` được định nghĩa là `w` của phương trình 2. trong [Imagen Paper](https://huggingface.co/papers/2205.11487). Thang độ dẫn hướng được kích hoạt bằng cách đặt `guidance_scale > 1`. Thang độ dẫn hướng cao hơn khuyến khích tạo ra các video gắn kết chặt chẽ với `prompt` văn bản, thường phải đánh đổi bằng chất lượng video thấp hơn.

video_length (`int`, *tuỳ chọn*, mặc định là 16) : Số khung hình video được tạo ra. Mặc định là 16 khung hình, tương đương 8 khung hình mỗi giây

num_images_per_prompt (`int`, *tuỳ chọn*, mặc định là 1) : Số lượng video cần tạo cho mỗi prompt.

height (`int`, *tuỳ chọn*, mặc định là self.unet.config.sample_size) : Chiều cao tính bằng pixel của video được tạo ra.

width (`int`, *tuỳ chọn*, mặc định là self.unet.config.sample_size) : Độ rộng tính bằng pixel của video được tạo ra.

eta (`float`, *optional*, mặc định là 0.0) : Tương ứng với tham số eta (η) trong bài báo DDIM: https://huggingface.co/papers/2010.02502. Chỉ áp dụng cho [schedulers.DDIMScheduler](/docs/diffusers/v0.43.0/vi/api/schedulers/ddim#diffusers.DDIMScheduler), sẽ bị bỏ qua với các trình lập lịch khác.

generator (`torch.Generator` hoặc `list[torch.Generator]`, *tùy chọn*) : Một hoặc một danh sách [torch generator](https://pytorch.org/docs/stable/generated/torch.Generator.html) để đảm bảo quá trình sinh là tất định.

latents (`torch.FloatTensor`, *tùy chọn*) : Các latents nhiễu được tạo trước, lấy mẫu từ phân phối Gaussian, dùng làm đầu vào cho việc tạo video. Có thể dùng để tinh chỉnh cùng một quá trình tạo với các prompt khác nhau. Nếu không được cung cấp, một tensor latents sẽ được tạo bằng cách lấy mẫu sử dụng `generator` ngẫu nhiên được cung cấp.

prompt_embeds (`torch.FloatTensor`, *tùy chọn*) : Các vector nhúng văn bản đã được tạo trước. Có thể được sử dụng để dễ dàng điều chỉnh các đầu vào văn bản, *vd.* trọng số của prompt. Nếu không được cung cấp, các vector nhúng văn bản sẽ được tạo từ đối số đầu vào `prompt`.

negative_prompt_embeds (`torch.FloatTensor`, *tùy chọn*) : Các vector nhúng văn bản âm đã được tạo trước. Đối với Latte, prompt âm này nên là "". Nếu không được cung cấp, negative_prompt_embeds sẽ được tạo từ đối số đầu vào `negative_prompt`.

output_type (`str`, *tùy chọn*, mặc định là `"pil"`) : Định dạng đầu ra của video được tạo. Chọn giữa [PIL](https://pillow.readthedocs.io/en/stable/): `PIL.Image.Image` hoặc `np.array`.

return_dict (`bool`, *tùy chọn*, mặc định là `True`) : Có nên trả về một `~pipelines.stable_diffusion.IFPipelineOutput` thay vì một tuple thông thường hay không.

callback_on_step_end (`Callable[[int, int], None]`, `PipelineCallback`, `MultiPipelineCallbacks`, *optional*) : Một hàm callback hoặc danh sách các hàm callback sẽ được gọi vào cuối mỗi bước khử nhiễu.

callback_on_step_end_tensor_inputs (`list[str]`, *tùy chọn*) : Một danh sách các đầu vào tensor cần được truyền đến hàm callback. Nếu không được định nghĩa, tất cả các đầu vào tensor sẽ được truyền.

clean_caption (`bool`, *tùy chọn*, mặc định là `True`) : Có dọn dẹp chú thích trước khi tạo embeddings hay không. Yêu cầu `beautifulsoup4` và `ftfy` phải được cài đặt. Nếu các phụ thuộc này không được cài đặt, embeddings sẽ được tạo từ prompt thô.

mask_feature (`bool` mặc định là `True`) : Nếu được đặt thành `True`, các nhúng văn bản sẽ bị che.

enable_temporal_attentions (`bool`, *tùy chọn*, mặc định là `True`) : Có bật chú ý thời gian (temporal attentions) hay không

decode_chunk_size (`int`, *optional*) : Số khung hình cần giải mã mỗi lần. Chunk size lớn hơn giúp tăng tính nhất quán theo thời gian nhưng đổi lại là mức sử dụng bộ nhớ cao hơn. Mặc định, trình giải mã sẽ giải mã tất cả các khung hình cùng lúc để đạt chất lượng tối đa. Để giảm mức sử dụng bộ nhớ, hãy giảm `decode_chunk_size`.

**Trả về:** `LattePipelineOutput` hoặc `tuple`

Nếu `return_dict` là `True`, `LattePipelineOutput` sẽ được trả về, ngược lại một `tuple` sẽ được trả về trong đó phần tử đầu tiên là một danh sách chứa các hình ảnh đã tạo

Hàm được gọi khi gọi pipeline cho việc sinh.

Ví dụ:
```py
>>> import torch
>>> from diffusers import LattePipeline
>>> from diffusers.utils import export_to_gif

>>> # You can replace the checkpoint id with "maxin-cn/Latte-1" too.
>>> pipe = LattePipeline.from_pretrained("maxin-cn/Latte-1", torch_dtype=torch.float16)
>>> # Enable memory optimizations.
>>> pipe.enable_model_cpu_offload()

>>> prompt = "A small cactus with a happy face in the Sahara desert."
>>> videos = pipe(prompt).frames[0]
>>> export_to_gif(videos, "latte.gif")
```

#### encode_prompt[[diffusers.LattePipeline.encode_prompt]]

```python
encode_prompt(prompt: str | list[str], do_classifier_free_guidance: bool = True, negative_prompt: str = '', num_images_per_prompt: int = 1, device: typing.Optional[torch.device] = None, prompt_embeds: typing.Optional[torch.FloatTensor] = None, negative_prompt_embeds: typing.Optional[torch.FloatTensor] = None, clean_caption: bool = False, mask_feature: bool = True, dtype = None)
```

[Nguồn](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/pipelines/latte/pipeline_latte.py#L206)

**Tham số:**

prompt (`str` hoặc `list[str]`, *tùy chọn*) : prompt cần được mã hóa

negative_prompt (`str` hoặc `list[str]`, *tuỳ chọn*) : Prompt không dùng để định hướng việc tạo video. Nếu không được định nghĩa, cần truyền `negative_prompt_embeds` thay thế. Bỏ qua khi không sử dụng guidance (tức là bỏ qua nếu `guidance_scale` nhỏ hơn `1`). Đối với Latte, giá trị này nên là "".

do_classifier_free_guidance (`bool`, *tùy chọn*, mặc định là `True`) : có sử dụng classifier free guidance hay không

num_images_per_prompt (`int`, *tuỳ chọn*, mặc định là 1) : số lượng video cần được tạo cho mỗi prompt

device : (`torch.device`, *tùy chọn*): thiết bị torch để đặt các embedding kết quả lên

prompt_embeds (`torch.FloatTensor`, *tùy chọn*) : Các vector nhúng văn bản đã được tạo trước. Có thể được sử dụng để dễ dàng điều chỉnh các đầu vào văn bản, *vd.* trọng số của prompt. Nếu không được cung cấp, các vector nhúng văn bản sẽ được tạo từ đối số đầu vào `prompt`.

negative_prompt_embeds (`torch.FloatTensor`, *tùy chọn*) : Các vector nhúng văn bản âm đã được tạo trước. Đối với Latte, đây nên là các vector nhúng của chuỗi "".

clean_caption (bool, mặc định là `False`) : Nếu `True`, hàm sẽ tiền xử lý và làm sạch chú thích được cung cấp trước khi mã hóa.

mask_feature : (bool, mặc định là `True`): Nếu `True`, hàm sẽ che (mask) các nhúng văn bản.

Mã hóa prompt thành các trạng thái ẩn của text encoder.

