---
title: hyworldvae
---

<div class="python-reference">
<a id="fastvideo.models.vaes.hyworldvae-classes"></a>
<a id="fastvideo.models.vaes.hyworldvae-functions"></a>
<a id="fastvideo.models.vaes.hyworldvae.AutoencoderKLHYWorld-functions"></a>
<a id="fastvideo.models.vaes.hyworldvae.HYWorldCausalConv3d-functions"></a>
<a id="fastvideo.models.vaes.hyworldvae.HYWorldDecoder3D-functions"></a>
<a id="fastvideo.models.vaes.hyworldvae.HYWorldDownBlock3D-functions"></a>
<a id="fastvideo.models.vaes.hyworldvae.HYWorldDownsample-functions"></a>
<a id="fastvideo.models.vaes.hyworldvae.HYWorldEncoder3D-functions"></a>
<a id="fastvideo.models.vaes.hyworldvae.HYWorldMidBlock-functions"></a>
<a id="fastvideo.models.vaes.hyworldvae.HYWorldResnetBlock-functions"></a>
<a id="fastvideo.models.vaes.hyworldvae.HYWorldUpBlock3D-functions"></a>
<a id="fastvideo.models.vaes.hyworldvae.HYWorldUpsample-functions"></a>
<a id="fastvideo.models.vaes.hyworldvae"></a>

<h2 id="fastvideo.models.vaes.hyworldvae.get_act_fn"><code>fastvideo.models.vaes.hyworldvae.get_act_fn</code></h2>
<pre class="doc-signature"><code>get_act_fn(act_fn_name: str) -&gt; nn.Module</code></pre>
<p>Get an activation function by name.</p>
<h2 id="fastvideo.models.vaes.hyworldvae.Hunyuan15VAEConfig"><code>fastvideo.models.vaes.hyworldvae.Hunyuan15VAEConfig</code></h2>
<pre class="doc-signature"><code>Hunyuan15VAEConfig(arch_config: VAEArchConfig = Hunyuan15VAEArchConfig(), load_encoder: bool = True, load_decoder: bool = True, tile_sample_min_height: int = 256, tile_sample_min_width: int = 256, tile_sample_min_num_frames: int = 16, tile_sample_stride_height: int = 192, tile_sample_stride_width: int = 192, tile_sample_stride_num_frames: int = 12, blend_num_frames: int = 0, use_tiling: bool = True, use_temporal_tiling: bool = True, use_parallel_tiling: bool = True, use_temporal_scaling_frames: bool = True, *, _resolved_attention_backend: AttentionBackendEnum | None = None)</code></pre>


<h2 id="fastvideo.models.vaes.hyworldvae.ParallelTiledVAE"><code>fastvideo.models.vaes.hyworldvae.ParallelTiledVAE</code></h2>
<pre class="doc-signature"><code>ParallelTiledVAE(config: VAEConfig, **kwargs)</code></pre>


<h3 id="fastvideo.models.vaes.hyworldvae.ParallelTiledVAE.to"><code>fastvideo.models.vaes.hyworldvae.ParallelTiledVAE.to</code></h3>
<pre class="doc-signature"><code>to(device) -&gt; ParallelTiledVAE</code></pre>

<h3 id="fastvideo.models.vaes.hyworldvae.ParallelTiledVAE.encode"><code>fastvideo.models.vaes.hyworldvae.ParallelTiledVAE.encode</code></h3>
<pre class="doc-signature"><code>encode(x: torch.Tensor) -&gt; torch.Tensor</code></pre>

<h3 id="fastvideo.models.vaes.hyworldvae.ParallelTiledVAE.decode"><code>fastvideo.models.vaes.hyworldvae.ParallelTiledVAE.decode</code></h3>
<pre class="doc-signature"><code>decode(z: torch.Tensor) -&gt; torch.Tensor</code></pre>

<h3 id="fastvideo.models.vaes.hyworldvae.ParallelTiledVAE.blend_v"><code>fastvideo.models.vaes.hyworldvae.ParallelTiledVAE.blend_v</code></h3>
<pre class="doc-signature"><code>blend_v(a: torch.Tensor, b: torch.Tensor, blend_extent: int) -&gt; torch.Tensor</code></pre>

<h3 id="fastvideo.models.vaes.hyworldvae.ParallelTiledVAE.blend_h"><code>fastvideo.models.vaes.hyworldvae.ParallelTiledVAE.blend_h</code></h3>
<pre class="doc-signature"><code>blend_h(a: torch.Tensor, b: torch.Tensor, blend_extent: int) -&gt; torch.Tensor</code></pre>

<h3 id="fastvideo.models.vaes.hyworldvae.ParallelTiledVAE.blend_t"><code>fastvideo.models.vaes.hyworldvae.ParallelTiledVAE.blend_t</code></h3>
<pre class="doc-signature"><code>blend_t(a: torch.Tensor, b: torch.Tensor, blend_extent: int) -&gt; torch.Tensor</code></pre>

<h3 id="fastvideo.models.vaes.hyworldvae.ParallelTiledVAE.spatial_tiled_encode"><code>fastvideo.models.vaes.hyworldvae.ParallelTiledVAE.spatial_tiled_encode</code></h3>
<pre class="doc-signature"><code>spatial_tiled_encode(x: torch.Tensor) -&gt; torch.Tensor</code></pre>
<p>Encode a batch of images using a tiled encoder.</p>
<h4>Parameters</h4>
<dl>
<dt><code>x: `torch.Tensor`</code></dt><dd><p>Input batch of videos.</p></dd>
</dl>
<h4>Returns</h4>
<dl>
<dt><code>torch.Tensor</code></dt><dd><p><code>torch.Tensor</code>:
The latent representation of the encoded videos.</p></dd>
</dl>
<h3 id="fastvideo.models.vaes.hyworldvae.ParallelTiledVAE.parallel_tiled_decode"><code>fastvideo.models.vaes.hyworldvae.ParallelTiledVAE.parallel_tiled_decode</code></h3>
<pre class="doc-signature"><code>parallel_tiled_decode(z: torch.FloatTensor) -&gt; torch.FloatTensor</code></pre>
<p>Parallel version of tiled_decode that distributes both temporal and spatial computation across GPUs</p>
<h3 id="fastvideo.models.vaes.hyworldvae.ParallelTiledVAE.spatial_tiled_decode"><code>fastvideo.models.vaes.hyworldvae.ParallelTiledVAE.spatial_tiled_decode</code></h3>
<pre class="doc-signature"><code>spatial_tiled_decode(z: torch.Tensor) -&gt; torch.Tensor</code></pre>
<p>Decode a batch of images using a tiled decoder.</p>
<h4>Parameters</h4>
<dl>
<dt><code>z: `torch.Tensor`</code></dt><dd><p>Input batch of latent vectors.</p></dd>
</dl>
<h4>Returns</h4>
<dl>
<dt><code>torch.Tensor</code></dt><dd><p><code>torch.Tensor</code>:
The decoded images.</p></dd>
</dl>
<h3 id="fastvideo.models.vaes.hyworldvae.ParallelTiledVAE.tiled_encode"><code>fastvideo.models.vaes.hyworldvae.ParallelTiledVAE.tiled_encode</code></h3>
<pre class="doc-signature"><code>tiled_encode(x: torch.Tensor) -&gt; torch.Tensor</code></pre>

<h3 id="fastvideo.models.vaes.hyworldvae.ParallelTiledVAE.tiled_decode"><code>fastvideo.models.vaes.hyworldvae.ParallelTiledVAE.tiled_decode</code></h3>
<pre class="doc-signature"><code>tiled_decode(z: torch.Tensor) -&gt; torch.Tensor</code></pre>

<h3 id="fastvideo.models.vaes.hyworldvae.ParallelTiledVAE.enable_tiling"><code>fastvideo.models.vaes.hyworldvae.ParallelTiledVAE.enable_tiling</code></h3>
<pre class="doc-signature"><code>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, blend_num_frames: int | None = None, use_tiling: bool | None = None, use_temporal_tiling: bool | None = None, use_parallel_tiling: bool | None = None) -&gt; None</code></pre>
<p>Enable tiled VAE decoding. When this option is enabled, the VAE will split the input tensor into tiles to
compute decoding and encoding in several steps. This is useful for saving a large amount of memory and to allow
processing larger images.</p>
<h4>Parameters</h4>
<dl>
<dt><code>tile_sample_min_height: `int`, *optional*</code></dt><dd><p>The minimum height required for a sample to be separated into tiles across the height dimension.</p></dd>
<dt><code>tile_sample_min_width: `int`, *optional*</code></dt><dd><p>The minimum width required for a sample to be separated into tiles across the width dimension.</p></dd>
<dt><code>tile_sample_min_num_frames: `int`, *optional*</code></dt><dd><p>The minimum number of frames required for a sample to be separated into tiles across the frame
dimension.</p></dd>
<dt><code>tile_sample_stride_height: `int`, *optional*</code></dt><dd><p>The minimum amount of overlap between two consecutive vertical tiles. This is to ensure that there are
no tiling artifacts produced across the height dimension.</p></dd>
<dt><code>tile_sample_stride_width: `int`, *optional*</code></dt><dd><p>The stride between two consecutive horizontal tiles. This is to ensure that there are no tiling
artifacts produced across the width dimension.</p></dd>
<dt><code>tile_sample_stride_num_frames: `int`, *optional*</code></dt><dd><p>The stride between two consecutive frame tiles. This is to ensure that there are no tiling artifacts
produced across the frame dimension.</p></dd>
</dl>
<h3 id="fastvideo.models.vaes.hyworldvae.ParallelTiledVAE.disable_tiling"><code>fastvideo.models.vaes.hyworldvae.ParallelTiledVAE.disable_tiling</code></h3>
<pre class="doc-signature"><code>disable_tiling() -&gt; None</code></pre>
<p>Disable tiled VAE decoding. If <code>enable_tiling</code> was previously enabled, this method will go back to computing
decoding in one step.</p>
<h2 id="fastvideo.models.vaes.hyworldvae.HYWorldRMS_norm"><code>fastvideo.models.vaes.hyworldvae.HYWorldRMS_norm</code></h2>
<pre class="doc-signature"><code>HYWorldRMS_norm(dim: int, channel_first: bool = True, images: bool = True, bias: bool = False)</code></pre>
<p>A custom RMS normalization layer.</p>
<h3>Parameters</h3>
<dl>
<dt><code>dim: int</code></dt><dd><p>The number of dimensions to normalize over.</p></dd>
<dt><code>channel_first: bool</code></dt><dd><p>Whether the input tensor has channels as the first dimension.
Default is True.</p></dd>
<dt><code>images: bool</code></dt><dd><p>Whether the input represents image data. Default is True.</p></dd>
<dt><code>bias: bool</code></dt><dd><p>Whether to include a learnable bias term. Default is False.</p></dd>
</dl>

<h3 id="fastvideo.models.vaes.hyworldvae.HYWorldRMS_norm.forward"><code>fastvideo.models.vaes.hyworldvae.HYWorldRMS_norm.forward</code></h3>
<pre class="doc-signature"><code>forward(x)</code></pre>

<h2 id="fastvideo.models.vaes.hyworldvae.HYWorldAttnBlock"><code>fastvideo.models.vaes.hyworldvae.HYWorldAttnBlock</code></h2>
<pre class="doc-signature"><code>HYWorldAttnBlock(in_channels: int)</code></pre>


