Nodes/WAS Node Suite v3/Latent Statistics
ComfyUI Node Runs on cloud

Latent Statistics

Know whether that latent is broken before you decode it

By WASasquatch·Created 3 years ago·Updated 4 days ago· 1,844
Latent Statistics
  • samples
  • index
  • mean
  • std
  • min
  • max
  • absolute_mean
  • batch_size
  • channels
  • height
  • width
  • is_finite
  • summary
scopewhole batch
out_of_rangeerror

Every ComfyUI user has had the moment: the sampler ran, the VAE decode ran, and out came a black frame, or a grey one, or a garble, with nothing in the console saying why. A sampler that diverged doesn't throw an error - it answers a latent full of nan or huge values, and the failure only becomes visible after you've paid for the decode. WAS Latent Statistics measures the values inside a latent, not its size, so you can catch the wreck before it hits the VAE.

The inputs are samples plus how you want to measure it. scope picks whole batch (one set of figures for every latent together) or one latent (just the one index picks, counted from 0, negatives from the end, decimals truncated). Feed out_of_range to decide what happens when the index misses: wrap cycles around, clamp pins to the edge, error stops the prompt and names the batch size. The defaults are sane - whole batch, index 0 - so you can just wire a latent in and read.

The outputs read like a medical chart for your tensor:

  • mean and std - the average and the spread. Fresh noise sits around mean 0, std ~1. A denoised latent drifts near 0 and moves with content, so compare between runs of one workflow rather than against a fixed figure. A std of 0.0 means an Empty Latent Image (all zeros) or a result that collapsed to a flat block - both worth knowing before decode.
  • min and max - together, the range. An ordinary SD latent stays inside roughly -10 to 10; a much wider range is a sampler running away. max comes back inf where the sampler overflowed.
  • absolute_mean - the average with signs dropped, so positives and negatives cancelling out can't hide a strong latent. Near 0.0 means empty or collapsed whatever mean says.
  • batch_size, channels, height, width - the shape facts. channels is the one to test before handing a latent to a different model than the one that made it: 4 for SD1.5 and SDXL, 16 for SD3, Flux and Wan. Height/width are in latent rows (an eighth of the decoded pixels: 64 here decodes to 512). batch_size can drive a loop's iterations if you want to walk the batch one latent at a time.
  • is_finite - false where any value is nan or inf, which is exactly what a diverging sampler leaves behind.
  • summary - every figure on one line, for a log or to burn into a frame with Image Draw Text.

The design intent is visible in the output list: this is a guard node, not a curiosity. The is_finite boolean exists to be wired into a gate - the tooltip names it: "Wire it into Any Gate so a broken run stops before the VAE decode instead of saving a black frame." Batch rendering unattended, loop runs, or any long pipeline where a single divergence wastes an hour - that's where this earns its place. The channels readout doubles as a sanity check when a workflow you downloaded expects a different model family than you loaded, a classic source of silent garbage.

One honest limitation, stated in the tooltips: mean is nan when any measured value is nan, so on a genuinely broken latent most numbers go useless at once - but that's precisely when is_finite does its job.

Install

Ships in WAS Node Suite v3. ComfyUI Manager, search "WAS Node Suite", or:

cd ComfyUI/custom_nodes
git clone https://github.com/WASasquatch/was-node-suite-comfyui

Restart after. Needs ComfyUI 0.14.0+ and Python 3.10+. No pip packages, no model downloads - it reads tensors ComfyUI already holds (v3 carries none of the old pack's install baggage).

Common issues

  • Black frames with no console error. Wire is_finite into a gate between the sampler and the VAE decode so a broken run stops instead of saving garbage.
  • Latent decoded by the wrong model. Check channels before decode - 4 vs 16 is the tell for SD-family vs SD3/Flux/Wan.
  • Std reads 0.0 on a "finished" sample. That's a collapsed or empty latent, whatever the image looks like after a heroic decode.
CategoryWAS Suite/Latent

Inputs (4)

NameTypeDefaultDescription
samplesLATENTThe latent to measure, from a sampler, a VAE Encode or an Empty Latent Image. It is read, never changed. A video latent shaped [batch, channels, frames, height, width] is measured the same way.
scopeCOMBOwhole batchWhat to measure. `whole batch` answers one set of figures for every latent together; `one latent` measures the one the index picks.
indexINT,NUMBER,FLOAT0-16384–16384Which latent to measure, read only when scope is `one latent`. Counts from 0, and negatives count from the end: -1 = last, -2 the one before it. A decimal is truncated: 2.7 = 2.
out_of_rangeCOMBOerrorIndex outside 0..batch_size-1, which index -1 never reaches. With 3 latents and index 4: `wrap` = latent 1, `clamp` = latent 2, `error` stops the prompt and names the batch size.

Outputs (11)

NameTypeDescription
meanFLOATAverage of every value measured. A denoised latent sits near 0.0 and drifts with the content, so compare it between runs of one workflow rather than against a fixed figure. nan when any value measured is nan.
stdFLOATSpread of the values around the mean, over all of them rather than a sample. Around 1.0 for fresh noise. 0.0 for an Empty Latent Image, which is all zeros, and for a result that has collapsed to a flat block.
minFLOATSmallest value measured. With max it gives the range: an ordinary SD latent stays inside roughly -10 to 10, and a much wider range is a sampler running away.
maxFLOATLargest value measured. inf where the sampler overflowed, which is also what turns is_finite false.
absolute_meanFLOATAverage of the values with their signs dropped, so positives and negatives cancelling out cannot hide a strong latent. Near 0.0 means an empty or collapsed latent whatever mean says.
batch_sizeINTHow many latents the batch holds, whatever index was set. Wire it into a loop's iterations to walk the batch one latent at a time.
channelsINTChannels each latent carries: 4 for SD1.5 and SDXL, 16 for SD3, Flux and Wan. Worth testing before a latent is handed to a different model than the one that made it.
heightINTLatent rows, an eighth of the decoded pixel height: 64 here decodes to 512 pixels. 0 for a latent with no rows, such as an audio one.
widthINTLatent columns, an eighth of the decoded pixel width: 64 here decodes to 512 pixels.
is_finiteBOOLEANfalse where any value measured is nan or inf, which is what a diverging sampler leaves behind. Wire it into Any Gate so a broken run stops before the VAE decode instead of saving a black frame.
summarySTRINGEvery figure on one line, as `index=all batch_size=1 channels=4 ... non_finite=0`. For a log, a console print, or burning into a frame with Image Draw Text.