SUPIR Sampler
Where the actual restoration happens
- SUPIR_model
- latents
- positive
- negative
- latent
This is the node doing the actual diffusion work - everything before it (loading, encoding, conditioning) is setup, and everything after it (decode) is just turning the result back into pixels. If you're trying to understand why your SUPIR output looks a certain way, the knobs that matter are almost all here.
Refreshingly, the author actually wrote a real explanation for most of these parameters directly in the node - which is rare enough in this ecosystem to be worth calling out, and worth reading in full rather than guessing at defaults.
How it works
SUPIR uses a linearly-scaled CFG rather than a flat value: the first sampling step uses cfg_scale_start, the last uses cfg_scale_end, and everything between is interpolated. Set them equal if you want plain constant CFG. control_scale_start/control_scale_end do the same linear interpolation for the strength of SUPIR's custom ControlNet - lower values give the model more freedom to deviate from your input image, which matters if you want it to invent more detail rather than stay literal.
There are two sampler families, chosen via sampler: EDM samplers want more steps but generally give better quality; DPMPP samplers work fine with far fewer steps, which is what you want if you're using a Lightning-distilled SDXL model for speed. Tiled variants of both (TiledRestoreDPMPP2MSampler, TiledRestoreEDMSampler) split the image into tiles during sampling - much slower, but it's how you push past what your VRAM would otherwise allow at high resolution. If you go tiled, use the SUPIR_tiles node first to preview how your image will actually get split before committing to a long run.
Inputs and outputs that matter
Required: SUPIR_model, latents, positive/negative (both from SUPIR_conditioner - these are SUPIR-specific conditioning types, not standard CONDITIONING), seed, steps, the CFG and control-scale start/end pairs above, and sampler.
A few more worth knowing: EDM_s_churn controls how aggressively the EDM sampler adapts to changing noise levels - it does nothing under DPMPP. s_noise controls how much noise gets injected at each step. DPMPP_eta is the DPMPP equivalent of that adaptation control - it does nothing under EDM. restore_cfg governs how strongly the process pulls back toward your original image during diffusion, essentially a fidelity dial. keep_model_loaded trades VRAM for reload speed on repeated runs.
One detail worth reading twice from the node's own description: latents matters less than it looks like it should. If you feed it a plain empty latent (matching your target shape), that's functionally identical to what SUPIR does internally - the shape is what's used, nothing else. Feed it something with actual content instead and no extra noise gets added; it's used as-is.
Optional: sampler_tile_size/sampler_tile_stride, which only do anything with a Tiled sampler selected - tile size should roughly evenly divide your image, stride controls how much tiles overlap.
Output: a single latent, which goes to SUPIR_decode.
How to install it
ComfyUI Manager: search "SUPIR", install, restart. Manually:
cd ComfyUI/custom_nodes
git clone https://github.com/kijai/ComfyUI-SUPIR
pip install -r ComfyUI-SUPIR/requirements.txt
Portable: python_embeded\python.exe -m pip install -r .... Needs a recent-ish PyTorch; xformers optional. This node doesn't load models itself - you need a loader node upstream feeding it SUPIR_model, which means a SUPIR checkpoint and an SDXL checkpoint in ComfyUI/models/checkpoints.
Common issues
Mismatched samplers and tile settings are the most common self-inflicted issue: if you pick a Tiled sampler but never adjust sampler_tile_size/stride to fit your image, tiling can be uneven and produce visible seams. Preview with SUPIR_tiles first.
Steps and sampler choice interact more than people expect - cranking steps on a DPMPP setup mostly just costs time without the quality gain EDM gets from the same increase, because they're built around different step-count assumptions. If you're chasing quality, EDM with a real step count is the more predictable lever; if you're iterating fast on a Lightning SDXL model, DPMPP at low steps is the actual intended use case, not a compromise.
Inputs (18)
| Name | Type | Default | Description |
|---|---|---|---|
| SUPIR_model | SUPIRMODEL | — | |
| latents | LATENT | — | |
| positive | SUPIR_cond_pos | — | |
| negative | SUPIR_cond_neg | — | |
| seed | INT | 1230–18446744073709550000 | — |
| steps | INT | 453–4096 | — |
| cfg_scale_start | FLOAT | 4.000–100 | — |
| cfg_scale_end | FLOAT | 4.000–100 | — |
| EDM_s_churn | INT | 50–40 | — |
| s_noise | FLOAT | 1.0031–1.1 | — |
| DPMPP_eta | FLOAT | 1.000–10 | — |
| control_scale_start | FLOAT | 1.000–10 | — |
| control_scale_end | FLOAT | 1.000–10 | — |
| restore_cfg | FLOAT | -1.00-1–20 | — |
| keep_model_loaded | BOOLEAN | false | — |
| sampler | COMBO | RestoreEDMSampler | 4 options: RestoreDPMPP2MSampler, RestoreEDMSampler, TiledRestoreDPMPP2MSampler, TiledRestoreEDMSampler |
| sampler_tile_sizeopt | INT | 102464–4096 | — |
| sampler_tile_strideopt | INT | 51232–2048 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| latent | LATENT | — |