Nodes/TiledUpscale/Tiled Upscale & Refine
ComfyUI Node

Tiled Upscale & Refine

The node that lets FLUX.2 klein go far past its native resolution — without the grid of seams

By GianlucaMancuso·Created about a month ago·Updated about a month ago· 8
Tiled Upscale & Refine
  • model
  • positive
  • negative
  • vae
  • image
  • image
  • info
upscale_by1.00
tile_size1024
overlap192
feather1.00
seed0
steps4
cfg1.0
sampler_nameeuler
schedulersimple
denoise1.00
sequential_contexttrue
color_match
color_match_strength0.80
final_color_matchtrue

FLUX.2 klein does edits like nothing else you can run locally - fast, detailed, the default open editor for most people in 2026. But it natively tops out around 1–2MP, and upscaling a generation doesn't add detail, it adds blur. Tiled Upscale & Refine fixes that: it upscales your image, slices it into overlapping tiles, regenerates each tile at full tile resolution, and blends everything back into one image. The author's own example goes from 1920×1088 to 7968×4512 - 36 megapixels, 15 tiles - with joins you'd have to hunt for. That's the pitch: Klein's detail, arbitrarily beyond Klein's resolution.

It ships in the same pack as Tile Grid Advisor (the size math) and the manual Tile Split / Tile Merge pair - but this is the one you'll actually run.

Why this is different from every other tiled upscale

Old-school tiling - Ultimate SD Upscale, Tiled Diffusion - has a known failure: each tile is generated separately, so every one invents its own lighting, tint and detail, and you see the grid even after blending. That's not a cosmetic bug, it's the default outcome, and it's why people have spent years bolting ControlNet Tile onto tiled upscales.

This node sidesteps the problem with the trick Klein is built for: reference-latent editing. Each tile is encoded to a latent and attached as a reference_latent on the conditioning - the same thing the ReferenceLatent node does - so the model is told "refine this crop," not "invent a tile here." You feed it a plain CLIPTextEncode conditioning and the per-tile reference latent is handled internally. No ReferenceLatent, EmptyLatent or KSampler wiring, no SplitSigmas hacks - the fiddly part is done, and done carefully.

Second trick: sequential_context (on by default). Each tile is cropped from the canvas of tiles already generated, so it continues real neighbouring pixels instead of regenerating that region blind. That's what keeps a face or a line that crosses a tile boundary lining up.

The inputs that matter

Most of the KSampler fields are exactly what they look like. The ones worth your attention:

  • upscale_by - how much to scale the source before tiling (Lanczos). 1.0 = refine at current size.
  • tile_size - the resolution each tile is regenerated at, and the VRAM lever. 1024 is a safe default; the README reports it runs fine at 2048 on that 36MP example.
  • overlap - how much neighbouring tiles share. Wider = smoother joins, more tiles, slower. 192 is a solid start.
  • sequential_context - leave it on; only turn it off if you want every tile regenerated independently.
  • color_match / color_match_strength - per-tile colour matching back to the source crop (mkl by default), which stops tiles drifting apart in exposure or tint - and doubles as the fix for Klein's known warm cast on edits. final_color_match adds one more pass over the finished image.

The sampler defaults - 4 steps, CFG 1, euler, simple - are the Klein-distilled settings, so for a distilled model you can just hit run. Base models want more steps and higher CFG. Outputs are image (the finished upscale) and info - a string listing the grid actually used and each tile's position and real overlap. Worth a glance; that's how you find out your "16 tiles" turned out to be 15.

Installing it

ComfyUI Manager: search ComfyUI-TiledUpscale, install, restart. Or by hand:

cd ComfyUI/custom_nodes
git clone https://github.com/GianlucaMancuso/ComfyUI-TiledUpscale
cd ComfyUI-TiledUpscale
pip install -r requirements.txt   # just "color-matcher"

No model files - it works with whatever model, VAE and conditioning you have, and the example workflow uses only core nodes besides this pack. That one dependency matters: without color-matcher the node doesn't crash, it logs a "colour matching is disabled" warning and silently skips the colour matching - then your tiles drift apart in exposure and you'll think the blending is broken. It isn't. Install the requirement.

Where people get burned

  • Missing color-matcher - see above; the console warning is the tell.
  • Visible seams - the blend fade comes from the real overlap, not the requested one, so a low feather leaves a hard 50/50 band where two tiles fully overlap. Keep feather near 1; widen overlap if joins still show.
  • Grids cutting through a face or hand - each tile is its own generation, and two separately-generated halves have to agree. sequential_context and a wider overlap help a lot.
  • VRAM - tile_size is the knob. If a 1024 tile OOMs on your card, drop it; you pay in tile count, not correctness.

One honest caveat: this is a new pack with almost no community footprint yet - well-documented, lightly battle-tested. If you've been getting moiré-grid flashbacks from old tiled upscales, this is the modern Klein-era answer, and it works.

CategoryTiled Upscale

Inputs (19)

NameTypeDefaultDescription
modelMODEL
positiveCONDITIONING
negativeCONDITIONING
vaeVAE
imageIMAGE
upscale_byFLOAT1.001–8
tile_sizeINT1024256–4096
overlapINT1920–2048
featherFLOAT1.000–1
seedINT00–18446744073709550000
stepsINT41–10000
cfgFLOAT1.00–100
sampler_nameCOMBOeuler44 options: euler, euler_cfg_pp, euler_ancestral, euler_ancestral_cfg_pp, heun, heunpp2, +38
schedulerCOMBOsimple9 options: simple, sgm_uniform, karras, exponential, ddim_uniform, beta, +3
denoiseFLOAT1.000–1
sequential_contextBOOLEANtrue
color_matchCOMBO7 options: mkl, hm, reinhard, mvgd, hm-mvgd-hm, hm-mkl-hm, +1
color_match_strengthFLOAT0.800–1
final_color_matchBOOLEANtrue

Outputs (2)

NameTypeDescription
imageIMAGE
infoSTRING