ComfyUI Node

Pre CFG perp-neg

Negative prompt fighting your subject? Perp-Neg stops it pulling against you

By Extraltodeus·Created 2 years ago·Updated about a year ago· 66
Pre CFG perp-neg
  • model
  • clip
  • MODEL
neg_scale1.0
set_context_lengthfalse
context_length1
start_at_sigma15.00
end_at_sigma0.00

Negative prompts have a dirty secret: they don't just delete things, they push. When you write "no text, no watermark" the model's unconditional prediction steers the whole image, and part of that push is a component pointing straight against your positive prompt. That's how you get the classic failure - you asked for "a red apple, no green," and the result is a washed-out apple that obeyed the negative more than the positive. Perp-Neg fixes exactly that.

The math is the whole trick, and it's honestly elegant. The node computes an empty-prompt prediction (nocond) as a reference point, then splits both your positive and negative predictions into components: one parallel to the other and one perpendicular. It keeps only the perpendicular part of the negative. Parallel means "fighting my prompt head-on," so it gets discarded; perpendicular means "removing something my prompt doesn't mention," which is what you actually wanted. This is the perp-neg logic from perp-neg.github.io, ported into a pre-CFG node (the author adapted ComfyAnon's implementation).

What you set:

  • neg_scale - how hard to push the perpendicular component. Default 1; raise to 2-3 if the negative isn't biting, but the effect gets aggressive fast.
  • clip - yes, this node needs a CLIP input, not just a model. It encodes an empty prompt at patch time to build the nocond reference, so you have to wire your CLIP in. This is the one pre-CFG node here that demands it.
  • set_context_length / context_length - a TensorRT quirk. If you're on an engine that needs a longer context, flip set_context_length on and raise the length; otherwise leave both alone.
  • start_at_sigma / end_at_sigma - sigma window, defaults spanning the whole SDXL range.

The honest cost: this is a slow node. It adds a third forward pass per step (the empty-cond reference) on top of CFG's two, so your render time jumps by roughly a third to a half. That's the price of the "nocond" reference, and every perp-neg implementation pays it. Worth it when a negative prompt is bleeding into your subject; overkill for simple "remove the watermark" jobs where a plain negative already works.

Where it fits: this is an SD 1.5/SDXL tool. The KB's negative-prompt notes are blunt that guidance-distilled models like Flux Dev/Schnell have no native negative at all - and that on those, perp-neg's whole mechanism has nothing to attach to (this node bails when there's no uncond prediction). The author only tested on SDXL. Use it there, with a real negative prompt, and it does the one thing nobody else in this pack does: stop your negative from fighting your positive.

Install, as with the whole pack:

cd ComfyUI/custom_nodes && git clone https://github.com/Extraltodeus/pre_cfg_comfy_nodes_for_ComfyUI

or ComfyUI Manager → search pre_cfg_comfy_nodes_for_ComfyUI → restart. No dependencies beyond ComfyUI itself, no model files. Start with neg_scale at 1 and a normal CFG 5-7 workflow, and compare a few seeds against your plain negative - the difference is usually most visible exactly where the negative was eating your subject.

Categorymodel_patches/Pre CFG

Inputs (7)

NameTypeDefaultDescription
modelMODEL
clipCLIP
neg_scaleFLOAT1.00–10
set_context_lengthBOOLEANfalse
context_lengthINT11–100
start_at_sigmaFLOAT15.000–1000
end_at_sigmaFLOAT0.000–1000

Outputs (1)

NameTypeDescription
MODELMODEL