# LTX2VideoDiffusionDecoderModel

Lightricks が LTX-2.5 で導入した拡散型ビデオデコーダーです。近傍アテンションの各ステージが潜在変数をコンテキストボリュームにアップサンプリングし、最終ステージがそのコンテキストを条件としてピクセルのノイズ除去を行います。

これはデコーダーであり、オートエンコーダーではありません。エンコーディングは[AutoencoderKLLTX2Video](/docs/diffusers/main/ja/api/models/autoencoderkl_ltx_2#diffusers.AutoencoderKLLTX2Video)に委ねられており、このモデルはその潜在空間をそのまま消費するため、潜在変数は畳み込みデコーダーとこのモデルの間で相互に交換可能です。このモデル自体が拡散モデルであるため、パイプラインの`vae`として渡されるのではなく、[LTX2VideoDiffusionDecodePipeline](/docs/diffusers/main/ja/api/pipelines/ltx2#diffusers.LTX2VideoDiffusionDecodePipeline)によって駆動されます。つまり、`output_type="latent"`を指定して任意のLTX-2パイプラインを実行し、その後デコードします。

```python
import torch
from diffusers import LTX2Pipeline, LTX2VideoDiffusionDecodePipeline, LTX2VideoDiffusionDecoderModel

pipe = LTX2Pipeline.from_pretrained("Lightricks/LTX-2.5-Diffusers", dtype=torch.bfloat16).to("cuda")  # or "mps", "xpu", "cpu"
latents = pipe(prompt="a potter shaping a clay vase", output_type="latent").frames

decoder = LTX2VideoDiffusionDecoderModel.from_pretrained(
    "Lightricks/LTX-2.5-Diffusers", subfolder="diffusion_decoder", dtype=torch.bfloat16
).to("cuda")
decode_pipe = LTX2VideoDiffusionDecodePipeline(diffusion_decoder=decoder, scheduler=pipe.scheduler)

# `denormalize=False`: `output_type="latent"` already applied the latent statistics, so applying them
# again here would scale every channel by its std a second time.
# The decoder also draws the noise it denoises, so decoding is only reproducible with a generator.
video = decode_pipe(
    latents, generator=torch.Generator("cuda").manual_seed(0), denormalize=False
).frames[0]
```

`vae` はデコードパイプラインにおける任意のコンポーネントです。`denormalize=True` の場合のみ潜在変数の統計量を取得するために参照され、デコーダー自体がそれらを保持しているため、デコード専用のワークフローでは第2のオートエンコーダーを読み込む必要はありません。

## アテンションのバックエンド

近傍アテンションのウィンドウは`BlockMask`として表現されるため、デコーダーはデフォルトで`flex`アテンションバックエンドで実行され、追加の依存関係は不要です。PyTorch は明示的に要求しない限り`flex_attention`をコンパイルせず、コンパイルされていない状態ではスコア行列全体がマテリアライズされるため、フル解像度のシーケンス長では実用的ではありません。そのため、デコーダーをコンパイルするか、元の実装でも使用されている[NATTEN](https://github.com/SHI-Labs/NATTEN)のカーネルに切り替えてください。プロセッサは[`kernels`](https://github.com/huggingface/kernels)パッケージを介して Hub から NATTEN（[`shi-labs/natten`](https://huggingface.co/kernels/shi-labs/natten)）を取得するため、ローカルでの NATTEN ビルドではなく`pip install kernels`が必要です。

```python
from diffusers.models.autoencoders.ltx2_diffusion_decoder import LTX2VideoVaeNeighborhoodNattenProcessor

decoder.set_attn_processor(LTX2VideoVaeNeighborhoodNattenProcessor())
```

Hub からカーネルのダウンロードコードを取得するため、`DIFFUSERS_DISABLE_REMOTE_CODE=true` でリモートコードがグローバルに無効化されている場合、プロセッサは例外を送出します。

デコーダーのすべてのアテンションモジュールは同じ近傍アテンション（カーネルサイズなどのステージごとの違いはモジュール側にあり、プロセッサー側にはない）であるため、`set_attn_processor` はこれらをすべて1つの共有インスタンスに置き換えます。

*バックエンド*を`flex`以外の値に切り替えた場合(`decoder.set_attention_backend(...)`)、`BlockMask`を受け入れるバックエンドが存在しないため、例外が発生します。代わりに、上記のNATTENプロセッサを使用してください。

## タイル分割

`decoder.enable_tiling()` は、オーバーラップするタイル単位でデコードし、それらをブレンドして再結合します。これにより、ピークメモリは動画サイズではなくタイルサイズで上限が設定されます。低コストな初期アップサンプリング段階では依然として完全な潜在変数が参照されますが、デコード時のメモリ使用量を支配する最後のアップサンプリング段階と拡散段階のみがタイル単位で実行されるため、タイル化による出力への影響はタイル境界付近に限定されます。拡散段階では各タイルが個別にデノイズされるため、タイル化されたデコードは非タイル化の結果を厳密に再現しません。デフォルトのタイルサイズとオーバーラップサイズは、参照実装のものと一致しています。近傍アテンションはカーネルより小さいグリッドを拒否するため、末尾の残りのタイルは単独でデコードされるのではなく、隣接するタイルにマージされます。

## LTX2VideoDiffusionDecoderModel[[diffusers.LTX2VideoDiffusionDecoderModel]]

#### diffusers.LTX2VideoDiffusionDecoderModel[[diffusers.LTX2VideoDiffusionDecoderModel]]

```python
diffusers.LTX2VideoDiffusionDecoderModel(out_channels: int = 3, latent_channels: int = 128, patch_size: int = 4, scaling_factor: float = 1.0, decoder_head_dim: int = 64, decoder_stage_channels: tuple[int, ...] = (2048, 1024, 512, 512, 256), decoder_stage_depths: tuple[int, ...] = (4, 6, 4, 2, 8), decoder_stage_kernels: tuple[tuple[int, int, int], ...] = ((3, 7, 7), (3, 7, 7), (3, 5, 5), (3, 5, 5)), decoder_upsample_strides: tuple[tuple[int, int, int], ...] = ((1, 2, 2), (2, 1, 1), (2, 2, 2), (2, 2, 2)), decoder_upsample_channel_reductions: tuple[int, ...] = (2, 2, 1, 2), decoder_stage5_kernel: tuple[int, int, int] = (11, 11, 11), decoder_t_emb_dim: int = 384, decoder_timestep_scale_multiplier: float = 1000.0, decoder_model_output_type: str = 'x0', decoder_num_inference_steps: int = 1, spatial_compression_ratio: int = 32, temporal_compression_ratio: int = 8)
```

[ソース](https://github.com/huggingface/diffusers/blob/main/src/diffusers/models/autoencoders/ltx2_diffusion_decoder.py#L700)

LTX-2.5 で導入された LTX-2 の拡散型動画デコーダー。

これはデコーダーであり、オートエンコーダーではありません。エンコーダーを備えておらず、潜在変数（latents）を生成することはできません。エンコーディングは[AutoencoderKLLTX2Video](/docs/diffusers/main/ja/api/models/autoencoderkl_ltx_2#diffusers.AutoencoderKLLTX2Video)が引き続き担当し、その潜在空間を本デコーダーはそのまま消費するため、潜在変数は畳み込みデコーダーと本デコーダーの間で相互に交換可能です。

また、これは決定論的なデコーダーではなく拡散モデルであり、潜変数から構築されたコンテキストボリュームに条件付けられてピクセルのノイズ除去を行うため、パイプラインの`vae`として渡されるのではなく、[LTX2VideoDiffusionDecodePipeline](/docs/diffusers/main/ja/api/pipelines/ltx2#diffusers.LTX2VideoDiffusionDecodePipeline)によって駆動されます。

潜在統計はバッファとして保持されており、2つのベクトルのために2番目のオートエンコーダーを読み込むことなく、デコードパイプラインでデノーマライズ処理を実行できるようにしています。

このモデルは [ModelMixin](/docs/diffusers/main/ja/api/models/overview#diffusers.ModelMixin) を継承しています。すべてのモデルに実装されている汎用的なメソッド（ダウンロードや保存など）については、スーパークラスのドキュメントを参照してください。

#### decode[[diffusers.LTX2VideoDiffusionDecoderModel.decode]]

```python
decode(z: Tensor, generator: typing.Optional[torch.Generator] = None, num_inference_steps: int | None = None, return_dict: bool = True)
```

[ソース](https://github.com/huggingface/diffusers/blob/main/src/diffusers/models/autoencoders/ltx2_diffusion_decoder.py#L988)

バッチの潜在変数をデコードします。

`z` はすでに正規化解除済みであることが前提です（パイプラインが `latents_mean` / `latents_std` を適用するため）。これは [AutoencoderKLLTX2Video](/docs/diffusers/main/ja/api/models/autoencoderkl_ltx_2#diffusers.AutoencoderKLLTX2Video) と一致します。このデコーダーはノイズ除去を行うため、再現性を確保するには `generator` を渡してください。

#### enable_tiling[[diffusers.LTX2VideoDiffusionDecoderModel.enable_tiling]]

```python
enable_tiling(tile_sample_min_height: int | None = None, tile_sample_min_width: int | None = None, tile_sample_min_num_frames: int | None = None, tile_sample_stride_height: int | None = None, tile_sample_stride_width: int | None = None, tile_sample_stride_num_frames: int | None = None)
```

[ソース](https://github.com/huggingface/diffusers/blob/main/src/diffusers/models/autoencoders/ltx2_diffusion_decoder.py#L787)

**パラメータ:**

tile_sample_min_height (`int`, *optional*) : 1つのデコード済みタイルの高さ（ピクセル単位）。

tile_sample_min_width (`int`, *任意*) : 1つのデコード済みタイルの幅（ピクセル単位）。

tile_sample_min_num_frames (`int`, *任意*) : 1つのデコード済みタイルのフレーム数。

tile_sample_stride_height (`int`, *optional*) : 2つの連続する縦方向のタイルの上端間のピクセル単位の距離。`tile_sample_min_height`との差がブレンドされたオーバーラップ部分です。

tile_sample_stride_width (`int`, *任意*) : 2つの連続する水平タイルの左端間のピクセル単位の距離。

tile_sample_stride_num_frames (`int`, *任意*) : 連続する2つの時間タイルの開始位置間のフレーム数。

タイル化デコーディングを有効にします。最後のステージを除く決定論的なアップサンプリングステージは、常に完全な潜在変数を処理します（低解像度で実行され、計算コストが低いためです）。一方、デコード時のメモリ使用量を支配する最後のステージおよびステージ5の拡散ブロックは、シームが線形にブレンドされる重複するタイル上で実行されます。

#### disable_tiling[[diffusers.LTX2VideoDiffusionDecoderModel.disable_tiling]]

```python
disable_tiling()
```

[ソース](https://github.com/huggingface/diffusers/blob/main/src/diffusers/models/autoencoders/ltx2_diffusion_decoder.py#L824)

タイル化デコーディングを無効にし、一度のパスで動画全体をデコードするようにします。

#### forward[[diffusers.LTX2VideoDiffusionDecoderModel.forward]]

```python
forward(z: Tensor, generator: typing.Optional[torch.Generator] = None, num_inference_steps: int | None = None, return_dict: bool = True)
```

[ソース](https://github.com/huggingface/diffusers/blob/main/src/diffusers/models/autoencoders/ltx2_diffusion_decoder.py#L1017)

**パラメータ:**

z (`torch.Tensor`) : `(B, C, F, H, W)` の形状を持つ Latents。すでにデノーマライズ済みであることが前提です（パイプラインは `latents_mean` / `latents_std` を適用します）。[AutoencoderKLLTX2Video](/docs/diffusers/main/ja/api/models/autoencoderkl_ltx_2#diffusers.AutoencoderKLLTX2Video) と一致します。

generator (`torch.Generator`、*任意*) : このデコーダーはノイズ除去を行うため、デコードを再現可能にするにはジェネレーターを渡してください。

num_inference_steps (`int`, *任意*) : デノイジングのステップ数。デフォルトでは、デコーダーの `decoder_num_inference_steps` 設定値が使用されます。

return_dict (`bool`、*任意*、デフォルトは`True`) : プレーンなタプルではなく[DecoderOutput](/docs/diffusers/main/ja/api/models/autoencoderkl_qwenimage#diffusers.models.autoencoders.vae.DecoderOutput)を返すかどうか。

**戻り値:** [DecoderOutput](/docs/diffusers/main/ja/api/models/autoencoderkl_qwenimage#diffusers.models.autoencoders.vae.DecoderOutput) または `tuple`

#### tiled_decode[[diffusers.LTX2VideoDiffusionDecoderModel.tiled_decode]]

```python
tiled_decode(z: Tensor, generator: typing.Optional[torch.Generator] = None, num_inference_steps: int | None = None)
```

[ソース](https://github.com/huggingface/diffusers/blob/main/src/diffusers/models/autoencoders/ltx2_diffusion_decoder.py#L855)

最後の決定論的ステージと、タイルごとに実行される拡散ステージを使用して、潜変数（latents）のバッチをデコードします。

Tiles は、最後の決定論的段階に入るグリッド上に存在します。この段階では、1 つのセルが出力ピクセルの固定ブロックに対応します。`tile_sample_*` のサイズは、このグリッドに変換されるため、セルサイズ（本番設定では空間方向 8 px、時間方向 2 フレーム）の倍数である必要があります。時間方向の Tiles は、因果的なフレームマッピングに従います。t=0 を含む Tile は、時間方向アップサンプルの重複する先頭フレームを破棄し、動画の末尾を含む Tile のみ NATTEN の境界パディングを持ちます。