<h3 id="fastvideo.models.vaes.hyworldvae.HYWorldAttnBlock.prepare_causal_attention_mask"><code>fastvideo.models.vaes.hyworldvae.HYWorldAttnBlock.prepare_causal_attention_mask</code></h3>
<pre class="doc-signature"><code>prepare_causal_attention_mask(n_frame: int, n_hw: int, dtype, device, batch_size: int = None)</code></pre>
<p>Prepare a causal attention mask for 3D videos.</p>
<h4>Parameters</h4>
<dl>
<dt><code>n_frame: int</code></dt><dd><p>Number of frames (temporal length).</p></dd>
<dt><code>n_hw: int</code></dt><dd><p>Product of height and width.</p></dd>
<dt><code>dtype</code></dt><dd><p>Desired mask dtype.</p></dd>
<dt><code>device</code></dt><dd><p>Device for the mask.</p></dd>
<dt><code>batch_size: int</code></dt><dd><p>If set, expands for batch.</p></dd>
</dl>
<h4>Returns</h4>
<dl>
<dt><code></code></dt><dd><p>torch.Tensor: Causal attention mask.</p></dd>
</dl>
<h3 id="fastvideo.models.vaes.hyworldvae.HYWorldAttnBlock.forward"><code>fastvideo.models.vaes.hyworldvae.HYWorldAttnBlock.forward</code></h3>
<pre class="doc-signature"><code>forward(x: torch.Tensor) -&gt; torch.Tensor</code></pre>

