Skip to content
FastVideo
Esc
↑↓navigate↵open⌘Jpreview
On this page

minimax_h3_nvfp4_checkpoint

Safetensors files for exported NVFP4 MiniMax-H3 video decoders.

Two formats share one file layout: tensors are prefixed decoder. or post_quant_conv.; the header holds format and nvfp4_metadata (JSON).

  • fastvideo_h3_decoder_nvfp4_deploy_v1: NVFP4 linears as bf16 master weights, packed at load (NVFP4DecoderLinear.freeze).
  • fastvideo_h3_decoder_nvfp4_packed_v1: the frozen layers' buffers as written by freeze on a Blackwell GPU, loaded as is. Per NVFP4 linear <name>: <name>.packed_weight (uint8 [out, in/2], two E2M1 codes per byte, FlashInfer fp4_quantize order), <name>.weight_inv_scale (E4M3 per-16 block scales, FlashInfer SfLayout.layout_128x4 swizzle), <name>.weight_global_sf (fp32 scalar), <name>.bias (in the compute dtype, which is exactly how inference consumes it) and <name>.input_amax (fp32 static activation range). Every other tensor keeps the dtype it is stored with in the trained decoder, so outputs stay bit-identical.

fastvideo.models.vaes.minimax_h3_nvfp4_checkpoint.NVFP4DecoderLinear

NVFP4DecoderLinear(weight: torch.Tensor, bias: torch.Tensor | None, rotation_group: int | None, compute_dtype: torch.dtype, act_scale: str = 'dynamic')

Drop-in for an nn.Linear in the H3 decoder blocks.

weight is the full-precision master (already rotated when rotation_group is set). With gradients enabled the forward is the STE; otherwise the cached packed weight is used, so call invalidate() after any weight update (the trainer does after each optimizer step).

act_scale="static" uses the persistent input_amax buffer. Set calibrating = True to run dynamically while folding each call's abs-max into it.

freeze() turns the layer inference-only: the packed weight becomes a buffer and the master weight is dropped (weight is None).

fastvideo.models.vaes.minimax_h3_nvfp4_checkpoint.NVFP4DecoderLinear.from_linear

from_linear(linear: nn.Linear, *, rotation_group: int | None, compute_dtype: torch.dtype, act_scale: str = 'dynamic') -> NVFP4DecoderLinear

fastvideo.models.vaes.minimax_h3_nvfp4_checkpoint.NVFP4DecoderLinear.from_packed

from_packed(packed: torch.Tensor, inv_scale: torch.Tensor, global_sf_w: torch.Tensor, bias: torch.Tensor | None, input_amax: torch.Tensor, *, in_features: int, rotation_group: int | None, compute_dtype: torch.dtype, act_scale: str) -> NVFP4DecoderLinear

