Patch Sol Sparse Attention
Attention that skips the boring parts on purpose
- model
- model
Here's the thing about long video generation on an old GPU: attention is quadratic, and your VRAM is not. Full dense attention over a long sequence is exactly what makes a 20-series card tap out on Wan or Bernini. Sol sparse attention is the strategy where the model only computes attention for the tokens that actually matter and approximates the rest - and this patch is how you switch it on in this pack.
The important word is patch. This is not a loader option buried in a checkbox; it's an explicit node you connect your MODEL through. The author made it separate on purpose, because the whole quality/performance trade is something you should opt into rather than inherit. Connect model in, get model out, and from that point forward the attention runs through the sparse backend.
How it works
Sol decides what to skip with an input-adaptive statistical threshold rather than a fixed pattern. For each block of queries it computes a proxy score against K centroids, and anything below mean + threshold × std gets skipped - its KV contribution is replaced by one stored 64-token centroid (the "skipped-block residual") plus an online-softmax correction, which is why the approximation stays in the right ballpark. Exact blocks run on the same INT8 Tensor-Core path the pack already uses.
On Turing, this is native: the bundled sm75 kernel handles it. On Ampere and newer it delegates the dense parts to the installed SageAttention or Comfy Kitchen W8A8 backend. There's an automatic crossover that falls back to dense when a sequence is short enough that sparsity isn't worth it, so you don't get punished for running a 5-frame clip.
The inputs that matter
Most of them have sane defaults. The ones worth your attention:
- routing_threshold -
1.0matches the official Sol policy. Lower it to preserve more exact blocks (safer, slower); raise it to skip more (faster, riskier). This is the main quality dial. - dense_prefix_steps / dense_suffix_steps - keep the first
1(default) and optionally last steps fully dense. First step is default dense because errors there cascade. - dense_prefix_layers - keep the first
2transformer layers dense every sparse step. First and last layers do disproportionate work. - skipped_residual -
1x64(default) uses one K/V centroid per skipped block;2x32keeps two for better approximation without changing routing. Only touch this if you see quality loss. - sparse_reference_video - default
true, meaning long reference-video interactions can use Sol routing.sparse_reference_imageandsparse_reference_audiodefault tofalse, protecting keyframes and audio/dialogue exactly. These three switches map to the semantic segments of the model's multimodal layout. - use_w8a8 (optional, default on) - the integer fast path for exact blocks; changes throughput, not routing policy.
There's also prefix_policy (auto/none/manual) and manual_prefix_tokens for when you want to hand-specify how many leading tokens stay dense instead of trusting the model's segments. And debug_route_density logs min/mean/max route density per step - useful once, then off.
How to install
Same as every node in this pack - it ships with ComfyUI Turing Utils ("comfyui-svdint4" in Manager):
cd ComfyUI/custom_nodes
git clone https://github.com/wjie98/comfyui-svdint4
cd comfyui-svdint4
python -m pip install -v --no-build-isolation -e ./kernel
The kernel build is manual and required - that's where the sparse backend lives. Restart ComfyUI after.
Where people get burned
Expect a quality change, not a bug, if you push the threshold up. The defaults are tuned to preserve the first denoising step and the first two layers dense for exactly this reason: skip too early and every later step inherits the error. And if a sequence is short or incompatible, the node silently uses the dense backend - that's the crossover doing its job, not a failure. Start at the defaults, verify the output looks right, then push routing_threshold up in small steps if you want more speed.
Inputs (14)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | — | |
| routing_threshold | FLOAT | 1.0-4–4 | Route blocks whose input-adaptive proxy score exceeds mean + threshold × standard deviation. Lower values preserve more exact blocks; 1.0 matches the official Sol policy. |
| prefix_policy | COMBO | auto | Auto applies the model's semantic segments and the three reference switches; none protects no modality ranges; manual protects only the leading token count below. |
| manual_prefix_tokens | INT | 00–262144 | Leading Query tokens kept dense and leading K/V tokens kept exact only for manual policy. Boundaries round outward to 64-token blocks. |
| skipped_residual | COMBO | 1x64 | Official-style 1x64 uses one K/V centroid per skipped block. 2x32 keeps two residual centroids for higher approximation quality without changing routing. |
| sparse_reference_image | BOOLEAN | false | Allow reference-image Query/KV interactions to use Sol routing. Disabled protects keyframes and reference images with dense Query and exact KV blocks. |
| sparse_reference_video | BOOLEAN | true | Allow long reference-video Query/KV interactions to use Sol routing instead of protecting the complete reference video. |
| sparse_reference_audio | BOOLEAN | false | Allow reference-audio Query/KV interactions to use Sol routing. Disabled preserves reference audio and dialogue conditioning exactly. |
| dense_prefix_steps | INT | 10–1000 | Number of early denoising steps that use the selected dense backend across every transformer layer (stable Sage, or W8A8 when enabled). |
| dense_suffix_steps | INT | 00–1000 | Number of final denoising steps that use the selected dense backend across every transformer layer (stable Sage, or W8A8 when enabled). |
| dense_prefix_layers | INT | 20–256 | Keep this many transformer layers at the beginning of every sparse step on the selected dense backend. If prefix + suffix reaches the model layer count, all layers use the dense backend without Sol preprocessing. |
| dense_suffix_layers | INT | 00–256 | Keep this many transformer layers at the end of every sparse step on the selected dense backend. Requires layer-count metadata; overlap with the prefix intentionally makes all layers dense. |
| use_w8a8opt | BOOLEAN | true | Use signed INT8 V and unsigned INT8 probability Tensor Cores for Sol exact blocks and protected dense steps/layers. Enabled is the default Turing fast path. |
| debug_route_densityopt | BOOLEAN | false | Log min/mean/max route density once per denoising step. Disabled by default; enabling it adds tiny reductions and one synchronization per step. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| model | MODEL | — |