<h2 id="fastvideo.models.vaes.hyworldvae.HYWorldCausalConv3d"><code>fastvideo.models.vaes.hyworldvae.HYWorldCausalConv3d</code></h2>
<pre class="doc-signature"><code>HYWorldCausalConv3d(in_channels: int, out_channels: int, kernel_size: Union&#91;int, Tuple&#91;int, int, int&#93;&#93; = 3, stride: Union&#91;int, Tuple&#91;int, int, int&#93;&#93; = 1, padding: Union&#91;int, Tuple&#91;int, int, int&#93;&#93; = 0, dilation: Union&#91;int, Tuple&#91;int, int, int&#93;&#93; = 1, bias: bool = True, pad_mode: str = &#x27;replicate&#x27;)</code></pre>
<p>Causal Conv3d with optional cache support for temporal feature caching.</p>

<details><summary>Source</summary><pre><code>class HYWorldCausalConv3d(nn.Module):
    &quot;&quot;&quot;Causal Conv3d with optional cache support for temporal feature caching.&quot;&quot;&quot;

    def __init__(
        self,
        in_channels: int,
        out_channels: int,
        kernel_size: Union&#91;int, Tuple&#91;int, int, int&#93;&#93; = 3,
        stride: Union&#91;int, Tuple&#91;int, int, int&#93;&#93; = 1,
        padding: Union&#91;int, Tuple&#91;int, int, int&#93;&#93; = 0,
        dilation: Union&#91;int, Tuple&#91;int, int, int&#93;&#93; = 1,
        bias: bool = True,
        pad_mode: str = &quot;replicate&quot;,
    ) -&gt; None:
        super().__init__()

        kernel_size = (kernel_size, kernel_size, kernel_size) if isinstance(kernel_size, int) else kernel_size

        self.pad_mode = pad_mode
        # Padding format: (W_left, W_right, H_left, H_right, T_left, T_right)
        self.time_causal_padding = (
            kernel_size&#91;0&#93; // 2,  # W_left (spatial)
            kernel_size&#91;0&#93; // 2,  # W_right (spatial)
            kernel_size&#91;1&#93; // 2,  # H_left (spatial)
            kernel_size&#91;1&#93; // 2,  # H_right (spatial)
            kernel_size&#91;2&#93; - 1,  # T_left (temporal causal padding)
            0,  # T_right (no future padding for causal)
        )

        self.conv = nn.Conv3d(in_channels, out_channels, kernel_size, stride, padding, dilation, bias=bias)

    def forward(self, hidden_states: torch.Tensor, cache_x: Optional&#91;torch.Tensor&#93; = None) -&gt; torch.Tensor:
        &quot;&quot;&quot;
        Forward pass with optional temporal caching.

        Args:
            hidden_states: Input tensor of shape (B, C, T, H, W)
            cache_x: Optional cached frames from previous chunk, shape (B, C, CACHE_T, H, W)
                    When provided, uses cached frames instead of padding for temporal dimension.
        &quot;&quot;&quot;
        padding = list(self.time_causal_padding)

        if cache_x is not None and self.time_causal_padding&#91;4&#93; &gt; 0:  # Has temporal padding and cache
            cache_x = cache_x.to(hidden_states.device)
            # Concatenate cached frames with current input on temporal dimension
            hidden_states = torch.cat(&#91;cache_x, hidden_states&#93;, dim=2)
            # Reduce temporal padding since we have cached frames
            padding&#91;4&#93; -= cache_x.shape&#91;2&#93;

        hidden_states = F.pad(hidden_states, padding, mode=self.pad_mode)
        return self.conv(hidden_states)</code></pre></details>
<h3 id="fastvideo.models.vaes.hyworldvae.HYWorldCausalConv3d.forward"><code>fastvideo.models.vaes.hyworldvae.HYWorldCausalConv3d.forward</code></h3>
<pre class="doc-signature"><code>forward(hidden_states: torch.Tensor, cache_x: Optional&#91;torch.Tensor&#93; = None) -&gt; torch.Tensor</code></pre>
<p>Forward pass with optional temporal caching.</p>
<h4>Parameters</h4>
<dl>
<dt><code>hidden_states: torch.Tensor</code></dt><dd><p>Input tensor of shape (B, C, T, H, W)</p></dd>
<dt><code>cache_x: Optional[torch.Tensor]</code></dt><dd><p>Optional cached frames from previous chunk, shape (B, C, CACHE_T, H, W)
    When provided, uses cached frames instead of padding for temporal dimension.</p></dd>
</dl>
<details><summary>Source</summary><pre><code>def forward(self, hidden_states: torch.Tensor, cache_x: Optional&#91;torch.Tensor&#93; = None) -&gt; torch.Tensor:
    &quot;&quot;&quot;
    Forward pass with optional temporal caching.

    Args:
        hidden_states: Input tensor of shape (B, C, T, H, W)
        cache_x: Optional cached frames from previous chunk, shape (B, C, CACHE_T, H, W)
                When provided, uses cached frames instead of padding for temporal dimension.
    &quot;&quot;&quot;
    padding = list(self.time_causal_padding)

    if cache_x is not None and self.time_causal_padding&#91;4&#93; &gt; 0:  # Has temporal padding and cache
        cache_x = cache_x.to(hidden_states.device)
        # Concatenate cached frames with current input on temporal dimension
        hidden_states = torch.cat(&#91;cache_x, hidden_states&#93;, dim=2)
        # Reduce temporal padding since we have cached frames
        padding&#91;4&#93; -= cache_x.shape&#91;2&#93;

    hidden_states = F.pad(hidden_states, padding, mode=self.pad_mode)
    return self.conv(hidden_states)</code></pre></details>
<h2 id="fastvideo.models.vaes.hyworldvae.HYWorldUpsample"><code>fastvideo.models.vaes.hyworldvae.HYWorldUpsample</code></h2>
<pre class="doc-signature"><code>HYWorldUpsample(in_channels: int, out_channels: int, add_temporal_upsample: bool = True)</code></pre>
<p>Hierarchical upsampling with temporal/spatial support and optional caching.</p>

<details><summary>Source</summary><pre><code>class HYWorldUpsample(nn.Module):
    &quot;&quot;&quot;Hierarchical upsampling with temporal/spatial support and optional caching.&quot;&quot;&quot;

    def __init__(self, in_channels: int, out_channels: int, add_temporal_upsample: bool = True):
        super().__init__()
        factor = 2 * 2 * 2 if add_temporal_upsample else 1 * 2 * 2
        self.conv = HYWorldCausalConv3d(in_channels, out_channels * factor, kernel_size=3)
        self.add_temporal_upsample = add_temporal_upsample
        self.repeats = factor * out_channels // in_channels

    def forward(
        self,
        x: torch.Tensor,
        feat_cache: Optional&#91;List&#91;Optional&#91;torch.Tensor&#93;&#93;&#93; = None,
        feat_idx: Optional&#91;List&#91;int&#93;&#93; = None,
        first_chunk: bool = False,
    ):
        &quot;&quot;&quot;
        Forward pass with optional temporal caching.

        Args:
            x: Input tensor of shape (B, C, T, H, W)
            feat_cache: List of cached features for each conv layer
            feat_idx: List containing current cache index &#91;idx&#93;
            first_chunk: Whether this is the first chunk (affects temporal upsample behavior)
        &quot;&quot;&quot;
        r1 = 2 if self.add_temporal_upsample else 1
        if feat_cache is not None and feat_idx is not None:
            idx = feat_idx&#91;0&#93;
            cache_x = x&#91;:, :, -CACHE_T:, :, :&#93;.clone()
            if cache_x.shape&#91;2&#93; &lt; 2 and feat_cache&#91;idx&#93; is not None:
                cache_x = torch.cat(
                    &#91;feat_cache&#91;idx&#93;&#91;:, :, -1, :, :&#93;.unsqueeze(2).to(cache_x.device), cache_x&#93;,
                    dim=2,
                )
            h = self.conv(x, feat_cache&#91;idx&#93;)
            feat_cache&#91;idx&#93; = cache_x
            feat_idx&#91;0&#93; += 1
        else:
            h = self.conv(x)

        if self.add_temporal_upsample:
            if first_chunk:
                # First chunk: only spatial upsample
                h = rearrange(h, &quot;b (r2 r3 c) f h w -&gt; b c f (h r2) (w r3)&quot;, r2=2, r3=2)
                h = h&#91;:, :h.shape&#91;1&#93; // 2&#93;
                # Compute the shortcut part
                shortcut = rearrange(x, &quot;b (r2 r3 c) f h w -&gt; b c f (h r2) (w r3)&quot;, r2=2, r3=2)
                shortcut = shortcut.repeat_interleave(repeats=self.repeats // 2, dim=1)
            elif feat_cache is None and x.shape&#91;2&#93; &gt; 1:
                # No cache and multiple frames: separate first frame and rest
                h_first = h&#91;:, :, :1, :, :&#93;
                h_rest = h&#91;:, :, 1:, :, :&#93;
                x_first = x&#91;:, :, :1, :, :&#93;
                x_rest = x&#91;:, :, 1:, :, :&#93;

                # First frame: only spatial upsample
                h_first = rearrange(h_first, &quot;b (r2 r3 c) f h w -&gt; b c f (h r2) (w r3)&quot;, r2=2, r3=2)
                h_first = h_first&#91;:, :h_first.shape&#91;1&#93; // 2&#93;
                shortcut_first = rearrange(x_first, &quot;b (r2 r3 c) f h w -&gt; b c f (h r2) (w r3)&quot;, r2=2, r3=2)
                shortcut_first = shortcut_first.repeat_interleave(repeats=self.repeats // 2, dim=1)
                out_first = h_first + shortcut_first

                # Remaining frames: spatio-temporal upsample
                h_rest = rearrange(h_rest, &quot;b (r1 r2 r3 c) f h w -&gt; b c (f r1) (h r2) (w r3)&quot;, r1=r1, r2=2, r3=2)
                shortcut_rest = rearrange(x_rest, &quot;b (r1 r2 r3 c) f h w -&gt; b c (f r1) (h r2) (w r3)&quot;, r1=r1, r2=2, r3=2)
                shortcut_rest = shortcut_rest.repeat_interleave(repeats=self.repeats, dim=1)
                out_rest = h_rest + shortcut_rest

                return torch.cat(&#91;out_first, out_rest&#93;, dim=2)
            else:
                # Subsequent chunks with cache: spatio-temporal upsample
                h = rearrange(h, &quot;b (r1 r2 r3 c) f h w -&gt; b c (f r1) (h r2) (w r3)&quot;, r1=r1, r2=2, r3=2)
                shortcut = rearrange(x, &quot;b (r1 r2 r3 c) f h w -&gt; b c (f r1) (h r2) (w r3)&quot;, r1=r1, r2=2, r3=2)
                shortcut = shortcut.repeat_interleave(repeats=self.repeats, dim=1)
        else:
            h = rearrange(h, &quot;b (r1 r2 r3 c) f h w -&gt; b c (f r1) (h r2) (w r3)&quot;, r1=r1, r2=2, r3=2)
            shortcut = x.repeat_interleave(repeats=self.repeats, dim=1)
            shortcut = rearrange(shortcut, &quot;b (r1 r2 r3 c) f h w -&gt; b c (f r1) (h r2) (w r3)&quot;, r1=r1, r2=2, r3=2)

        return h + shortcut</code></pre></details>
<h3 id="fastvideo.models.vaes.hyworldvae.HYWorldUpsample.forward"><code>fastvideo.models.vaes.hyworldvae.HYWorldUpsample.forward</code></h3>
<pre class="doc-signature"><code>forward(x: torch.Tensor, feat_cache: Optional&#91;List&#91;Optional&#91;torch.Tensor&#93;&#93;&#93; = None, feat_idx: Optional&#91;List&#91;int&#93;&#93; = None, first_chunk: bool = False)</code></pre>
<p>Forward pass with optional temporal caching.</p>
<h4>Parameters</h4>
<dl>
<dt><code>x: torch.Tensor</code></dt><dd><p>Input tensor of shape (B, C, T, H, W)</p></dd>
<dt><code>feat_cache: Optional[List[Optional[torch.Tensor]]]</code></dt><dd><p>List of cached features for each conv layer</p></dd>
<dt><code>feat_idx: Optional[List[int]]</code></dt><dd><p>List containing current cache index [idx]</p></dd>
<dt><code>first_chunk: bool</code></dt><dd><p>Whether this is the first chunk (affects temporal upsample behavior)</p></dd>
</dl>
<details><summary>Source</summary><pre><code>def forward(
    self,
    x: torch.Tensor,
    feat_cache: Optional&#91;List&#91;Optional&#91;torch.Tensor&#93;&#93;&#93; = None,
    feat_idx: Optional&#91;List&#91;int&#93;&#93; = None,
    first_chunk: bool = False,
):
    &quot;&quot;&quot;
    Forward pass with optional temporal caching.

    Args:
        x: Input tensor of shape (B, C, T, H, W)
        feat_cache: List of cached features for each conv layer
        feat_idx: List containing current cache index &#91;idx&#93;
        first_chunk: Whether this is the first chunk (affects temporal upsample behavior)
    &quot;&quot;&quot;
    r1 = 2 if self.add_temporal_upsample else 1
    if feat_cache is not None and feat_idx is not None:
        idx = feat_idx&#91;0&#93;
        cache_x = x&#91;:, :, -CACHE_T:, :, :&#93;.clone()
        if cache_x.shape&#91;2&#93; &lt; 2 and feat_cache&#91;idx&#93; is not None:
            cache_x = torch.cat(
                &#91;feat_cache&#91;idx&#93;&#91;:, :, -1, :, :&#93;.unsqueeze(2).to(cache_x.device), cache_x&#93;,
                dim=2,
            )
        h = self.conv(x, feat_cache&#91;idx&#93;)
        feat_cache&#91;idx&#93; = cache_x
        feat_idx&#91;0&#93; += 1
    else:
        h = self.conv(x)

    if self.add_temporal_upsample:
        if first_chunk:
            # First chunk: only spatial upsample
            h = rearrange(h, &quot;b (r2 r3 c) f h w -&gt; b c f (h r2) (w r3)&quot;, r2=2, r3=2)
            h = h&#91;:, :h.shape&#91;1&#93; // 2&#93;
            # Compute the shortcut part
            shortcut = rearrange(x, &quot;b (r2 r3 c) f h w -&gt; b c f (h r2) (w r3)&quot;, r2=2, r3=2)
            shortcut = shortcut.repeat_interleave(repeats=self.repeats // 2, dim=1)
        elif feat_cache is None and x.shape&#91;2&#93; &gt; 1:
            # No cache and multiple frames: separate first frame and rest
            h_first = h&#91;:, :, :1, :, :&#93;
            h_rest = h&#91;:, :, 1:, :, :&#93;
            x_first = x&#91;:, :, :1, :, :&#93;
            x_rest = x&#91;:, :, 1:, :, :&#93;

            # First frame: only spatial upsample
            h_first = rearrange(h_first, &quot;b (r2 r3 c) f h w -&gt; b c f (h r2) (w r3)&quot;, r2=2, r3=2)
            h_first = h_first&#91;:, :h_first.shape&#91;1&#93; // 2&#93;
            shortcut_first = rearrange(x_first, &quot;b (r2 r3 c) f h w -&gt; b c f (h r2) (w r3)&quot;, r2=2, r3=2)
            shortcut_first = shortcut_first.repeat_interleave(repeats=self.repeats // 2, dim=1)
            out_first = h_first + shortcut_first

            # Remaining frames: spatio-temporal upsample
            h_rest = rearrange(h_rest, &quot;b (r1 r2 r3 c) f h w -&gt; b c (f r1) (h r2) (w r3)&quot;, r1=r1, r2=2, r3=2)
            shortcut_rest = rearrange(x_rest, &quot;b (r1 r2 r3 c) f h w -&gt; b c (f r1) (h r2) (w r3)&quot;, r1=r1, r2=2, r3=2)
            shortcut_rest = shortcut_rest.repeat_interleave(repeats=self.repeats, dim=1)
            out_rest = h_rest + shortcut_rest

            return torch.cat(&#91;out_first, out_rest&#93;, dim=2)
        else:
            # Subsequent chunks with cache: spatio-temporal upsample
            h = rearrange(h, &quot;b (r1 r2 r3 c) f h w -&gt; b c (f r1) (h r2) (w r3)&quot;, r1=r1, r2=2, r3=2)
            shortcut = rearrange(x, &quot;b (r1 r2 r3 c) f h w -&gt; b c (f r1) (h r2) (w r3)&quot;, r1=r1, r2=2, r3=2)
            shortcut = shortcut.repeat_interleave(repeats=self.repeats, dim=1)
    else:
        h = rearrange(h, &quot;b (r1 r2 r3 c) f h w -&gt; b c (f r1) (h r2) (w r3)&quot;, r1=r1, r2=2, r3=2)
        shortcut = x.repeat_interleave(repeats=self.repeats, dim=1)
        shortcut = rearrange(shortcut, &quot;b (r1 r2 r3 c) f h w -&gt; b c (f r1) (h r2) (w r3)&quot;, r1=r1, r2=2, r3=2)

    return h + shortcut</code></pre></details>
<h2 id="fastvideo.models.vaes.hyworldvae.HYWorldDownsample"><code>fastvideo.models.vaes.hyworldvae.HYWorldDownsample</code></h2>
<pre class="doc-signature"><code>HYWorldDownsample(in_channels: int, out_channels: int, add_temporal_downsample: bool = True)</code></pre>
<p>Hierarchical downsampling with temporal/spatial support and optional caching.</p>

<details><summary>Source</summary><pre><code>class HYWorldDownsample(nn.Module):
    &quot;&quot;&quot;Hierarchical downsampling with temporal/spatial support and optional caching.&quot;&quot;&quot;

    def __init__(self, in_channels: int, out_channels: int, add_temporal_downsample: bool = True):
        super().__init__()
        factor = 2 * 2 * 2 if add_temporal_downsample else 1 * 2 * 2
        self.conv = HYWorldCausalConv3d(in_channels, out_channels // factor, kernel_size=3)

        self.add_temporal_downsample = add_temporal_downsample
        self.group_size = factor * in_channels // out_channels

    def forward(
        self,
        x: torch.Tensor,
        feat_cache: Optional&#91;List&#91;Optional&#91;torch.Tensor&#93;&#93;&#93; = None,
        feat_idx: Optional&#91;List&#91;int&#93;&#93; = None,
    ):
        &quot;&quot;&quot;
        Forward pass with optional temporal caching.

        Args:
            x: Input tensor of shape (B, C, T, H, W)
            feat_cache: List of cached features for each conv layer
            feat_idx: List containing current cache index &#91;idx&#93;
        &quot;&quot;&quot;
        r1 = 2 if self.add_temporal_downsample else 1

        # Apply conv with caching
        if feat_cache is not None and feat_idx is not None:
            idx = feat_idx&#91;0&#93;
            cache_x = x&#91;:, :, -CACHE_T:, :, :&#93;.clone()
            if cache_x.shape&#91;2&#93; &lt; 2 and feat_cache&#91;idx&#93; is not None:
                cache_x = torch.cat(
                    &#91;feat_cache&#91;idx&#93;&#91;:, :, -1, :, :&#93;.unsqueeze(2).to(cache_x.device), cache_x&#93;,
                    dim=2,
                )
            h = self.conv(x, feat_cache&#91;idx&#93;)
            feat_cache&#91;idx&#93; = cache_x
            feat_idx&#91;0&#93; += 1
        else:
            h = self.conv(x)  # Change the channel, ready for spatial or temporal downsample

        if self.add_temporal_downsample:
            if x.shape&#91;2&#93; == 1:
                # Single frame: only spatial downsample
                h = rearrange(h, &quot;b c f (h r2) (w r3) -&gt; b (r2 r3 c) f h w&quot;, r2=2, r3=2)
                h = torch.cat(&#91;h, h&#93;, dim=1)
                # Compute the shortcut part
                shortcut = rearrange(x, &quot;b c f (h r2) (w r3) -&gt; b (r2 r3 c) f h w&quot;, r2=2, r3=2)
                B, C, T, H, W = shortcut.shape
                shortcut = shortcut.view(B, h.shape&#91;1&#93;, self.group_size // 2, T, H, W).mean(dim=2)
            else:
                # Multiple frames: full spatio-temporal downsample
                h = rearrange(h, &quot;b c (f r1) (h r2) (w r3) -&gt; b (r1 r2 r3 c) f h w&quot;, r1=r1, r2=2, r3=2)
                # Shortcut computation
                shortcut = rearrange(x, &quot;b c (f r1) (h r2) (w r3) -&gt; b (r1 r2 r3 c) f h w&quot;, r1=r1, r2=2, r3=2)
                B, C, T, H, W = shortcut.shape
                shortcut = shortcut.view(B, h.shape&#91;1&#93;, self.group_size, T, H, W).mean(dim=2)
        else:
            h = rearrange(h, &quot;b c (f r1) (h r2) (w r3) -&gt; b (r1 r2 r3 c) f h w&quot;, r1=r1, r2=2, r3=2)
            shortcut = rearrange(x, &quot;b c (f r1) (h r2) (w r3) -&gt; b (r1 r2 r3 c) f h w&quot;, r1=r1, r2=2, r3=2)
            B, C, T, H, W = shortcut.shape
            shortcut = shortcut.view(B, h.shape&#91;1&#93;, self.group_size, T, H, W).mean(dim=2)

        return h + shortcut</code></pre></details>
<h3 id="fastvideo.models.vaes.hyworldvae.HYWorldDownsample.forward"><code>fastvideo.models.vaes.hyworldvae.HYWorldDownsample.forward</code></h3>
<pre class="doc-signature"><code>forward(x: torch.Tensor, feat_cache: Optional&#91;List&#91;Optional&#91;torch.Tensor&#93;&#93;&#93; = None, feat_idx: Optional&#91;List&#91;int&#93;&#93; = None)</code></pre>
<p>Forward pass with optional temporal caching.</p>
<h4>Parameters</h4>
<dl>
<dt><code>x: torch.Tensor</code></dt><dd><p>Input tensor of shape (B, C, T, H, W)</p></dd>
<dt><code>feat_cache: Optional[List[Optional[torch.Tensor]]]</code></dt><dd><p>List of cached features for each conv layer</p></dd>
<dt><code>feat_idx: Optional[List[int]]</code></dt><dd><p>List containing current cache index [idx]</p></dd>
</dl>
<details><summary>Source</summary><pre><code>def forward(
    self,
    x: torch.Tensor,
    feat_cache: Optional&#91;List&#91;Optional&#91;torch.Tensor&#93;&#93;&#93; = None,
    feat_idx: Optional&#91;List&#91;int&#93;&#93; = None,
):
    &quot;&quot;&quot;
    Forward pass with optional temporal caching.

    Args:
        x: Input tensor of shape (B, C, T, H, W)
        feat_cache: List of cached features for each conv layer
        feat_idx: List containing current cache index &#91;idx&#93;
    &quot;&quot;&quot;
    r1 = 2 if self.add_temporal_downsample else 1

    # Apply conv with caching
    if feat_cache is not None and feat_idx is not None:
        idx = feat_idx&#91;0&#93;
        cache_x = x&#91;:, :, -CACHE_T:, :, :&#93;.clone()
        if cache_x.shape&#91;2&#93; &lt; 2 and feat_cache&#91;idx&#93; is not None:
            cache_x = torch.cat(
                &#91;feat_cache&#91;idx&#93;&#91;:, :, -1, :, :&#93;.unsqueeze(2).to(cache_x.device), cache_x&#93;,
                dim=2,
            )
        h = self.conv(x, feat_cache&#91;idx&#93;)
        feat_cache&#91;idx&#93; = cache_x
        feat_idx&#91;0&#93; += 1
    else:
        h = self.conv(x)  # Change the channel, ready for spatial or temporal downsample

    if self.add_temporal_downsample:
        if x.shape&#91;2&#93; == 1:
            # Single frame: only spatial downsample
            h = rearrange(h, &quot;b c f (h r2) (w r3) -&gt; b (r2 r3 c) f h w&quot;, r2=2, r3=2)
            h = torch.cat(&#91;h, h&#93;, dim=1)
            # Compute the shortcut part
            shortcut = rearrange(x, &quot;b c f (h r2) (w r3) -&gt; b (r2 r3 c) f h w&quot;, r2=2, r3=2)
            B, C, T, H, W = shortcut.shape
            shortcut = shortcut.view(B, h.shape&#91;1&#93;, self.group_size // 2, T, H, W).mean(dim=2)
        else:
            # Multiple frames: full spatio-temporal downsample
            h = rearrange(h, &quot;b c (f r1) (h r2) (w r3) -&gt; b (r1 r2 r3 c) f h w&quot;, r1=r1, r2=2, r3=2)
            # Shortcut computation
            shortcut = rearrange(x, &quot;b c (f r1) (h r2) (w r3) -&gt; b (r1 r2 r3 c) f h w&quot;, r1=r1, r2=2, r3=2)
            B, C, T, H, W = shortcut.shape
            shortcut = shortcut.view(B, h.shape&#91;1&#93;, self.group_size, T, H, W).mean(dim=2)
    else:
        h = rearrange(h, &quot;b c (f r1) (h r2) (w r3) -&gt; b (r1 r2 r3 c) f h w&quot;, r1=r1, r2=2, r3=2)
        shortcut = rearrange(x, &quot;b c (f r1) (h r2) (w r3) -&gt; b (r1 r2 r3 c) f h w&quot;, r1=r1, r2=2, r3=2)
        B, C, T, H, W = shortcut.shape
        shortcut = shortcut.view(B, h.shape&#91;1&#93;, self.group_size, T, H, W).mean(dim=2)

    return h + shortcut</code></pre></details>
<h2 id="fastvideo.models.vaes.hyworldvae.HYWorldResnetBlock"><code>fastvideo.models.vaes.hyworldvae.HYWorldResnetBlock</code></h2>
<pre class="doc-signature"><code>HYWorldResnetBlock(in_channels: int, out_channels: Optional&#91;int&#93; = None, non_linearity: str = &#x27;swish&#x27;)</code></pre>


<details><summary>Source</summary><pre><code>class HYWorldResnetBlock(nn.Module):

    def __init__(
        self,
        in_channels: int,
        out_channels: Optional&#91;int&#93; = None,
        non_linearity: str = &quot;swish&quot;,
    ) -&gt; None:
        super().__init__()
        self.in_channels = in_channels
        out_channels = in_channels if out_channels is None else out_channels
        self.out_channels = out_channels

        self.nonlinearity = get_act_fn(non_linearity)

        self.norm1 = HYWorldRMS_norm(in_channels, images=False)
        self.conv1 = HYWorldCausalConv3d(in_channels, out_channels, kernel_size=3)

        self.norm2 = HYWorldRMS_norm(out_channels, images=False)
        self.conv2 = HYWorldCausalConv3d(out_channels, out_channels, kernel_size=3)
        if in_channels != out_channels:
            self.nin_shortcut = nn.Conv3d(in_channels, out_channels, kernel_size=1, stride=1, padding=0)

    def forward(
        self,
        hidden_states: torch.Tensor,
        feat_cache: Optional&#91;List&#91;Optional&#91;torch.Tensor&#93;&#93;&#93; = None,
        feat_idx: Optional&#91;List&#91;int&#93;&#93; = None,
    ) -&gt; torch.Tensor:
        &quot;&quot;&quot;
        Forward pass with optional temporal feature caching.

        Args:
            hidden_states: Input tensor of shape (B, C, T, H, W)
            feat_cache: List of cached features for each conv layer
            feat_idx: List containing current cache index &#91;idx&#93;
        &quot;&quot;&quot;
        residual = hidden_states

        hidden_states = self.norm1(hidden_states)
        hidden_states = self.nonlinearity(hidden_states)

        # apply the feature cacheing mechanism
        if feat_cache is not None and feat_idx is not None:
            # Retrieve the current layer index.
            idx = feat_idx&#91;0&#93;

            # Clone the last CACHE_T frames from the current input to store for the next step.
            cache_x = hidden_states&#91;:, :, -CACHE_T:, :, :&#93;.clone()

            # Handle boundary conditions: if the current temporal chunk is too short (&lt; 2 frames)
            # and we have a previous cache, prepend the last frame of the previous cache.
            # This ensures sufficient temporal context for the convolution kernel.
            if cache_x.shape&#91;2&#93; &lt; 2 and feat_cache&#91;idx&#93; is not None:
                # actually this means chunk 1 after chunk 0
                cache_x = torch.cat(
                    &#91;feat_cache&#91;idx&#93;&#91;:, :, -1, :, :&#93;.unsqueeze(2).to(cache_x.device), cache_x&#93;,
                    dim=2,
                )

            # Apply the convolution layer using `hidden_states`and the *previous* cached state.
            hidden_states = self.conv1(hidden_states, feat_cache&#91;idx&#93;)

            # Update the cache for this layer with the newly prepared context (&#x27;cache_x&#x27;).
            feat_cache&#91;idx&#93; = cache_x

            # Increment the global layer index.
            feat_idx&#91;0&#93; += 1
        else:
            hidden_states = self.conv1(hidden_states)

        hidden_states = self.norm2(hidden_states)
        hidden_states = self.nonlinearity(hidden_states)

        # Second conv with caching
        if feat_cache is not None and feat_idx is not None:
            idx = feat_idx&#91;0&#93;
            cache_x = hidden_states&#91;:, :, -CACHE_T:, :, :&#93;.clone()
            if cache_x.shape&#91;2&#93; &lt; 2 and feat_cache&#91;idx&#93; is not None:
                cache_x = torch.cat(
                    &#91;feat_cache&#91;idx&#93;&#91;:, :, -1, :, :&#93;.unsqueeze(2).to(cache_x.device), cache_x&#93;,
                    dim=2,
                )
            hidden_states = self.conv2(hidden_states, feat_cache&#91;idx&#93;)
            feat_cache&#91;idx&#93; = cache_x
            feat_idx&#91;0&#93; += 1
        else:
            hidden_states = self.conv2(hidden_states)

        if self.in_channels != self.out_channels:
            residual = self.nin_shortcut(residual)

        return hidden_states + residual</code></pre></details>
<h3 id="fastvideo.models.vaes.hyworldvae.HYWorldResnetBlock.forward"><code>fastvideo.models.vaes.hyworldvae.HYWorldResnetBlock.forward</code></h3>
<pre class="doc-signature"><code>forward(hidden_states: torch.Tensor, feat_cache: Optional&#91;List&#91;Optional&#91;torch.Tensor&#93;&#93;&#93; = None, feat_idx: Optional&#91;List&#91;int&#93;&#93; = None) -&gt; torch.Tensor</code></pre>
<p>Forward pass with optional temporal feature caching.</p>
<h4>Parameters</h4>
<dl>
<dt><code>hidden_states: torch.Tensor</code></dt><dd><p>Input tensor of shape (B, C, T, H, W)</p></dd>
<dt><code>feat_cache: Optional[List[Optional[torch.Tensor]]]</code></dt><dd><p>List of cached features for each conv layer</p></dd>
<dt><code>feat_idx: Optional[List[int]]</code></dt><dd><p>List containing current cache index [idx]</p></dd>
</dl>
<details><summary>Source</summary><pre><code>def forward(
    self,
    hidden_states: torch.Tensor,
    feat_cache: Optional&#91;List&#91;Optional&#91;torch.Tensor&#93;&#93;&#93; = None,
    feat_idx: Optional&#91;List&#91;int&#93;&#93; = None,
) -&gt; torch.Tensor:
    &quot;&quot;&quot;
    Forward pass with optional temporal feature caching.

    Args:
        hidden_states: Input tensor of shape (B, C, T, H, W)
        feat_cache: List of cached features for each conv layer
        feat_idx: List containing current cache index &#91;idx&#93;
    &quot;&quot;&quot;
    residual = hidden_states

    hidden_states = self.norm1(hidden_states)
    hidden_states = self.nonlinearity(hidden_states)

    # apply the feature cacheing mechanism
    if feat_cache is not None and feat_idx is not None:
        # Retrieve the current layer index.
        idx = feat_idx&#91;0&#93;

        # Clone the last CACHE_T frames from the current input to store for the next step.
        cache_x = hidden_states&#91;:, :, -CACHE_T:, :, :&#93;.clone()

        # Handle boundary conditions: if the current temporal chunk is too short (&lt; 2 frames)
        # and we have a previous cache, prepend the last frame of the previous cache.
        # This ensures sufficient temporal context for the convolution kernel.
        if cache_x.shape&#91;2&#93; &lt; 2 and feat_cache&#91;idx&#93; is not None:
            # actually this means chunk 1 after chunk 0
            cache_x = torch.cat(
                &#91;feat_cache&#91;idx&#93;&#91;:, :, -1, :, :&#93;.unsqueeze(2).to(cache_x.device), cache_x&#93;,
                dim=2,
            )

        # Apply the convolution layer using `hidden_states`and the *previous* cached state.
        hidden_states = self.conv1(hidden_states, feat_cache&#91;idx&#93;)

        # Update the cache for this layer with the newly prepared context (&#x27;cache_x&#x27;).
        feat_cache&#91;idx&#93; = cache_x

        # Increment the global layer index.
        feat_idx&#91;0&#93; += 1
    else:
        hidden_states = self.conv1(hidden_states)

    hidden_states = self.norm2(hidden_states)
    hidden_states = self.nonlinearity(hidden_states)

    # Second conv with caching
    if feat_cache is not None and feat_idx is not None:
        idx = feat_idx&#91;0&#93;
        cache_x = hidden_states&#91;:, :, -CACHE_T:, :, :&#93;.clone()
        if cache_x.shape&#91;2&#93; &lt; 2 and feat_cache&#91;idx&#93; is not None:
            cache_x = torch.cat(
                &#91;feat_cache&#91;idx&#93;&#91;:, :, -1, :, :&#93;.unsqueeze(2).to(cache_x.device), cache_x&#93;,
                dim=2,
            )
        hidden_states = self.conv2(hidden_states, feat_cache&#91;idx&#93;)
        feat_cache&#91;idx&#93; = cache_x
        feat_idx&#91;0&#93; += 1
    else:
        hidden_states = self.conv2(hidden_states)

    if self.in_channels != self.out_channels:
        residual = self.nin_shortcut(residual)

    return hidden_states + residual</code></pre></details>
<h2 id="fastvideo.models.vaes.hyworldvae.HYWorldMidBlock"><code>fastvideo.models.vaes.hyworldvae.HYWorldMidBlock</code></h2>
<pre class="doc-signature"><code>HYWorldMidBlock(in_channels: int, num_layers: int = 1, add_attention: bool = True)</code></pre>
<p>Mid block with attention and resnet blocks, with optional caching support.</p>

<details><summary>Source</summary><pre><code>class HYWorldMidBlock(nn.Module):
    &quot;&quot;&quot;Mid block with attention and resnet blocks, with optional caching support.&quot;&quot;&quot;

    def __init__(
        self,
        in_channels: int,
        num_layers: int = 1,
        add_attention: bool = True,
    ) -&gt; None:
        super().__init__()
        self.add_attention = add_attention

        # There is always at least one resnet
        resnets = &#91;HYWorldResnetBlock(
            in_channels=in_channels,
            out_channels=in_channels,
        )&#93;
        attentions = &#91;&#93;

        for _ in range(num_layers):
            if self.add_attention:
                attentions.append(HYWorldAttnBlock(in_channels))
            else:
                attentions.append(None)

            resnets.append(HYWorldResnetBlock(
                in_channels=in_channels,
                out_channels=in_channels,
            ))

        self.attentions = nn.ModuleList(attentions)
        self.resnets = nn.ModuleList(resnets)

        self.gradient_checkpointing = False

    def forward(
        self,
        hidden_states: torch.Tensor,
        feat_cache: Optional&#91;List&#91;Optional&#91;torch.Tensor&#93;&#93;&#93; = None,
        feat_idx: Optional&#91;List&#91;int&#93;&#93; = None,
    ) -&gt; torch.Tensor:
        &quot;&quot;&quot;
        Forward pass with optional temporal caching.

        Args:
            hidden_states: Input tensor of shape (B, C, T, H, W)
            feat_cache: List of cached features for each conv layer
            feat_idx: List containing current cache index &#91;idx&#93;
        &quot;&quot;&quot;
        hidden_states = self.resnets&#91;0&#93;(hidden_states, feat_cache, feat_idx)

        for attn, resnet in zip(self.attentions, self.resnets&#91;1:&#93;):
            if attn is not None:
                hidden_states = attn(hidden_states)
            hidden_states = resnet(hidden_states, feat_cache, feat_idx)

        return hidden_states</code></pre></details>
<h3 id="fastvideo.models.vaes.hyworldvae.HYWorldMidBlock.forward"><code>fastvideo.models.vaes.hyworldvae.HYWorldMidBlock.forward</code></h3>
<pre class="doc-signature"><code>forward(hidden_states: torch.Tensor, feat_cache: Optional&#91;List&#91;Optional&#91;torch.Tensor&#93;&#93;&#93; = None, feat_idx: Optional&#91;List&#91;int&#93;&#93; = None) -&gt; torch.Tensor</code></pre>
<p>Forward pass with optional temporal caching.</p>
<h4>Parameters</h4>
<dl>
<dt><code>hidden_states: torch.Tensor</code></dt><dd><p>Input tensor of shape (B, C, T, H, W)</p></dd>
<dt><code>feat_cache: Optional[List[Optional[torch.Tensor]]]</code></dt><dd><p>List of cached features for each conv layer</p></dd>
<dt><code>feat_idx: Optional[List[int]]</code></dt><dd><p>List containing current cache index [idx]</p></dd>
</dl>
<details><summary>Source</summary><pre><code>def forward(
    self,
    hidden_states: torch.Tensor,
    feat_cache: Optional&#91;List&#91;Optional&#91;torch.Tensor&#93;&#93;&#93; = None,
    feat_idx: Optional&#91;List&#91;int&#93;&#93; = None,
) -&gt; torch.Tensor:
    &quot;&quot;&quot;
    Forward pass with optional temporal caching.

    Args:
        hidden_states: Input tensor of shape (B, C, T, H, W)
        feat_cache: List of cached features for each conv layer
        feat_idx: List containing current cache index &#91;idx&#93;
    &quot;&quot;&quot;
    hidden_states = self.resnets&#91;0&#93;(hidden_states, feat_cache, feat_idx)

    for attn, resnet in zip(self.attentions, self.resnets&#91;1:&#93;):
        if attn is not None:
            hidden_states = attn(hidden_states)
        hidden_states = resnet(hidden_states, feat_cache, feat_idx)

    return hidden_states</code></pre></details>
<h2 id="fastvideo.models.vaes.hyworldvae.HYWorldDownBlock3D"><code>fastvideo.models.vaes.hyworldvae.HYWorldDownBlock3D</code></h2>
<pre class="doc-signature"><code>HYWorldDownBlock3D(in_channels: int, out_channels: int, num_layers: int = 1, downsample_out_channels: Optional&#91;int&#93; = None, add_temporal_downsample: int = True)</code></pre>
<p>Down block with resnet blocks and optional downsampling, with caching support.</p>

<details><summary>Source</summary><pre><code>class HYWorldDownBlock3D(nn.Module):
    &quot;&quot;&quot;Down block with resnet blocks and optional downsampling, with caching support.&quot;&quot;&quot;

    def __init__(
        self,
        in_channels: int,
        out_channels: int,
        num_layers: int = 1,
        downsample_out_channels: Optional&#91;int&#93; = None,
        add_temporal_downsample: int = True,
    ) -&gt; None:
        super().__init__()
        resnets = &#91;&#93;

        for i in range(num_layers):
            in_channels = in_channels if i == 0 else out_channels
            resnets.append(HYWorldResnetBlock(
                in_channels=in_channels,
                out_channels=out_channels,
            ))

        self.resnets = nn.ModuleList(resnets)

        if downsample_out_channels is not None:
            self.downsamplers = nn.ModuleList(&#91;
                HYWorldDownsample(
                    out_channels,
                    out_channels=downsample_out_channels,
                    add_temporal_downsample=add_temporal_downsample,
                )
            &#93;)
        else:
            self.downsamplers = None

        self.gradient_checkpointing = False

    def forward(
        self,
        hidden_states: torch.Tensor,
        feat_cache: Optional&#91;List&#91;Optional&#91;torch.Tensor&#93;&#93;&#93; = None,
        feat_idx: Optional&#91;List&#91;int&#93;&#93; = None,
    ) -&gt; torch.Tensor:
        &quot;&quot;&quot;
        Forward pass with optional temporal caching.

        Args:
            hidden_states: Input tensor of shape (B, C, T, H, W)
            feat_cache: List of cached features for each conv layer
            feat_idx: List containing current cache index &#91;idx&#93;
        &quot;&quot;&quot;
        for resnet in self.resnets:
            hidden_states = resnet(hidden_states, feat_cache, feat_idx)

        if self.downsamplers is not None:
            for downsampler in self.downsamplers:
                hidden_states = downsampler(hidden_states, feat_cache, feat_idx)

        return hidden_states</code></pre></details>
<h3 id="fastvideo.models.vaes.hyworldvae.HYWorldDownBlock3D.forward"><code>fastvideo.models.vaes.hyworldvae.HYWorldDownBlock3D.forward</code></h3>
<pre class="doc-signature"><code>forward(hidden_states: torch.Tensor, feat_cache: Optional&#91;List&#91;Optional&#91;torch.Tensor&#93;&#93;&#93; = None, feat_idx: Optional&#91;List&#91;int&#93;&#93; = None) -&gt; torch.Tensor</code></pre>
<p>Forward pass with optional temporal caching.</p>
<h4>Parameters</h4>
<dl>
<dt><code>hidden_states: torch.Tensor</code></dt><dd><p>Input tensor of shape (B, C, T, H, W)</p></dd>
<dt><code>feat_cache: Optional[List[Optional[torch.Tensor]]]</code></dt><dd><p>List of cached features for each conv layer</p></dd>
<dt><code>feat_idx: Optional[List[int]]</code></dt><dd><p>List containing current cache index [idx]</p></dd>
</dl>
<details><summary>Source</summary><pre><code>def forward(
    self,
    hidden_states: torch.Tensor,
    feat_cache: Optional&#91;List&#91;Optional&#91;torch.Tensor&#93;&#93;&#93; = None,
    feat_idx: Optional&#91;List&#91;int&#93;&#93; = None,
) -&gt; torch.Tensor:
    &quot;&quot;&quot;
    Forward pass with optional temporal caching.

    Args:
        hidden_states: Input tensor of shape (B, C, T, H, W)
        feat_cache: List of cached features for each conv layer
        feat_idx: List containing current cache index &#91;idx&#93;
    &quot;&quot;&quot;
    for resnet in self.resnets:
        hidden_states = resnet(hidden_states, feat_cache, feat_idx)

    if self.downsamplers is not None:
        for downsampler in self.downsamplers:
            hidden_states = downsampler(hidden_states, feat_cache, feat_idx)

    return hidden_states</code></pre></details>
<h2 id="fastvideo.models.vaes.hyworldvae.HYWorldUpBlock3D"><code>fastvideo.models.vaes.hyworldvae.HYWorldUpBlock3D</code></h2>
<pre class="doc-signature"><code>HYWorldUpBlock3D(in_channels: int, out_channels: int, num_layers: int = 1, upsample_out_channels: Optional&#91;int&#93; = None, add_temporal_upsample: bool = True)</code></pre>
<p>Up block with resnet blocks and optional upsampling, with caching support.</p>

<details><summary>Source</summary><pre><code>class HYWorldUpBlock3D(nn.Module):
    &quot;&quot;&quot;Up block with resnet blocks and optional upsampling, with caching support.&quot;&quot;&quot;

    def __init__(
        self,
        in_channels: int,
        out_channels: int,
        num_layers: int = 1,
        upsample_out_channels: Optional&#91;int&#93; = None,
        add_temporal_upsample: bool = True,
    ) -&gt; None:
        super().__init__()
        resnets = &#91;&#93;

        for i in range(num_layers):
            input_channels = in_channels if i == 0 else out_channels

            resnets.append(HYWorldResnetBlock(
                in_channels=input_channels,
                out_channels=out_channels,
            ))

        self.resnets = nn.ModuleList(resnets)

        if upsample_out_channels is not None:
            self.upsamplers = nn.ModuleList(&#91;
                HYWorldUpsample(
                    out_channels,
                    out_channels=upsample_out_channels,
                    add_temporal_upsample=add_temporal_upsample,
                )
            &#93;)
        else:
            self.upsamplers = None

        self.gradient_checkpointing = False

    def forward(
        self,
        hidden_states: torch.Tensor,
        feat_cache: Optional&#91;List&#91;Optional&#91;torch.Tensor&#93;&#93;&#93; = None,
        feat_idx: Optional&#91;List&#91;int&#93;&#93; = None,
        first_chunk: bool = False,
    ) -&gt; torch.Tensor:
        &quot;&quot;&quot;
        Forward pass with optional temporal caching.

        Args:
            hidden_states: Input tensor of shape (B, C, T, H, W)
            feat_cache: List of cached features for each conv layer
            feat_idx: List containing current cache index &#91;idx&#93;
            first_chunk: Whether this is the first chunk (for upsampling behavior)
        &quot;&quot;&quot;
        if torch.is_grad_enabled() and self.gradient_checkpointing:
            for resnet in self.resnets:
                hidden_states = self._gradient_checkpointing_func(resnet, hidden_states)
        else:
            for resnet in self.resnets:
                hidden_states = resnet(hidden_states, feat_cache, feat_idx)

        if self.upsamplers is not None:
            for upsampler in self.upsamplers:
                hidden_states = upsampler(hidden_states, feat_cache, feat_idx, first_chunk)

        return hidden_states</code></pre></details>
<h3 id="fastvideo.models.vaes.hyworldvae.HYWorldUpBlock3D.forward"><code>fastvideo.models.vaes.hyworldvae.HYWorldUpBlock3D.forward</code></h3>
<pre class="doc-signature"><code>forward(hidden_states: torch.Tensor, feat_cache: Optional&#91;List&#91;Optional&#91;torch.Tensor&#93;&#93;&#93; = None, feat_idx: Optional&#91;List&#91;int&#93;&#93; = None, first_chunk: bool = False) -&gt; torch.Tensor</code></pre>
<p>Forward pass with optional temporal caching.</p>
<h4>Parameters</h4>
<dl>
<dt><code>hidden_states: torch.Tensor</code></dt><dd><p>Input tensor of shape (B, C, T, H, W)</p></dd>
<dt><code>feat_cache: Optional[List[Optional[torch.Tensor]]]</code></dt><dd><p>List of cached features for each conv layer</p></dd>
<dt><code>feat_idx: Optional[List[int]]</code></dt><dd><p>List containing current cache index [idx]</p></dd>
<dt><code>first_chunk: bool</code></dt><dd><p>Whether this is the first chunk (for upsampling behavior)</p></dd>
</dl>
<details><summary>Source</summary><pre><code>def forward(
    self,
    hidden_states: torch.Tensor,
    feat_cache: Optional&#91;List&#91;Optional&#91;torch.Tensor&#93;&#93;&#93; = None,
    feat_idx: Optional&#91;List&#91;int&#93;&#93; = None,
    first_chunk: bool = False,
) -&gt; torch.Tensor:
    &quot;&quot;&quot;
    Forward pass with optional temporal caching.

    Args:
        hidden_states: Input tensor of shape (B, C, T, H, W)
        feat_cache: List of cached features for each conv layer
        feat_idx: List containing current cache index &#91;idx&#93;
        first_chunk: Whether this is the first chunk (for upsampling behavior)
    &quot;&quot;&quot;
    if torch.is_grad_enabled() and self.gradient_checkpointing:
        for resnet in self.resnets:
            hidden_states = self._gradient_checkpointing_func(resnet, hidden_states)
    else:
        for resnet in self.resnets:
            hidden_states = resnet(hidden_states, feat_cache, feat_idx)

    if self.upsamplers is not None:
        for upsampler in self.upsamplers:
            hidden_states = upsampler(hidden_states, feat_cache, feat_idx, first_chunk)

    return hidden_states</code></pre></details>
<h2 id="fastvideo.models.vaes.hyworldvae.HYWorldEncoder3D"><code>fastvideo.models.vaes.hyworldvae.HYWorldEncoder3D</code></h2>
<pre class="doc-signature"><code>HYWorldEncoder3D(in_channels: int = 3, out_channels: int = 64, block_out_channels: Tuple&#91;int, ...&#93; = (128, 256, 512, 1024, 1024), layers_per_block: int = 2, temporal_compression_ratio: int = 4, spatial_compression_ratio: int = 16, downsample_match_channel: bool = True)</code></pre>
<p>3D vae encoder for HunyuanImageRefiner with optional temporal caching.</p>

<details><summary>Source</summary><pre><code>class HYWorldEncoder3D(nn.Module):
    r&quot;&quot;&quot;
    3D vae encoder for HunyuanImageRefiner with optional temporal caching.
    &quot;&quot;&quot;

    def __init__(
        self,
        in_channels: int = 3,
        out_channels: int = 64,
        block_out_channels: Tuple&#91;int, ...&#93; = (128, 256, 512, 1024, 1024),
        layers_per_block: int = 2,
        temporal_compression_ratio: int = 4,
        spatial_compression_ratio: int = 16,
        downsample_match_channel: bool = True,
    ) -&gt; None:
        super().__init__()

        self.in_channels = in_channels
        self.out_channels = out_channels
        self.group_size = block_out_channels&#91;-1&#93; // self.out_channels
        self.block_out_channels = block_out_channels

        self.conv_in = HYWorldCausalConv3d(in_channels, block_out_channels&#91;0&#93;, kernel_size=3)
        self.mid_block = None
        self.down_blocks = nn.ModuleList(&#91;&#93;)

        input_channel = block_out_channels&#91;0&#93;
        for i in range(len(block_out_channels)):
            add_spatial_downsample = i &lt; np.log2(spatial_compression_ratio)
            output_channel = block_out_channels&#91;i&#93;
            if not add_spatial_downsample:
                down_block = HYWorldDownBlock3D(
                    num_layers=layers_per_block,
                    in_channels=input_channel,
                    out_channels=output_channel,
                    downsample_out_channels=None,
                    add_temporal_downsample=False,
                )
                input_channel = output_channel
            else:
                add_temporal_downsample = i &gt;= np.log2(spatial_compression_ratio // temporal_compression_ratio)
                downsample_out_channels = block_out_channels&#91;i + 1&#93; if downsample_match_channel else output_channel
                down_block = HYWorldDownBlock3D(
                    num_layers=layers_per_block,
                    in_channels=input_channel,
                    out_channels=output_channel,
                    downsample_out_channels=downsample_out_channels,
                    add_temporal_downsample=add_temporal_downsample,
                )
                input_channel = downsample_out_channels

            self.down_blocks.append(down_block)

        self.mid_block = HYWorldMidBlock(in_channels=block_out_channels&#91;-1&#93;)

        self.norm_out = HYWorldRMS_norm(block_out_channels&#91;-1&#93;, images=False)
        self.conv_act = nn.SiLU()
        self.conv_out = HYWorldCausalConv3d(block_out_channels&#91;-1&#93;, out_channels, kernel_size=3)

        self.gradient_checkpointing = False

    def forward(
        self,
        hidden_states: torch.Tensor,
        feat_cache: Optional&#91;List&#91;Optional&#91;torch.Tensor&#93;&#93;&#93; = None,
        feat_idx: Optional&#91;List&#91;int&#93;&#93; = None,
    ) -&gt; torch.Tensor:
        &quot;&quot;&quot;
        Forward pass with optional temporal caching.

        Args:
            hidden_states: Input tensor of shape (B, C, T, H, W)
            feat_cache: List of cached features for each conv layer
            feat_idx: List containing current cache index &#91;idx&#93;
        &quot;&quot;&quot;
        # conv_in with caching
        if feat_cache is not None and feat_idx is not None:
            idx = feat_idx&#91;0&#93;
            cache_x = hidden_states&#91;:, :, -CACHE_T:, :, :&#93;.clone()
            if cache_x.shape&#91;2&#93; &lt; 2 and feat_cache&#91;idx&#93; is not None:
                cache_x = torch.cat(
                    &#91;feat_cache&#91;idx&#93;&#91;:, :, -1, :, :&#93;.unsqueeze(2).to(cache_x.device), cache_x&#93;,
                    dim=2,
                )
            hidden_states = self.conv_in(hidden_states, feat_cache&#91;idx&#93;)
            feat_cache&#91;idx&#93; = cache_x
            feat_idx&#91;0&#93; += 1
        else:
            hidden_states = self.conv_in(hidden_states)

        if torch.is_grad_enabled() and self.gradient_checkpointing:
            for down_block in self.down_blocks:
                hidden_states = self._gradient_checkpointing_func(down_block, hidden_states)
            hidden_states = self._gradient_checkpointing_func(self.mid_block, hidden_states)
        else:
            for down_block in self.down_blocks:
                hidden_states = down_block(hidden_states, feat_cache, feat_idx)
            hidden_states = self.mid_block(hidden_states, feat_cache, feat_idx)

        batch_size, _, frame, height, width = hidden_states.shape
        short_cut = hidden_states.view(batch_size, -1, self.group_size, frame, height, width).mean(dim=2)

        hidden_states = self.norm_out(hidden_states)
        hidden_states = self.conv_act(hidden_states)

        # conv_out with caching
        if feat_cache is not None and feat_idx is not None:
            idx = feat_idx&#91;0&#93;
            cache_x = hidden_states&#91;:, :, -CACHE_T:, :, :&#93;.clone()
            if cache_x.shape&#91;2&#93; &lt; 2 and feat_cache&#91;idx&#93; is not None:
                cache_x = torch.cat(
                    &#91;feat_cache&#91;idx&#93;&#91;:, :, -1, :, :&#93;.unsqueeze(2).to(cache_x.device), cache_x&#93;,
                    dim=2,
                )
            hidden_states = self.conv_out(hidden_states, feat_cache&#91;idx&#93;)
            feat_cache&#91;idx&#93; = cache_x
            feat_idx&#91;0&#93; += 1
        else:
            hidden_states = self.conv_out(hidden_states)

        hidden_states += short_cut

        return hidden_states</code></pre></details>
<h3 id="fastvideo.models.vaes.hyworldvae.HYWorldEncoder3D.forward"><code>fastvideo.models.vaes.hyworldvae.HYWorldEncoder3D.forward</code></h3>
<pre class="doc-signature"><code>forward(hidden_states: torch.Tensor, feat_cache: Optional&#91;List&#91;Optional&#91;torch.Tensor&#93;&#93;&#93; = None, feat_idx: Optional&#91;List&#91;int&#93;&#93; = None) -&gt; torch.Tensor</code></pre>
<p>Forward pass with optional temporal caching.</p>
<h4>Parameters</h4>
<dl>
<dt><code>hidden_states: torch.Tensor</code></dt><dd><p>Input tensor of shape (B, C, T, H, W)</p></dd>
<dt><code>feat_cache: Optional[List[Optional[torch.Tensor]]]</code></dt><dd><p>List of cached features for each conv layer</p></dd>
<dt><code>feat_idx: Optional[List[int]]</code></dt><dd><p>List containing current cache index [idx]</p></dd>
</dl>
<details><summary>Source</summary><pre><code>def forward(
    self,
    hidden_states: torch.Tensor,
    feat_cache: Optional&#91;List&#91;Optional&#91;torch.Tensor&#93;&#93;&#93; = None,
    feat_idx: Optional&#91;List&#91;int&#93;&#93; = None,
) -&gt; torch.Tensor:
    &quot;&quot;&quot;
    Forward pass with optional temporal caching.

    Args:
        hidden_states: Input tensor of shape (B, C, T, H, W)
        feat_cache: List of cached features for each conv layer
        feat_idx: List containing current cache index &#91;idx&#93;
    &quot;&quot;&quot;
    # conv_in with caching
    if feat_cache is not None and feat_idx is not None:
        idx = feat_idx&#91;0&#93;
        cache_x = hidden_states&#91;:, :, -CACHE_T:, :, :&#93;.clone()
        if cache_x.shape&#91;2&#93; &lt; 2 and feat_cache&#91;idx&#93; is not None:
            cache_x = torch.cat(
                &#91;feat_cache&#91;idx&#93;&#91;:, :, -1, :, :&#93;.unsqueeze(2).to(cache_x.device), cache_x&#93;,
                dim=2,
            )
        hidden_states = self.conv_in(hidden_states, feat_cache&#91;idx&#93;)
        feat_cache&#91;idx&#93; = cache_x
        feat_idx&#91;0&#93; += 1
    else:
        hidden_states = self.conv_in(hidden_states)

    if torch.is_grad_enabled() and self.gradient_checkpointing:
        for down_block in self.down_blocks:
            hidden_states = self._gradient_checkpointing_func(down_block, hidden_states)
        hidden_states = self._gradient_checkpointing_func(self.mid_block, hidden_states)
    else:
        for down_block in self.down_blocks:
            hidden_states = down_block(hidden_states, feat_cache, feat_idx)
        hidden_states = self.mid_block(hidden_states, feat_cache, feat_idx)

    batch_size, _, frame, height, width = hidden_states.shape
    short_cut = hidden_states.view(batch_size, -1, self.group_size, frame, height, width).mean(dim=2)

    hidden_states = self.norm_out(hidden_states)
    hidden_states = self.conv_act(hidden_states)

    # conv_out with caching
    if feat_cache is not None and feat_idx is not None:
        idx = feat_idx&#91;0&#93;
        cache_x = hidden_states&#91;:, :, -CACHE_T:, :, :&#93;.clone()
        if cache_x.shape&#91;2&#93; &lt; 2 and feat_cache&#91;idx&#93; is not None:
            cache_x = torch.cat(
                &#91;feat_cache&#91;idx&#93;&#91;:, :, -1, :, :&#93;.unsqueeze(2).to(cache_x.device), cache_x&#93;,
                dim=2,
            )
        hidden_states = self.conv_out(hidden_states, feat_cache&#91;idx&#93;)
        feat_cache&#91;idx&#93; = cache_x
        feat_idx&#91;0&#93; += 1
    else:
        hidden_states = self.conv_out(hidden_states)

    hidden_states += short_cut

    return hidden_states</code></pre></details>
<h2 id="fastvideo.models.vaes.hyworldvae.HYWorldDecoder3D"><code>fastvideo.models.vaes.hyworldvae.HYWorldDecoder3D</code></h2>
<pre class="doc-signature"><code>HYWorldDecoder3D(in_channels: int = 32, out_channels: int = 3, block_out_channels: Tuple&#91;int, ...&#93; = (1024, 1024, 512, 256, 128), layers_per_block: int = 2, spatial_compression_ratio: int = 16, temporal_compression_ratio: int = 4, upsample_match_channel: bool = True)</code></pre>
<p>Causal decoder for 3D video-like data used for HunyuanImage-1.5 Refiner with optional temporal caching.</p>

<details><summary>Source</summary><pre><code>class HYWorldDecoder3D(nn.Module):
    r&quot;&quot;&quot;
    Causal decoder for 3D video-like data used for HunyuanImage-1.5 Refiner with optional temporal caching.
    &quot;&quot;&quot;

    def __init__(
        self,
        in_channels: int = 32,
        out_channels: int = 3,
        block_out_channels: Tuple&#91;int, ...&#93; = (1024, 1024, 512, 256, 128),
        layers_per_block: int = 2,
        spatial_compression_ratio: int = 16,
        temporal_compression_ratio: int = 4,
        upsample_match_channel: bool = True,
    ):
        super().__init__()
        self.layers_per_block = layers_per_block
        self.in_channels = in_channels
        self.out_channels = out_channels
        self.block_out_channels = block_out_channels
        self.repeat = block_out_channels&#91;0&#93; // self.in_channels

        self.conv_in = HYWorldCausalConv3d(self.in_channels, block_out_channels&#91;0&#93;, kernel_size=3)
        self.up_blocks = nn.ModuleList(&#91;&#93;)

        # mid
        self.mid_block = HYWorldMidBlock(in_channels=block_out_channels&#91;0&#93;)

        # up
        input_channel = block_out_channels&#91;0&#93;
        for i in range(len(block_out_channels)):
            output_channel = block_out_channels&#91;i&#93;

            add_spatial_upsample = i &lt; np.log2(spatial_compression_ratio)
            add_temporal_upsample = i &lt; np.log2(temporal_compression_ratio)
            if add_spatial_upsample or add_temporal_upsample:
                upsample_out_channels = block_out_channels&#91;i + 1&#93; if upsample_match_channel else output_channel
                up_block = HYWorldUpBlock3D(
                    num_layers=self.layers_per_block + 1,
                    in_channels=input_channel,
                    out_channels=output_channel,
                    upsample_out_channels=upsample_out_channels,
                    add_temporal_upsample=add_temporal_upsample,
                )
                input_channel = upsample_out_channels
            else:
                up_block = HYWorldUpBlock3D(
                    num_layers=self.layers_per_block + 1,
                    in_channels=input_channel,
                    out_channels=output_channel,
                    upsample_out_channels=None,
                    add_temporal_upsample=False,
                )
                input_channel = output_channel

            self.up_blocks.append(up_block)

        # out
        self.norm_out = HYWorldRMS_norm(block_out_channels&#91;-1&#93;, images=False)
        self.conv_act = nn.SiLU()
        self.conv_out = HYWorldCausalConv3d(block_out_channels&#91;-1&#93;, out_channels, kernel_size=3)

        self.gradient_checkpointing = False

    def forward(
        self,
        hidden_states: torch.Tensor,
        feat_cache: Optional&#91;List&#91;Optional&#91;torch.Tensor&#93;&#93;&#93; = None,
        feat_idx: Optional&#91;List&#91;int&#93;&#93; = None,
        first_chunk: bool = False,
    ) -&gt; torch.Tensor:
        &quot;&quot;&quot;
        Forward pass with optional temporal caching.

        Args:
            hidden_states: Input tensor of shape (B, C, T, H, W)
            feat_cache: List of cached features for each conv layer
            feat_idx: List containing current cache index &#91;idx&#93;
            first_chunk: Whether this is the first chunk (for upsampling behavior)
        &quot;&quot;&quot;
        # conv_in with caching
        if feat_cache is not None and feat_idx is not None:
            idx = feat_idx&#91;0&#93;
            cache_x = hidden_states&#91;:, :, -CACHE_T:, :, :&#93;.clone()
            if cache_x.shape&#91;2&#93; &lt; 2 and feat_cache&#91;idx&#93; is not None:
                cache_x = torch.cat(
                    &#91;feat_cache&#91;idx&#93;&#91;:, :, -1, :, :&#93;.unsqueeze(2).to(cache_x.device), cache_x&#93;,
                    dim=2,
                )
            hidden_states = self.conv_in(hidden_states, feat_cache&#91;idx&#93;) + hidden_states.repeat_interleave(
                repeats=self.repeat, dim=1)
            feat_cache&#91;idx&#93; = cache_x
            feat_idx&#91;0&#93; += 1
        else:
            hidden_states = self.conv_in(hidden_states) + hidden_states.repeat_interleave(repeats=self.repeat, dim=1)

        if torch.is_grad_enabled() and self.gradient_checkpointing:
            hidden_states = self._gradient_checkpointing_func(self.mid_block, hidden_states)
            for up_block in self.up_blocks:
                hidden_states = self._gradient_checkpointing_func(up_block, hidden_states)
        else:
            hidden_states = self.mid_block(hidden_states, feat_cache, feat_idx)
            for up_block in self.up_blocks:
                hidden_states = up_block(hidden_states, feat_cache, feat_idx, first_chunk)

        # post-process
        hidden_states = self.norm_out(hidden_states)
        hidden_states = self.conv_act(hidden_states)

        # conv_out with caching
        if feat_cache is not None and feat_idx is not None:
            idx = feat_idx&#91;0&#93;
            cache_x = hidden_states&#91;:, :, -CACHE_T:, :, :&#93;.clone()
            if cache_x.shape&#91;2&#93; &lt; 2 and feat_cache&#91;idx&#93; is not None:
                cache_x = torch.cat(
                    &#91;feat_cache&#91;idx&#93;&#91;:, :, -1, :, :&#93;.unsqueeze(2).to(cache_x.device), cache_x&#93;,
                    dim=2,
                )
            hidden_states = self.conv_out(hidden_states, feat_cache&#91;idx&#93;)
            feat_cache&#91;idx&#93; = cache_x
            feat_idx&#91;0&#93; += 1
        else:
            hidden_states = self.conv_out(hidden_states)

        return hidden_states</code></pre></details>
<h3 id="fastvideo.models.vaes.hyworldvae.HYWorldDecoder3D.forward"><code>fastvideo.models.vaes.hyworldvae.HYWorldDecoder3D.forward</code></h3>
<pre class="doc-signature"><code>forward(hidden_states: torch.Tensor, feat_cache: Optional&#91;List&#91;Optional&#91;torch.Tensor&#93;&#93;&#93; = None, feat_idx: Optional&#91;List&#91;int&#93;&#93; = None, first_chunk: bool = False) -&gt; torch.Tensor</code></pre>
<p>Forward pass with optional temporal caching.</p>
<h4>Parameters</h4>
<dl>
<dt><code>hidden_states: torch.Tensor</code></dt><dd><p>Input tensor of shape (B, C, T, H, W)</p></dd>
<dt><code>feat_cache: Optional[List[Optional[torch.Tensor]]]</code></dt><dd><p>List of cached features for each conv layer</p></dd>
<dt><code>feat_idx: Optional[List[int]]</code></dt><dd><p>List containing current cache index [idx]</p></dd>
<dt><code>first_chunk: bool</code></dt><dd><p>Whether this is the first chunk (for upsampling behavior)</p></dd>
</dl>
<details><summary>Source</summary><pre><code>def forward(
    self,
    hidden_states: torch.Tensor,
    feat_cache: Optional&#91;List&#91;Optional&#91;torch.Tensor&#93;&#93;&#93; = None,
    feat_idx: Optional&#91;List&#91;int&#93;&#93; = None,
    first_chunk: bool = False,
) -&gt; torch.Tensor:
    &quot;&quot;&quot;
    Forward pass with optional temporal caching.

    Args:
        hidden_states: Input tensor of shape (B, C, T, H, W)
        feat_cache: List of cached features for each conv layer
        feat_idx: List containing current cache index &#91;idx&#93;
        first_chunk: Whether this is the first chunk (for upsampling behavior)
    &quot;&quot;&quot;
    # conv_in with caching
    if feat_cache is not None and feat_idx is not None:
        idx = feat_idx&#91;0&#93;
        cache_x = hidden_states&#91;:, :, -CACHE_T:, :, :&#93;.clone()
        if cache_x.shape&#91;2&#93; &lt; 2 and feat_cache&#91;idx&#93; is not None:
            cache_x = torch.cat(
                &#91;feat_cache&#91;idx&#93;&#91;:, :, -1, :, :&#93;.unsqueeze(2).to(cache_x.device), cache_x&#93;,
                dim=2,
            )
        hidden_states = self.conv_in(hidden_states, feat_cache&#91;idx&#93;) + hidden_states.repeat_interleave(
            repeats=self.repeat, dim=1)
        feat_cache&#91;idx&#93; = cache_x
        feat_idx&#91;0&#93; += 1
    else:
        hidden_states = self.conv_in(hidden_states) + hidden_states.repeat_interleave(repeats=self.repeat, dim=1)

    if torch.is_grad_enabled() and self.gradient_checkpointing:
        hidden_states = self._gradient_checkpointing_func(self.mid_block, hidden_states)
        for up_block in self.up_blocks:
            hidden_states = self._gradient_checkpointing_func(up_block, hidden_states)
    else:
        hidden_states = self.mid_block(hidden_states, feat_cache, feat_idx)
        for up_block in self.up_blocks:
            hidden_states = up_block(hidden_states, feat_cache, feat_idx, first_chunk)

    # post-process
    hidden_states = self.norm_out(hidden_states)
    hidden_states = self.conv_act(hidden_states)

    # conv_out with caching
    if feat_cache is not None and feat_idx is not None:
        idx = feat_idx&#91;0&#93;
        cache_x = hidden_states&#91;:, :, -CACHE_T:, :, :&#93;.clone()
        if cache_x.shape&#91;2&#93; &lt; 2 and feat_cache&#91;idx&#93; is not None:
            cache_x = torch.cat(
                &#91;feat_cache&#91;idx&#93;&#91;:, :, -1, :, :&#93;.unsqueeze(2).to(cache_x.device), cache_x&#93;,
                dim=2,
            )
        hidden_states = self.conv_out(hidden_states, feat_cache&#91;idx&#93;)
        feat_cache&#91;idx&#93; = cache_x
        feat_idx&#91;0&#93; += 1
    else:
        hidden_states = self.conv_out(hidden_states)

    return hidden_states</code></pre></details>
<h2 id="fastvideo.models.vaes.hyworldvae.AutoencoderKLHYWorld"><code>fastvideo.models.vaes.hyworldvae.AutoencoderKLHYWorld</code></h2>
<pre class="doc-signature"><code>AutoencoderKLHYWorld(config: Hunyuan15VAEConfig)</code></pre>
<p>A VAE model with KL loss for encoding videos into latents and decoding latent representations into videos.
Revised from HunyuanVideo-1.5 with temporal caching support for HY-WorldPlay integration.</p>

<details><summary>Source</summary><pre><code>class AutoencoderKLHYWorld(nn.Module, ParallelTiledVAE):
    r&quot;&quot;&quot;
    A VAE model with KL loss for encoding videos into latents and decoding latent representations into videos.
    Revised from HunyuanVideo-1.5 with temporal caching support for HY-WorldPlay integration.
    &quot;&quot;&quot;

    _supports_gradient_checkpointing = True

    def __init__(
            self,
            config: Hunyuan15VAEConfig,  # HYWorld use the same VAE architecture as HunyuanVideo-1.5
    ) -&gt; None:
        nn.Module.__init__(self)
        ParallelTiledVAE.__init__(self, config)

        self.encoder: Optional&#91;HYWorldEncoder3D&#93; = None
        self.decoder: Optional&#91;HYWorldDecoder3D&#93; = None

        if config.load_encoder:
            self.encoder = HYWorldEncoder3D(
                in_channels=config.in_channels,
                out_channels=config.latent_channels * 2,
                block_out_channels=config.block_out_channels,
                layers_per_block=config.layers_per_block,
                temporal_compression_ratio=config.temporal_compression_ratio,
                spatial_compression_ratio=config.spatial_compression_ratio,
                downsample_match_channel=config.downsample_match_channel,
            )

        if config.load_decoder:
            self.decoder = HYWorldDecoder3D(
                in_channels=config.latent_channels,
                out_channels=config.out_channels,
                block_out_channels=list(reversed(config.block_out_channels)),
                layers_per_block=config.layers_per_block,
                temporal_compression_ratio=config.temporal_compression_ratio,
                spatial_compression_ratio=config.spatial_compression_ratio,
                upsample_match_channel=config.upsample_match_channel,
            )

        # TODO: Add spatial tiling.
        self.use_tiling = False

        # The minimal tile height and width for spatial tiling to be used
        self.tile_sample_min_height = 256
        self.tile_sample_min_width = 256
        self.tile_sample_min_num_frames = 2000  # Fill in a random large number, as hy1.5 vae does not use temporal tiling

        # Cache-related attributes (initialized in clear_cache)
        self._conv_num: int = 0
        self._conv_idx: List&#91;int&#93; = &#91;0&#93;
        self._feat_map: List&#91;Optional&#91;torch.Tensor&#93;&#93; = &#91;&#93;
        self._enc_conv_num: int = 0
        self._enc_conv_idx: List&#91;int&#93; = &#91;0&#93;
        self._enc_feat_map: List&#91;Optional&#91;torch.Tensor&#93;&#93; = &#91;&#93;

        # Precompute and cache conv counts for encoder and decoder for clear_cache speedup
        self._cached_conv_counts = &#123;
            &quot;decoder&quot;: (sum(1 for m in self.decoder.modules()
                            if isinstance(m, HYWorldCausalConv3d)) if self.decoder is not None else 0),
            &quot;encoder&quot;: (sum(1 for m in self.encoder.modules()
                            if isinstance(m, HYWorldCausalConv3d)) if self.encoder is not None else 0),
        &#125;

    def clear_cache(self) -&gt; None:
        &quot;&quot;&quot;
        Initialize/clear the feature cache for chunk-based encoding/decoding.

        This should be called before starting a new encode/decode sequence to ensure
        the cache is properly initialized.
        &quot;&quot;&quot;
        # Cache for decoder
        self._conv_num = self._cached_conv_counts&#91;&quot;decoder&quot;&#93;
        self._conv_idx = &#91;0&#93;
        self._feat_map: List&#91;Optional&#91;torch.Tensor&#93;&#93; = &#91;None&#93; * self._conv_num

        # Cache for encoder
        self._enc_conv_num = self._cached_conv_counts&#91;&quot;encoder&quot;&#93;
        self._enc_conv_idx = &#91;0&#93;
        self._enc_feat_map: List&#91;Optional&#91;torch.Tensor&#93;&#93; = &#91;None&#93; * self._enc_conv_num

    def _encode(self, x: torch.Tensor) -&gt; torch.Tensor:
        &quot;&quot;&quot;
        Encode video with temporal caching for chunk-based processing.

        This processes video in chunks (first frame separately, then 4 frames at a time)
        while maintaining temporal context through caching. This matches the HY-WorldPlay
        behavior for memory-efficient long video encoding.

        Args:
            x: Input video tensor of shape (B, C, T, H, W)

        Returns:
            Encoded latent tensor
        &quot;&quot;&quot;
        assert self.encoder is not None, &quot;Encoder not loaded&quot;
        _, _, num_frame, _, _ = x.shape

        self.clear_cache()

        # Process in chunks: first frame alone, then groups of 4 frames
        iter_ = 1 + (num_frame - 1) // 4
        for i in range(iter_):
            self._enc_conv_idx = &#91;0&#93;
            if i == 0:
                # First frame
                out = self.encoder(
                    x&#91;:, :, :1, :, :&#93;,
                    feat_cache=self._enc_feat_map,
                    feat_idx=self._enc_conv_idx,
                )
            else:
                # Subsequent frames in groups of 4
                out_ = self.encoder(
                    x&#91;:, :, 1 + 4 * (i - 1):1 + 4 * i, :, :&#93;,
                    feat_cache=self._enc_feat_map,
                    feat_idx=self._enc_conv_idx,
                )
                out = torch.cat(&#91;out, out_&#93;, dim=2)

        self.clear_cache()
        return out

    def _decode(self, z: torch.Tensor) -&gt; torch.Tensor:
        &quot;&quot;&quot;
        Decode latents with temporal caching for chunk-based processing.

        This processes latents one frame at a time while maintaining temporal context
        through caching. This matches the HY-WorldPlay behavior for memory-efficient
        long video decoding.

        Args:
            z: Latent tensor of shape (B, C, T, H, W)

        Returns:
            Decoded video tensor
        &quot;&quot;&quot;
        assert self.decoder is not None, &quot;Decoder not loaded&quot;
        _, _, num_frame, _, _ = z.shape

        self.clear_cache()

        # Process one frame at a time with caching
        for i in range(num_frame):
            self._conv_idx = &#91;0&#93;
            if i == 0:
                # First frame with first_chunk=True
                out = self.decoder(
                    z&#91;:, :, i:i + 1, :, :&#93;,
                    feat_cache=self._feat_map,
                    feat_idx=self._conv_idx,
                    first_chunk=True,
                )
            else:
                # Subsequent frames
                out_ = self.decoder(
                    z&#91;:, :, i:i + 1, :, :&#93;,
                    feat_cache=self._feat_map,
                    feat_idx=self._conv_idx,
                    first_chunk=False,
                )
                out = torch.cat(&#91;out, out_&#93;, dim=2)

        self.clear_cache()
        return out

    def forward(
        self,
        sample: torch.Tensor,
        sample_posterior: bool = False,
        return_dict: bool = True,
        generator: Optional&#91;torch.Generator&#93; = None,
    ) -&gt; torch.Tensor:
        r&quot;&quot;&quot;
        Args:
            sample (`torch.Tensor`): Input sample.
            sample_posterior (`bool`, *optional*, defaults to `False`):
                Whether to sample from the posterior.
            return_dict (`bool`, *optional*, defaults to `True`):
                Whether or not to return a &#91;`DecoderOutput`&#93; instead of a plain tuple.
            generator (`torch.Generator`, *optional*):
                Generator for sampling.
        &quot;&quot;&quot;
        x = sample

        # encode() uses temporal caching by default (via _encode)
        posterior = self.encode(x)

        z = posterior.sample(generator=generator) if sample_posterior else posterior.mode()

        # decode() uses temporal caching by default (via _decode)
        dec = self.decode(z)

        return dec</code></pre></details>
<h3 id="fastvideo.models.vaes.hyworldvae.AutoencoderKLHYWorld.clear_cache"><code>fastvideo.models.vaes.hyworldvae.AutoencoderKLHYWorld.clear_cache</code></h3>
<pre class="doc-signature"><code>clear_cache() -&gt; None</code></pre>
<p>Initialize/clear the feature cache for chunk-based encoding/decoding.</p>
<p>This should be called before starting a new encode/decode sequence to ensure
the cache is properly initialized.</p>
<details><summary>Source</summary><pre><code>def clear_cache(self) -&gt; None:
    &quot;&quot;&quot;
    Initialize/clear the feature cache for chunk-based encoding/decoding.

    This should be called before starting a new encode/decode sequence to ensure
    the cache is properly initialized.
    &quot;&quot;&quot;
    # Cache for decoder
    self._conv_num = self._cached_conv_counts&#91;&quot;decoder&quot;&#93;
    self._conv_idx = &#91;0&#93;
    self._feat_map: List&#91;Optional&#91;torch.Tensor&#93;&#93; = &#91;None&#93; * self._conv_num

    # Cache for encoder
    self._enc_conv_num = self._cached_conv_counts&#91;&quot;encoder&quot;&#93;
    self._enc_conv_idx = &#91;0&#93;
    self._enc_feat_map: List&#91;Optional&#91;torch.Tensor&#93;&#93; = &#91;None&#93; * self._enc_conv_num</code></pre></details>
<h3 id="fastvideo.models.vaes.hyworldvae.AutoencoderKLHYWorld.forward"><code>fastvideo.models.vaes.hyworldvae.AutoencoderKLHYWorld.forward</code></h3>
<pre class="doc-signature"><code>forward(sample: torch.Tensor, sample_posterior: bool = False, return_dict: bool = True, generator: Optional&#91;torch.Generator&#93; = None) -&gt; torch.Tensor</code></pre>
<h4>Parameters</h4>
<dl>
<dt><code>sample: `torch.Tensor`</code></dt><dd><p>Input sample.</p></dd>
<dt><code>sample_posterior: `bool`, *optional*, defaults to `False`</code></dt><dd><p>Whether to sample from the posterior.</p></dd>
<dt><code>return_dict: `bool`, *optional*, defaults to `True`</code></dt><dd><p>Whether or not to return a [<code>DecoderOutput</code>] instead of a plain tuple.</p></dd>
<dt><code>generator: `torch.Generator`, *optional*</code></dt><dd><p>Generator for sampling.</p></dd>
</dl>
<details><summary>Source</summary><pre><code>def forward(
    self,
    sample: torch.Tensor,
    sample_posterior: bool = False,
    return_dict: bool = True,
    generator: Optional&#91;torch.Generator&#93; = None,
) -&gt; torch.Tensor:
    r&quot;&quot;&quot;
    Args:
        sample (`torch.Tensor`): Input sample.
        sample_posterior (`bool`, *optional*, defaults to `False`):
            Whether to sample from the posterior.
        return_dict (`bool`, *optional*, defaults to `True`):
            Whether or not to return a &#91;`DecoderOutput`&#93; instead of a plain tuple.
        generator (`torch.Generator`, *optional*):
            Generator for sampling.
    &quot;&quot;&quot;
    x = sample

    # encode() uses temporal caching by default (via _encode)
    posterior = self.encode(x)

    z = posterior.sample(generator=generator) if sample_posterior else posterior.mode()

    # decode() uses temporal caching by default (via _decode)
    dec = self.decode(z)

    return dec</code></pre></details>
</div>
