Nodes/ComfyUI-LTX-Attention-Toolkit/LTX Attn — Head Candidates
ComfyUI Node

LTX Attn — Head Candidates

Stop eyeballing heatmaps, get a shortlist

By g-raw·Created 3 months ago·Updated 2 months ago· 2
LTX Attn — Head Candidates
    • report
    • candidates_csv
    • control_csv
    store_handle_a
    store_handle_b
    attn_typesa
    metricstemporal,frame_dist_mean_norm,frame_dist_std_norm
    step_idx-1
    top_k12
    control_modelowest_score
    control_k12
    seed0

    Compare Runs hands you a diff heatmap and a ranked table per metric. Then you stare at several of those tables and try to figure out which heads keep showing up. Head Candidates automates that last, tedious step: it combines several metrics' zscore diffs into one composite score per head - mean(|zscore(A − B)|) across the metrics you list - and outputs a ranked shortlist of candidate heads plus a control group, ready to paste into Head Freeze.

    This is the node that closes the loop between "profiling two runs" and "intervening." Its whole point is that the output CSV is copy-paste compatible with the intervention nodes' targets widgets, so the workflow becomes: capture A, capture B, run Head Candidates, paste candidates_csv into Head Freeze, regenerate, see if it does anything.

    How it works

    It reuses Compare Runs' store-loading and zscore logic, but instead of rendering a heatmap it computes, for each (block, head), the mean absolute zscore across the metric list you provide - the composite. A head that's a consistent outlier on temporal, frame_dist_mean_norm, and frame_dist_std_norm scores high because it moved across every metric; a head carried by only one metric scores lower. The report shows each individual metric's zscore per head, not just the composite, so you can tell "consistently implicated" from "one metric fluke."

    Two groups come out: the candidate shortlist (top top_k by composite score) and a control group - either the heads least implicated (control_mode=lowest_score) or a random sample (random + seed). The control group excludes anything already in the candidates, and it exists because an intervention experiment without a control is just a video you made.

    The inputs that matter

    • store_handle_a / store_handle_b - the two runs.
    • metrics - comma-separated, e.g. temporal,frame_dist_mean_norm,frame_dist_std_norm. Use _norm variants when the runs don't share frame count/resolution.
    • attn_type - sa or ca.
    • top_k - candidate shortlist size.
    • control_mode / control_k / seed - control group behavior; control_k=0 skips it.

    Outputs are report (STRING, the readable breakdown), candidates_csv (STRING, one block,head per line for pasting), and control_csv (STRING, same format for the control group).

    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. The pack is work-in-progress, so treat saved stores as breakable between versions.

    Common issues

    Same input hygiene as Compare Runs: dump-and-reload a .pt via Store Load first if your runs aren't live in the registry, and use _norm distance metrics for cross-resolution comparisons. Since this only needs metrics (computed in every capture mode), no full-map capture is required - that's the nice part. If the composite scores all come out near zero, you're comparing two runs that are essentially identical on the metrics you picked; either the difference is real but elsewhere (try other metrics), or your two generations really didn't diverge.

    Categoryg_raw/LTX/Profiler

    Inputs (9)

    NameTypeDefaultDescription
    store_handle_aSTRING
    store_handle_bSTRING
    attn_typeCOMBOsa2 options: sa, ca
    metricsSTRINGtemporal,frame_dist_mean_norm,frame_dist_std_normComma-separated metric names. Composite score = mean(|zscore|) across all of them, per (block, head).
    step_idxINT-1-1–255
    top_kINT121–1536How many (block, head) candidates to shortlist, ranked by the composite score.
    control_modeCOMBOlowest_scoreHow to pick the control group: the heads least implicated by these metrics, or a random sample (excluding the candidates either way).
    control_kINT120–1536Control group size. 0 to skip it.
    seedINT00–2147483647Only used when control_mode=random.

    Outputs (3)

    NameTypeDescription
    reportSTRING
    candidates_csvSTRING
    control_csvSTRING