# SANA-WM

SANA-WM은 SANA를 기반으로 구축된 카메라 제어 이미지-비디오 월드 모델입니다. 첫 프레임 이미지, 텍스트 프롬프트, 카메라 궤도(명시적인 `c2w` 포즈 또는 WASD/IJKL 액션 문자열)를 입력으로 받아, 요청된 카메라 경로를 따르는 움직임이 포함된 비디오를 생성합니다.

Inference는 두 단계로 실행됩니다:

1. **1단계 — SANA-WM DiT.** GDN-Triton 선형 어텐션과 UCPE 카메라 제어 분기를 갖춘 1.6B 파라미터 양방향 DiT입니다. 샘플링에는 토큰별 타임스텝을 사용하는 LTX 스타일 플로우 매칭 오일러 스케줄러를 사용하며, 첫 번째 잠재 프레임이 조건부 앵커 역할을 합니다.
2. **Stage 2 — LTX-2 refiner (선택 사항).** [SanaWMLTX2RefinerTransformer3DModel](/docs/diffusers/main/ko/api/models/sana_wm_refiner_transformer3d#diffusers.SanaWMLTX2RefinerTransformer3DModel) + `LTX2TextConnectors`와 Gemma-3 텍스트 인코더를 래핑하는 독립적인 sink-bidirectional Euler refiner 파이프라인([SanaWMLTX2Refiner](/docs/diffusers/main/ko/api/pipelines/sana_wm#diffusers.SanaWMLTX2Refiner))으로, 3개의 증류된 sigma 단계 동안 실행됩니다.

두 단계 모두 [AutoencoderKLLTX2Video](/docs/diffusers/main/ko/api/models/autoencoderkl_ltx_2#diffusers.AutoencoderKLLTX2Video) VAE를 통해 디코딩됩니다.

사용 가능한 모델:

| 모델 | 권장 dtype |
|:-----:|:-----------------:|
| [`Efficient-Large-Model/SANA-WM_bidirectional-diffusers`](https://huggingface.co/Efficient-Large-Model/SANA-WM_bidirectional-diffusers) | `torch.bfloat16` |
| [`Efficient-Large-Model/SANA-WM_bidirectional-diffusers-refiner`](https://huggingface.co/Efficient-Large-Model/SANA-WM_bidirectional-diffusers-refiner) | `torch.bfloat16` |

> [!TIP]
> SANA-WM은 고정된 704×1280 해상도로 학습됩니다. transformer 가중치에 권장되는 dtype는 `torch.bfloat16`이며, 최적의 수치 안정성을 위해 텍스트 인코더는 `torch.bfloat16`, VAE는 `torch.float32`로 유지하세요. 파이프라인은 *원본 이미지* 픽셀 좌표계의 카메라 내재적 `[fx, fy, cx, cy]`를 기대하며, 리사이즈 및 중앙 크롭 변환은 내부적으로 적용됩니다.

## 추론

```python
import torch
from PIL import Image

from diffusers import SanaWMPipeline
from diffusers.utils import export_to_video

pipe = SanaWMPipeline.from_pretrained(
    "Efficient-Large-Model/SANA-WM_bidirectional-diffusers",
    torch_dtype=torch.bfloat16,
)
pipe.enable_model_cpu_offload()  # ~45 GB of weights — offload between stages

# SANA-WM was trained on the LTX-2 VAE in framewise mode with tiling enabled. Without these
# settings the VAE encodes the whole (B, C, T, H, W) clip in one shot, which gives subtly
# different numerics from the released checkpoint.
pipe.vae.enable_tiling()
pipe.vae.use_framewise_encoding = True
pipe.vae.use_framewise_decoding = True
pipe.vae.tile_sample_stride_num_frames = 64
pipe.vae.tile_sample_min_num_frames = 96

prompt = "A car driving across a vast desert plain at golden hour."
output = pipe(
    image=Image.open("input.png").convert("RGB"),
    prompt=prompt,
    action="w-80,jw-40,w-40",        # WASD-style action DSL: forward 80f, jump+forward 40f, forward 40f
    intrinsics=[800.0, 800.0, 845.0, 464.0],  # fx, fy, cx, cy in original-image pixels
    num_frames=161,
    num_inference_steps=60,
    guidance_scale=5.0,
    generator=torch.Generator(device="cuda").manual_seed(42),
    output_type="latent",            # hand the latents to the refiner below
)
```

`action=None`를 전달하고 자체 `c2w` 포즈(`(F, 4, 4)` numpy 배열)를 제공하여 카메라 궤적을 명시적으로 제어합니다. `output_type="latent"`를 제거하면 1단계에서 바로 비디오를 얻고 리파이너를 건너뛸 수 있습니다.

### Stage 2 — LTX-2 리파이너

[SanaWMLTX2Refiner](/docs/diffusers/main/ko/api/pipelines/sana_wm#diffusers.SanaWMLTX2Refiner)는 SDXL이 base와 refiner를 분리하는 방식과 마찬가지로 자체 저장소로 제공됩니다. 가중치가 두 번 로드되지 않고 공유되도록 base 파이프라인의 VAE를 전달하세요:

```python
from diffusers import SanaWMLTX2Refiner

refiner = SanaWMLTX2Refiner.from_pretrained(
    "Efficient-Large-Model/SANA-WM_bidirectional-diffusers-refiner",
    vae=pipe.vae,
    torch_dtype=torch.bfloat16,
)
refiner.enable_model_cpu_offload()

frames = refiner(output.latent, prompt, fps=16)
export_to_video(list(frames), "sana_wm.mp4", fps=16)
```

`vae`가 없으면 refiner는 비디오 대신 정제된 latents를 반환합니다. 이는 직접 디코딩을 원하는 경우 유용합니다.

> [!TIP]
> **두** 파이프라인 모두에서 offloading을 활성화하거나, stage 2를 실행하기 전에 stage 1을 해제(`pipe.transformer.to("cpu")`)할 수 있습니다. 두 stage의 합계는 `torch.bfloat16`에서 약 45 GB이며, 두 stage를 모두 80 GB 카드 하나에 상주시키면 activations를 위한 여유 공간이 부족합니다. 또한 stage 2는 `torch_dtype`을 따르므로, refiner를 `torch.float32`로 로드하면 메모리가 약 2배로 증가하고 출력이 약간 달라집니다.

카메라 내재적 매개변수(camera intrinsics)가 없는 경우, 호스팅된 [모듈형 블록(modular block)](../../modular_diffusers/overview)을 사용하여 단일 프레임에서 이를 추정할 수 있습니다. 이 블록은 Pi3X를 가져오기 때문에 `diffusers` 외부에 위치합니다. Pi3X는 추가적인 의존성과 두 번째 체크포인트를 의미하므로, 사용자가 요청할 때까지 아무것도 다운로드되지 않습니다:

```python
from diffusers import ModularPipeline

# One-time per image. Requires `pip install pi3-vision`.
estimator = ModularPipeline.from_pretrained(
    "Efficient-Large-Model/pi3x-intrinsics-estimator", trust_remote_code=True
)
estimator.load_components(dtype=torch.bfloat16)
intrinsics = estimator(image=Image.open("input.png").convert("RGB"), output="intrinsics")
```

## 발행된 체크포인트 변환

소스 SANA-WM 릴리스(사전 변환된 diffusers 스냅샷이 아닌)를 가지고 있다면, 변환 스크립트를 한 번 실행하세요:

```bash
python scripts/convert_sana_wm_to_diffusers.py \
    --src Efficient-Large-Model/SANA-WM_bidirectional \
    --dst ./SANA-WM_bidirectional-diffusers
```

이 명령은 두 개의 디렉터리를 작성합니다. 기본 파이프라인은 `--dst`에, stage-2 refiner는 `./SANA-WM_bidirectional-diffusers-refiner`에 함께 생성됩니다(`--dst-refiner`로 덮어쓸 수 있음). 이후 각 경로를 로컬 경로에서 일반적 방식으로 로드합니다.

## 구성 요소

- `tokenizer` — `GemmaTokenizerFast`
- `text_encoder` — Gemma-2 (디코더 히든 상태를 반환)
- `vae` — [AutoencoderKLLTX2Video](/docs/diffusers/main/ko/api/models/autoencoderkl_ltx_2#diffusers.AutoencoderKLLTX2Video) (LTX-2, 공간 ×32 / 시간 ×8)
- `transformer` — [SanaWMTransformer3DModel](/docs/diffusers/main/ko/api/models/sana_wm_transformer3d#diffusers.SanaWMTransformer3DModel), 16억 파라미터 양방향 DiT
- `scheduler` — [FlowMatchEulerDiscreteScheduler](/docs/diffusers/main/ko/api/schedulers/flow_match_euler_discrete#diffusers.FlowMatchEulerDiscreteScheduler)

stage-2 refiner는 자체 `transformer`([SanaWMLTX2RefinerTransformer3DModel](/docs/diffusers/main/ko/api/models/sana_wm_refiner_transformer3d#diffusers.SanaWMLTX2RefinerTransformer3DModel)), `connectors`(`LTX2TextConnectors`), `tokenizer`, Gemma-3 `text_encoder` 및 `scheduler`를 갖춘 별도의 저장소입니다. 자체 `vae`가 없으므로 base pipeline의 것을 전달해야 합니다.

## SanaWMPipeline[[diffusers.SanaWMPipeline]]

#### diffusers.SanaWMPipeline[[diffusers.SanaWMPipeline]]

```python
diffusers.SanaWMPipeline(tokenizer: GemmaTokenizer | GemmaTokenizerFast, text_encoder: Gemma2PreTrainedModel, vae: AutoencoderKLLTX2Video, transformer: SanaWMTransformer3DModel, scheduler: FlowMatchEulerDiscreteScheduler)
```

[소스](https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/sana_wm/pipeline_sana_wm.py#L143)

**매개변수:**

tokenizer ([*GemmaTokenizer*] 또는 [*GemmaTokenizerFast*]) : Gemma-2 토크나이저.

text_encoder ([*Gemma2PreTrainedModel*]) : Gemma-2 텍스트 인코더입니다.

vae ([*AutoencoderKLLTX2Video*]) : LTX-2 VAE입니다.

transformer ([*SanaWMTransformer3DModel*]) : 1600M 양방향 SANA-WM DiT입니다.

scheduler ([*FlowMatchEulerDiscreteScheduler*]) : Flow-matching Euler 스케줄러 (LTX 스타일의 토큰별 timesteps). latents를 직접

SANA-WM 카메라 제어 이미지-비디오 파이프라인.

첫 프레임 이미지, 텍스트 프롬프트, 카메라 궤도(명시적 `c2w` 포즈 또는 WASD/IJKL 액션 문자열)를 사용하여 비디오를 생성합니다. 1단계 샘플링에는 1600M 양방향 SANA DiT를, 2단계 정제에는 LTX-2 sink-bidirectional Euler refiner를 사용하며, 두 단계 모두 LTX-2 VAE를 통해 디코딩됩니다.

#### __호출__[[diffusers.SanaWMPipeline.__call__]]

```python
__call__(image: PIL.Image.Image | str | Path, prompt: str, c2w: np.ndarray | None = None, action: str | None = None, intrinsics: np.ndarray | list[float] | None = None, height: int = 704, width: int = 1280, num_frames: int = 161, fps: int = 16, num_inference_steps: int = 60, guidance_scale: float = 5.0, negative_prompt: str = '', generator: torch.Generator | list[torch.Generator] | None = None, prompt_embeds: torch.Tensor | None = None, prompt_attention_mask: torch.Tensor | None = None, negative_prompt_embeds: torch.Tensor | None = None, negative_prompt_attention_mask: torch.Tensor | None = None, max_sequence_length: int = 300, chi_prompt: list[str] | None = None, output_type: Literal['np', 'pil', 'pt', 'latent'] = 'np', callback_on_step_end: Callable[[DiffusionPipeline, int, int, dict], dict] | None = None, callback_on_step_end_tensor_inputs: list[str] = ['latents'], return_dict: bool = True)
```

[소스](https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/sana_wm/pipeline_sana_wm.py#L457)

**매개변수:**

image (*PIL.Image.Image* 또는 *str*) : 첫 번째 프레임 이미지 (PIL 또는 경로).

prompt (*str*) : 텍스트 프롬프트.

c2w (*np.ndarray*, *선택 사항*) : `(F, 4, 4)` 카메라에서 세계 좌표계로의 포즈. *action*과 상호 배타적입니다.

action (*str*, *선택 사항*) : `"w-80,jw-40,w-40"`과 같은 Action-DSL 문자열. *c2w*와 상호 배타적입니다.

intrinsics (*np.ndarray* 또는 *list[float]*) : **원본 이미지** 픽셀 좌표계의 `[fx, fy, cx, cy]`. 파이프라인은 내부적으로 리사이즈+크롭 변환을 적용합니다.

height (*int*, 기본값 704) : 출력 프레임 높이 (공개 모델의 경우 고정됨).

width (*int*, 기본값 1280) : 출력 프레임의 너비 (공개 모델의 경우 고정됨).

num_frames (*int*, 기본값 161) : 대상 프레임 수; `8k+1`로 정렬됩니다 (LTX-2 VAE 제약 조건).

fps (*int*, 기본값 16) : 출력 프레임 속도(리파이너에도 전달됨).

num_inference_steps (*int*, 기본값 60) : 1단계 DiT 샘플링 단계 수.

guidance_scale (*float*, 기본값 5.0) : Classifier-free guidance scale입니다.

negative_prompt (*str*, 기본값 "") : 선택적 negative prompt입니다.

generator (*torch.Generator* 또는 *list[torch.Generator]*, *optional*) : 노이즈 샘플링을 결정적으로 만들기 위한 하나 이상의 torch 생성기입니다. *None*인 경우 샘플링은 비결정적입니다.

prompt_embeds (*torch.Tensor*, *선택*) : 텍스트 인코더를 건너뛰기 위해 사전 계산된 텍스트 임베딩입니다. *prompt_attention_mask*와 함께 전달해야 합니다.

prompt_attention_mask (*torch.Tensor*, *선택*) : *prompt_embeds*에 대한 어텐션 마스크입니다.

negative_prompt_embeds (*torch.Tensor*, *선택*) : 사전 계산된 부정 텍스트 임베딩입니다. *negative_prompt_attention_mask*와 함께 전달해야 합니다.

negative_prompt_attention_mask (*torch.Tensor*, *선택*) : *negative_prompt_embeds*에 대한 어텐션 마스크입니다.

max_sequence_length (*int*, 기본값 300) : 최대 프롬프트 토큰 수.

chi_prompt (*list[str]*, *선택*) : chi-prompt 접두사를 재정의합니다(기본값은 공개 릴리스와 동일합니다).

output_type (*"np"*, *"pil"*, *"pt"* 또는 *"latent"*, 기본값은 *"np"*) : 출력 형식.

callback_on_step_end (*Callable*, *선택 사항*) : *callback_on_step_end_tensor_inputs*에 명시된 텐서를 *callback_kwargs*가 포함하도록, 각 디노이징 단계의 끝에서 *callback_on_step_end(self, step, timestep, callback_kwargs)*로 호출됩니다. 반환된 dict의 텐서는 파이프라인의 텐서를 대체합니다.

callback_on_step_end_tensor_inputs (*list[str]*, 기본값 *["latents"]*) : *callback_on_step_end*에 전달할 텐서를 지정합니다. *._callback_tensor_inputs*의 부분 집합이어야 합니다.

return_dict (*bool*, 기본값 True) : [*SanaWMPipelineOutput*] 또는 tuple을 반환합니다.

**반환값:**

`(T, H, W, 3)` 모양의 *.frames*를 가진 [*SanaWMPipelineOutput*]. *output_type="np"*인 경우 `[0, 1]` 범위의 float `np.ndarray`, *"pil"*인 경우 길이 `T`의 `PIL.Image.Image` 목록, *"pt"*인 경우 `(T, 3, H, W)` 텐서, 또는 *"latent"*인 경우 원시 latent 텐서를 반환합니다.

SANA-WM 카메라 제어 비디오를 생성합니다.

예:
```py
>>> import torch
>>> from PIL import Image
>>> from diffusers import SanaWMPipeline

>>> pipe = SanaWMPipeline.from_pretrained(
...     "Efficient-Large-Model/SANA-WM_bidirectional-diffusers", torch_dtype=torch.bfloat16
... ).to("cuda")

>>> output = pipe(
...     image=Image.open("input.png").convert("RGB"),
...     prompt="A car driving across a vast desert plain at golden hour.",
...     action="w-80,jw-40,w-40",
...     intrinsics=[800.0, 800.0, 845.0, 464.0],  # fx, fy, cx, cy in original-image pixels
...     num_inference_steps=60,
... )
>>> # output.frames is (T, H, W, 3) float np.ndarray in [0, 1] (diffusers convention).
```

#### check_inputs[[diffusers.SanaWMPipeline.check_inputs]]

```python
check_inputs(c2w: np.ndarray | None, action: str | None, intrinsics: np.ndarray | list[float] | None, callback_on_step_end_tensor_inputs: list[str] | None = None)
```

[소스](https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/sana_wm/pipeline_sana_wm.py#L335)

`__call__` 입력을 검증합니다. 잘못된 입력인 경우 예외를 발생시키고 아무것도 반환하지 않습니다.

#### encode_prompt[[diffusers.SanaWMPipeline.encode_prompt]]

```python
encode_prompt(prompt: str, negative_prompt: str = '', device: torch.device | None = None, max_sequence_length: int = 300, chi_prompt: list[str] | None = None, prompt_embeds: torch.Tensor | None = None, prompt_attention_mask: torch.Tensor | None = None, negative_prompt_embeds: torch.Tensor | None = None, negative_prompt_attention_mask: torch.Tensor | None = None)
```

[소스](https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/sana_wm/pipeline_sana_wm.py#L204)

**반환값:**

`(cond, cond_mask, neg, neg_mask)` 여기서 `cond`와 `neg`는 `(1, 1, L, D)` 형태의 Gemma hidden states이고, 마스크는 `(1, L)`입니다.

Gemma-2를 통해 프롬프트와 네거티브 프롬프트를 인코딩합니다.

SANA의 chi-prompt-prefix 트릭을 따릅니다: chi 프롬프트를 사용자 프롬프트 앞에 붙인 후, `select_index = [0, -L+1, ..., -1]` 슬라이스로 BOS 토큰과 마지막 `max_sequence_length - 1`개의 토큰을 가져옵니다.

#### prepare_camera_trajectory[[diffusers.SanaWMPipeline.prepare_camera_trajectory]]

```python
prepare_camera_trajectory(c2w: np.ndarray | None, action: str | None, intrinsics: np.ndarray | list[float], num_frames: int)
```

[소스](https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/sana_wm/pipeline_sana_wm.py#L365)

카메라 입력을 `(c2w_(F, 4, 4), intrinsics_(F, 4))`로 정규화합니다.

`num_frames`을 VAE에 적합한 `8k+1`로 정렬하고 두 배열을 일치하도록 잘라냅니다. 잘린 이미지와 재조정된 내재적 매개변수는 대상 해상도가 알려진 후에 제공됩니다.

#### prepare_latents[[diffusers.SanaWMPipeline.prepare_latents]]

```python
prepare_latents(first_latent: torch.Tensor, num_frames: int, height: int, width: int, dtype: torch.dtype, device: torch.device, generator: torch.Generator)
```

[소스](https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/sana_wm/pipeline_sana_wm.py#L403)

초기 latents를 샘플링하고 첫 번째 프레임을 conditioning anchor로 고정합니다.

`(latents, condition_mask)`을 반환합니다. 여기서 `condition_mask`는 첫 번째 프레임의 토큰에 1을, 나머지 부분에 0을 가집니다(첫 번째 프레임의 토큰은 샘플링 전체 과정에서 깨끗한 상태로 유지됩니다).

## SanaWMLTX2Refiner[[diffusers.SanaWMLTX2Refiner]]

LTX-2 stage-2 refiner는 stage-1 latents를 입력으로 받는 독립형 [DiffusionPipeline](/docs/diffusers/main/ko/api/pipelines/overview#diffusers.DiffusionPipeline)입니다. `vae`(기본 파이프라인의 vae로, 가중치가 공유됩니다)을 제공하면 비디오로 디코딩하며, 제공하지 않으면 정제된 latents를 반환합니다.

#### diffusers.SanaWMLTX2Refiner[[diffusers.SanaWMLTX2Refiner]]

```python
diffusers.SanaWMLTX2Refiner(transformer: SanaWMLTX2RefinerTransformer3DModel, connectors: LTX2TextConnectors, tokenizer: GemmaTokenizer | GemmaTokenizerFast, text_encoder: Gemma3ForConditionalGeneration, scheduler: FlowMatchEulerDiscreteScheduler, vae: AutoencoderKLLTX2Video | None = None, text_max_sequence_length: int = 1024)
```

[소스](https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/sana_wm/refiner.py#L47)

**매개변수:**

transformer ([*SanaWMLTX2RefinerTransformer3DModel*]) : chunk-causal sliding-window KV 캐시를 사용하는 LTX-2 비디오 DiT입니다.

connectors ([*LTX2TextConnectors*]) : LTX-2 텍스트 커넥터입니다.

tokenizer : Gemma-3 토크나이저.

text_encoder : Gemma-3 텍스트 인코더.

scheduler ([*FlowMatchEulerDiscreteScheduler*]) : Flow-matching Euler 스케줄러입니다. `shift=1.0`으로 생성되어 증류된 시그마가 수정되지 않고 그대로 통과합니다.

vae ([*AutoencoderKLLTX2Video*], *선택*) : [*SanaWMPipeline*]에서 사용하는 것과 동일한 VAE입니다. 가중치를 공유하려면 *vae=pipe.vae*를 전달하세요. 값이 주어지면 리파이너는 비디오로 디코딩하고, 그렇지 않으면 정제된 latents를 반환합니다.

text_max_sequence_length (*int*, 기본값 1024) : Gemma-3 토크나이저에 전달되는 최대 토큰 수.

LTX-2 sink-bidirectional Euler refiner — SANA-WM stage 2, 독립형 파이프라인으로.

LTX-2 구성 요소(리파이너 트랜스포머 + 텍스트 커넥터 + Gemma-3 텍스트 인코더 + 토크나이저)와 증류된 시그마 스케줄을 포함하고 오일러 스텝을 수행하는 [*FlowMatchEulerDiscreteScheduler*]를 래핑합니다. [*SanaWMPipeline*]의 선택적 구성 요소로 등록되며, 1단계 레이턴트를 정제하기 위해 단독으로도 사용할 수 있습니다.

#### __호출__[[diffusers.SanaWMLTX2Refiner.__call__]]

```python
__call__(sana_latent: torch.Tensor, prompt: str, fps: float, sink_size: int = 1, generator: torch.Generator | None = None, block_size: int = 3, kv_max_frames: int = 11, sigmas: tuple[float, ...] = (0.909375, 0.725, 0.421875, 0.0), output_type: str = 'np')
```

[소스](https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/sana_wm/refiner.py#L107)

**매개변수:**

sana_latent : `(B, C, F, H, W)` 단계 1 잠재 변수.

prompt : 텍스트 프롬프트.

fps : 비디오 프레임 속도(LTX-2 RoPE 시간 스케일링을 제어합니다).

sink_size : attention sink으로 고정할 앞쪽의 원시 `z_sana` 프레임 수 (기본값: 1).

generator : FM 엔드포인트 노이즈에 사용되는 torch.Generator. 기본적으로 42로 시드된 생성기를 사용하여 결과의 재현성을 보장합니다.

block_size : AR 블록당 잠재 프레임 수 (기본값: 3).

kv_max_frames : 슬라이딩 윈도우에 유지되는 최대 컨텍스트+활성 프레임 수 (기본값: 11 = 1 sink + 10 recent).

sigmas : 0.0에서 종료되는 내림차순 Euler 스케줄(정규화된 3단계 증류: `(0.909375, 0.725, 0.421875, 0.0)`). `self.scheduler`에 전달되며, 마지막의 0.0은 제외됩니다(스케줄러가 자체적으로 추가함).

output_type : *"latent"*은 정제된 latents를 반환합니다. 그 외의 값은 *self.vae*를 통해 디코딩한 후 해당 유형(*"np"*, *"pt"*, *"pil"*)으로 후처리합니다. *vae*가 없으면 어떤 경우에도 latents가 반환됩니다.

**반환값:** `*torch.Tensor*`

`(B, C, F, H, W)` 형태의 정제된 VAE latents — 처음 `sink_size` 프레임은 변경되지 않은 raw stage-1 sink latents를 포함하고, 나머지 프레임은 정제된 출력을 포함합니다.

LTX-2 리파이너를 실행하고 정제된 VAE 잠재를 반환합니다.

모델 학습에 사용된 chunk-causal AR 레시피(`block_size=3`, `kv_max_frames=11`)를 사용합니다. `[source_sink + recent_history + active_block]` 슬라이딩 윈도우의 K/V를 블록 단위로 transformer에 입력하므로 블록별 계산량이 제한되고, 전체 리파인 비용은 비디오 길이에 선형으로 비례합니다.

## SanaWMPipelineOutput[[diffusers.SanaWMPipelineOutput]]

#### diffusers.SanaWMPipelineOutput[[diffusers.SanaWMPipelineOutput]]

```python
diffusers.SanaWMPipelineOutput(frames: typing.Union[torch.Tensor, numpy.ndarray, list[list[PIL.Image.Image]]], c2w: numpy.ndarray | None = None, latent: typing.Optional[torch.Tensor] = None)
```

[소스](https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/sana_wm/pipeline_output.py#L25)

**매개변수:**

frames (*torch.Tensor*, *np.ndarray*, 또는 *list[PIL.Image.Image]*) : 생성된 비디오: `output_type="np"`인 경우 `[0, 1]` 범위의 `(T, H, W, 3)` 형상의 float `np.ndarray`, `"pt"`인 경우 `(T, 3, H, W)` 형상의 텐서, `"pil"`인 경우 `T`개의 `PIL.Image`로 구성된 리스트, 또는 `"latent"`인 경우 `(B, C, T_lat, H_lat, W_lat)` 형상의 잠재 텐서.

c2w (*np.ndarray*) : `frames`와 정렬된 카메라-월드 포즈 `(T, 4, 4)` (리파이너가 실행된 경우, sink 앵커 프레임이 제거되고 이 배열도 그에 따라 다시 정렬됩니다).

latent (*torch.Tensor*, 선택 사항) : LTX-2 VAE 공간의 잠재 텐서, 모양은 `(B, C, T_lat, H_lat, W_lat)`입니다. `output_type="latent"`일 때 반환됩니다.

SANA-WM 이미지-비디오 파이프라인의 출력 클래스입니다.