A frozen layer built from already packed tensors (freeze()'s buffers), with no master weight.

packed holds two FP4 codes per byte, so its shape is [out_features, in_features // 2]. Nothing full-precision is allocated: the constructor's placeholder weight lives on meta.

fastvideo.models.vaes.minimax_h3_nvfp4_checkpoint.NVFP4DecoderLinear.invalidate

invalidate() -> None

fastvideo.models.vaes.minimax_h3_nvfp4_checkpoint.NVFP4DecoderLinear.freeze

freeze() -> None

Pack the weight once and drop the full-precision master (inference only, irreversible).

Resident memory falls to the packed FP4 weight and its scales. Outputs are unchanged: the same packed tensors feed the eager GEMM and fused_state(). Buffers are non-persistent, so a frozen layer's state_dict() holds only bias and input_amax.

fastvideo.models.vaes.minimax_h3_nvfp4_checkpoint.NVFP4DecoderLinear.fused_state

fused_state() -> NVFP4FusedState | None

Cached inference state for the fused decoder kernels, or None when they cannot reproduce this layer.

The fused kernels quantize with a precomputed global scale, so a dynamic (per-call abs-max) scale, calibration, and the activation rotation keep the eager path.

fastvideo.models.vaes.minimax_h3_nvfp4_checkpoint.NVFP4DecoderLinear.clear_offload_caches

clear_offload_caches() -> None

Drop the packed and fused caches, which are plain attributes and so invisible to offload.

pinned_offload moves parameters and buffers only; these caches hold device tensors, so without this they stay on the GPU after an unload and accumulate across clips. The data-pointer keys re-create them on the next forward.

fastvideo.models.vaes.minimax_h3_nvfp4_checkpoint.NVFP4DecoderLinear.extra_repr

extra_repr() -> str

fastvideo.models.vaes.minimax_h3_nvfp4_checkpoint.NVFP4DecoderLinear.forward

forward(x: torch.Tensor) -> torch.Tensor

fastvideo.models.vaes.minimax_h3_nvfp4_checkpoint.check_num_linears

check_num_linears(metadata: dict[str, Any], found: int) -> None

fastvideo.models.vaes.minimax_h3_nvfp4_checkpoint.enable_fused_blocks

enable_fused_blocks(decoder: nn.Module) -> None

Run eligible NVFP4 block stacks through the bit-exact fused kernels (see that module).

fastvideo.models.vaes.minimax_h3_nvfp4_checkpoint.nvfp4_decoder_linear_names

nvfp4_decoder_linear_names(decoder: nn.Module, skip_blocks: tuple[int, ...] = ()) -> list[str]

Names (relative to the decoder) of the block linears to replace.

fastvideo.models.vaes.minimax_h3_nvfp4_checkpoint.write_nvfp4_decoder_safetensors

write_nvfp4_decoder_safetensors(path: str, checkpoint: dict[str, Any]) -> None

Write {"format", "metadata", "decoder", "post_quant_conv"} as one safetensors file.

Source
def write_nvfp4_decoder_safetensors(path: str, checkpoint: dict[str, Any]) -> None:
    """Write ``{"format", "metadata", "decoder", "post_quant_conv"}`` as one safetensors file."""
    from safetensors.torch import save_file
if checkpoint&#91;&quot;format&quot;&#93; not in NVFP4_DECODER_FORMATS:
    raise ValueError(f&quot;unknown NVFP4 decoder format &#123;checkpoint&#91;&#x27;format&#x27;&#93;!r&#125;&quot;)
tensors = &#123;
    f&quot;&#123;group&#125;.&#123;key&#125;&quot;: value.detach().contiguous().cpu().clone()
    for group in GROUPS for key, value in checkpoint&#91;group&#93;.items()
&#125;
header = &#123;&quot;format&quot;: checkpoint&#91;&quot;format&quot;&#93;, &quot;nvfp4_metadata&quot;: json.dumps(checkpoint&#91;&quot;metadata&quot;&#93;)&#125;
save_file(tensors, path, metadata=header)</code></pre></details>

fastvideo.models.vaes.minimax_h3_nvfp4_checkpoint.read_nvfp4_decoder_safetensors

read_nvfp4_decoder_safetensors(path: str, device: torch.device | str = 'cpu') -> dict[str, Any]

Read either safetensors format; packed tensors go straight to device (bf16 masters stay on CPU).

Source
def read_nvfp4_decoder_safetensors(path: str, device: torch.device | str = "cpu") -> dict[str, Any]:
    """Read either safetensors format; packed tensors go straight to ``device`` (bf16 masters stay on CPU)."""
    from safetensors import safe_open
    from safetensors.torch import load_file
with safe_open(path, framework=&quot;pt&quot;) as handle:
    header = handle.metadata() or &#123;&#125;
fmt = header.get(&quot;format&quot;)
if fmt not in NVFP4_DECODER_FORMATS:
    raise ValueError(f&quot;&#123;path&#125; is not an NVFP4 decoder safetensors file (format: &#123;fmt!r&#125;); &quot;
                     f&quot;expected one of &#123;NVFP4_DECODER_FORMATS&#125;&quot;)
if &quot;nvfp4_metadata&quot; not in header:
    raise ValueError(f&quot;&#123;path&#125; is missing the nvfp4_metadata header&quot;)
tensors = load_file(path, device=str(device) if fmt == NVFP4_DECODER_PACKED_FORMAT else &quot;cpu&quot;)
checkpoint: dict&#91;str, Any&#93; = &#123;&quot;format&quot;: fmt, &quot;metadata&quot;: json.loads(header&#91;&quot;nvfp4_metadata&quot;&#93;)&#125;
for group in GROUPS:
    prefix = f&quot;&#123;group&#125;.&quot;
    checkpoint&#91;group&#93; = &#123;key&#91;len(prefix):&#93;: value for key, value in tensors.items() if key.startswith(prefix)&#125;
unknown = &#91;key for key in tensors if not key.startswith(tuple(f&quot;&#123;group&#125;.&quot; for group in GROUPS))&#93;
if unknown:
    raise ValueError(f&quot;&#123;path&#125; has tensors outside &#123;GROUPS&#125;: &#123;unknown&#91;:5&#93;&#125;&quot;)
return checkpoint</code></pre></details>

fastvideo.models.vaes.minimax_h3_nvfp4_checkpoint.packed_nvfp4_decoder_checkpoint

packed_nvfp4_decoder_checkpoint(vae: nn.Module, metadata: dict[str, Any]) -> dict[str, Any]

The packed-format checkpoint of a VAE whose NVFP4 decoder linears are all frozen.

Source
def packed_nvfp4_decoder_checkpoint(vae: nn.Module, metadata: dict[str, Any]) -> dict[str, Any]:
    """The packed-format checkpoint of a VAE whose NVFP4 decoder linears are all frozen."""
    decoder = vae.decoder
    state = dict(decoder.state_dict())
    layers = {name: module for name, module in decoder.named_modules() if isinstance(module, NVFP4DecoderLinear)}
    if not layers:
        raise ValueError("the VAE decoder has no NVFP4 linears")
    for name, layer in layers.items():
        if not layer.frozen:
            raise ValueError(f"NVFP4 linear {name} is not frozen; freeze the decoder before exporting packed weights")
        for buffer in PACKED_BUFFERS:
            state[f"{name}.{buffer}"] = getattr(layer, buffer)
        if layer.bias is not None:
            state[f"{name}.bias"] = layer.bias.detach().to(layer.compute_dtype)
    packed_metadata = {**metadata, "packed_layout": PACKED_LAYOUT, "num_linears": len(layers)}
    return {
        "format": NVFP4_DECODER_PACKED_FORMAT,
        "metadata": packed_metadata,
        "decoder": state,
        "post_quant_conv": dict(vae.post_quant_conv.state_dict()),
    }

fastvideo.models.vaes.minimax_h3_nvfp4_checkpoint.apply_packed_nvfp4_decoder

apply_packed_nvfp4_decoder(vae: nn.Module, checkpoint: dict[str, Any]) -> None

Replace the (already depth-cut) dense decoder linears with frozen layers built from packed tensors.

The dense linears are dropped one at a time, so no full-precision copy of a quantized weight is ever made. Everything else is loaded strictly.

Source
def apply_packed_nvfp4_decoder(vae: nn.Module, checkpoint: dict[str, Any]) -> None:
    """Replace the (already depth-cut) dense decoder linears with frozen layers built from packed tensors.
The dense linears are dropped one at a time, so no full-precision copy of a quantized weight is
ever made. Everything else is loaded strictly.
&quot;&quot;&quot;
metadata = checkpoint&#91;&quot;metadata&quot;&#93;
decoder = vae.decoder
state = dict(checkpoint&#91;&quot;decoder&quot;&#93;)
names = nvfp4_decoder_linear_names(decoder, tuple(metadata.get(&quot;skip_blocks&quot;) or ()))
check_num_linears(metadata, len(names))
act_scale = metadata.get(&quot;act_scale&quot;, &quot;dynamic&quot;)
for name in names:
    if act_scale != &quot;static&quot;:
        # Only static scaling reads input_amax, so a file may omit it; the strict load still needs the key.
        state.setdefault(f&quot;&#123;name&#125;.input_amax&quot;, torch.zeros((), dtype=torch.float32))
    required = PACKED_BUFFERS + (&quot;input_amax&quot;, )
    missing = &#91;f&quot;&#123;name&#125;.&#123;buffer&#125;&quot; for buffer in required if f&quot;&#123;name&#125;.&#123;buffer&#125;&quot; not in state&#93;
    if missing:
        raise ValueError(f&quot;the packed NVFP4 decoder does not fit this VAE&#x27;s architecture: missing &#123;missing&#125;&quot;)
    parent_name, _, child = name.rpartition(&quot;.&quot;)
    parent = decoder.get_submodule(parent_name)
    dense = parent&#91;int(child)&#93; if child.isdigit() else getattr(parent, child)
    packed = state.pop(f&quot;&#123;name&#125;.packed_weight&quot;)
    if packed.shape&#91;0&#93; != dense.out_features:
        raise ValueError(f&quot;the packed NVFP4 decoder does not fit this VAE&#x27;s architecture: &#123;name&#125; has &quot;
                         f&quot;&#123;packed.shape&#91;0&#93;&#125; outputs, the VAE &#123;dense.out_features&#125;&quot;)
    layer = NVFP4DecoderLinear.from_packed(packed,
                                           state.pop(f&quot;&#123;name&#125;.weight_inv_scale&quot;),
                                           state.pop(f&quot;&#123;name&#125;.weight_global_sf&quot;),
                                           state.get(f&quot;&#123;name&#125;.bias&quot;),
                                           state&#91;f&quot;&#123;name&#125;.input_amax&quot;&#93;,
                                           in_features=dense.in_features,
                                           rotation_group=metadata.get(&quot;rotation_group&quot;),
                                           compute_dtype=torch.bfloat16,
                                           act_scale=act_scale)
    if child.isdigit():
        parent&#91;int(child)&#93; = layer
    else:
        setattr(parent, child, layer)
    del dense
enable_fused_blocks(decoder)
try:
    decoder.load_state_dict(state, strict=True)
    vae.post_quant_conv.load_state_dict(checkpoint&#91;&quot;post_quant_conv&quot;&#93;, strict=True)
except RuntimeError as error:
    raise ValueError(f&quot;the packed NVFP4 decoder does not fit this VAE&#x27;s architecture: &#123;error&#125;&quot;) from error
vae.requires_grad_(False)</code></pre></details>

Was this page helpful?