ComfyUI Node

Tile Test: Upscale

Upscale — The Node That Exists So You Never Pay for the Upscale Twice

By Blakeem·Created 3 months ago·Updated 8 days ago· 28
Tile Test: Upscale
  • image
  • layout
  • upscale_model
  • IMAGE

This is the smallest node in the pack and arguably the smartest design decision in it. Tile Test: Upscale does one thing: it runs the upscale stage that the all-in-one Tile Upscale (VL) node would run, as a node of its own - for no other reason than ComfyUI caches node output.

That sounds like plumbing. It's the difference between a satisfying afternoon and a miserable one. The caption and tag pass in this pack is the expensive part - per-tile vision encodes and text generation - and the upscale pass in front of it isn't free either. Split the upscale into its own node and ComfyUI keeps the upscaled canvas in cache. Change the seed, change the denoise, swap the sampler, re-render a couple of tiles: the canvas doesn't move, and you don't pay for it again.

Why upscale first at all

Most tiled upscalers go the other way: cut the source into tiles and sample each one larger. That's the Ultimate SD Upscale lineage, and it costs two Lanczos resamples per tile - up to the sample size, back down to paste. You lose detail both ways and throw away the compute spent generating those pixels.

Context-Anchored Tile Refine inverts it. Get the image to its final size first, then refine it tile by tile at native resolution, with no resizing anywhere in the loop. The README's own samples were made this way: a two-pass chain, 4x then 2x, denoise 0.35, six tiles to reach 4096×2304 and then 24 tiles to 8192×4608. The pack's author has been blunt about why he stopped using the older approach - it does not re-diffuse the same pixels twice, and the seam handling happens in conditioning rather than in a post-hoc blend.

So the upscale stage is real work. It's just work you'd rather only do once.

What it actually does

Two steps, in order. If an upscale_model is connected - an ESRGAN-family model, a 4x upscaler, whatever you like - it runs over the entire image first. Then a single lanczos pass brings the result to the exact target size the layout asked for. If nothing is connected, the lanczos pass does the whole job alone.

The multiplier isn't a widget here. It comes from the layout.

Inputs

Two required, one optional:

  • image - the same image you gave Tile Test: Layout. Not an upscaled version, not a variant. The same one.
  • layout - the CATR_LAYOUT from Tile Test: Layout. It carries the upscale multiplier, so this node's job is defined entirely by the grid you already solved.
  • upscale_model (optional, UPSCALE_MODEL) - run over the whole image before the resize to the exact target.

One output: an IMAGE at the layout's target size. Wire it into Tile Test: Captions and Tile Test: Render. Both of them check that the canvas matches what the layout was solved for, so there's no ambiguity about which image goes where.

The already-upscaled case

If your input is already at the size you want, you don't need this node in a meaningful sense. Set upscale_by to 1.0 on the Layout node, where target size equals source size, and it becomes a pass-through.

Installing it

Same pack, same install. ComfyUI Manager, search "Context-Anchored Tile Refine". Or:

cd ComfyUI/custom_nodes
git clone https://github.com/Blakeem/ComfyUI-ContextAnchoredTileRefine
cd ComfyUI-ContextAnchoredTileRefine
pip install -r requirements.txt

Then restart. The only Python dependency is logit-classifier>=0.4.0, and the pack wants ComfyUI 0.3.45 or newer. For the full VL chain you'll also need the Krea 2 stack on disk - the diffusion model, the Qwen3-VL text encoder (~8GB) and the Qwen-Image VAE. Upscale models are whatever you already have in ComfyUI/models/upscale_models.

Things that will stop it

Three errors you'll actually see, and all three are the node being reasonable:

"upscales one picture at a time." It refuses a batch. Five images means five queue runs, not one batch - annoying, but it's what keeps the geometry checks honest.

A source size mismatch. The layout was solved for one input shape; feed a different one and it errors rather than produce a grid that doesn't line up.

A target size mismatch after the upscale. If the upscale_model doesn't land on the layout's target after the resize, the node errors instead of letting everything downstream inherit a broken grid. That check is doing you a favour.

One practical note on the caching: it only helps if you don't change the upscale stage. Touch upscale_by or swap the upscale_model and the canvas genuinely is different, so you pay again. Everything else - seed, steps, denoise, tile list - is downstream and free.

Categoryimage/upscaling/tile testing

Inputs (3)

NameTypeDefaultDescription
imageIMAGEThe same image Tile Test: Layout was given.
layoutCATR_LAYOUTThe layout from Tile Test: Layout. It carries the upscale multiplier.
upscale_modeloptUPSCALE_MODELOptional upscale model, run over the entire image before the resize to the exact target.

Outputs (1)

NameTypeDescription
IMAGEIMAGEThe upscaled canvas at the layout's target size. Feed it to Tile Test: Captions and Tile Test: Render.