Donut Tiled Upscale
Tiled img2img that works on any model
- image
- upscale_model
- model
- positive
- negative
- vae
- clip
- edit_model
- edit_source_image
- edit_source_image_b
- color_reference
- nag_negative
- nag_ref_boost_mask
- image
- debug_image
The wall every ComfyUI user hits eventually: your image looks great at 1024×1024, but at 4K the GPU chokes, and the moment you try to denoise a big latent you get CUDA out of memory. The standard escape is tiled upscaling - process the image in overlapping tiles, blend the seams, and never hold the whole thing in VRAM at once. DonutTiledUpscale is that idea, but deliberately model-agnostic: it samples with the same approach as the core KSampler, so it works with SDXL, Z-Image/Lumina2, and the rest of the modern architectures rather than being hard-wired to one UNet layout.
How it works
Two passes, the standard shape for this kind of node:
- Pixel upscale - your
upscale_model(an ESRGAN-style model like 4x-UltraSharp, or whatever you load into an Upscale Model loader) resizes the image, tiled internally with overlap so the upscaler itself doesn't blow memory. - Diffusion refinement - the upscaled canvas is sliced into roughly 1-megapixel tiles, each run through an img2img denoise with your prompt, then stitched back with feathered overlap so seams don't show.
feather(default 15, as a % of tile size) is your seam-blending knob.
That two-stage flow matters. The pixel pass adds the pixels; the diffusion pass adds the detail - this is "more detail" territory, not just "more pixels," so expect the model to gently re-render things. Keep your denoise low (default 0.35) unless you want a rewrite.
Inputs that actually matter
The plumbing is standard: image, upscale_model, model, positive/negative, vae - then sampler settings (seed, steps, cfg, sampler_name, scheduler, denoise) exactly like a KSampler. The Donut-specific ones:
- rescale_factor - the upscale factor (1–8, default 2). The tooltip explains the real behavior: regular mode picks ~1MP tiles; edit mode snaps the target to a 32px grid.
- resampling_method - lanczos (default), bicubic, bilinear, or nearest. Lanczos is the right default.
- feather - seam blend width, regular mode only.
- tiled_vae - use a tiled VAE decode to save even more VRAM (regular mode only).
- tiled_diffusion (optional, default on) - process in overlapping diffusion tiles. Turn it off for one full-resolution diffusion pass; the tooltip is not kidding about needing "substantially more VRAM."
- turbo_mode (optional) - for distilled models (Z-Image Turbo, Lightning): treats your steps as the model's supported Turbo steps and snaps denoise to the nearest valid scheduler point. Use this if your images come out over-sampled on a Turbo model.
Outputs are image and debug_image - the second shows the tile layout, which is genuinely useful the first time seams appear.
The edit mode
There's an optional edit_mode that's a completely different animal: one full-frame Krea2 img2img upscale against a full reference, no diffusion or VAE tiling. It needs clip (required in this mode), an edit_source_image identity reference, edit_prompt/edit_negative_prompt, and optionally edit_model (a Krea2 model with the Identity Edit LoRA pre-applied). If that sentence means nothing to you, ignore the toggle - it's for identity-preserving edits on Krea2 models, and the default off is the sensible place for it.
Install
Ships in ComfyUI-DonutNodes: ComfyUI Manager → search "DonutNodes" → install → restart. Manual:
cd ComfyUI/custom_nodes
git clone https://github.com/DonutsDelivery/ComfyUI-DonutNodes.git donutnodes
cd donutnodes
python -m pip install -r requirements.txt
No model downloads in the pack itself - but the node needs an upscale_model you supply (any ESRGAN-style .safetensors in your upscale_models folder). Dependencies are opencv-python-headless, scipy, matplotlib, psutil, tqdm, requests.
Where people get burned
- Seams or tile-boundary artifacts - raise
feather, and glance atdebug_imageto see your actual grid. - Content drift at high denoise - this is a detail pass, not a free lunch. Denoise above ~0.5 and the model starts re-imagining; below ~0.2 and it does almost nothing. 0.3–0.4 is the honest sweet spot for most models.
- Edit mode with no CLIP - it hard-requires
clipand anedit_source_image; wire them or the mode is a footgun. - VRAM still OOMs - that's
tiled_diffusionoff ortiled_vaeoff. Turn both on for the memory-friendly path.
Compared to the established giants (Ultimate SD Upscale from Impact Pack, Tiled Diffusion), this doesn't reinvent the wheel - its selling point is that it samples like core ComfyUI, so it keeps working as new architectures (Z-Image and friends) arrive. If you're on SDXL and already happy with Ultimate SD Upscale, there's no urgent reason to switch. If you're on a newer model where the old tiling nodes misbehave, this is the one to reach for.
Inputs (40)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| upscale_model | UPSCALE_MODEL | — | |
| model | MODEL | — | |
| positive | CONDITIONING | — | |
| negative | CONDITIONING | — | |
| vae | VAE | — | |
| seed | INT | 00–18446744073709550000 | — |
| steps | INT | 201–10000 | — |
| cfg | FLOAT | 7.000–100 | — |
| sampler_name | COMBO | 44 options: euler, euler_cfg_pp, euler_ancestral, euler_ancestral_cfg_pp, heun, heunpp2, +38 | |
| scheduler | COMBO | 9 options: simple, sgm_uniform, karras, exponential, ddim_uniform, beta, +3 | |
| denoise | FLOAT | 0.350–1 | — |
| rescale_factor | FLOAT | 2.01–8 | Upscale factor. Regular mode selects ~1MP tiles; edit mode snaps the full-frame target to a 32-pixel grid. |
| resampling_method | COMBO | lanczos | 4 options: lanczos, nearest, bilinear, bicubic |
| feather | FLOAT | 150–50 | Regular tiled mode only. Feather/blend zone as percentage of tile size. |
| tiled_vae | BOOLEAN | false | Regular mode only. Edit mode forces one full-frame regular VAE decode. |
| edit_modeopt | BOOLEAN | false | Run one full-frame Krea2 img2img upscale against the full reference at the configured denoise; no diffusion or VAE tiling. |
| clipopt | CLIP | Required when edit_mode is enabled. | |
| edit_modelopt | MODEL | Optional Krea2 model with the Identity Edit LoRA already applied. Falls back to model. | |
| edit_source_imageopt | IMAGE | Full identity reference used for edit-mode source patching and grounded encoding. | |
| edit_promptopt | STRING | — | |
| edit_negative_promptopt | STRING | — | |
| grounding_pxopt | INT | 7680–4096 | — |
| turbo_modeopt | BOOLEAN | false | Treat steps as the model's supported Turbo steps and snap denoise to the nearest valid scheduler point. |
| tiled_diffusionopt | BOOLEAN | true | Process the upscaled canvas in overlapping diffusion tiles. Disable for one full-resolution diffusion pass; this requires substantially more VRAM. |
| edit_source_image_bopt | IMAGE | Optional second edit reference (subject/identity). edit_source_image is the scene/base. | |
| color_referenceopt | IMAGE | Optional color reference. Defaults to the input image. | |
| color_preserve_strengthopt | FLOAT | 0.000–1 | 0 disables preservation; 1 fully matches output RGB mean/std to the reference after sampling and decode. |
| nag_enabledopt | BOOLEAN | false | Apply Krea2 NAG inside sampling (requires krea2-nag). Uses CFG 1; Turbo negative conditioning stays zeroed. |
| nag_negativeopt | CONDITIONING | Unzeroed negative prompt for NAG. Defaults to edit_negative_prompt in edit mode, otherwise negative. | |
| nag_phiopt | FLOAT | 4.00–20 | — |
| nag_tauopt | FLOAT | 2.500.01–20 | — |
| nag_alphaopt | FLOAT | 0.250–1 | — |
| nag_sigma_startopt | FLOAT | 1000.00–1000 | — |
| nag_sigma_endopt | FLOAT | 0.00–1000 | — |
| nag_ref_boostopt | FLOAT | 1.000–1000 | — |
| nag_ref_boost_aopt | FLOAT | 1.000–1000 | — |
| nag_fit_modeopt | COMBO | fit | 2 options: fit, crop (legacy) |
| nag_ref_boost_maskopt | MASK | — | |
| enabledopt | BOOLEAN | true | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |
| debug_image | IMAGE | — |