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 (58)
| 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. Fusion Rebalance/taps are applied to match the positive stream. 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 | — | |
| nag_auto_phiopt | BOOLEAN | false | Derive phi from alpha so alpha*phi keeps the upstream default linear guidance strength (0.25*4 = 1.0). |
| nag_phi_scaleopt | FLOAT | 1.000–4 | Multiplier for auto phi. 1.0 keeps upstream-default linear guidance strength; higher/lower scales it. |
| edit_inpaintopt | DONUT_INPAINT | Selected-area mask and base image from Edit Studio. | |
| sda_enabledopt | BOOLEAN | false | Krea2 Turbo SDA: one uninterrupted run; its reference 2/8 gate scales to the configured step count (12 steps gates the first 3). Supports Euler, ER-SDE and DPM++ 2M, including V4's Bleh preset (ODE) + beta. Preserves preset options and supports Donut hard-swap merges in Experimental bypass. Requires the F16 ComfyUI SDA file; does not auto-download. |
| sda_strengthopt | FLOAT | 1.000–2 | SDA strength; 1.0 is the reference. Zero is an exact SDA-off pass-through. |
| grounding_scheduleopt | COMBO | constant | Preferred wiring: connect Edit Studio's grounding_schedule output so editing settings live in one place. Constant uses Edit Studio's grounding_px directly. Dynamic curves reach start/end over the executed steps in one run, Euler/ER-SDE/DPM++ 2M including Bleh presets. Supports NAG, reference guidance and inpainting; multi-model runs are not yet supported. |
| grounding_start_pxopt | INT | 5120–4096 | First-step semantic grounding resolution cap. Zero means native/unlimited, not disabled grounding; use positive endpoints for a changing schedule. |
| grounding_end_pxopt | INT | 10880–4096 | Last-step semantic grounding resolution. Higher values provide more reference information, not a guaranteed identity-strength multiplier. Distinct resolutions add encoding time and conditioning memory. |
| txtfusion_internal_guardopt | BOOLEAN | false | Legacy sampler-local switch. Now NAG-independent, including alpha 0, editing and SDA. For all connected stages use Models > Txtfusion RMS guard instead. |
| txtfusion_reference_checkpointopt | COMBO | None | Deprecated compatibility field, no file is read. Reference is now captured automatically from the effective checkpoint/merge before adapters, for both native and bypass execution. |
| nag_alpha_scheduleopt | COMBO | constant | Global NAG alpha curve for the base sampler, Donut tiled upscales, and Face Detailer. Each stage spans its own executed steps; constant uses nag_alpha and dynamic curves resolve auto phi per step. |
| nag_alpha_startopt | FLOAT | 0.250–1 | First executed step's NAG alpha across the enabled sampling stages. If auto phi is on, phi is recalculated for this alpha. |
| nag_alpha_endopt | FLOAT | 0.250–1 | Last executed step's NAG alpha across the enabled sampling stages. If auto phi is on, phi is recalculated for this alpha. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| latent | LATENT | — |
| cfg_progression_info | STRING | — |