Noise Reuse Options
Start the second pass from the noise the first pass used
- options
- options
Every hires pass throws the first pass's noise in the bin. Pass one sampled from one noise tensor; pass two - upscaled latent, lower denoise - gets a fresh noise tensor because that's what samplers do by default. The composition survived the resize, but the noise field under it did not, so pass two spends its first few steps re-deciding structure that pass one had already settled. Noise Reuse Options asks for it back.
What it is in the graph
This is a sampler-options node: a small capability object you chain onto the options input of KSampler (SimpleSyrup) (or onto another options node, e.g. the tiling, inversion, contextual-diffusion and attention-coupling ones). Its optional options input exists so you can stack several of them on one wire, and the socket type matches its own output, so bypassing the node drops just its contribution without any rewiring.
The clever part is not in the node. It's what the pack does at prompt-validation time when this node is present and enabled. SimpleSyrup walks backward from the receiving sampler's latent_image, through only the nodes that provably preserve a latent - Latent From Image, Simple Upscale Latent, latent upscale passes with crop disabled - until it finds the source sampler. It then reaches into that source run and installs an observer on its model so the source saves its real intermediate states. Your measured result: pass two starts from the noise pass one actually used, not a fresh roll of the dice.
The four settings
- enabled - defaults on. Off passes your preceding options through untouched, so it behaves as if the node weren't there.
- finishing_steps - 0 to 100, default 0. At 0 you get straight capture-and-reuse, which is what most people want. Above 0, the capture happens earlier in the noise level and that many full-resolution inversion steps run before your sampler starts, to reconstruct a state that the receiving model considers self-consistent. Euler costs one model evaluation per step, Heun two - so this is a real, visible cost on top of your sampling.
- finishing_method -
eulerorheun. Heun is the more accurate integration; euler is the cheap one. - finishing_start_fraction - default 0.75, and only meaningful when finishing is on. It sets how far below the receiving sampler's starting noise level the capture point sits. 0.75 means the source saves its state at 75% of that level and the finishing steps walk the rest of the way up.
Output is a single options socket. Wire it into the KSampler's options input, or into the next options node in your chain.
Install
Manager: search the Node Pack list for SimpleSyrup, install, restart. Legacy Manager: the same search lives under Custom Nodes Manager.
cd ComfyUI/custom_nodes
git clone https://github.com/Artificial-Sweetener/SimpleSyrup.git
cd SimpleSyrup
../../venv/bin/python -m pip install -r requirements.txt
Restart after installing, and be on a current ComfyUI - the pack uses the v3 extension API and the internal nodes this feature injects come from it.
How the reuse actually works
The source run doesn't just hand over a copy of its starting noise. It saves its real noisy state at a specific noise-level coordinate and separates out the noise in the source model's own parameterization. That residual is what travels. When the receiving sampler starts at a bigger resolution than the source, the residual is lifted with a spatial DCT: the source's low-frequency coefficients are kept exactly, and only the new high-frequency bands that didn't exist before are filled in from fresh noise. At unchanged size, the residual is reused outright. That's a much better answer than resizing a noise tensor, because it preserves the structure that actually decides your composition.
Where people get burned
The failure is loud, which is good. Resolve the provenance chain wrong and you don't silently get fresh noise - a Noise Reuse Validation (Internal) node errors with a readable message. If pass two just looks like a normal second pass, reuse probably isn't active at all.
One pass per receiver. A sampler consumes the captured state once. A conditioning batch, or an extra sampling stage off the same capture, needs its own sampler.
The source and receiver models have to agree on latent format. Different families, different latent shapes - the pack refuses rather than producing mush.
You may need to queue twice after changing things. Changing the receiving sampler's steps, scheduler or denoise changes the coordinate it asks for. If the source sampler's output is already cached with an older capture, you'll be told to queue again so the source actually saves the level you now want.
Not every node can be walked through. The trace has to stay on the pack's own resize/provenance path, or Comfy's latent nodes with crop disabled. Any other hop stops it - by design, since the alternative is guessing.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| enabled | BOOLEAN | true | Requests captured source noise when enabled; disabled passes preceding options through unchanged. |
| finishing_steps | INT | 00–100 | Full-resolution inversion steps before sampling; 0 reuses captured noise without finishing. |
| finishing_method | COMBO | euler | Euler uses one evaluation per finishing step; Heun uses two for greater accuracy. |
| finishing_start_fraction | FLOAT | 0.750.01–0.99 | With finishing enabled, captures at this fraction of the receiving sampler's starting noise coordinate. |
| optionsopt | SIMPLE_SYRUP_SAMPLER_OPTIONS | Optional preceding sampler options; bypass this node to omit its contribution. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| options | SIMPLE_SYRUP_SAMPLER_OPTIONS | Combined sampler options; connect another options node or KSampler. |