Nodes/Asymmetric Quantization Sampler/Dual Model KSampler (Step Switch)
ComfyUI Node

Dual Model KSampler (Step Switch)

Skip precision on the denoising steps that don't need it

By lee09lee26·Created 5 months ago·Updated 5 months ago· 1
Dual Model KSampler (Step Switch)
  • model_a
  • model_b
  • positive
  • negative
  • latent_image
  • latent
  • info
seed42
steps20
cfg1.0
sampler_name
scheduler
switch_step5
denoise1.00
switch_end0

This is the node behind the claim that keeps showing up in your feed: the first few denoising steps of a flow-matching model don't care about precision, so you can run them on a tiny Q2_K GGUF and then switch to a quality model for the rest - and end up with an image that matches full-precision output. It's a real research claim (2,000 images, 8 quantization levels, on FLUX.1-dev), not a vibe, and the author shipped a node so you can test it yourself. The name is a slight lie, by the way: nothing here is quantized. You bring two already-quantized GGUF checkpoints; this node just switches between them mid-schedule.

Here's the mechanism. DualModelKSampler is a normal KSampler with a model_a and a model_b input. It runs the first switch_step steps through model_a, then hands the latent to model_b for the rest, using ComfyUI's start_step/last_step to partition the noise schedule and passing disable_noise=True on the second phase so the sampling continues instead of re-noising. The latent never touches the VAE, so the swap is invisible to your conditioning - it's pure sampler-level surgery. Set switch_end to anything greater than switch_step and it becomes a 3-phase sandwich (A → B → A), which the paper uses to test whether late steps want precision back. The info STRING output tells you exactly what ran, e.g. 2-Phase: A(1-3) -> B(4-20).

The inputs that matter are only three. model_a and model_b are two GGUF checkpoints of the same model at different quants - on FLUX that means flux1-dev-Q2_K.gguf and flux1-dev-Q5_1.gguf, loaded through city96's ComfyUI-GGUF, plus your CLIP text encoder and VAE as usual. Then switch_step, which defaults to 5. Everything else (seed, cfg, sampler_name, scheduler, denoise) behaves exactly like the stock KSampler. Outputs: latent (wire it to VAE Decode) and info.

The author's recommended configs, straight from the README: Q2_K → Q5_1 at switch_step=3 for best quality/efficiency, Q4_0 → Q5_1 at 5 as the "minimal risk" conservative pick, and Q2_K → Q4_1 at 3 if you're chasing maximum savings. For FLUX, cfg=1.0, steps=20, Euler - and don't grab Karras for the scheduler; the flow-matching community has been telling people that for a while and it applies here too.

Now the part the author himself is honest about, which is more than most node READMEs give you. In the launch thread he admits the current implementation is a net slowdown for small switch points: swapping models costs roughly 7 seconds on an RTX 4070, and that eats any speed gain from running a lighter model on three steps. The value right now is the finding - you can verify with your own eyes that early steps are quantization-robust - not your render time. Peak VRAM is also set by the bigger model, since it has to be resident by step k. And it's only been validated on FLUX.1-dev; other flow-matching models may have a different robust zone. One commenter on the launch post also flagged that single-subject test images flatter the trick - complex multi-subject compositions are where a sloppy first three steps might actually cost you.

Install is refreshingly boring: ComfyUI Manager → search "Asymmetric Quantization Sampler", or:

cd ComfyUI/custom_nodes/
git clone https://github.com/lee09lee26/ComfyUI-AsymQuantSampler.git

Then restart ComfyUI. There are zero pip dependencies - the requirements file is empty, it runs on ComfyUI's built-ins, which puts it in a minority of custom nodes. You still need ComfyUI-GGUF installed to load the .gguf files in the first place. It's a small, recent, research-grade pack (one star, two forks, paper PDF included), so treat it as an experiment rig rather than a daily-driver optimization. But it's a genuinely interesting one.

Categorysampling/custom

Inputs (13)

NameTypeDefaultDescription
model_aMODEL
model_bMODEL
positiveCONDITIONING
negativeCONDITIONING
latent_imageLATENT
seedINT420–18446744073709550000
stepsINT201–200
cfgFLOAT1.00–100
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
switch_stepINT51–199Phase1->Phase2 switch step
denoiseFLOAT1.000–1
switch_endoptINT00–1990=2-phase, >0=3-phase sandwich

Outputs (2)

NameTypeDescription
latentLATENT
infoSTRING