LTX Attn — Zone Analysis
Which heads care about the region you care about
- zone_mask
- zone_heatmap
- ranked_heads
Here's the question this node exists for: "which attention heads are responsible for my subject's face?" All the heatmaps tell you about entropy and temporal locality in the abstract; Zone Analysis grounds it - you draw a mask over a region of the frame, and it ranks every head by how much attention it concentrates on that region, versus what you'd expect from uniform attention. It's the direct path from "I can see something's wrong with the face" to "head 32-7 is the one carrying the face."
It's the most practical node in the pack for video-editing work, because it bridges the gap between the raw research view and an actual target for intervention: the ranked output feeds straight into Head Freeze or QKV Transfer.
How it works
For each (block, head), it computes the ratio:
attention mass landing on the zone / (zone's fraction of the frame)
Ratio > 1 means the head focuses on the zone; ratio ≈ 1 means it attends uniformly (no preference); ratio < 1 means it actively avoids the zone. The mask you supply uses pixel coordinates, and it's automatically resized down to latent space (divided by 32 for LTX-2.3, where 1 latent pixel ≈ a 32×32 image patch), then binarized with mask_threshold. query_mode flips the direction: key_mass measures mass received by zone tokens (who looks at the zone), query_mass measures mass emitted (where the zone looks), and both averages them.
The inputs that matter
zone_mask- a MASK input. This is the whole point of the node: draw/paint a mask over the frame region you're investigating.query_mode-key_mass/query_mass/both, as above.step_idx--1(default) averages over all captured steps.num_frames,latent_height,latent_width- must match the capture geometry, same as the map viewers.attn_type-saorca.aggregate_time- true = aggregate over all frames; false = frame 0 only.mask_threshold,colormap,cell_size,top_k- the last one controls how many heads land in theranked_headstext output.
Outputs are zone_heatmap (IMAGE, the per-head ratio rendered as a grid) and ranked_heads (STRING, the ranked list).
Install
cd ComfyUI/custom_nodes
git clone https://github.com/g-raw/ComfyUI-LTX-Attention-Toolkit.git
Restart ComfyUI. No extra dependencies, no model files. Work-in-progress pack, so store formats can shift between versions - pin the repo if you depend on it.
Common issues
Zone Analysis needs full attention maps, so the capture must be full_fp16 or hybrid with this block in full_blocks - a reduced capture gives it nothing to measure, and a sparse full_targets block raises. Geometry must match or the reshape fails, so feed it LTX Latent Dims outputs. And remember the mask is resized to latent space: a tiny mask in image space may end up covering just a handful of latent pixels, which makes the ratio noisy. Bigger zones, cleaner ratios. Two-run workflow applies as usual - capture first, analyze in a later queue pass.
Inputs (12)
| Name | Type | Default | Description |
|---|---|---|---|
| zone_mask | MASK | — | |
| attn_type | COMBO | sa | 2 options: sa, ca |
| step_idx | INT | -1-1–255 | -1 = average over all steps. |
| num_frames | INT | 11–256 | — |
| latent_height | INT | 161–256 | — |
| latent_width | INT | 161–256 | — |
| query_mode | COMBO | key_mass | key_mass : mass received by zone tokens (which LOOK AT the zone?) query_mass : mass emitted by zone tokens (from where does the zone LOOK?) both : average of both |
| aggregate_time | BOOLEAN | true | True = aggregate over all frames. False = analyze only frame 0. |
| mask_threshold | FLOAT | 0.500–1 | Binarization threshold for the latent mask. |
| colormap | COMBO | viridis | 4 options: viridis, inferno, turbo, coolwarm |
| cell_size | INT | 164–64 | — |
| top_k | INT | 101–64 | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| zone_heatmap | IMAGE | — |
| ranked_heads | STRING | — |