BSZ Principled Sampler
One sampler that runs base + refiner, and fixes batch seeds while it's at it
- base_model
- base_clip
- latent
- refiner_model
- refiner_clip
- latent
- positive_prompt
- negative_prompt
- steps
- denoise
- cfg
- refiner_amount
- refiner_asc_pos
- refiner_asc_neg
- sampler
- scheduler
- seed
BSZ Principled Sampler is the flagship node of this pack: a whole text-to-image / image-to-image pipeline - prompting, conditioning, base sampling, optional SDXL refiner pass - collapsed into one node. It's opinionated, it's handy, and it does one thing stock ComfyUI genuinely gets wrong: batches are seeded by increment, so batch index 3 of seed 4 is the same image as seed 7. No more "why does my batch look nothing like the seed I picked?"
Why you'd reach for it
You want the whole SDXL base-plus-refiner dance without babysitting five KSamplers, you want your conditioning to auto-fit the latent's resolution, and you want batch results that are actually reproducible. This node gives you all of that in one box. The author's design philosophy (from the pack FAQ) is chained single-stage nodes rather than all-in-one monsters, because that plays nice with ComfyUI's caching - but the sampler itself is deliberately the big convenience node.
It also has real history: when Terminus XL - a v-prediction, zero-terminal-SNR SDXL model - shipped, its author pointed people at Beinsezii's BSZ nodes as the way to run it properly in ComfyUI. Full control over sampling start/end steps and force-full-denoise is exactly what zero-terminal-SNR models need, and this node has it.
Inputs that matter
base_model/base_clip- from your Load Checkpoint.latent- empty latent, or the input image's latent for img2img.positive_prompt/negative_prompt- plain text, no conditioning nodes needed.steps,denoise,cfg- the usual knobs. README recommendation: denoise 0.3 for img2img / pixel scale, 0.6 for latent scale.refiner_model/refiner_clip- optional, and you must supply both or neither. Only one raises an error.refiner_amount- fraction of steps handed to the refiner (default 0.15).refiner_asc_pos/refiner_asc_neg- refiner aesthetic scores; ignored unless your refiner is SDXL-refiner architecture.sampler/scheduler- defaults euler + normal, which the README says are what you want for proper refiner use.
Outputs: the latent, plus echoes of every setting - positive/negative prompt, steps, denoise, cfg, refiner values, sampler, scheduler, seed. That echo list is the point: you can chain this node into a second stage (like BSZ Principled Scale) and pass the exact same settings forward.
How it works
Under the hood it's two common_ksampler calls: a base pass from start_step to base_end (computed from denoise and refiner_amount), then a refiner pass with noise disabled, then it restores the original noise function. The seed-by-increment behavior comes from hot-patching comfy.sample.prepare_noise so each batch slot gets seed + index - and it carefully restores the original function afterward, including on errors.
Install & gotchas
cd ComfyUI/custom_nodes
git clone https://github.com/Beinsezii/bsz-cui-extras
restart, or use ComfyUI Manager. No requirements to install. Two things to watch: it hot-patches a ComfyUI internals function while running, so it's worth keeping ComfyUI reasonably current - and the conditioning it builds internally is resolution-aware (see BSZ Principled Conditioning), so don't feed it a latent whose aspect is wildly off from what your model was trained on. Also note the author's FAQ: they recommend launching ComfyUI with --preview-method latent2rgb so you get live previews of each stage, since this node runs long.
Inputs (16)
| Name | Type | Default | Description |
|---|---|---|---|
| base_model | MODEL | — | |
| base_clip | CLIP | — | |
| latent | LATENT | — | |
| positive_prompt | STRING | analogue photograph of a kitten | — |
| negative_prompt | STRING | blurry, cropped, text | — |
| steps | INT | 300–10000 | — |
| denoise | FLOAT | 1.000–1 | — |
| cfg | FLOAT | 8.000–100 | — |
| refiner_amount | FLOAT | 0.150–1 | — |
| refiner_asc_pos | FLOAT | 6.000–1000 | — |
| refiner_asc_neg | FLOAT | 2.500–1000 | — |
| sampler | COMBO | euler | 34 options: euler, euler_cfg_pp, euler_ancestral, euler_ancestral_cfg_pp, heun, heunpp2, +28 |
| scheduler | COMBO | 9 options: normal, karras, exponential, sgm_uniform, simple, ddim_uniform, +3 | |
| seed | INT | 00–18446744073709550000 | — |
| refiner_modelopt | MODEL | — | |
| refiner_clipopt | CLIP | — |
Outputs (12)
| Name | Type | Description |
|---|---|---|
| latent | LATENT | — |
| positive_prompt | STRING | — |
| negative_prompt | STRING | — |
| steps | INT | — |
| denoise | FLOAT | — |
| cfg | FLOAT | — |
| refiner_amount | FLOAT | — |
| refiner_asc_pos | FLOAT | — |
| refiner_asc_neg | FLOAT | — |
| sampler | euler,euler_cfg_pp,euler_ancestral,euler_ancestral_cfg_pp,heun,heunpp2,dpm_2,dpm_2_ancestral,lms,dpm_fast,dpm_adaptive,dpmpp_2s_ancestral,dpmpp_2s_ancestral_cfg_pp,dpmpp_sde,dpmpp_sde_gpu,dpmpp_2m,dpmpp_2m_cfg_pp,dpmpp_2m_sde,dpmpp_2m_sde_gpu,dpmpp_3m_sde,dpmpp_3m_sde_gpu,ddpm,lcm,ipndm,ipndm_v,deis,res_multistep,res_multistep_cfg_pp,res_multistep_ancestral,res_multistep_ancestral_cfg_pp,gradient_estimation,ddim,uni_pc,uni_pc_bh2 | — |
| scheduler | normal,karras,exponential,sgm_uniform,simple,ddim_uniform,beta,linear_quadratic,kl_optimal | — |
| seed | INT | — |