ComfyUI-ScaleLockedResidualDiffusion
A custom ComfyUI node pack implementing a practical MVP of Scale-Locked Residual Diffusion for the specific failure mode where a model behaves well around its native / comfortable resolution (for example ~1 MP) but drifts badly in composition, anatomy, or identity at much higher resolutions.
What it does
Instead of letting the high-resolution branch freely re-plan the image, the node:
- creates a low-resolution planner pass at a target megapixel level,
- records the planner's per-step denoised x0 trajectory,
- builds nested high-resolution noise so the high-res branch shares the same coarse stochastic layout,
- runs the final high-res sampling with a custom CFG guider that locks only the low-frequency denoised structure toward the planner trajectory while preserving the base model's high-frequency residual detail.
In practice, this is meant to reduce:
- composition drift,
- anatomy drift,
- duplicate limbs / body parts,
- scene re-planning between 1 MP and 4 MP,
- the "looks like a different sample entirely" problem.
Nodes
1. Scale-Locked Residual KSampler
Main all-in-one node.
Outputs
output: final high-res latentlowres_planner: final low-res planner latentdenoised_output: final high-res denoised x0 latent when available
Important controls
target_megapixels: planner resolution in pixel-space megapixels (usually0.8to1.5for Flux-like native planning)lock_strength: global multiplier for the scale locklock_strength_start/lock_strength_end: how strongly the lock applies early vs late in denoisinglock_schedule: linear / cosine / flat interpolation for the lock schedulecoarse_cutoff: retained spatial fraction for the strongest coarse lock bandmid_band_cutoff: retained spatial fraction for an additional mid-frequency lock bandmid_band_strength: how strongly the mid-band is pulled toward the planner relative to the low-band schedulenested_noise_strength: amount of zero-mean high-frequency detail noise added on top of the lifted low-res noiselock_mask(optional): spatial mask to strengthen the lock only in selected regions (for example body / face / hands)pin_anchors: store planner anchors in pinned CPU memory when possible for faster non-blocking transfer during the high-res passsampler_guard:warn/error/offguard for samplers outside a conservative alignment-safe allowlist
2. Scale-Locked Nested Noise Preview
Utility/debug node to inspect the nested-noise construction separately.
Installation
Clone or copy this directory into your ComfyUI custom_nodes folder:
git clone <this-repo> ComfyUI/custom_nodes/ComfyUI-ScaleLockedResidualDiffusion
Then restart ComfyUI.
No extra Python dependencies are required beyond ComfyUI + PyTorch.
Suggested first settings for Flux.2 Klein 9B style use
For a first test when your high-res target is around 4 MP:
target_megapixels = 1.0lock_strength = 0.85lock_strength_start = 0.95lock_strength_end = 0.25lock_schedule = cosinecoarse_cutoff = 0.33mid_band_cutoff = 0.60mid_band_strength = 0.35sampler_guard = warnnested_noise_strength = 0.35
If the result still drifts too much:
- raise
lock_strengthtoward0.95 - lower
coarse_cutofftoward0.25 - use a
lock_maskover body / face / hands
If the result feels too constrained / too similar to the low-res planner:
- lower
mid_band_strength - raise
mid_band_cutoff - lower
lock_strength - raise
coarse_cutoff - lower
lock_strength_end
Recommended workflow pattern
Use this node exactly where you would normally use a KSampler for the high-resolution generation pass.
Typical graph:
- checkpoint / text encodes
- empty latent or incoming img2img latent at your final target resolution
- Scale-Locked Residual KSampler
- VAE decode / detailers / final upscaling if desired
The node internally creates the planner pass for you, so you do not need to build a separate 1 MP sampler branch unless you want to compare outputs.
Current limitations
This is a carefully implemented MVP, not a mathematically complete research system.
What is already implemented:
- low-res planner trajectory capture,
- nested-noise initialization,
- denoised-space low-frequency locking,
- denoised-space mid-frequency locking,
- residual-preserving coarse-field replacement,
- optional pinned-memory anchor staging,
- conservative sampler-alignment safety gating,
- optional spatial masking.
What is not implemented yet:
- automatic anatomy / pose / segmentation mask extraction,
- explicit residual-only tiled model execution,
- sigma-perfect trajectory matching for samplers that perform unusual extra model evaluations,
- multi-stage 1 MP -> 2 MP -> 4 MP progressive ladder inside one node,
- exact support tuning for every possible exotic custom sampler.
Why this implementation is conservative
This node avoids invasive patching of ComfyUI's internal sampler code. Instead it uses:
- the standard Comfy custom-node registration path,
- the standard custom-sampling guider path,
- standard sigma generation,
- standard sampler objects,
- standard preview callback behavior.
That makes it much easier to maintain and much less likely to break when ComfyUI internals shift.
Files
__init__.py- node registrationnodes.py- ComfyUI node definitions and runtime integrationslrd_core.py- algorithm core, nested noise, latent resizing, residual locking, trajectory helpers
Sampler safety note
The current implementation aligns planner anchors to the final pass using outer-step / sigma progression heuristics. That works best with a conservative subset of samplers whose effective evaluation pattern is close to one visible step <-> one anchor step.
Because Comfy's custom sampling system is flexible and some samplers can perform more complicated internal evaluations,
the node exposes sampler_guard:
warn: log a warning for samplers outside the conservative safe seterror: refuse to run those samplersoff: trust the sampler and run anyway