BSAI FastH3 Native VSA (recipe)
Sparse Attention Is Why H3 Video Fits on Your Card
- model
- MODEL
MiniMax-H3 is a 33B omni-modal video model that generates its audio track in the same pass - impressive, and also why it's a bear to run locally. Self-attention over a packed sequence of video, audio, text and reference tokens grows quadratically with clip length. FastH3's other half - the half nobody posts about because it doesn't show up in a filename - is VSA, Video Sparse Attention, and it's the difference between "short clip on a big card" and "short clip on yours."
BSAIFastH3NativeVSA is the node that installs it, plus the recipe plumbing that goes with it. If you only set one thing on it, set the recipe dropdown and walk away.
The mechanism, briefly
VSA doesn't make every video token attend to every other video token. It tiles the video part of the sequence into 64-token blocks, scores the blocks, and runs exact attention only on the top slice of them - about 10% for the 4-step checkpoint, about 20% for the 8-step V2. Conditioning rows (text, audio, reference latents) stay exact, because those are the rows that carry what you asked for.
It patches H3's attention at the seam ComfyUI already reads (optimized_attention_override in the model's transformer options) and publishes H3's packed segment layout so it knows where the video span starts and ends. Nothing in ComfyUI's own source gets edited - the model is cloned and the patch rides along on the clone, so a ComfyUI update doesn't quietly break it.
Two backends. native uses the comfy_kitchen.sol_attn kernel (BF16, head_dim 128, sm_80+, CUDA - Blackwell is where it really pays). torch is a pure-PyTorch block-sparse implementation over the same 64-token tiles: slower, but it works on a 40-series at any dtype. auto picks native when the kernel is importable and torch otherwise.
Worth knowing: the module treats every ambiguous case as "run dense." A mask, cross-attention, a sequence shorter than min_tokens, no published span - all fall back to the ordinary attention path. The scarce failure mode isn't wrong output, it's silently not being sparse, which is what BSAIFastH3VSAStats exists to catch.
The inputs that matter
recipe is the one-click preset, and it drives two things at once. It forces video_keep_percent (10% for 4-step, 20% for V2, 100% for TaoMate) and, for 8-step V2, patches the model's ModelSamplingAV video shift to 10/3 - because V2's video shift is 10, not the 12 everyone learned from the 4-step checkpoint. That patch fires even with enabled off, deliberately: shift and sparsity are separate facts about the checkpoint, and only one of them is optional. custom leaves both to you.
video_keep_percent is the actual knob: lower is faster and lighter, higher is more faithful. The official operating points are 10 and 20, and straying far below them is how you get mush on fast motion.
min_tokens (default 8192) refuses to sparsify short sequences where the bookkeeping costs more than it saves. start_percent and end_percent run Dense outside a window - warm-up at the top of sampling stabilises structure, dense at the tail refines detail. Leave them at 0 and 1 unless you're chasing a specific artifact.
sink_conditioning decides how much conditioning you protect: exact_kv (default) keeps every video query seeing the conditioning rows exactly, for a few percent overhead; exact_kv_and_rows also runs the conditioning queries dense, which is what you want when the audio has to stay locked to a reference; off is cheapest and only sensible for pure text-to-video, where there's nothing to align to.
enabled is a passthrough switch, backend and strict_native_backend are the pair people trip over, and verbose logs each VSA hit's shape and backend - useful exactly once.
One output, MODEL. From here it goes into BSAIFastH3Timesteps, your guider, and the sampler - all of them on this patched model, not the loader's raw output.
Install
Manager → search BSAI-ComfyUI-FastH3, or:
cd ComfyUI/custom_nodes
git clone https://github.com/xm6018924/BSAI-ComfyUI-FastH3.git
python -m pip install comfy_kitchen # optional, native kernel
Restart afterwards. There's no requirements file in the repo; without comfy_kitchen the torch path does the job, just slower.
Where it goes wrong
A red node reading "expects a MiniMax-H3 diffusion model" means exactly that: the model on the wire isn't H3 (the check looks for the H3 diffusion module's rope_freqs and _forward). You're feeding it a Wan or Flux checkpoint, or a bare model object from somewhere else.
If you set backend=native on a 40-series card with strict_native_backend on, you get a hard error about comfy_kitchen.sol_attn being unavailable. That's the strict flag doing its job. Use backend=torch, or flip the flag off and let it degrade.
If another attention patch is already in the graph - a Sage low-VRAM patch, say - this node chains onto the existing override rather than clobbering it, and gates foreign patched forwards so they don't skip the VSA pass. When you're debugging weird attention output, though, pull the other patch first; two stacked patches is the least legible state a graph can be in.
Finally: if a run looks like VSA isn't helping, don't guess - read the stats node and check sparse is above zero.
Inputs (11)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | — | |
| enabled | BOOLEAN | true | When off, passes the model through without installing the VSA patch. Can be driven by BSAI H3 MotionFix.vsa_enabled. |
| video_keep_percent | FLOAT | 10.00.5–100 | Percentage of video tokens that keep exact attention. Official: ~10% for 4-step v1/v0.2 (90% sparse); ~20% for 8-step V2 (80% sparse). Lower = less VRAM / faster, but more detail loss. Can be driven by BSAI H3 MotionFix.video_keep_percent. |
| start_percent | FLOAT | 0.000–1 | Steps before this sampling progress run Dense (high-temperature warmup). |
| end_percent | FLOAT | 1.000–1 | Steps after this sampling progress run Dense. |
| min_tokens | INT | 81920–1048576 | Attention calls with sequence length below this stay Dense (sparsity has no benefit on short sequences). |
| sink_conditioning | COMBO | exact_kv | exact_kv: all video queries see text/audio/ref conditioning rows exactly (~3% overhead). exact_kv_and_rows: additionally runs Dense on conditioning query rows (more stable audio). off: only video-block top-k is kept, lowest memory but weaker conditioning alignment. |
| backend | COMBO | auto | auto: uses native (Blackwell kernel) when comfy_kitchen.sol_attn is available, else torch. native: force the comfy_kitchen kernel. torch: pure PyTorch block sparsity (works on 40-series). |
| strict_native_backend | BOOLEAN | true | True: error out when native is unavailable. False: automatically fall back to torch sparsity. |
| verbose | BOOLEAN | true | Print the shape and backend info of every VSA hit. |
| recipe | COMBO | 8-step OmniRef (999,874,749,624,500,375,250,125 · shift 12/3 · keep 10%) | Official one-click recipe presets. 4-step: shift 12/3 + keep 10%. 8-step V2: shift 10/3 + keep 20% (auto-patches the model ModelSamplingAV video shift to 10). 8-step OmniRef (2026-10-20): shift 12/3 + keep 10% (reference-to-video checkpoint, 9 images + 3 videos + 3 audios). 3-step TaoMate: shift 12/3 + keep 100% (Dense; pairs with the original minimax_h3_fl2va base + TaoMate LoRA, not sparse). custom: fully manual (keep and shift managed by you). |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| MODEL | MODEL | — |