ComfyUI Extension: ComfyUI-FluxProgressiveLockedUpscale
Run ComfyUI workflows without the setup
No installs, no CUDA version roulette, no GPU sitting idle on your bill. Bring a workflow and run it in the browser.
Single-node, 3-stage Flux pipeline: base generation, progressive locked-noise upscale, and an optional refine pass. Driven by any SAMPLER (e.g. RES4LYF ClownSampler) and preserves composition across resolution changes via orthogonal subspace noise locking.
Looking for a different extension?
Custom Nodes (1)
README
ComfyUI-FluxProgressiveLockedUpscale
A single ComfyUI node that runs a 3-stage Flux pipeline — base generation, progressive
locked-noise upscale, and an optional refine pass — all driven by a SAMPLER you connect
(e.g. a RES4LYF ClownSampler).
It is a Flux-oriented port of the idea in
ComfyUI-ZImageTurboProgressiveLockedUpscale,
reworked so that all sampling goes through comfy.sample.sample_custom with your SAMPLER
object instead of the built-in KSampler. That means you get the full RES4LYF engine —
eta, SDE noise modes, res_2m / res_3s, bongmath, guides — for free, just by wiring a
ClownSampler in.
Node name:
Flux: Locked Progressive Upscale 3-Stage (RES4LYF)Category:upscale
Why this exists
Normal latent upscaling re-noises the whole image, so the model is free to drift the composition, faces, and text every time you go up in resolution. This node keeps the composition-bearing coarse structure exactly while only letting the model add fresh high-frequency detail at each new resolution.
It does that with four mechanics (all latent-shape based, so they're model-agnostic):
- Progressive scale ladder — the total upscale is split into several small steps
(each
<= max_step_scale) instead of one big jump. - Locked noise (orthogonal subspace) — the noise used at the new resolution keeps the
previous stage's coarse modes exactly and only injects new noise in the orthogonal
(high-frequency) complement. It's still statistically
N(0, I)at the new resolution, so the sampler behaves normally — but composition is preserved. - Pixel-space lifting — between stages the latent is decoded → upscaled (with your
upscale_modelif provided, else bicubic) → re-encoded, so detail rides on real pixels. - Sigma-sliced partial denoise — each upscale stage runs only the tail of the
schedule (
tail_steps_*), so the model refines rather than redraws.
The 3 stages
| Stage | When it runs | Controls |
|-------|--------------|----------|
| 1 — Base generation | Only when an empty latent is fed in | base_steps, base_scheduler, optional base_sampler |
| 2 — Progressive locked upscale | Always | upscale_factor, max_step_scale, upscale_steps, upscale_scheduler, tail_steps_first_upscale, tail_steps_last_upscale, main sampler, optional upscale_model |
| 3 — Refine | When enable_refine is on | refine_steps, refine_scheduler, refine_enter_sigma, optional refine_sampler |
All three stages currently share the same model, vae, positive, negative, cfg, and
seed (single-model Flux). Each stage gets its own scheduler + step count, and Stage 1 /
Stage 3 can take their own SAMPLER (or fall back to the main one).
Inputs
Shared
| Input | Type | Notes |
|-------|------|-------|
| model | MODEL | Your Flux model. |
| latent | LATENT | Empty latent → full generation (Stage 1 runs). Non-empty → img2img-style upscale (Stage 1 skipped). |
| positive / negative | CONDITIONING | Prompt conditioning. |
| vae | VAE | Used for the decode/encode handoffs between stages. |
| sampler | SAMPLER | Main sampler (RES4LYF ClownSampler). Drives Stage 2, and is the fallback for Stages 1 & 3. |
| cfg | FLOAT | Keep 1.0 for guidance-distilled Flux (use a FluxGuidance node on the conditioning instead). |
| seed | INT | Master seed; per-stage seeds are derived deterministically from it. |
Stage 1 — Base generation
| Input | Type | Default |
|-------|------|---------|
| base_steps | INT | 20 |
| base_scheduler | combo | beta57 |
| base_sampler (optional) | SAMPLER | falls back to sampler |
Stage 2 — Progressive locked upscale
| Input | Type | Default | Notes |
|-------|------|---------|-------|
| upscale_factor | FLOAT | 6.0 | Total upscale relative to the input latent. |
| max_step_scale | FLOAT | 1.6 | Max per-stage ratio. Number of stages ≈ ceil(log(factor)/log(max_step_scale)). |
| upscale_steps | INT | 20 | Base schedule length; each stage runs only its tail. |
| upscale_scheduler | combo | beta57 | beta57 / ays_kl / any comfy scheduler. |
| tail_steps_first_upscale | INT | 6 | Tail steps for the first (smallest) upscale → stronger refine. |
| tail_steps_last_upscale | INT | 3 | Tail steps for the last (largest) upscale → lighter touch. |
| upscale_model (optional) | UPSCALE_MODEL | — | Pixel-space upscaler (e.g. RealESRGAN); bicubic if unset. |
Stage 3 — Refine
| Input | Type | Default | Notes |
|-------|------|---------|-------|
| enable_refine | BOOLEAN | True | Off → node returns the upscale result directly. |
| refine_steps | INT | 20 | Schedule length; executed steps depend on refine_enter_sigma. |
| refine_scheduler | combo | beta57 | |
| refine_enter_sigma | FLOAT | 0.60 | Enter the schedule at this sigma. Lower = less denoise = more preservation. Retune for Flux (often higher than the Z-Image default). |
| refine_sampler (optional) | SAMPLER | falls back to sampler |
Outputs
| Output | Type |
|--------|------|
| latent | LATENT |
| image | IMAGE |
| seed | INT |
Example workflow (full generation → finished image)
Load Checkpoint / UNet ─┬─ MODEL ─────────────────────────────┐
└─ VAE ────────────────────────────┐ │
CLIP Text Encode (+) ── CONDITIONING ─(FluxGuidance)─┐ │ │
CLIP Text Encode (−) ── CONDITIONING ────────────┐ │ │ │
EmptyLatentImage (e.g. 144×208) ── LATENT ─────┐ │ │ │ │
RES4LYF ClownSampler ── SAMPLER ────────────┐ │ │ │ │ │
▼ ▼ ▼ ▼ ▼ ▼
Flux: Locked Progressive Upscale 3-Stage
│
├── IMAGE → Save Image
└── LATENT → (optional further work)
- Full generation: feed an empty
EmptyLatentImageat your small base size (e.g. 144×208). Stage 1 generates the base, Stage 2 walks it up byupscale_factor, Stage 3 polishes. The whole image comes out of one node. - Upscale an existing image:
VAE Encodeyour image → feed that LATENT in. Stage 1 is skipped automatically and the node just upscales + refines.
eta, bongmath, SDE noise mode, res_2m/res_3s, etc. are all set on the ClownSampler
node, not here — wire different ClownSamplers into sampler / base_sampler /
refine_sampler if you want different behavior per stage (e.g. eta=0.5 for base/upscale,
a clean eta=0.0 ClownSampler for refine).
Installation
ComfyUI Manager (Git URL)
Manager → Install via Git URL:
https://github.com/lookuters22/ComfyUI-FluxProgressiveLockedUpscale
Manual
cd ComfyUI/custom_nodes
git clone https://github.com/lookuters22/ComfyUI-FluxProgressiveLockedUpscale
Restart ComfyUI. No extra Python dependencies — it only uses what ComfyUI already ships
(torch, comfy internals). A RES4LYF install is recommended so you have a ClownSampler
node to drive it (any SAMPLER works, but RES4LYF is the intended pairing).
Notes & tuning
cfg: leave at1.0for distilled Flux and control guidance via aFluxGuidancenode on the positive conditioning.refine_enter_sigma: Flux flow sigmas differ from Z-Image. Start around0.5–0.8and raise it for a stronger refine, lower it to preserve more of the upscale result.- Stages count: with
upscale_factor=6.0andmax_step_scale=1.6you get ~4 upscale stages, which is why starting from a small base (e.g. ~140×200) is cheap and fast. - Single-model for now: all stages use the same Flux model. Cross-model setups (e.g. Z-Image base + Flux refine) are a planned extension — the pixel-space handoffs are already in place to make that a clean upgrade.
Credits
- Locked-noise / progressive-upscale concept:
ComfyUI-ZImageTurboProgressiveLockedUpscaleby peterkickasspeter-civit. - Sampler engine: RES4LYF by ClownsharkBatwing.
License
MIT
Run ComfyUI workflows without the setup
No installs, no CUDA version roulette, no GPU sitting idle on your bill. Bring a workflow and run it in the browser.