CoolFace
Apppublic

wood07/fasth3-4-step-demo

sourceHugging Faceupdated 23d agoView on Hugging Face
0likes
App README

<!-- Runs its own copy of the ZeroGPU Gradio app (app.py, h3splitblocks.py, requirements.txt, packages.txt, workflow.json — duplicated from FastVideo/fastvideo-fasth3-preview). Flipped live 2026-09-03 once the account upgraded to PRO (up to 10 ZeroGPU-hosted Spaces); no community grant needed. xlarge is requested in-app via @spaces.GPU GPU_SIZE=xlarge. index.html (the prior static holding page, embedding the official demo) is no longer used now that this Space runs its own copy. -->

FastVideo FastH3 Preview — MiniMax-H3 in four forward passes

`FastVideo/FastVideo-FastH3-4-step-Preview-v1-VSA-DataFree` is a data-free DMD2 + VSA-H3 distillation of `MiniMaxAI/MiniMax-H3`, the 33B dual-modality DiT that emits a video and its synchronized soundtrack from one denoising pass. The student keeps the teacher's architecture exactly and only replaces transformer/, so it is a drop-in for the same diffusers modular pipeline — but it needs four DiT forwards instead of thirty.

Everything runs unquantized at bfloat16.

The sampling contract: five grid points, four forwards

MiniMaxH3Scheduler.set_timesteps(n) builds linspace(1, 0, n), applies the shift σ' = s·σ / (1 + (s−1)·σ), and then drops the trailing zero when it forms the timesteps — so `n` sigma grid points drive `n − 1` model evaluations. The distilled ladder is t = 1000, 750, 500, 250 → 0: five points, four forwards.

This Space therefore fixes num_inference_steps = 5, which is exactly what FastVideo's own reference script `examples/inference/basic/basic_fasth3.py` uses (--steps 5). It is not a knob: v0.1 shipped with 4 in its card, which is three forwards, and the model card corrects it. The native shifted grid reproduces the trained ladder to five decimals (video shift 12.0 → 1.0, 0.972973, 0.923077, 0.8; the card's ladder is 0.9999, 0.972832, 0.923077, 0.8), so no custom sigma list is needed. There is no CFG and no negative prompt — the teacher is guidance-distilled and the student inherits that.

Split across two Spaces

MiniMax-H3 is 195.9 GiB in bfloat16 and a ZeroGPU Space is evicted at 150 GB of storage, so no single unquantized Space can hold it. Cutting MiniMaxH3Blocks at its text_encoder step splits it in two, and both halves fit:

SpaceSubfoldersDownloadResident
`multimodalart/qwen3vl-conditioner`text_encoder/ + tokenizer/ + processor/66.7 GB62.15 GiB bf16
this onetransformer/ + vae/ + audio_vae/~81 GB61.73 GiB bf16 + 10.43 GiB fp32

The conditioner is a public Space and is unchanged by the distillation — the student's modular_model_index.json points its text_encoder at the same Qwen3-VL weights — so this Space reuses it as-is and calls it over the gradio API for every request.

h3_split_blocks.py subclasses MiniMaxH3Blocks with the text_encoder step removed. Dropping the step drops the components it declares, so load_components resolves only transformer / vae / audio_vae / the two schedulers, and prompt_embeds + text_token_tags become ordinary required pipeline inputs. The wire format is those two tensors — (1, num_text_tokens, 5120) bfloat16 and (num_text_tokens,) int64 — in one safetensors file with the resolved height / width / num_frames in its metadata header.

Text-to-video+audio only

The preview distills the T2VA path only (the card is explicit), so this Space exposes no keyframe / reference inputs — the student's transformer_ref tower is not packaged. Image conditioning is what `multimodalart/minimax-h3` (the undistilled 30-step teacher) is for.

Prompt format

MiniMax-H3 is trained on a structured multimodal caption, not a bare sentence:

integrated_multimodal_description: <shots, camera, subjects, action, lighting>
overall_soundscape: <diegetic sound>
non_diegetic_music: <score>

Expand prompt (on by default) sends a short prompt through the conditioner's Qwen3-VL prompt rewriter, which writes that structure for you and returns it. Turn it off when you have already written a full-format prompt — the examples that carry MiniMax's own official prompts do exactly that.

