Sol-H3 SOL Attention (Experimental)
Sparse H3 attention, and the one default that saves your opening shot
- model
- MODEL
"Experimental" is doing a lot of work in this node's name, and the author knows it. This is the node that actually makes MiniMax-H3 sampling faster - by stopping it from computing all of attention - and it ships with one setting that will quietly wreck your opening seconds if you get it wrong.
It attaches to the MODEL you're about to sample and wraps H3's attention calls with Sol-Attn, the sparse implementation from Sana's sol-engine branch, run through a CUTLASS CuTe kernel. Eligible H3 calls (plus VDN grouped attention, if you use that companion) take the sparse path; everything else delegates to the inherited dense provider with an explicit receipt. A run with zero sparse calls is valid - just not accelerated.
What the speed actually is
The author's controlled, same-seed A/B with SOL on dense_evaluations=0 versus SOL disabled, at matched 40 logical / 25 actual / 15 forecast call topology: 332.56 s vs 374.84 s sampler wall, 380.57 s vs 420.81 s end-to-end. Call it 11% of sampling on an SM120 card - deployment-specific, not a universal percentage, and the author says so repeatedly. Sparse attention is one of the standard video levers, and like step distillation it trades something away.
How the sparsity works
Keys are grouped into 64-token blocks, and each block gets a summary - a centroid plus a diagonal variance. For each query block, the kernel estimates what the logits against those summaries would look like and sets a threshold of mean + tau * std. Blocks clearing that bar are kept; the rest fold into an approximated mass. A leading sink interval (the global/prefix K/V rows) always stays exact, rounded outward to whole 64-row blocks. If the selector ends up choosing everything, the call is checked against an independent BF16 SDPA result rather than trusted.
On the memory side, the bridge keeps H3's BTHD tensors as strided views instead of materialising copies - a micro-optimization (0.11 s across 144 calls), not the headline. The vendored kernel table also names SM90 and SM100 backends, but only the SM120 path is validated here; don't assume your 4090 gets the same code.
The inputs that matter
Five required inputs, one output. The ones you'll actually touch:
model(MODEL) - patches first, then this node, then sample. Two differently-configured SOL nodes on the same branch are ambiguous; use separate branches.exact_fusion(defaulttrue) - also requests the Exact Runtime fusion in the same lifecycle, so a later Exact Runtime node won't install a second copy.tau(0–3, default1.0) - the selector's how-far-above-the-mean knob. Raise it and more blocks get pruned (faster, more approximation); lower it and you converge back toward dense attention.dense_evaluations(default1) - keeps the first complete denoiser evaluation on dense attention before SOL takes over. This is your safety net, and the default matters.dense_layers(default2) - a per-evaluation policy: the first two H3 blocks of every otherwise-SOL evaluation stay dense. No extra denoiser pass, and not a substitute fordense_evaluations.
Output is a single MODEL.
The trap: dense_evaluations=0
v0.1.2 defaulted this to 0 for a good reason: starting dense, then switching to SOL, invalidates Spectrum's dense forecasting anchor and can turn the first would-be forecast into a real extra NFE.
It also removes your safety net. A controlled same-seed comparison caught the failure plainly - at 0, the opening motion snapped to a different pose and heading through heavy smearing before settling; at 1, the same opening was a continuous turn. v0.1.3 restored 1 as the default: the scheduling analysis held, the quality call outranked it. 0 remains as an explicit maximum-speed opt-in if you've looked at your own output and accepted it.
The nastier version: saved workflows keep their serialized value. Create that node under v0.1.2 and it still says 0 after you upgrade - the new default never applies. Open the node and check.
Install
Manager search ComfyUI-Sol-H3, or:
export COMFYUI_ROOT=/path/to/ComfyUI
cd "$COMFYUI_ROOT/custom_nodes"
git clone https://github.com/xmarre/ComfyUI-Sol-H3.git
cd ComfyUI-Sol-H3
python -m pip install -r requirements.txt
Linux/WSL2 only installs the real kernel stack: triton>=3.6,<4, nvidia-cutlass-dsl[cu13], cuda-python, apache-tvm-ffi. Install into ComfyUI's own Python env - custom nodes share it with everything else you own, which is where dependency conflicts come from. The optional companions (VDN-H3-Plus, Spectrum, Untwisting RoPE, Flow) are not installed for you and are pinned to reviewed commits; stack them only at those revisions, or their wrappers read as unknown and force a full dense call.
When it doesn't do anything
Native Windows. NVIDIA's CuTe DSL has no Windows support, so SOL delegates to inherited dense attention and records a compatibility fallback; you'd see sparse_calls: 0. Harmless, just useless - run Linux or WSL2 on SM120 hardware.
Nothing is actually sparse. Check sol_backend, sol_eligible_calls, sparse_calls and compatibility_fallbacks before believing a speed change, and don't attribute multi-second workflow variance to a kernel whose measured win was 0.79 ms per call.
Loader failures. If an optimized_attention_override provider (KJ Sage, say) throws an ImportError/OSError, it's demoted to plain Comfy attention for that request. Arbitrary CUDA compute failures are not swallowed - those surface as real errors, and the provider is what to fix.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | — | |
| exact_fusion | BOOLEAN | true | — |
| tau | FLOAT | 1.00–3 | — |
| dense_evaluations | INT | 10–100 | — |
| dense_layers | INT | 20–100 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| MODEL | MODEL | — |