Nodes/FiL_Design_ImageMind/📐 Latent Upscaler Pro
ComfyUI Node

📐 Latent Upscaler Pro

Land your Hires pass on a real grid, not 1824×1248

By FiL-Design-Ai·Created 2 months ago·Updated 2 days ago· 8
📐 Latent Upscaler Pro
  • samples
  • latent
  • width
  • height
modeBy Factor
scale_by1.50
target_width1024
target_height1024
longest_edge1536
upscale_methodbislerp
snap_to64 px (U-Net & DiT Safe)
round_modenearest

The Hires-fix step everyone skips past

Hires fix is two passes: generate small, scale the latent up, sample again at low denoise to let the model put real detail in. The middle step is the boring one, and it's where the damage happens. Core's Latent Upscale does exactly what you ask - multiply the latent by 1.5 and interpolate - and your architecture has opinions about that number.

At 1.5×, an SDXL 1216×832 bucket wants to become 1824×1248. Neither number divides by 64. You get a second pass at a size the model never saw, and the classic symptoms people blame on the upscaler: soft frames, seam lines, faint grid tiling, a border that goes slightly weird. "Divisible by 64" isn't folklore - it's the constraint Flux carries natively and SDXL carries in practice, and it's why "generate at native resolution, then upscale" is the standard advice.

📐 Latent Upscaler Pro does one unglamorous thing about it: it does the arithmetic before it interpolates.

How it works

It reads the latent's current size, works out the pixel dimensions you asked for (current pixels × scale_by in By Factor mode, your numbers in Target Size, aspect ratio preserved toward longest_edge in Longest Edge), then rounds that result to a multiple of your chosen snap_to step - 64 by default, with 32, 16, 8 and Disabled (Exact) available in the source. Only then does it hand the latent to ComfyUI's own common_upscale with your upscale_method.

Two details worth knowing. It assumes the standard 8× spatial compression - one latent pixel is eight image pixels - so a 1856×1280 target decodes from a 232×160 latent, and that's what width/height report. And if your latent arrives with a noise_mask, the mask is rescaled alongside it instead of being silently dropped, which is the difference between a clean masked second pass and a strange square appearing in your inpaint. Video latents (5D, B, C, F, H, W) get folded into the batch, resized, and put back.

Concretely, the same 1216×832 at 1.5×:

python -c "print(1856//8, 1280//8)"   # 232 160 -> the latent tensor you actually get

Inputs and outputs

Nine inputs, but a beginner sets three:

  • mode - By Factor (the usual one), Target Size, Longest Edge.
  • scale_by - 0.05–8.0, default 1.5. The hires sweet spot is 1.5–2× with a second-pass denoise of 0.3–0.5; above 0.5 you're changing the composition, not adding detail.
  • snap_to - 64 px by default (safe for U-Net and DiT alike); 16 px is the author's pick when you want even latents for Flux, 8 px when you want one-latent-pixel granularity. Disabled (Exact) turns the whole feature off.

round_mode is the quiet one: nearest at 1.5× on the example above gives you 1856×1280, down gives 1792×1216, up gives 1856×1280. Pick a direction and stick to it if you want a batch of images that are all the same size.

The outputs are latent, width and height. Wire latent into your second sampler (or a noise-mask node, or VAE Decode). The two INTs are the honest final pixel size - feed them into a filename pattern or a parallel branch rather than recomputing the maths in your head and getting it wrong by four pixels.

Installing it

Both nodes here live in FiL_Design_ImageMind. In ComfyUI Manager, search FiL_Design_ImageMind and install; or:

cd ComfyUI/custom_nodes
git clone https://github.com/FiL-Design-Ai/FiL_Design_ImageMind.git
pip install -r FiL_Design_ImageMind/requirements.txt

Portable builds should use their own interpreter - python_embeded\python.exe -m pip install -r ComfyUI\custom_nodes\FiL_Design_ImageMind\requirements.txt - or just run install_requirements.bat in the pack folder, which finds the right Python for you. Restart ComfyUI; the node is under 🎨 FiL Design/🖼️ Image.

The dependency list is light (requests, aiohttp, PyYAML, Pillow, numpy, pydantic) and this node downloads no models - it works on a latent you already have. One real requirement: ComfyUI 0.3.60 or newer, because the pack is written against the V3 node API. The half of the README about API keys and LLM providers doesn't apply to this node at all.

Where it bites

Target Size squashes. Only Longest Edge preserves aspect ratio. Ask for 1024×1024 with a 16:9 latent in the node and you get a stretched picture, then you blame the sampler. Use By Factor for upscaling; use Target Size only when you genuinely want those exact dimensions.

Nothing appears in the node list. That's almost always ComfyUI being older than 0.3.60 - the pack's nodes register via comfy_api.latest, and an older core simply won't load them. Check the startup console for the import error before you reinstall anything.

The panel is missing but the node runs. The widgets you see are a bundled Vue panel, not native ones; if frontend/dist didn't come down with the clone, the node still executes.

ls ComfyUI/custom_nodes/FiL_Design_ImageMind/frontend/dist | head

You turned snapping off and it got worse. Disabled (Exact) plus bicubic is just core's Latent Upscale with extra steps. Snapping is the product here; leave it at 64 unless you know why you're moving it.

Worth saying plainly: this pack is young and has essentially no forum trail, so the README and the shipped code are your documentation. Read the snap_to tooltip, it's accurate.

Category🎨 FiL Design/🖼️ Image

Inputs (9)

NameTypeDefaultDescription
samplesLATENTInput latent to upscale.
modeCOMBOBy FactorScaling mode: 'By Factor' uses multiplier, 'Target Size' scales to exact dimensions, 'Longest Edge' scales preserving aspect ratio.
scale_byFLOAT1.500.05–8Upscale factor used when mode is 'By Factor'.
target_widthINT102464–8192Target width in pixels (used in 'Target Size' mode).
target_heightINT102464–8192Target height in pixels (used in 'Target Size' mode).
longest_edgeINT1536128–8192Longest edge in pixels (used in 'Longest Edge' mode).
upscale_methodCOMBObislerpInterpolation method for latent tensors. 'bislerp' is standard for diffusion latents.
snap_toCOMBO64 px (U-Net & DiT Safe)Grid snapping rule. 64 px eliminates border artifacts on SD1.5/SDXL and DiT; 16 px guarantees even latents for Flux.
round_modeCOMBOnearestRounding direction when snapping to the grid.

Outputs (3)

NameTypeDescription
latentLATENTResized latent tensor with clean boundary alignment.
widthINTResulting image width in pixels (divisible by chosen snap).
heightINTResulting image height in pixels (divisible by chosen snap).