ComfyUI Node

PerpCFG

The CFG patch that stops your colors from getting deep-fried

By bvhari·Created 2 years ago·Updated about a year ago· 1
PerpCFG
  • model
  • MODEL

You know the look: you crank CFG past 8 on an SDXL checkpoint to force prompt adherence, and suddenly everything is neon, oversaturated, and one wrong step from burned-out faces. The usual advice is "lower your CFG" - which works, but it also lowers how well the image follows your prompt. PerpCFG is the trick for having both. It's a single node that patches the model's CFG math so you can run higher guidance without the color fry.

What it actually does

Drop it between your checkpoint loader and the KSampler, exactly like a model patch node (ModelSamplingDiscrete or the others of that family). It takes a MODEL in, returns a cloned, patched MODEL out. That's the whole interface - one input, one output, no settings to fiddle. Wire the output into your KSampler's model slot and generate.

How it works

Every CFG step runs two predictions: one toward your prompt (cond) and one toward the empty/unconditioned prompt (uncond). ComfyUI's stock formula is uncond + (cond - uncond) * scale, and the higher the scale, the harder the result is shoved away from the uncond prediction. The problem is that uncond is a duller, less-saturated version of the same image, so pushing away from it amplifies color and contrast along the cond direction. That's your fry.

PerpCFG decomposes the uncond prediction instead: it normalizes cond, splits uncond into the component parallel to cond and the component perpendicular to it, and keeps only the perpendicular part when computing guidance. The parallel part of uncond is exactly what's causing the saturation overshoot, so dropping it gets you the prompt-adherence push without the color blowout. It's the same perpendicular-decomposition idea as Perp-Neg (the CVPR 2024 paper behind ComfyUI's PerpNegGuider), just applied to the denoised latent predictions rather than to text embeddings - a sampler CFG patch instead of a conditioning guider.

What to actually run

The author's own advice is right there in the README: schedule your CFG scale with a cosine schedule. Start guidance high early in denoising when it buys real adherence, then ramp it down so the late steps don't over-cook. That pattern plus PerpCFG is the intended combo - the node removes the saturation cost of the high early values, and the cosine schedule avoids the end-of-generation blowup that high CFG at the tail end causes.

A couple of honest gotchas:

  • It does nothing at CFG 1. ComfyUI skips the unconditioned pass entirely at scale 1 (the disable_cfg1_optimization skip), so there's no uncond prediction left to decompose. This node is strictly for CFG above 1.
  • Skip it on distilled checkpoints. Turbo, Lightning, Z-Image Turbo and friends are designed to run at CFG 1 - guidance is baked into the weights. Bolting PerpCFG onto them is patching a mechanism that isn't running.
  • The effect is subtle. It's a saturation rescue, not a style changer. A/B it on a fixed seed at CFG 9–12 against the stock formula before you declare it a staple.

Install

Zero dependencies beyond torch, which ComfyUI already has. No model files, no requirements.txt drama - this is about as friction-free as a custom node gets. Either grab it in ComfyUI Manager (search "ComfyUI_PerpCFG") or:

cd ComfyUI/custom_nodes
git clone https://github.com/bvhari/ComfyUI_PerpCFG

then restart ComfyUI. Because the patch works on a clone of the model, removing it is just reconnecting the loader to the sampler - no reload needed. If you've been fighting oversaturation on SD 1.5 or SDXL and want to keep your CFG up where the prompt adherence lives, this is the node.

Categoryadvanced/model

Inputs (1)

NameTypeDefaultDescription
modelMODEL

Outputs (1)

NameTypeDescription
MODELMODEL