Latent Upscaler
The hi-res fix that doesn't deep-fry your image
- samples
- LATENT
You know that moment in a hi-res fix where the second KSampler pass comes out blocky, checkerboarded, or just wrong - even at a low denoise? That's your upscaled latent lying to the VAE. This node is the fix, from city96 (the same person behind ComfyUI-GGUF and the SD-Latent-Interposer), and it's the only one you'll ever need if you do generation-then-upscale in latent space.
What it actually is
ComfyUI has a built-in LatentUpscale node, and for a lot of people it's fine. But nearest-neighbor or bilinear interpolation of a latent is a hack: latent space is a compressed, roughly-normalized distribution, and when you stretch it and feed it to a VAE decoder that was never trained on stretched latents, you get artifacts. The decoder doesn't know what it's looking at.
LatentUpscaler replaces the dumb interpolation with a tiny convolutional network - the author calls it "an ESRGAN for latents, except severely undertrained." It doesn't add real detail (no model can; the information was never in the latent). What it does is produce a bigger latent that decodes cleanly, so your second pass at low denoise keeps the composition instead of re-cooking it. The README's own example runs the second stage at denoise 0.2 and the image barely changes. That's the whole point.
The inputs that matter
- samples - your LATENT, straight out of the first KSampler.
- latent_ver -
v1orxl. Match it to your checkpoint family: SD 1.5 and 2.x arev1, SDXL isxl. The two families have different latent distributions, and the node pulls separate weights for each. - scale_factor -
1.25,1.5, or2.0. Each factor is a different model, because the upsampling is baked into the network architecture. Want 4x? Chain two nodes.
The single output is a LATENT that feeds straight into the second KSampler. That's it - three knobs, one output. About as beginner-friendly as a custom node gets.
How it works under the hood
Version 2.1 of the network is a head of Conv2d → ReLU → Upsample(nearest) followed by sixteen 3×3 convolution layers with ReLU, then a tail convolution back down to 4 channels (the SD/SDXL latent depth). Trained for a million iterations on DIV2K + Flickr2K with AdamW and an L1 loss. On your first run it pulls the right .safetensors from Hugging Face automatically - latent-upscaler-v2.1_SDxl-x1.5.safetensors, that naming - and caches it in your HF cache, so it's a one-time download of a few tens of MB. It also handles inpainting: if your latent carries a noise_mask, it gets interpolated to match, so masked workflows don't break.
Installing it
Easiest path is ComfyUI Manager - search "SD-Latent-Upscaler" and hit install. Or, if you'd rather be explicit:
cd ComfyUI/custom_nodes
git clone https://github.com/city96/SD-Latent-Upscaler
Then restart ComfyUI. The node depends on huggingface-hub, which a stock ComfyUI install usually already has; if you get an import error, run pip install huggingface-hub in your venv. No other dependencies, no weights to manually fetch.
If you're offline or your connection to HF is flaky, the node checks custom_nodes/SD-Latent-Upscaler/models first - drop the safetensors there (or clone the HF repo into that folder) and it'll use local files instead.
Where people get burned
- SDXL hue shift. The author is upfront about it: "Currently, SDXL has some minimal hue shift issues. Because of course it does." Minor color drift on XL, generally acceptable, still worth knowing before you blame your workflow.
- Wrong
latent_ver. Grab the model meant for the other family and the mismatch silently degrades quality - no error, just a worse image. Set it once and it's hard to get wrong again. - Expecting it to add detail. It won't. This is a middle step in a hi-res fix, not a replacement for ESRGAN or SeedVR2. If you want new detail on an already-final image, that's a different job entirely.
The honest take: the built-in LatentUpscale gets most people 80% of the way, which is why this pack doesn't dominate discussions. If you're happy with your current hi-res fix, don't fix what isn't broken. But if you've ever stared at a checkerboard mess and wondered why the second pass ruined a good image, this is a two-minute install that quietly fixes it forever.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| samples | LATENT | — | |
| latent_ver | COMBO | 2 options: v1, xl | |
| scale_factor | COMBO | 3 options: 1.25, 1.5, 2.0 |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| LATENT | LATENT | — |