|
Download README.md from FenomAI/MiniMax-H3: direct link, hf CLI and curl.
- Browser
- Download file 9.17 kB
-
https://huggingface.co/FenomAI/MiniMax-H3/resolve/main/README.md
- Command line
-
hf download hf://FenomAI/MiniMax-H3/README.md
-
curl -L -o README.md https://huggingface.co/FenomAI/MiniMax-H3/resolve/main/README.md
9.17 kB
| license: other | |
| license_name: minimax-h3-community-license-agreement | |
| license_link: https://huggingface.co/MiniMaxAI/MiniMax-H3/blob/main/LICENSE | |
| tags: | |
| - comfyui | |
| - nvfp4 | |
| - quantized | |
| - video | |
| - text-to-video | |
| base_model: MiniMaxAI/MiniMax-H3 | |
| base_model_relation: quantized | |
| # MiniMax H3 β NVFP4 | |
| NVFP4 quantizations of the **MiniMax-H3** ref2va diffusion transformer for ComfyUI. | |
| - Original model: https://huggingface.co/MiniMaxAI/MiniMax-H3 | |
| - ComfyUI repackage these derive from: https://huggingface.co/Comfy-Org/MiniMax-H3 | |
| **NVFP4 requires an NVIDIA Blackwell GPU** (RTX 50-series, RTX PRO 6000, B200). On Ada, | |
| Hopper or older the NVFP4 path is emulated β use Comfy-Org's `int8_convrot` files instead. | |
| ## Which file do I want? | |
| | file | size | s/it | VRAM (DiT) | notes | | |
| |---|---|---|---|---| | |
| | **`minimax_h3_ref2va_pruned_nvfp4.safetensors`** | **12.5 GB** | **1.90** | 11.9 GB | **recommended** | | |
| | `minimax_h3_ref2va_nvfp4_mixed.safetensors` | 24.4 GB | 1.92 | ~20 GB | from unpruned bf16 | | |
| | `minimax_h3_ref2va_nvfp4_full.safetensors` | 18.7 GB | 1.91 | ~16 GB | experimental | | |
| Take **`pruned_nvfp4`** unless you have a specific reason not to: half the size of the | |
| alternatives at identical speed, and it leaves the modulation path at full precision. | |
| ## Why the pruned base is the right one to quantize | |
| Comfy-Org's `pruned` checkpoint is not lossily pruned β it is a **structural refactor of | |
| AdaLN**, and understanding it explains the whole table above. | |
| In the bf16 model, AdaLN modulation dominates the parameter count: | |
| | group | bf16 | pruned | | |
| |---|---|---| | |
| | `adaln_proj` | **13.04B (39.4%)** | **0.04B (0.2%)** | | |
| | `mlp` | 12.02B | 11.56B | | |
| | `attn` | 8.02B | 7.71B | | |
| | token_refiner / norms / embedders | 0.05B | 0.80B | | |
| | **total** | **33.12B** | **20.11B** | | |
| The bf16 model projects a 5376-dim conditioning vector into modulation parameters per block. | |
| The pruned model replaces this with an 8-dim timestep table (`adaln_t_table`, shape | |
| `[1025, 8]`) feeding `adaln_proj.linear` of shape `[96768, 8]`. Because modulation depends | |
| only on the timestep, that 5376-wide projection was almost entirely redundant β 13.04B | |
| parameters collapse to 0.04B, a ~326x reduction. | |
| This matters for quantization because AdaLN is the part you least want to quantize: it emits | |
| the scale and shift applied to every residual stream, so error there is multiplicative and | |
| compounds across all 50 blocks and every sampling step. In the bf16 model you face a bad | |
| choice β protect AdaLN and produce a ~36 GB file (larger than the 34 GB int8 it should beat), | |
| or quantize 39% of the model and hope. **In the pruned model the problem disappears**: AdaLN | |
| is already tiny, so you keep it at full precision for free and quantize only attn+mlp, which | |
| are error-tolerant. | |
| Comfy-Org's `pruned_int8_convrot` quantizes exactly those 200 attn/mlp layers to | |
| int8_convrot and leaves everything else alone. `pruned_nvfp4` takes that same set to NVFP4. | |
| ## Measured | |
| RTX PRO 6000 Blackwell (96 GB), ComfyUI 0.30.0, ref2va, 864x480, 39 frames, 20 steps, | |
| `res_multistep` / `beta`, three matched seeds: | |
| | model | size | staged VRAM | s/it | | |
| |---|---|---|---| | |
| | `pruned_int8_convrot` (Comfy-Org) | 21.0 GB | 19,995 MB | 2.17 | | |
| | **`pruned_nvfp4` (this repo)** | **12.5 GB** | **11,944 MB** | **1.90** | | |
| **-40% file size, -8.0 GB VRAM, -12.4% sampling time.** | |
| At ~12 GB for the DiT, a 32 GB card (RTX 5090) becomes viable if the text encoder is | |
| offloaded to CPU after encoding β it runs once per prompt, not once per sampling step. | |
| ## How `pruned_nvfp4` was built | |
| The obvious tool does **not** work. The StarNodes model converter passes non-floating-point | |
| tensors through untouched: | |
| ```python | |
| if not tensor.dtype.is_floating_point: | |
| return tensor # already-int8 weights are copied verbatim | |
| ``` | |
| so running it on an int8 checkpoint silently produces a byte-identical file. A real | |
| dequantize -> requantize is required. `comfy-kitchen` exposes both halves: | |
| ```python | |
| params = ckt.TensorWiseINT8Layout.Params( | |
| scale=weight_scale, orig_dtype=torch.bfloat16, orig_shape=qdata.shape, | |
| is_weight=True, convrot=True, convrot_groupsize=256) | |
| deq = ckt.TensorWiseINT8Layout.dequantize(qdata, params) # -> bf16 | |
| nq, nparams = ckt.TensorCoreNVFP4Layout.quantize(deq.contiguous()) # -> NVFP4 | |
| tensors = ckt.TensorCoreNVFP4Layout.state_dict_tensors(nq, nparams) | |
| ``` | |
| Per-layer config lives in a `comfy_quant` uint8 tensor holding JSON, e.g. | |
| `{"format": "int8_tensorwise", "convrot": true, "convrot_groupsize": 256}`, rewritten to | |
| `{"format": "nvfp4"}` on output. Note `quantize()` requires bf16/fp16 β float32 raises | |
| `Unsupported dtype code`. | |
| Full script: `pruned_to_nvfp4.py` in this repo. 200 layers, ~6 seconds on one GPU. | |
| ## Prompting: H3 wants a structured IR, not prose | |
| **Read this before blaming the weights for bad output.** H3 was trained on the structured | |
| output of **H3-Context-IR**, a preprocessing model that rewrites a plain request into | |
| labelled sections; MiniMax's model card calls it "critical to the quality of the final | |
| output". ComfyUI passes your raw string straight to the DiT, so you must write that | |
| structure yourself. | |
| Official guides: | |
| [base](https://huggingface.co/MiniMaxAI/MiniMax-H3/blob/main/docs/VIDEO_PROMPT_WRITING_GUIDE_base_en.md) Β· | |
| [ref](https://huggingface.co/MiniMaxAI/MiniMax-H3/blob/main/docs/VIDEO_PROMPT_WRITING_GUIDE_ref_en.md) | |
| ```text | |
| For the target video, at 0.00 seconds into the target video, <Picture 1> (from [Shot 1]) is fully referenced. | |
| integrated_multimodal_description: [Shot 1] Live-action, cinematic, the young woman shown in | |
| <Picture 1> remains beside the rain-covered train window, preserving her appearance and the | |
| carriage layout. The camera trucks right with small amplitude at slow speed as she lifts her | |
| gaze toward the passing city lights. The quiet, breathy young woman (S1) says: | |
| <d>[English] I get off at the next station.</d> She folds the letter along its existing crease. | |
| overall_soundscape: The train wheels produce a steady metallic rhythm beneath a low | |
| ventilation hum. Rain ticks against the window while paper rustles softly in her hands. | |
| non_diegetic_music: Sustained cello notes at a slow tempo with widely spaced piano tones. | |
| ``` | |
| **Dialogue must be explicit or you get gibberish.** Speech is generated jointly with video, | |
| so saying *that* someone speaks without giving the words yields correct prosody and mouth | |
| shapes with no lexical content. Speaker identity, action and delivery go *outside* `<d>`; | |
| only the language tag and verbatim words go *inside*. Use stable IDs `(S1)`, `(S2)`, and | |
| `(S1,S2)` for simultaneous speech. | |
| Other essentials: `[Shot 1]` carries no timestamp, later shots use `[Shot N] At MM:SS.mmm`; | |
| aim for 350-500 words of description; write camera motion as type + amplitude + speed; | |
| reference tags must appear in the order the inputs were connected. ref2va accepts up to 9 | |
| reference images, and 3-4 varied shots hold identity far better than one. | |
| ## Companion files (mirrored, not ours) | |
| | file | precision | origin | | |
| |---|---|---| | |
| | `text_encoders/qwen3vl_32b_minimax_h3_nvfp4_awq.safetensors` | NVFP4-AWQ | **Comfy-Org, unmodified** | | |
| | `vae/minimax_h3_video_vae_fp16.safetensors` | FP16 | **Comfy-Org, unmodified** | | |
| | `vae/minimax_h3_audio_vae_fp32.safetensors` | FP32 | **Comfy-Org, unmodified** | | |
| **The NVFP4 text encoder is Comfy-Org's work, not ours.** Only the | |
| `minimax_h3_ref2va_*nvfp4*.safetensors` diffusion models here are new. | |
| VAEs are deliberately **not** quantized: they are small, run once per generation rather than | |
| per step, and decode straight to pixels and audio samples where error is immediately | |
| visible. The text encoder being NVFP4 buys VRAM, not speed β it also runs once per prompt. | |
| ## Usage | |
| ``` | |
| π ComfyUI/models/ | |
| βββ π diffusion_models/ | |
| β βββ minimax_h3_ref2va_pruned_nvfp4.safetensors | |
| βββ π text_encoders/ | |
| β βββ qwen3vl_32b_minimax_h3_nvfp4_awq.safetensors | |
| βββ π vae/ | |
| βββ minimax_h3_video_vae_fp16.safetensors | |
| βββ minimax_h3_audio_vae_fp32.safetensors | |
| ``` | |
| Recommended stack total: **33.7 GB**. Use the official | |
| [R2V template](https://github.com/Comfy-Org/workflow_templates/blob/main/templates/video_minimax_h3_r2v.json), | |
| swapping the diffusion model. Requires ComfyUI >= 0.30.0 (native H3 support in | |
| `comfy/ldm/minimax/`). `CLIPLoader` type must be `minimax`; sampler `res_multistep`; | |
| frame `length` must satisfy 17n+5. | |
| ## Honest limitations | |
| - Quality was compared against `pruned_int8_convrot` at three matched seeds with no visible | |
| degradation, but this is **not a rigorous evaluation** β no FVD, no human study, no | |
| long-duration or 2K testing. | |
| - `pruned_nvfp4` is **doubly quantized** (bf16 -> int8_convrot by Comfy-Org -> NVFP4 here). | |
| Error from both passes compounds. It held up in testing, but that is a real caveat. | |
| - Only **ref2va** is converted. `fl2va` is not included. | |
| - Benchmarks are single-GPU, one card, one resolution. | |
| Failure cases are welcome in the discussions tab β concrete artifacts beat aggregate scores. | |
| ## License | |
| Inherits the MiniMax-H3 Community License Agreement from the original model. | |