#
# 根据 Apache 许可证 2.0 版本（“许可证”）授权
# 您只能在遵守许可证的情况下使用本文件。
# 您可以在以下位置获取许可证副本
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# 除非适用法律要求或双方书面同意，软件
# 根据许可证分发，本软件按“原样”
# 不附带任何明示或暗示的保证或条件。
# 请参阅许可证中关于权限的具体语言
# 许可证下的限制。-->

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

该论文的摘要如下：

*我们提出了一种新颖的潜在扩散 Transformer，即 Latte，用于视频生成。Latte 首先从输入视频中提取时空 token，然后采用一系列 Transformer 块在潜在空间中建模视频分布。为了对从视频中提取的大量 token 进行建模，我们从分解输入视频的空间和时间维度的角度，引入了四种高效变体。为了提高生成视频的质量，我们通过严格的实验分析确定了 Latte 的最佳实践，包括视频片段 patch 嵌入、模型变体、时间步-类别信息注入、时间位置嵌入以及学习策略。我们的全面评估表明，Latte 在四个标准视频生成数据集（即 FaceForensics、SkyTimelapse、UCF101 和 Taichi-HD）上均达到了最先进的性能。此外，我们将 Latte 扩展到文本到视频生成（T2V）任务，其中 Latte 取得了与近期 T2V 模型相当的结果。我们坚信，Latte 为未来将 Transformer 融入扩散模型以进行视频生成的研究提供了宝贵的见解。*

