#
# Apache License, Version 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)

Monash University, Shanghai AI Lab, Nanjing University, Nanyang Technological University의 [Latte: Latent Diffusion Transformer for Video Generation](https://huggingface.co/papers/2401.03048).

해당 논문의 초록은 다음과 같습니다:

*본 논문에서는 비디오 생성을 위한 새로운 Latent Diffusion Transformer, 즉 Latte를 제안합니다. Latte는 먼저 입력 비디오에서 시공간 토큰을 추출한 후, 일련의 Transformer 블록을 채택하여 잠재 공간에서 비디오 분포를 모델링합니다. 비디오에서 추출된 상당한 수의 토큰을 모델링하기 위해, 입력 비디오의 공간 및 시간 차원을 분해하는 관점에서 네 가지 효율적인 변형이 도입되었습니다. 생성된 비디오의 품질을 향상시키기 위해, 비디오 클립 패치 임베딩, 모델 변형, 타임스텝-클래스 정보 주입, 시간 위치 임베딩, 학습 전략을 포함한 엄격한 실험적 분석을 통해 Latte의 최적 관행을 결정했습니다. 포괄적인 평가는 Latte가 FaceForensics, SkyTimelapse, UCF101, Taichi-HD라는 네 가지 표준 비디오 생성 데이터셋 전반에서 최첨단 성능을 달성함을 보여줍니다. 또한, Latte를 텍스트-비디오 생성(T2V) 작업으로 확장했으며, 여기서 Latte는 최근 T2V 모델과 비교할 만한 결과를 달성했습니다. 우리는 Latte가 비디오 생성을 위한 확산 모델에 Transformer를 통합하는 미래 연구에 귀중한 통찰력을 제공한다고 확신합니다.*

**주요 특징**: Latte는 다양한 모달리티를 모델링하기 위한 백본으로 제안된 잠재 확산 변환기(latent diffusion transformer)입니다(여기서는 텍스트-비디오 생성을 위해 학습됨). Latte는 [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]
> Scheduler의 [가이드](../../using-diffusers/schedulers)를 확인하여 스케줄러의 속도와 품질 사이의 트레이드오프를 탐색하는 방법을 배우고, [파이프라인 간 구성 요소 재사용](../../using-diffusers/loading#reusing-models-in-multiple-pipelines) 섹션을 확인하여 동일한 구성 요소를 여러 파이프라인에 효율적으로 로드하는 방법을 배워보세요.

### 추론

[`torch.compile`](https://huggingface.co/docs/diffusers/main/en/tutorials/fast_diffusion#torchcompile)를 사용하여 추론 지연 시간을 줄입니다.

먼저, 파이프라인을 로드합니다:

```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 머신에서 [벤치마크](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은 모델 가중치를 더 낮은 정밀도의 데이터 타입으로 저장하여 매우 큰 모델의 메모리 요구 사항을 줄이는 데 도움이 됩니다. 그러나 quantization은 비디오 모델에 따라 비디오 품질에 다양한 영향을 미칠 수 있습니다.

지원되는 양자화 백엔드와 사용 사례에 맞는 양자화 백엔드 선택에 대해 자세히 알아보려면 [Quantization](../../quantization/overview) 개요를 참조하세요. 아래 예제는 bitsandbytes를 사용하여 추론을 위해 양자화된 [LattePipeline](/docs/diffusers/main/ko/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/main/src/diffusers/pipelines/latte/pipeline_latte.py#L145)

**매개변수:**

vae ([AutoencoderKL](/docs/diffusers/main/ko/api/models/autoencoderkl#diffusers.AutoencoderKL)) : 비디오를 잠재 표현으로 인코딩하고 디코딩하는 Variational Auto-Encoder (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/main/ko/api/models/latte_transformer3d#diffusers.LatteTransformer3DModel)) : 텍스트 조건부 `LatteTransformer3DModel`로 인코딩된 비디오 라텐트를 디노이즈합니다.

scheduler ([SchedulerMixin](/docs/diffusers/main/ko/api/schedulers/overview#diffusers.SchedulerMixin)) : `transformer`와 함께 사용되어 인코딩된 비디오 latents의 노이즈를 제거하는 스케줄러입니다.

Latte를 사용한 텍스트-비디오 생성을 위한 Pipeline

이 모델은 [DiffusionPipeline](/docs/diffusers/main/ko/api/pipelines/overview#diffusers.DiffusionPipeline)에서 상속됩니다. 라이브러리가 모든 파이프라인에 대해 구현하는 일반적 메서드(다운로드 또는 저장, 특정 디바이스에서 실행 등)에 대해서는 상위 클래스 문서를 확인하세요.

#### __호출__[[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 = ['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/main/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]`, *선택 사항*) : 노이즈 제거 과정에 사용할 커스텀 timesteps입니다. 정의되지 않은 경우, 균등 간격의 `num_inference_steps` timesteps가 사용됩니다. 내림차순으로 정렬되어 있어야 합니다.

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 논문(https://huggingface.co/papers/2010.02502)의 파라미터 eta (η)에 해당합니다. [schedulers.DDIMScheduler](/docs/diffusers/main/ko/api/schedulers/ddim#diffusers.DDIMScheduler)에만 적용되며, 다른 스케줄러에서는 무시됩니다.

generator (`torch.Generator` 또는 `list[torch.Generator]`, *선택 사항*) : 생성을 결정적으로 만들기 위한 [torch generator](https://pytorch.org/docs/stable/generated/torch.Generator.html) 하나 또는 목록.

latents (`torch.FloatTensor`, *선택 사항*) : 가우시안 분포에서 샘플링하여 생성된 노이즈가 포함된 사전 생성된 latents로, 비디오 생성의 입력으로 사용됩니다. 동일한 생성을 다른 프롬프트로 조정하는 데 사용할 수 있습니다. 제공되지 않으면, 제공된 랜덤 `generator`를 사용하여 샘플링을 통해 latents 텐서가 생성됩니다.

prompt_embeds (`torch.FloatTensor`, *선택 사항*) : 미리 생성된 텍스트 임베딩입니다. 텍스트 입력을 쉽게 조정하는 데 사용할 수 있으며, *예를 들어* 프롬프트 가중치 설정에 활용할 수 있습니다. 제공되지 않으면 `prompt` 입력 인자로부터 텍스트 임베딩이 생성됩니다.

negative_prompt_embeds (`torch.FloatTensor`, *선택*) : 미리 생성된 부정 텍스트 임베딩입니다. Latte의 경우 이 negative prompt는 ""여야 합니다. 제공되지 않으면 `negative_prompt` 입력 인자로부터 negative_prompt_embeds가 생성됩니다.

output_type (`str`, *선택 사항*, 기본값 `"pil"`) : generate video의 출력 형식입니다. [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`, *선택 사항*) : 한 번에 디코딩할 프레임 수입니다. chunk size가 클수록 메모리 사용량이 증가하는 대신 시간적 일관성이 향상됩니다. 기본적으로 디코더는 최대 품질을 위해 모든 프레임을 한 번에 디코딩합니다. 메모리 사용량을 줄이려면 `decode_chunk_size`를 감소시키세요.

**반환값:** `LattePipelineOutput` 또는 `tuple`

`return_dict`가 `True`인 경우 `LattePipelineOutput`가 반환되고, 그렇지 않으면 첫 번째 요소가 생성된 이미지의 목록인 `tuple`이 반환됩니다.

생성을 위해 파이프라인을 호출할 때 호출되는 함수.

예:
```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/main/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`) : classifier free guidance를 사용할지 여부

num_images_per_prompt (`int`, *선택 사항*, 기본값 1) : 프롬프트당 생성할 비디오의 수

device : (`torch.device`, *선택 사항*): 생성된 임베딩을 배치할 torch device

prompt_embeds (`torch.FloatTensor`, *선택 사항*) : 미리 생성된 텍스트 임베딩입니다. 텍스트 입력을 쉽게 조정하는 데 사용할 수 있으며, *예를 들어* 프롬프트 가중치 설정에 활용할 수 있습니다. 제공되지 않으면 `prompt` 입력 인자로부터 텍스트 임베딩이 생성됩니다.

negative_prompt_embeds (`torch.FloatTensor`, *선택 사항*) : 미리 생성된 부정 텍스트 임베딩. Latte의 경우, "" 문자열의 임베딩이어야 합니다.

clean_caption (bool, 기본값 `False`) : `True`인 경우, 인코딩 전에 제공된 캡션을 전처리하고 정리합니다.

mask_feature : (bool, 기본값 `True`): `True`인 경우, 이 함수는 텍스트 임베딩을 마스킹합니다.

프롬프트를 텍스트 인코더의 히든 상태로 인코딩합니다.

