Patch Sol-Attn
Skip most of attention and barely notice
- model
- MODEL
Patch Sol-Attn is a training-free speed hack for diffusion self-attention, dropped into ComfyUI by kijai - the person who basically is the ComfyUI video scene (WanVideoWrapper, KJNodes, day-one ports of every model that matters). It implements Sol-Attn (arXiv 2607.24027), a sparse-attention method that figures out on the fly which parts of a sequence are actually worth attending to and skips the rest. If you generate long video with MiniMax-H3 or Wan and attention is your wall, this is the kind of node you want to know about.
Fair warning: it's marked experimental, the README says it's been tested on an RTX 4090 and a 5090 with MiniMax-H3, and there are sharp edges. But it's genuinely clever - and unlike a lot of "speed" nodes, the quality dial is one honest slider.
How it works
Attention cost grows with sequence length, and video sequences are enormous. Sol-Attn's trick: chunk the sequence into 64-token blocks, compute a cheap summary per block, and use those summaries to predict which blocks each query actually cares about. Blocks that pass the threshold get full exact attention; the rest get an approximate pass from the block summaries. That's the whole idea - most of the attention matrix is near-zero anyway.
The tau slider is the throttle. It sets the routing threshold as mean + tau × std of the block-score distribution, so higher tau means fewer blocks kept exact: the tooltip says tau 1.0 keeps about 16% of blocks exact, 1.5 about 7%, 2.0 about 2.7%. There's no free lunch - higher tau is faster and slightly worse. 1.3 is the default and a sane starting point.
A few other inputs earn their keep:
- start_percent / end_percent - the paper runs dense before 20% of sampling (early steps set the composition), so
start_percentdefaults to 0.2. Leave it. - min_tokens (default 4096) - sequences shorter than this stay dense. Short clips gain nothing here.
- dense_blocks - a string like
0-2,-1that keeps specific transformer blocks exact. The first and last blocks are the fragile ones, because their error hits the output with no later block to absorb it. - tau_profile (optional input) - per-block tau, e.g.
0-30=2.0then39-42=0.9. Block sensitivity genuinely varies several-fold across depth; the Block Probe exists to find the fragile blocks. - morton - reorders Wan and MiniMax-H3 video tokens into Z-order so each 64-token block is a compact 3D neighborhood instead of a 2-row strip. Routing gets far more accurate at the same density. Logged and skipped on other models, so it's safe to leave on.
Then the stuff you can mostly ignore: int8_qk and int8_pv (INT8 in the exact branch, Sage-style - on by default, "measured free in quality"), sink_conditioning (MiniMax-H3 only; keeps the packed text/audio/reference rows exact so you don't lose prompt adherence), and use_tma (off by default because it "has not measured faster on any tested GPU" - it wants SM90+ and Triton 3.3+).
The output is a patched MODEL, straight into your KSampler. One input (your loaded model), one output.
Installing it
No model files, no extra checkpoints - it patches models you already have. ComfyUI Manager: search "ComfyUI-SolAttn_triton" and install, or manually:
cd ComfyUI/custom_nodes
git clone https://github.com/kijai/ComfyUI-SolAttn_triton
then restart ComfyUI. The real dependency is Triton - the kernels are pure Triton and compile on first use, so your first run is slower while it autotunes. On Linux, torch ships with a working Triton. On Windows it famously doesn't, and you'll likely need the community triton-windows wheel (the same pain SageAttention users have been through - if that install defeated you before, this is the same wall).
Where people get burned
- It silently does nothing on most models. The kernel is bf16 and head_dim 128 only. Masked attention, cross-attention, fp32, or a model with a different head dim all fall back to the existing attention backend - no error, no speedup. It's built for MiniMax-H3 and Wan, and the README only claims the H3 path.
- Silent fallbacks, noisy blocks. If a Triton kernel fails mid-run it logs
[sol_attn] kernel failedand falls back dense, so watch the console if you're not seeing speedup. - First run is slow. Kernel compilation, then autotune. Give it a real generation before judging.
- It also composes with KJNodes' memory-efficient Sage patch instead of fighting it - Sol-Attn takes eligible self-attention and hands the rest back.
Honest take: if you're on an NVIDIA card generating long H3 or Wan clips, it's worth 20 minutes. If you're on image models or short clips, it'll add a node and do nothing.
Inputs (14)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | — | |
| tau | FLOAT | 1.300–4 | Threshold beta. Higher is sparser: 1.0 ~ 16% of blocks kept exact, 1.5 ~ 7%, 2.0 ~ 2.7%. |
| start_percent | FLOAT | 0.200–1 | Run dense before this point. The paper uses 0.2. |
| end_percent | FLOAT | 0.900–1 | — |
| min_tokens | INT | 40960–1048576 | Sequences shorter than this stay dense. |
| int8_qk | BOOLEAN | true | INT8 QK in the exact branch (Sage-style: smoothed K, per-token scales). Measured free in quality; helps at tau<=1.5, a net loss at tau>=2.0 where the quantize pass outweighs the shrinking exact branch. |
| sink_conditioning | COMBO | exact_kv_and_rows | MiniMax-H3 only. exact_kv: every query sees the packed text/audio/reference rows exactly (~3% cost). exact_kv_and_rows: also runs those query rows dense, making the generated audio stream exact (~20% cost). No effect on other models. |
| morton | BOOLEAN | false | Reorder video tokens into Morton (Z-order) so each 64-token block is a compact 3D neighbourhood instead of a 2-row strip, which makes routing far more accurate at a given density. Exactly neutral for dense attention. Wan and MiniMax-H3 only; logged and skipped elsewhere. |
| morton_curve | COMBO | 2d_frame | 3d interleaves t/h/w equally. 2d_frame Z-orders within each frame and leaves frame order alone -- use it when the temporal axis is not uniformly spaced (MiniMax-H3's frame spacing is non-uniform; try this if 3d degrades at some frame counts). |
| int8_pv | BOOLEAN | true | Also run the exact branch's P@V in INT8, with a per-row P scale and per-channel V scale. PV and QK cost the same, so this is the other half of the int8 win. Only applies when int8_qk is on. |
| verbose | BOOLEAN | false | — |
| use_tma | BOOLEAN | false | Use the TMA descriptor kernels instead of the pointer ones. Descriptors address strided inputs directly, so this no longer copies q/k/v and peak VRAM matches the pointer path. Off by default because it has not measured faster on any tested GPU. Requires SM90+ and Triton 3.3+; ignored otherwise. 'verbose' logs the path used. |
| dense_blocks | STRING | Transformer blocks to keep dense, e.g. '0-2,-1' for the first three and the last. Negative indices count from the end. The first and last blocks are the most approximation-sensitive: their error reaches the output with no later block to absorb it. Empty means sparsify all. | |
| tau_profileopt | STRING | Per-block tau, overriding the base value. 'blocks=tau' entries separated by ';' or newlines, so a multiline text node works: '0-30=2.0' then '39-42=0.9'. '#' starts a comment. Block sensitivity varies several-fold across depth, so one tau either over-serves the insensitive blocks or under-serves the fragile ones — use the Block Probe to find them. Leave unconnected for a single tau everywhere. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| MODEL | MODEL | — |