**亮点**：Latte 是一种潜在扩散 Transformer，被提出作为建模不同模态的骨干网络（此处用于训练文本到视频生成）。它在四个标准视频基准测试——[FaceForensics](https://huggingface.co/papers/1803.09179)、[SkyTimelapse](https://huggingface.co/papers/1709.07592)、[UCF101](https://huggingface.co/papers/1212.0402) 和 [Taichi-HD](https://huggingface.co/papers/2003.00196)——上均达到了最先进的性能。如需准备并下载用于评估的数据集，请参阅 [此链接](https://github.com/Vchitect/Latte/blob/main/docs/datasets_evaluation.md)。

此流水线由 [maxin-cn](https://github.com/maxin-cn) 贡献。原始代码库可在[此处](https://github.com/Vchitect/Latte)找到。原始权重可在 [hf.co/maxin-cn](https://huggingface.co/maxin-cn) 下找到。

> [!TIP]
> 请务必参阅 [调度器指南](../../using-diffusers/schedulers)，了解如何探索调度器速度与质量之间的权衡，并查看 [跨流水线复用组件](../../using-diffusers/loading#reusing-models-in-multiple-pipelines) 部分，了解如何高效地将相同组件加载到多个流水线中。

### 推理

使用 [`torch.compile`](https://huggingface.co/docs/diffusers/main/en/tutorials/fast_diffusion#torchcompile) 来降低推理延迟。

首先，加载 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"
```

然后，将流水线中 `transformer` 和 `vae` 组件的内存布局更改为 `torch.channels-last`：

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

最后，编译组件并运行推理：

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

在 80GB A100 机器上的 [benchmark](https://gist.github.com/a-r-r-o-w/4e1694ca46374793c0361d740a99ff19) 结果如下：

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

## 量化

量化通过以较低精度的数据类型存储模型权重，有助于降低超大模型的内存需求。不过，量化对视频质量的影响会因视频模型的不同而有所差异。

请参阅 [量化](../../quantization/overview) 概述，以了解支持的量化后端以及如何选择支持您使用场景的量化后端。以下示例演示了如何使用 bitsandbytes 加载用于推理的量化 [LattePipeline](/docs/diffusers/v0.43.0/zh/api/pipelines/latte#diffusers.LattePipeline)。

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

[源代码](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/pipelines/latte/pipeline_latte.py#L145)

**参数：**

vae ([AutoencoderKL](/docs/diffusers/v0.43.0/zh/api/models/autoencoderkl#diffusers.AutoencoderKL))：用于将视频编码和解码到潜在表示的变分自编码器（VAE）模型。

text_encoder (`T5EncoderModel`)：冻结的文本编码器。Latte 使用 [T5](https://huggingface.co/docs/transformers/model_doc/t5#transformers.T5EncoderModel)，具体为 [t5-v1_1-xxl](https://huggingface.co/PixArt-alpha/PixArt-alpha/tree/main/t5-v1_1-xxl) 变体。

tokenizer (`T5Tokenizer`)：[T5Tokenizer](https://huggingface.co/docs/transformers/model_doc/t5#transformers.T5Tokenizer) 类的分词器。

transformer ([LatteTransformer3DModel](/docs/diffusers/v0.43.0/zh/api/models/latte_transformer3d#diffusers.LatteTransformer3DModel))：一个以文本为条件的 `LatteTransformer3DModel`，用于对编码后的视频潜变量进行去噪。

scheduler ([SchedulerMixin](/docs/diffusers/v0.43.0/zh/api/schedulers/overview#diffusers.SchedulerMixin))：用于与 `transformer` 配合，对编码后的视频潜变量进行去噪的调度器。

使用 Latte 进行文本到视频生成的 Pipeline。

该模型继承自 [DiffusionPipeline](/docs/diffusers/v0.43.0/zh/api/pipelines/overview#diffusers.DiffusionPipeline)。请查阅父类文档，了解该库为所有 pipeline 实现的通用方法（例如下载或保存、在特定设备上运行等）。

#### __调用__[[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)
```

[源代码](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/pipelines/latte/pipeline_latte.py#L613)

**参数：**

prompt (`str` 或 `list[str]`，*可选*)：用于引导视频生成的提示词或提示词列表。如果未定义，则必须改为传入 `prompt_embeds`。

negative_prompt (`str` 或 `list[str]`，*可选*)：用于引导视频生成的负面提示词或提示词列表。如果未定义，则必须传入 `negative_prompt_embeds`。在未使用引导时（即 `guidance_scale` 小于 `1` 时）将被忽略。

num_inference_steps (`int`，*可选*，默认值为 100)：去噪步数。更多的去噪步数通常能带来更高质量的视频，但代价是推理速度变慢。

timesteps (`list[int]`, *可选*) : 用于去噪过程的自定义时间步。如果未定义，则使用等间距的 `num_inference_steps` 个时间步。必须按降序排列。

guidance_scale (`float`，*可选*，默认值为 7.0)：如[Classifier-Free Diffusion Guidance](https://huggingface.co/papers/2207.12598)中定义的引导尺度。`guidance_scale` 定义为 [Imagen Paper](https://huggingface.co/papers/2205.11487) 中公式 2 的 `w`。通过设置 `guidance_scale > 1` 来启用引导尺度。较高的引导尺度会促使生成与文本 `prompt` 紧密关联的视频，但通常以牺牲视频质量为代价。

video_length (`int`，*可选*，默认为 16)：生成的视频帧数。默认为 16 帧，即每秒 8 帧

num_images_per_prompt (`int`，*可选*，默认为 1)：每个提示词生成的视频数量。

height (`int`，*可选*，默认为 self.unet.config.sample_size)：生成视频的高度（以像素为单位）。

width (`int`，*可选*，默认为 self.unet.config.sample_size)：生成视频的像素宽度。

eta (`float`，*可选*，默认值为 0.0)：对应 DDIM 论文中的参数 eta (η)：https://huggingface.co/papers/2010.02502。仅适用于 [schedulers.DDIMScheduler](/docs/diffusers/v0.43.0/zh/api/schedulers/ddim#diffusers.DDIMScheduler)，对其他调度器将被忽略。

generator (`torch.Generator` 或 `list[torch.Generator]`，*可选*)：一个或一组 [torch 生成器](https://pytorch.org/docs/stable/generated/torch.Generator.html)，用于使生成过程具有确定性。

latents (`torch.FloatTensor`, *可选*) : 预生成的噪声潜变量，从高斯分布中采样得到，用作视频生成的输入。可用于以不同的提示词微调同一生成过程。如果未提供，将通过使用提供的随机`generator`进行采样来生成潜变量张量。

prompt_embeds (`torch.FloatTensor`，*可选*)：预生成的文本嵌入。可用于轻松调整文本输入，*例如*提示词加权。如果未提供，则将从 `prompt` 输入参数生成文本嵌入。

negative_prompt_embeds (`torch.FloatTensor`, *可选*) : 预生成的负向文本嵌入。对于 Latte，此负向提示应为 ""。如果未提供，negative_prompt_embeds 将根据 `negative_prompt` 输入参数生成。

output_type (`str`，*可选*，默认为 `"pil"`)：生成视频的输出格式。可选 [PIL](https://pillow.readthedocs.io/en/stable/)：`PIL.Image.Image` 或 `np.array`。

return_dict (`bool`，*可选*，默认为 `True`)：是否返回 `~pipelines.stable_diffusion.IFPipelineOutput` 而不是普通元组。

callback_on_step_end (`Callable[[int, int], None]`、`PipelineCallback`、`MultiPipelineCallbacks`、*可选*)：在每个去噪步骤结束时调用的回调函数或回调函数列表。

callback_on_step_end_tensor_inputs (`list[str]`，*可选*) : 应传递给回调函数的张量输入列表。如果未定义，则所有张量输入都会被传递。

clean_caption (`bool`，*可选*，默认为 `True`)：是否在创建嵌入之前清理字幕。需要安装 `beautifulsoup4` 和 `ftfy`。如果未安装这些依赖项，嵌入将直接从原始提示创建。

mask_feature (`bool`，默认为 `True`)：如果设置为 `True`，则文本嵌入将被屏蔽。

enable_temporal_attentions (`bool`，*可选*，默认为 `True`)：是否启用时间注意力

decode_chunk_size (`int`，*可选*)：每次解码的帧数。较大的块大小可提升时间一致性，但会增加内存占用。默认情况下，解码器会一次性解码所有帧以获得最佳质量。如需降低内存占用，请减小 `decode_chunk_size`。

**返回：** `LattePipelineOutput` 或 `tuple`

如果 `return_dict` 为 `True`，则返回 `LattePipelineOutput`，否则返回一个 `tuple`，其中第一个元素是包含生成图像的列表

调用生成 pipeline 时调用的函数。

示例：
```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)
```

[源代码](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/pipelines/latte/pipeline_latte.py#L206)

**参数：**

prompt (`str` 或 `list[str]`，*可选*)：要编码的提示

negative_prompt (`str` 或 `list[str]`，*可选*)：用于引导视频生成的负面提示词。如果未定义，则必须传入 `negative_prompt_embeds`。在未使用引导时会被忽略（即当 `guidance_scale` 小于 `1` 时会被忽略）。对于 Latte，此值应为 ""。

do_classifier_free_guidance (`bool`，*可选*，默认为 `True`)：是否使用无分类器引导

num_images_per_prompt (`int`，*可选*，默认为 1)：每个提示词应生成的视频数量

device : (`torch.device`, *可选*): 用于放置生成的嵌入的 torch 设备

prompt_embeds (`torch.FloatTensor`，*可选*)：预生成的文本嵌入。可用于轻松调整文本输入，*例如*提示词加权。如果未提供，则将从 `prompt` 输入参数生成文本嵌入。

negative_prompt_embeds (`torch.FloatTensor`, *可选*) : 预生成的负文本嵌入。对于 Latte，它应该是 "" 字符串的嵌入。

clean_caption (bool, 默认为 `False`) : 如果 `True`，该函数将在编码之前对提供的字幕进行预处理和清理。

mask_feature : (bool, 默认为 `True`): 如果 `True`，该函数将屏蔽文本嵌入。

将提示词编码为文本编码器的隐藏状态。

