ComfyUI Node

Denoise Chooser

Stop hand-editing denoise every time you switch between txt2img and img2img

By Koushakur·Created 2 years ago·Updated about a year ago· 4
Denoise Chooser
  • Latent
  • LATENT
  • FLOAT
FloatIfEmpty1.00
FloatIfNot0.75

Denoise Chooser exists for exactly one annoying problem, and it solves it in about twenty lines of code. If you run two-pass workflows - generate on an empty latent at full denoise, then feed the result back through a second pass at low denoise to add detail - you know the drill: every time you flip between the "fresh generation" path and the "refine what I already made" path, you have to remember to retype the denoise value. Koushakur got tired of it and shipped this node. It looks at your latent, decides which denoise you meant, and hands the latent through untouched so nothing else in your graph changes.

It lands under Add Node → advanced → Denoise Chooser.

How it works

The trick is embarrassingly simple once you know it: an Empty Latent Image node produces a latent tensor that is all zeros, while a latent that came from encoding a real image (or from an upscaler) has nonzero values. The node counts them with Latent['samples'].count_nonzero(). Zero nonzero values → empty latent → it's a txt2img-style pass. Anything else → you're img2img-ing or refining, which means a low denoise.

It's a heuristic, not magic, but it's a sound one: that all-zero state is exactly what ComfyUI's empty latent produces, and it's what you'd have if you hand-toggled the input yourself. The latent you feed in comes back out the LATENT output byte-for-byte unaltered, so you can drop this node in front of your KSampler without changing the rest of the wiring.

The three inputs that matter

  • Latent - the latent that feeds your sampler. This is what gets inspected, and what gets passed through.
  • FloatIfEmpty - the denoise used when the latent is empty (all zeros). Default 1.0, i.e. full noise.
  • FloatIfNot - the denoise used when it isn't (default 0.75).

Both floats accept 0 to 100. And here's the bonus feature worth knowing: anything above 1.0 gets divided by 100, so 75 and 0.75 produce identical output. That's handy when you're copy-pasting values between nodes or scripts that express denoise as a percentage.

The FLOAT output is the one you wire into your KSampler's denoise input; the LATENT output goes into the sampler's latent socket. In the typical setup you'd use one KSampler for both paths - the empty-latent branch runs it at full denoise, the upscaled branch runs it low - and Denoise Chooser picks the right value per branch without you touching anything.

Install

Boring and easy, as a node this small should be. ComfyUI Manager: search ComfyUI-DenoiseChooser and hit install. Or, by hand:

cd ComfyUI/custom_nodes
git clone https://github.com/Koushakur/ComfyUI-DenoiseChooser

Then restart ComfyUI (or refresh the node list). That's the whole install: the pack has zero Python dependencies beyond what ComfyUI already ships, and no model files to download. The entire node is one node.py - it runs a tensor count and a comparison.

Gotchas and honest takes

  • It decides on "any nonzero value", not "image present". A latent with noise in it that isn't from a VAE encode still counts as "not empty." In practice the two states you care about - brand-new empty latent vs. an encoded/upscaled image - are cleanly separated, but don't feed it something weird and expect philosophy.
  • The defaults are a starting point, not a law. 0.75 as the not-empty denoise is on the high side for a classic hires-fix second pass (0.3–0.5 is the usual range, as the denoise strength conventions in the KB's upscaling notes describe). If you use this for two-pass upscaling, drop FloatIfNot to match your actual workflow.
  • You don't need this if you never toggle. This is a pure quality-of-life node for people who keep one workflow wired for both branches. If you always hand-build each graph, it saves you exactly nothing.

The honest verdict: this is a one-trick personal-workflow release with zero community footprint, and that's fine. The trick is a good one - a true "why did nobody ship this sooner" moment for anyone who's retyped 0.45 one too many times.

Categoryadvanced

Inputs (3)

NameTypeDefaultDescription
LatentLATENT
FloatIfEmptyFLOAT1.000–100
FloatIfNotFLOAT0.750–100

Outputs (2)

NameTypeDescription
LATENTLATENT
FLOATFLOAT