DonutSampler
A KSampler with a CFG that changes as it denoises
- model
- positive
- negative
- latent_image
- model_2
- model_3
- source_image
- vae
- clip
- edit_model
- source_image_b
- nag_negative
- nag_ref_boost_mask
- edit_inpaint
- latent
- cfg_progression_info
Stock KSampler holds CFG fixed for all N steps. DonutSampler's whole reason to exist is that this is a weird constraint: early steps shape composition, late steps lock detail, and the guidance that's right for one is often wrong for the other. So DonutSampler is a KSampler with a three-point CFG progression - cfg_start → cfg_halfway → cfg_end - swept across the run, with the progression visible in a text output so you can see exactly what each step did. It's the pack's flagship sampling node, and it's the thing most people come to DonutNodes for.
It's also three samplers in one via the mode dropdown:
simple- the default: your CFG curve, the standard inputs, done.advanced- addsadd_noise,noise_seed,start_at_step/end_at_step,return_with_leftover_noise, and honorscfg_curveon the curve itself.multi_model- up to three models with step-based handoff (this is where the old DonutMultiModelSampler went).
Plus two genuinely modern extras: turbo_mode and edit_mode.
The CFG progression
The engine computes a CFG value per step. With a halfway point enabled (when cfg_halfway differs from both ends), it interpolates start→halfway over the first halfway_step, then halfway→end over the rest. One nuance worth knowing: simple mode is piecewise-linear - a straight three-point line, matching the original DonutSampler's behavior. The cfg_curve list (linear, exponential, sine, cosine, smooth_step, circular, and more) is what shapes the descent into a curve, and it only takes effect in advanced and multi_model modes. The cfg_progression_info STRING output prints the per-step CFG chart as ASCII, which is the pack's way of making the black box legible.
The inputs that matter
- cfg_start (default 8) / cfg_halfway (default 4) / halfway_step (default 10) / cfg_end (default 1) / cfg_curve (linear default) - the curve.
- model, seed, steps, sampler_name, scheduler, positive, negative, latent_image, denoise - the standard kit.
The modern extras
turbo_mode (default off) treats your steps as the model's supported Turbo step count and snaps denoise to the nearest valid scheduler point - the pack maintains an exact denoise-point table for the bong_tangent scheduler (user-verified for 8-step Turbo schedules) and interpolates it for other step counts. For distilled/Turbo checkpoints, that's the difference between "works" and "screaming oversaturation," and it automates the manual dance people normally do.
edit_mode is for Krea 2: it uses your supplied latent shape as an empty edit target, with source_image + vae + clip providing clean reference conditioning, and an optional edit_model (a Krea2 model with the Identity Edit LoRA pre-applied, falling back to model). This is advanced territory - you need the Krea 2 edit stack to use it - but it's how this pack does in-graph image editing.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/DonutsDelivery/ComfyUI-DonutNodes.git donutnodes
cd donutnodes
python -m pip install -r requirements.txt
or ComfyUI Manager → "DonutNodes," restart.
The honest advice
For most people, the win is the simple curve: start at a normal CFG and ease down to ~1 by the end - it frees late steps from fighting the prompt, which is where over-baked "AI look" artifacts come from. Don't skip the cfg_progression_info output; reading the chart once tells you more than ten blind runs. And the KB's sampler rule applies double here: this is a scheduler-plus-guider wrapper, so your sampler/scheduler pair still has to match your architecture - on a flow-matching or distilled model, pair it with the conservative schedulers, and if you're on a Turbo checkpoint, flip turbo_mode on before you start blaming the curve.
Inputs (46)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | — | |
| seed | INT | 00–18446744073709550000 | — |
| steps | INT | 201–10000 | — |
| cfg_start | FLOAT | 8.00–100 | — |
| cfg_halfway | FLOAT | 4.00–100 | — |
| cfg_end | FLOAT | 1.00–100 | — |
| halfway_step | INT | 101–10000 | — |
| 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 | |
| positive | CONDITIONING | — | |
| negative | CONDITIONING | — | |
| latent_image | LATENT | — | |
| denoise | FLOAT | 1.000–1 | — |
| modeopt | COMBO | simple | 3 options: simple, advanced, multi_model |
| cfg_curveopt | COMBO | linear | 20 options: linear, exponential, logarithmic, ease_in, ease_out, ease_in_out, +14 |
| add_noiseopt | COMBO | 2 options: enable, disable | |
| start_at_stepopt | INT | 00–10000 | — |
| end_at_stepopt | INT | 100000–10000 | — |
| return_with_leftover_noiseopt | COMBO | 2 options: disable, enable | |
| randomize_seed_per_modelopt | COMBO | enable | 2 options: disable, enable |
| switch_at_step_1opt | INT | 101–10000 | — |
| switch_at_step_2opt | INT | 151–10000 | — |
| model_2opt | MODEL | — | |
| model_3opt | MODEL | — | |
| edit_modeopt | BOOLEAN | false | Krea2 edit with clean reference conditioning. Uses an empty target for whole-image edits, or a masked base target when Edit Studio inpaint is connected. |
| source_imageopt | IMAGE | Required when edit_mode is enabled. | |
| vaeopt | VAE | Required when edit_mode is enabled. | |
| 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_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. |
| source_image_bopt | IMAGE | Optional second edit reference (subject/identity). source_image is the scene/base; both images condition the edit. | |
| 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 | — | |
| edit_inpaintopt | DONUT_INPAINT | Selected-area mask and base image from Edit Studio. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| latent | LATENT | — |
| cfg_progression_info | STRING | — |