Examples

The two long examples are MiniMax's own published prompts, taken verbatim from the base model's repo (Apache-2.0 code / docs):

  • —the starship-bridge two-shot from scripts/readme/reproducible-768p-t2va-request.sh
  • —the bakery two-shot, Case 1 of docs/VIDEO_PROMPT_WRITING_GUIDE_base_en.md

Generation constraints

Fixed by the checkpoint: 24 fps, a 768 pixel short edge at the training canvas, num_frames snapped up to the next 17·n + 5. The distillation's operating point is 1344×768 × 124 frames (≈5 s) — that is the default. The duration slider reaches 10 s and the canvas dropdown offers smaller/faster grids, both outside the distilled operating point, so quality degrades gracefully rather than being guaranteed.

The checkpoint itself is a preview, saved at step 1300 and trained with VSA-H3 attention at 90% sparsity; the card notes quality is still maturing.

Measured

On this Space, driven over gradio_client. Startup — the ~81 GB download and the load, with no placement and therefore no pack — is 78 s. The first request of a cold worker carries the one-time .to("cuda"), ~11 s.

Canvas × framesPacked rowsDenoise + decodePer forwardPeak allocated
544×544 × 56 (2.3 s)4 91320 s (cold, incl. placement)—77.05 GiB
1344×768 × 124 (5.2 s)37 29657 s14.2 s78.78 GiB
1344×768 × 243 (10.1 s)72 576151 s37.8 s84.81 GiB

72.16 GiB of weights sit resident on a 95.0 GiB card, so there is no offloading in the request path at all, and the 10 s maximum still leaves ~10 GiB of headroom. get_duration is fitted to exactly these three points (7.413e-4·rows + 1.751e-8·rows², plus the placement allowance and 15%), so a request books close to what it actually uses rather than a padded worst case: 81 s at the 5 s default, 189 s at the 10 s maximum.

The teacher needs thirty forwards for the same canvas, and measures 10.6 s/step there — so a default-canvas video is 57 s here against ~320 s, about 5.6× faster wall-clock.

Why no AoTI

The teacher Space compiles its 50 repeated transformer blocks with AoTI, which removes a near-constant ~0.5 s/step of kernel-launch and epilogue overhead. Over 30 steps that is worth 15 s; over four forwards it is ~2 s of a ~110 s request. Not worth the loader and its keying risk, so this Space runs eager.

Likewise VSA (Video Sparse Attention): the student was trained with 64-token tiles at 90% sparsity and carries the attn.to_gate_compress gate parameters, but the kernel is sm100a (GB200) and the ZeroGPU pool is sm120. The card documents dense as the default and this Space runs dense — diffusers logs the 50 gate tensors as unexpected keys and drops them, so they cost disk but no VRAM. Attention is cuDNN's fused kernel (_native_cudnn), 10–20% faster than the SDPA default and needing nothing installed.

Placement

H3_PLACEMENT=lazy: the weights move onto the card on the first GPU call and stay there. spaces' startup torch.pack() would write a second on-disk copy of every resident CUDA tensor, and 81 + 70 GB exceeds the 150 GB quota, so packing is not an option here. The one-time .to("cuda") is ~10–15 s inside the first request of a cold worker; after that there is no offloading in the request path at all.

Space variables

VariableDefaultMeaning
H3_MODEL_REPOFastVideo/FastVideo-FastH3-4-step-Preview-v1-VSA-DataFreeThe distilled diffusers-layout checkpoint. Public.
H3_CONDITIONERmultimodalart/qwen3vl-conditionerThe public Space this one asks for embeddings.
H3_PLACEMENTlazylazy moves all weights onto the card on the first GPU call; offload hands placement to ComponentsManager.enable_auto_cpu_offload.
H3_ATTENTION_native_cudnncuDNN's fused kernel. flash-attention 3 is sm90-only and this pool is sm120.
H3_GPU_SIZExlargeZeroGPU allocation size. large (48 GB) does not fit 72 GiB of weights.

Secrets

None. Every weight this Space downloads is public, and the conditioner is a public Space called on the requesting user's own ZeroGPU token.

License

The weights are under the MiniMax H3 Community License, inherited from the base model — it carries territory and acceptable-use restrictions. Read the base model's license before using outputs.