ComfyUI Node

NaiveCFG++

CFG++ as a model patch — the 'Naive' in NaiveCFG++ is doing real work

By xxiiyu·Created 9 months ago·Updated 9 months ago· 0
NaiveCFG++
  • model
  • MODEL
◄print_debugfalse►

The name is honest. NaiveCFG++ (cfgpp_cui-ggf) is CFG++ done the naive way - not as a sampler, but as a per-step weight schedule patched into your model. If you've poked at ComfyUI's _cfg_pp sampler family (euler_cfg_pp and friends) and wished you could get that behavior on a sampler that doesn't have a native version, this is the node. It's one of two nodes in the cui_generalized_guidance_forms pack, both built from the same "generalized guidance" paper (arXiv 2502.07849).

What it actually does

CFG++ (Chung et al., KAIST, arXiv 2406.08070) is the manifold-constrained take on guidance: instead of scaling up (pos − neg) and renoising from the conditional prediction, it steers from the unconditional prediction. The community's verdict, well established by now: it's built for the sub-1 regime - CFG 1 to 1.5 - and it's the recommendation for v-prediction models like NoobAI vpred. People who try it at CFG 7 on SDXL and declare it broken are using it wrong.

A true _cfg_pp sampler bakes CFG++ into its stepping math. This node takes the other path: it computes an effective CFG scale at every step from the sigma schedule, multiplies that by whatever you set in the KSampler's CFG box, and injects the result through set_model_sampler_cfg_function. It detects your model type - flow-matching/RF models (Flux, SD3, Wan, Qwen-Image) get one schedule, SD-lineage/VE models get another. The CFG box on your sampler stays your main dial; this node just rescales it each step.

The one caveat that matters

It's exactly equivalent to a real euler_cfg_pp only when your sampler is euler. With anything else you're approximating, and the author (xxiiyu, who posts as x11iyu on Reddit) is upfront about why: multistep samplers can't be replicated faithfully, because the history steps would need to become the unconditioned prediction, which a weight schedule can't do. Ancestral _cfg_pp samplers also have access to more accurate step sizes. So the honest workflow is: use euler if you want a drop-in CFG++ replacement, or accept the approximation if you're stuck with another sampler. Relatedly, the author notes that among the native samplers, euler_cfg_pp is the only one properly fixed for flow-matching models - which is exactly the gap this patch fills for everyone else.

Inputs and output

Nothing to fear here, it's a two-widget node:

  • model (MODEL in) - your checkpoint, probably straight from a loader or after a LoRA. Output (MODEL) goes into the KSampler's model socket. That's the whole wiring job.
  • print_debug (BOOLEAN, default false) - prints sigma, the per-step scale, and the effective_cfg to the console at every sampling step. Turn it on once to see the schedule working; it's the best way to confirm the patch is live.

Installing it

Through ComfyUI Manager, search for CUI-GeneralizedGuidanceForms, or manually:

cd ComfyUI/custom_nodes
git clone https://github.com/xxiiyu/cui_generalized_guidance_forms.git

Then restart ComfyUI. The pack has zero pip dependencies and downloads no model files - it's pure Python over ComfyUI's own sampling internals. The one real requirement is a ComfyUI recent enough to have disable_cfg1_optimization support (anything that ships the _cfg_pp samplers, i.e. any modern install). It's GPL-3, so keep that in mind if you vendor it into a big stack.

Gotchas

  • CFG 1 is not half-price here. Normal ComfyUI skips the negative pass at exactly CFG 1. This node disables that optimization, because the negative term no longer cancels out - it needs both predictions. Expect the full two-pass cost.
  • Output differs from euler_cfg_pp on a non-euler sampler? That's the documented behavior, not a bug. Swap to euler before filing an issue.
  • Nothing changes at all? Check the wire: MODEL out → KSampler model in, and make sure the KSampler's CFG isn't pinned to 1 in a way that zeroes the schedule.

If your target is a distilled model, skip this entirely - guidance-distilled checkpoints run at CFG 1 by design and don't want a CFG++ patch bolted on. For everything else, this is the easiest way to taste the CFG++ regime without changing samplers.

Categoryadvanced/guidance

Inputs (2)

NameTypeDefaultDescription
modelMODEL—
print_debugBOOLEANfalsePrint this node's calculations to console at each sampling step.

Outputs (1)

NameTypeDescription
MODELMODEL—