Nodes/ComfyUI-ScheduledGuider-Ext/PerpNegScheduledCFGGuider
ComfyUI Node

PerpNegScheduledCFGGuider

A scheduled CFG curve with a real negative-guardrail

By mfg637·Created 2 years ago·Updated about a year ago· 11
PerpNegScheduledCFGGuider
  • model
  • positive
  • negative
  • unconditional
  • sigmas
  • GUIDER
cfg_max12.0
cfg_min1.0
neg_scale1.00
use_negative_as_unconditionaltrue

If you've read the ScheduledCFGGuider article, this is the "and also" version: same step-by-step CFG curve, plus perpendicular negative guidance bolted on. PerpNeg - short for perpendicular negative - is the negative-prompt technique that doesn't just pull the image away from the negative embedding, it steers it along the component of that push that's perpendicular to the positive direction. The result is a cleaner negative: it suppresses what you listed without dragging your actual subject off-course the way a strong plain negative can.

Where ScheduledCFGGuider needs only positive and unconditional, this node asks for a real negative conditioning too, and it's the only node in the pack that needs one.

How it works

Mechanically it's the same guider as the non-PerpNeg version, with two additions. At each step, after computing the scheduled CFG value off your curve, it runs the perpendicular negative math - the exact perp_neg function ComfyUI already ships in comfy_extras.nodes_perpneg, which is why this pack has no extra dependencies for it. And it runs a third model pass per step to get that negative prediction, so this is the more expensive sibling: roughly 1.5× the cost of a normal two-pass CFG step. You're paying for the guardrail.

The inputs that matter

  • positive, negative, unconditional - three conditionings. unconditional is your empty-prompt baseline; negative is what you want to steer away from.
  • cfg_max (12.0) / cfg_min (1.0) - the guidance range your curve maps onto.
  • neg_scale (1.0) - how hard the perpendicular negative pushes. This is your "how much do I hate blurry" dial. 1.0 is the standard PerpNeg strength; nudge it up only if the negative isn't biting.
  • sigmas - the CFG curve shape, same deal as ScheduledCFGGuider. More points = smoother curve; it doesn't change your step count.
  • use_negative_as_unconditional (True) - if you leave it on, the negative conditioning is handed to any post-CFG hooks in your workflow as the "uncond" slot. Turn it off if your workflow's post-CFG function explicitly expects the empty-prompt uncond there. You'll know when the math starts feeling wrong.

Output is a single GUIDER that plugs into a SamplerCustom node's guider socket.

Install

Same as the rest of the pack. ComfyUI Manager, search ComfyUI-ScheduledGuider-Ext, install, restart. Or:

cd ComfyUI/custom_nodes
git clone https://github.com/mfg637/ComfyUI-ScheduledGuider-Ext

No models, no extra Python packages - the perpneg math is already in ComfyUI core.

Common issues

Naming collision, again: ComfyUI-Inspire-Pack has a ScheduledPerpNegCFGGuider with the same name, and its node-conflict detector flags them against each other. If a workflow you downloaded won't load and the error names this node, check which pack the node actually resolves to. This pack's version is the lean one.

Beyond that, the usual suspects apply: if your CFG curve never seems to do anything, it's too flat (remember, only the shape of the sigmas matters - the guider normalizes it), and if the negative suddenly feels like it's doing nothing, check that you actually wired negative and didn't leave it at the empty-prompt uncond. And don't bother with this node on guidance-distilled models - CFG scheduling and perpendicular negatives both presuppose a real unconditional pass, which those models skip by design.

Categorysampling/custom_sampling/guiders

Inputs (9)

NameTypeDefaultDescription
modelMODEL
positiveCONDITIONING
negativeCONDITIONING
unconditionalCONDITIONING
cfg_maxFLOAT12.00–100
cfg_minFLOAT1.00–100
neg_scaleFLOAT1.000–100
sigmasSIGMAS
use_negative_as_unconditionalBOOLEANtrue

Outputs (1)

NameTypeDescription
GUIDERGUIDER