πΎ LTX Calibrator Flush
The node that turns calibration logs into a mask file
- latent
- latent
- report
LTXCalibratorFlush is the payoff half of the calibration pair: it takes the running-mean E[xΒ²] mask that LTXActivationCalibrator accumulated during sampling and writes it to a safetensors file you can actually use. If the calibrator is the microscope, this is the button that saves the photograph.
The one structural detail that explains why this node exists: forward hooks fire during sampling, which is after a node's function returns. So the calibrator can set up capture but can't be the thing that writes the result - it would write before any sampling happened. The fix is to place this node downstream of the sampler. It takes a LATENT input precisely so it sequences after the sampling pass, writes the accumulated bucket to disk, and passes the latent through unchanged. The latent input is scaffolding; the real work is the side-effect write.
The inputs
latent- required, and deliberately so: it guarantees this node runs after the sampler. Wire whatever latent your sampler produces.output_path- must match the calibrator'soutput_pathor you'll flush a different (or empty) bucket than the one you accumulated. Defaultcalib/override_agree.safetensors.clear_after_flush(False) - drop the in-memory bucket after writing. Keep it False while you're accumulating a multi-prompt pool; set True for the final flush if you want a clean slate next run.
Outputs: latent (the passthrough) and report (a STRING with the write summary - pipe it to a text display to confirm the file and its counts).
How to use it with the calibrator
The mental model is "one bucket per condition, one file per condition":
Calibrator(output_path="calib/override_agree.safetensors", condition_label="agree", reset=True)
β Sampler β CalibratorFlush(output_path="calib/override_agree.safetensors")
Queue a pool of AGREE prompts (first one with reset=True), then repeat with a second path for CONFLICT prompts. Because the global accumulator persists across queued prompts, each flush writes cumulative-so-far - the final prompt's flush is the complete pool. A downstream tool like the pack's outlier_dampen.py differences the masks (conflict β agree) to find which activation directions actually drive the behavioral difference, optionally sparing directions that light up on a separate DMD on/off axis.
The honest framing: this node does almost nothing on its own. It's the save-button for a calibration pipeline, and it only matters if you're doing spectral-compression research on LTX2. If you're not, you can safely skip both nodes - but knowing the pair exists means you'll recognize it when a workflow dump hands you calib/*.safetensors files and you wonder where they came from.
Install is the pack-wide clone (10S_Nodes into custom_nodes, restart, or ComfyUI Manager β "10S-Comfy-nodes"), no extra deps. The file format is sum_sq+counts_v1 - resumable across runs, which is exactly what a multi-prompt calibration pool needs.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| latent | LATENT | β | |
| output_path | STRING | calib/override_agree.safetensors | Must match the calibrator's output_path. |
| clear_after_flushopt | BOOLEAN | false | Drop the in-memory bucket after writing. Leave False while accumulating a pool. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| latent | LATENT | β |
| report | STRING | β |