Nodes/ComfyUI-VariationLab/VariationLab: CFG Explorer
ComfyUI Node

VariationLab: CFG Explorer

Stop guessing CFG — sweep it on a locked seed

By Legorobotdude·Created about a year ago·Updated about a year ago· 1
VariationLab: CFG Explorer
  • model
  • positive
  • negative
  • latent
  • vae
  • images
  • latents
seed0
steps20
cfg_start1.0
cfg_end20.0
cfg_steps5
sampler_nameeuler
schedulernormal
denoise1.00

If you've ever re-rolled the same prompt at CFG 5, 7, 9 and 11 in separate queues and still couldn't tell which one was "better," this node is for you. VariationLab: CFG Explorer (class CFGExplorer) renders a whole batch of images across a CFG range in a single queue item - and it locks the seed, so every variant starts from the same noise and the only thing changing between frames is the number you're actually testing. That fixed-seed design is the entire point. It's the difference between a real comparison and a coin flip dressed up as one.

What it actually does

You wire it up like a KSampler - model, positive and negative conditioning, a latent, a VAE - and give it a CFG range. Internally it builds the range with numpy.linspace(cfg_start, cfg_end, cfg_steps), prepares the noise exactly once from your seed, then runs ComfyUI's core sampling loop once per CFG value and concatenates the decoded frames into a single image batch. Same code path a normal KSampler uses, just looped.

The few inputs you'll actually set:

  • cfg_start / cfg_end - the range, default 1 to 20.
  • cfg_steps - how many points in between (min 2). With defaults that's 1, ~5.75, 10.5, ~15.25 and 20: a spread that mostly teaches you where your model burns. Narrow it to the range you care about.
  • steps, seed, sampler_name, scheduler, denoise - shared by every variant. Lock the seed and forget it.

Outputs are images (an IMAGE batch, one frame per CFG value) and latents (the same batch pre-decode, in case you want to re-decode or feed something else).

Reading the results

Here's where a little grounding helps. On SD 1.5/SDXL-lineage models the sweet spot is roughly 5–9; Pony and Illustrious sit lower at 4–6. Above that you're charting the burn zone - oversaturated, high-contrast, faces coming apart. Two things worth knowing before you judge the output: at CFG 1 the unconditioned pass isn't even computed, so that bookend runs fast but your negative prompt is doing nothing; and if you're testing a guidance-distilled model (any Turbo/Lightning build, Flux), this node is the wrong tool - those want CFG 1 by design and there's nothing to sweep. This is an SD-lineage instrument.

Also: the output is a batch, not a grid. Preview will show you one frame; Save Image writes a separate file per variant. For a side-by-side you'll want a grid or contact-sheet node. ComfyUI's built-in XY Plot can do this too with a nicer grid - this node's advantage is that it's one node, no XY configuration, and the seed handling is automatic.

Install

ComfyUI Manager is the easy path: search ComfyUI-VariationLab, install, restart. Manually:

cd ComfyUI/custom_nodes
git clone https://github.com/Legorobotdude/ComfyUI-VariationLab
# then restart ComfyUI

One trap: the pack's own README literally ships a placeholder clone URL (yourusername/...) that doesn't exist, so don't copy-paste from there - use the repo above or Manager. Nothing else to install: requirements.txt is just numpy and torch, which ComfyUI already has, so no pip installs and no model downloads. You'll find the node under a "VariationLab" category.

Troubleshooting

The most confusing failure mode is built into the node: on any exception it swallows the error and returns a tiny 64×64 black image with the traceback printed to your terminal only. Black tile in the output = read the console. If everything's fine and you just see one image, remember it's a batch - split or grid it. And if your CFG sweep comes back looking uniformly deep-fried, that's not the node breaking; that's real CFG past its ceiling.

CategoryVariationLab

Inputs (13)

NameTypeDefaultDescription
modelMODEL
positiveCONDITIONING
negativeCONDITIONING
latentLATENT
vaeVAE
seedINT00–18446744073709550000
stepsINT201–10000
cfg_startFLOAT1.00–100
cfg_endFLOAT20.00–100
cfg_stepsINT52–50
sampler_nameCOMBOeuler34 options: euler, euler_cfg_pp, euler_ancestral, euler_ancestral_cfg_pp, heun, heunpp2, +28
schedulerCOMBOnormal9 options: normal, karras, exponential, sgm_uniform, simple, ddim_uniform, +3
denoiseFLOAT1.000–1

Outputs (2)

NameTypeDescription
imagesIMAGE
latentsLATENT