minimax_h3_checkpoint_nvfp4 ¶
Serialized NVFP4 execution for the MiniMax-H3 Qwen3-VL encoder.
The bf16 conditioner is 48 GB resident and sets the single-GB10 peak once the DiT runs in FP8. A checkpoint written by scripts/checkpoint_conversion/convert_minimax_h3_text_encoder_nvfp4.py stores every language_model.layers.* linear as three tensors and no weight::
<prefix>.weight_packed uint8 [out, in // 2] two E2M1 values per byte
<prefix>.weight_scale uint8 [out, in // 16] one E4M3 scale per 16 values,
FlashInfer 128x4 swizzled layout
<prefix>.weight_global_scale float32 [1] (448 * 6) / amax(|W|)
The bytes are exactly what flashinfer.nvfp4_quantize(W, global_scale, sfLayout=SfLayout.layout_128x4) returns, so loading them reproduces the state nvfp4_config.convert_model_to_nvfp4 builds at runtime without ever materializing the bf16 weight. Activations are quantized per call with a unit global scale and multiplied with flashinfer.mm_fp4.
The checkpoint selects this path through config.json; every field is required so a checkpoint from another exporter cannot pass by omission::
"quantization_config": {"quant_method": "nvfp4", "activation_scheme": "dynamic",
"fmt": "e2m1", "group_size": 16, "scale_fmt": "e4m3",
"scale_layout": "128x4",
"modules_to_not_convert": ["model.visual", "lm_head"]}
Whole projection kinds may stay bf16 by listing their suffix in modules_to_not_convert (for example "mlp.down_proj"); those linears keep a plain weight and the unquantized method. Only the seven language projection names are accepted there, so a typo fails at config time.
Single GPU only: packed columns and swizzled scale rows cannot be narrowed per tensor-parallel rank without repacking. Missing tensors are reported by the loader's strict check before the post-load hook runs; the hook adds only the content checks a copied tensor can still fail.
Classes¶
fastvideo.models.encoders.minimax_h3_checkpoint_nvfp4.MiniMaxH3SerializedNVFP4Config ¶
Bases: QuantizationConfig
Serialized 16-group NVFP4 contract for the H3 text encoder.
The group size and scale layout are fixed by the loader's parameter shapes, so the only state is which projection kinds the checkpoint kept in bf16.
Source code in fastvideo/models/encoders/minimax_h3_checkpoint_nvfp4.py
fastvideo.models.encoders.minimax_h3_checkpoint_nvfp4.MiniMaxH3SerializedNVFP4LinearMethod ¶
Bases: LinearMethodBase
Execute serialized NVFP4 weights without re-quantizing them.
Methods:¶
fastvideo.models.encoders.minimax_h3_checkpoint_nvfp4.MiniMaxH3SerializedNVFP4LinearMethod.process_weights_after_loading ¶
Reject a layer the checkpoint did not fill and derive the GEMM multiplier.
Shapes and dtypes are fixed by create_weights and enforced by the weight loader's copy, and the loader reports missing tensors by name before this runs; what remains is content a copied tensor can still get wrong: a non-positive global scale, or a scale tile left at its 0xFF initializer by a direct caller that bypassed the loader.
Source code in fastvideo/models/encoders/minimax_h3_checkpoint_nvfp4.py
Functions:¶
fastvideo.models.encoders.minimax_h3_checkpoint_nvfp4.nvfp4_weight_global_scale ¶
The per-tensor scale convert_model_to_nvfp4 uses: E4M3 max times E2M1 max over amax.
Unlike the runtime converter this refuses NaN or infinite weights instead of mapping them to zero, because a checkpoint written from them would be wrong forever.
Source code in fastvideo/models/encoders/minimax_h3_checkpoint_nvfp4.py
fastvideo.models.encoders.minimax_h3_checkpoint_nvfp4.serialized_nvfp4_quantization_config ¶
serialized_nvfp4_quantization_config(*, keep_bf16: tuple[str, ...] | list[str] = (), producer: dict[str, Any] | None = None) -> dict[str, Any]
The config.json quantization_config the converter writes and from_config accepts.
keep_bf16 lists projection kinds from LANGUAGE_PROJECTIONS that stay bf16 in every language layer; they are appended to modules_to_not_convert.