Nodes/ComfyUI Smart Model Loader Nova/Qwen Image 2.1 Scheduler
ComfyUI Node

Qwen Image 2.1 Scheduler

The sigmas your resolution actually needs

By r-vage·Created 23 days ago·Updated 3 days ago· 0
Qwen Image 2.1 Scheduler
  • pipe
  • latent
  • pipe
  • sigmas
◄steps40►
◄denoise1.00►
◄width1024►
◄height1024►
◄base_image_seq_len256►
◄base_shift0.5►
◄max_image_seq_len8192►
◄max_shift0.9►
◄use_dynamic_shiftingtrue►
◄time_shift_typeexponential►
◄shift_terminal0.020►
◄num_train_timesteps1000►
◄shift1.00►

Here's a thing that quietly degrades Qwen Image output at non-square sizes: the model's schedule is supposed to shift depending on how many image tokens you're generating. Load a fixed scheduler, and a 1536×640 image gets the same noise curve as a 1024×1024 one. It mostly works, and it's wrong.

Qwen Image 2.1 Scheduler [SML2] builds the SIGMAS properly - resolution-dependent shifting, terminal stretching, the whole config from the model's own scheduler_config.json - and hands them out as a SIGMAS you can feed to SamplerCustomAdvanced.

How the schedule is built

The normalized inference grid runs from 1 down to 1/steps, then gets shifted, then terminally stretched, then closed with a final zero. The shift is where resolution enters: compute the target latent's image-token count, then interpolate between two anchors -

  • base_image_seq_len (default 256) with base_shift (default 0.5) at the low end,
  • max_image_seq_len (default 8192) with max_shift (default 0.9) at the high end,

with time_shift_type (exponential, which is what Qwen Image 2.1 uses, or linear) shaping the interpolation. Sizes beyond the upper anchor extrapolate rather than clamp. use_dynamic_shifting off means you get a fixed shift (default 1.0) instead of the resolution-aware curve.

shift_terminal (default 0.02) sets the last positive sigma before the final zero, and 0 disables stretching. num_train_timesteps exists because the formula is expressed in training-timestep units - they cancel out in Qwen's normalized inference sigmas, so changing it alone changes nothing. That's stated in the docs because people do try.

Token maths: the Qwen 2.1 target has 64 latent channels and one token per latent spatial position, equivalent to a 16×16 output-pixel area. Reference-image tokens are not counted.

Where the size comes from

Priority order, and it surprises people: a connected target latent wins, then the pipe's latent, then the pipe's width/height, then the node's own width/height widgets (1024×1024). So if you're doing an edit, connect Text Encode Qwen Image 2.1's latent here and the schedule matches your references without you typing a number.

steps (default 40) and denoise are set on this node and they overwrite the corresponding fields in the output pipe. The incoming pipe does not supply them - if you want the loader's values, wire IO Checkpoint Loader's steps and denoise outputs into the matching inputs. Denoise works the way ComfyUI schedulers always do: it keeps the final steps of the longer shifted and stretched schedule for img2img. Denoise 0 returns an empty schedule; a single full-denoise step returns [1, 0] without trying to stretch a nonexistent interval.

Outputs are pipe (contents retained, sigmas added, steps/denoise/width/height updated, input pipe not mutated) and sigmas.

Wiring it

Smart Model Loader PIPE → Qwen Image 2.1 Scheduler PIPE → IO Checkpoint Loader
                                                           └─ sigmas → SamplerCustomAdvanced

CFGGuider takes the IO node's model, SamplerCustomAdvanced takes its latent, and you also supply the guider's positive/negative, a RandomNoise and a KSamplerSelect. The scheduler's direct sigmas output works too, or route it into the IO node's final sigmas input. Standard EmptyLatentImage is supported - its 4-channel placeholder is converted by ComfyUI before sampling, and the scheduler reads the latent's own downscale metadata to keep the size maths honest.

Installing it

ComfyUI Manager → search Smart Model Loader Nova, or:

cd ComfyUI/custom_nodes
git clone https://github.com/r-vage/ComfyUI_SmartModelLoader_Nova.git
cd ComfyUI_SmartModelLoader_Nova
python -m pip install -r requirements.txt

ComfyUI's own Python environment, then restart, then Add Node → 🌒 Smart Model Loader Nova → Sampler. Note what it doesn't need: Diffusers. The schedule is computed inline; you're not pulling another library in for a timestep formula.

Where people get burned

KSampler Pipe ignores these sigmas. It uses its own scheduler selection and won't consume explicit SIGMAS from a pipe. If you built this schedule and then sampled with KSampler Pipe, you got none of it - use SamplerCustomAdvanced, or move the sigmas through IO Checkpoint Loader.

Non-empty image latents must have Qwen's 64 channels. An SDXL-encoded image latent is 4-channel and will be rejected. Empty latents are fine because ComfyUI converts them.

Assuming the loader's steps apply. They don't unless you wire them. A graph where the loader says 20 steps and the scheduler says 40 runs a 40-step schedule, and the pipe afterwards records 40.

Double-shifting. If you use the loader's model-sampling override and this node, shifts get applied twice. The docs are explicit that explicit SIGMAS make the override unnecessary - pick the scheduler path and leave the loader's sampling section off.

Right VAE or no decode. As with any Qwen 2.1 workflow: matching VAE, or the sampling pass finishes and the decode fails.

Category🌒 Smart Model Loader Nova/ Sampler

Inputs (15)

NameTypeDefaultDescription
stepsINT401–10000Sampling steps for this schedule; also written to the output pipe.
denoiseFLOAT1.000–1Keep the final steps of a longer schedule for img2img. 0 disables sampling.
widthINT102416–32768Fallback pixel width. A connected target latent, pipe latent or pipe width wins.
heightINT102416–32768Fallback pixel height. A connected target latent, pipe latent or pipe height wins.
base_image_seq_lenINT2561–4194304—
base_shiftFLOAT0.50–100—
max_image_seq_lenINT81922–4194304Upper shift anchor; larger images extrapolate beyond max_shift.
max_shiftFLOAT0.90–100—
use_dynamic_shiftingBOOLEANtrueCompute the shift from target image tokens and both shift anchors.
time_shift_typeCOMBOexponentialDynamic shift transform. Qwen Image 2.1 uses exponential.
shift_terminalFLOAT0.0200–0.999Last positive sigma before the final zero. 0 disables terminal stretching.
num_train_timestepsINT10001–1000000Training timestep units. They cancel in Qwen's normalized inference SIGMAS.
shiftFLOAT1.000.01–100Fixed multiplicative shift, used only when dynamic shifting is disabled.
pipeoptPIPEOptional loader pipe. Adds SIGMAS while retaining its contents.
latentoptLATENTActual Qwen 2.1 target latent, including from the text encoder. Overrides pipe latent.

Outputs (2)

NameTypeDescription
pipePIPE—
sigmasSIGMAS—