Nodes/ComfyUI-Adaptive-Noise-Scale/Adaptive Noise Scale Sampler
ComfyUI Node

Adaptive Noise Scale Sampler

It's a sampler that watches its own noise scale and fixes it mid-generation

By nawka12·Created 5 months ago·Updated 5 months ago· 1
Adaptive Noise Scale Sampler
  • sampler
  • sampler
warmup_steps5
correction_power0.50
dampen_floor0.80
boost_ceiling1.15
phase_binnedtrue

Ancestral samplers like Euler a and DPM++ SDE add fresh noise at every step - that's what makes them never quite settle, and it's also what makes them sprinkle in noise that's out of proportion to where you are in the denoise. Turn the CFG up and the excess gets worse: blotchy texture, over-baked detail, that slightly fried look. Adaptive Noise Scale Sampler is a wrapper that measures the problem while it's happening and rescales the per-step noise accordingly. If you're fighting noise-induced artifacts on an ancestral sampler and are tired of hand-tuning, this is the niche tool for you.

It's a port of the author's own sd-webui-adaptive-noise-scale extension, and a single node: you drop it between KSamplerSelect and KSampler (Advanced).

[KSamplerSelect] → [Adaptive Noise Scale Sampler] → [KSampler (Advanced)]

How it actually works

Two passes, which is the whole personality of the node. Pass 1 is a short calibration run: it samples with a special callback that compares how fast the denoised output is changing against how fast the sigma schedule is dropping - that ratio is the "excess." If the image is changing faster than the schedule says it should, the injected noise is too hot; if it's changing slower, you could stand a little more. It collects these measurements during the texture phase (σ between 0.5 and 5.0), aborts early once it has enough, and computes:

correction = clamp(1 / median_excess^power, floor, ceiling)

Then Pass 2 restarts from the exact same latent and noise and redoes the whole generation with the correction applied to every intra-step noise injection. So the final image benefits from the calibration, and the calibration doesn't pollute the result.

The implementation detail worth knowing: for non-SDE samplers it monkeypatches ComfyUI's default_noise_sampler for the duration of the run, and for SDE samplers it injects a scaled BrownianTreeNoiseSampler via the sampler's extra_options. Both are restored afterward, so it's safe to run alongside other custom samplers.

The inputs that matter

Only one of these deserves your attention on day one:

  • correction_power (default 0.5) - the exponent on the correction. 0.5 is gentle (square root), 1.0 is linear, above 1 is aggressive. Start at the default.
  • warmup_steps (default 5) - how many texture-phase measurements to collect before calibrating. More = more robust, but the calibration pass runs longer.
  • dampen_floor (default 0.80) - the lowest multiplier allowed. This is your safety rail: the node won't damp noise below 0.8× no matter what the measurements say.
  • boost_ceiling (default 1.15) - the highest multiplier. The asymmetry is intentional; the tool's main job is damping.
  • phase_binned (default on) - computes separate corrections for the structural (σ > 5), texture, and cleanup phases instead of one global number. Leave it on; bins with too few samples fall back to the global value anyway.

Output is a single sampler, which wires straight into the sampler port of KSampler (Advanced). Same seed in, same seed out - the noise path is the only thing that changes.

Installing it

Via ComfyUI Manager, search ComfyUI-Adaptive-Noise-Scale. Or manually:

cd ComfyUI/custom_nodes
git clone https://github.com/nawka12/comfyui-adaptive-noise-scale

Restart ComfyUI. Good news on the dependency front: the only Python dependency is torch, which you already have. No model files, no API keys, nothing to download. This is about as light an install as custom nodes get.

Where people get burned

It doubles your sampling time. Every generation is a calibration pass plus a production pass. That's the price of the design, and the one thing you'll notice immediately.

Don't use it with deterministic samplers. DPM++ 2M, LMS, and friends produce a nearly-constant change between steps, so the calibration never finds a texture phase. The node prints a warning and runs the whole thing again - you pay double for zero benefit. This tool only makes sense on ancestral and SDE samplers.

SDE detection is by name. The node identifies SDE samplers by matching against a hardcoded list (sample_dpmpp_sde, sample_dpmpp_2m_sde, etc.). A third-party or renamed SDE sampler that's not on that list gets treated as non-SDE, and its Brownian noise won't actually be scaled - it'll silently do the wrong thing. If you're running a custom sampler pack, keep that in mind.

The honest caveat: there's essentially no community chatter around this node - it's a niche, author-ported tool, not an ecosystem staple. But the mechanism is straightforward and the defaults are sensible, so the worst case is you lose a bit of render time, not an evening.

Categorysampling/custom_sampling/samplers

Inputs (6)

NameTypeDefaultDescription
samplerSAMPLER
warmup_stepsINT51–20Texture-phase steps (0.5 < sigma < 5.0) to collect before calibrating
correction_powerFLOAT0.500.1–2Exponent: 0.5=gentle (sqrt), 1.0=linear, >1=aggressive
dampen_floorFLOAT0.800.5–1Minimum correction multiplier
boost_ceilingFLOAT1.151–2Maximum correction multiplier
phase_binnedBOOLEANtrueSeparate correction factors for structural / texture / cleanup phases

Outputs (1)

NameTypeDescription
samplerSAMPLER