Nodes/ComfyUI-DonutNodes/DonutMultiModelSampler (DEPRECATED)
ComfyUI Node

DonutMultiModelSampler (DEPRECATED)

Sample with three models and a CFG that slides

By DonutsDelivery·Created 2 years ago·Updated 3 days ago· 26
DonutMultiModelSampler (DEPRECATED)
  • model_1
  • positive
  • negative
  • latent_image
  • model_2
  • model_3
  • nag_negative
  • latent
  • sampling_info
◄add_noise▾►
◄steps20►
◄cfg_start8.0►
◄cfg_halfway4.0►
◄cfg_end1.0►
◄halfway_step10►
◄sampler_name▾►
◄scheduler▾►
◄noise_seed0►
◄start_at_step0►
◄end_at_step10000►
◄return_with_leftover_noise▾►
◄randomize_seed_per_modelenable►
◄denoise1.00►
◄cfg_curvelinear►
◄switch_at_step_110►
◄switch_at_step_215►
◄nag_enabledfalse►
◄nag_phi4.0►
◄nag_tau2.50►
◄nag_alpha0.25►
◄nag_sigma_start1000.0►
◄nag_sigma_end0.0►
◄nag_auto_phifalse►
◄nag_phi_scale1.00►

Most workflows use one model for the whole denoising run. DonutMultiModelSampler is the "why not three?" node: you hand it up to three MODEL inputs and two switch_at_step values, and it runs phase one on model_1, hands off to model_2 at step 10, and finishes on model_3 at step 15 - all while its CFG value slides along a configurable curve. It's a sampler, a model blender, and a dynamic-CFG controller in one box.

It's DEPRECATED, with a twist worth knowing: it wasn't removed, it was absorbed. The current DonutSampler node has a mode dropdown with multi_model as one of its three modes, and this standalone node is the pinned-multi-model alias kept so old graphs load. If you're building fresh, DonutSampler → mode multi_model is the same engine with the bonus of the other two modes.

How it works

The engine (_DonutSamplerEngine in the pack's DonutKSamplerCFGLinear.py) is what the whole sampler family shares. For multi-model mode, it plans model phases from your switch_at_step_1 / switch_at_step_2 boundaries, computes a CFG value per step from your three-point curve, and patches a DynamicCFGGuider into the sampling loop so each step runs at its own guidance. randomize_seed_per_model (default enable) gives each phase a fresh seed so you're not sampling the same latent three times in a row.

The CFG controls are the three-point setup: cfg_start (default 8), cfg_halfway (default 4 at halfway_step 10), cfg_end (default 1), plus a cfg_curve (20 easing options, linear default). So a typical run ramps guidance down as detail locks in - the opposite of the old "constant CFG 7 the whole way," and closer to how a lot of people now argue sampling should work.

The inputs that matter

  • model_1 (required), model_2, model_3 (optional) with the two switch points.
  • cfg_start / cfg_halfway / cfg_end / halfway_step / cfg_curve - the dynamic guidance.
  • steps, sampler_name, scheduler, denoise - standard sampling kit.
  • positive / negative / latent_image / noise_seed - the usual plumbing.

Outputs: latent (feed a VAE Decode) and sampling_info - a STRING with a per-step CFG chart the pack formats as ASCII. That chart is genuinely useful for debugging, so route it to a text display.

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 caveat

Three-model switching is a real technique for blending, but it's also the fiddliest thing in the sampler family: the handoff points live in latent-space denoising progress, so a bad switch_at_step mid-detail phase produces an abrupt style jump that reads as "the image broke." Start with one model and just use the CFG curve - that's the part most people actually want - and add the second/third models only when you have a concrete blend in mind. And note the sampler/scheduler advice from the KB: your choices must match your architecture; don't carry SDXL habits onto a flow-matching model.

Categorydonut/sampling

Inputs (32)

NameTypeDefaultDescription
model_1MODEL—
add_noiseCOMBO2 options: enable, disable
stepsINT201–10000—
cfg_startFLOAT8.00–100—
cfg_halfwayFLOAT4.00–100—
cfg_endFLOAT1.00–100—
halfway_stepINT101–10000—
sampler_nameCOMBO44 options: euler, euler_cfg_pp, euler_ancestral, euler_ancestral_cfg_pp, heun, heunpp2, +38
schedulerCOMBO9 options: simple, sgm_uniform, karras, exponential, ddim_uniform, beta, +3
positiveCONDITIONING—
negativeCONDITIONING—
latent_imageLATENT—
noise_seedINT00–18446744073709550000—
start_at_stepINT00–10000—
end_at_stepINT100000–10000—
return_with_leftover_noiseCOMBO2 options: disable, enable
randomize_seed_per_modelCOMBOenable2 options: disable, enable
denoiseFLOAT1.000–1—
cfg_curveCOMBOlinear20 options: linear, exponential, logarithmic, ease_in, ease_out, ease_in_out, +14
model_2optMODEL—
model_3optMODEL—
switch_at_step_1optINT101–10000—
switch_at_step_2optINT151–10000—
nag_enabledoptBOOLEANfalseApply Krea2 NAG inside sampling (requires krea2-nag). Uses CFG 1; Turbo negative conditioning stays zeroed.
nag_negativeoptCONDITIONINGUnzeroed 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_phioptFLOAT4.00–20—
nag_tauoptFLOAT2.500.01–20—
nag_alphaoptFLOAT0.250–1—
nag_sigma_startoptFLOAT1000.00–1000—
nag_sigma_endoptFLOAT0.00–1000—
nag_auto_phioptBOOLEANfalseDerive phi from alpha so alpha*phi keeps the upstream default linear guidance strength (0.25*4 = 1.0).
nag_phi_scaleoptFLOAT1.000–4Multiplier for auto phi. 1.0 keeps upstream-default linear guidance strength; higher/lower scales it.

Outputs (2)

NameTypeDescription
latentLATENT—
sampling_infoSTRING—