✨Perpo-GuidanceDIT
S²-Guidance's sharper, orthogonal sibling (with a clamp)
- model
- model
S²-Guidance fixed your prompt adherence but made the image look a little flat? That's the moment to reach for ✨Perpo-GuidanceDIT. It's the same pack, the same stochastic layer-skipping trick, and the same goal - but where S²-Guidance subtracts the broken subnetwork's prediction directly, this one subtracts only the perpendicular part of it. The author (a solo dev, and honest about it: Perpo-Guidance is explicitly "my personal take" on the S² paper, arXiv 2508.12880) calls it Perpo-Guidance, and the result is often sharper fine detail and a different stylistic contrast than the faithful version.
What's different under the hood
Both nodes in this pack work the same way structurally: clone your model, hook the CFG function, randomly skip a percentage of transformer blocks each step, and run a prediction through the crippled subnetwork. The difference is in what happens to that prediction.
Regular S²-Guidance subtracts the raw subnetwork result, scaled, then re-normalizes the energy. Perpo-Guidance gets more mathematical. It flattens both the CFG result and the subnetwork prediction into vectors, works out how much of the subnetwork prediction points in the same direction as the CFG result (the "parallel" component), and removes it. What's left is the orthogonal component - the pure difference that CFG isn't already capturing - and that's what gets subtracted, scaled by perpo_guidance_scale. The idea is that you only push the model in directions it hasn't already committed to, instead of double-counting what CFG already steered.
Then, on top of that, it energy-normalizes to keep colors stable, and optionally clamps the final result to about three standard deviations. That last bit is the apply_clamping switch, and it's the main reason this node has one more input than its sibling.
The inputs
- model (required): your DiT model. Feed the output to your sampler.
- perpo_guidance_scale (Float, default 0.3, range 0–2): the strength of the orthogonal correction. Default is a touch higher than S²'s 0.25; test in 0.1–0.5 first.
- skip_layers_percentage (Int, default 1, 1–100): percentage of layers dropped each step. Single digits are the sweet spot here too.
- apply_clamping (Boolean, default True): clamps the output to roughly 3 standard deviations of its own values, which keeps stray spikes from wrecking a step. Leave it on unless the image starts feeling constrained or washed out - that's the sign to flip it and recompare.
Output: a single patched model. Wire it to your sampler and nowhere else, or you're running plain CFG and wondering why nothing changed.
When to pick Perpo over S²
The README's own guidance: if a model looks flat or desaturated with S²-Guidance, try Perpo-Guidance or lower the scale. The orthogonal subtraction tends to land sharper fine detail and stronger stylistic contrast, and the clamp gives you a bit more protection from runaway values. It's also the one I'd start with on models that were already behaving - the perpendicular trick is more surgical, so it's harder to blow out the image by accident.
Install and gotchas
Same story as the S² node - it ships in the same pack, so one install covers both. Find ComfyUI-S2Guidance in ComfyUI Manager, or:
cd ComfyUI/custom_nodes
git clone https://github.com/orpheus-gaze/ComfyUI-S2Guidance.git
Restart and refresh. No extra pip packages, no model downloads, nothing to configure. The shared caveats apply: this is a DiT-only technique, so if the console prints "Model not supported for Perpo-Guidance" the node passes your model through untouched (SD1.5/SDXL UNets will do this, and that's fine). It's built on the newer comfy_api extension framework, so update ComfyUI if the nodes don't show up. And the extra per-step forward pass roughly doubles sampling time - that's the price of admission for both nodes in the pack.
One thing worth knowing: this pack is young and barely benchmarked in the wild. The technique is real, the paper is solid, but treat Perpo-Guidance as "try it on your own models with a fixed seed and see." Start small, keep skip_layers_percentage in the 1–10 range, and judge over several generations rather than one lucky render.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | — | |
| apply_clamping | BOOLEAN | true | Set True when you want to clamp the final result. This will constrain the final result somewhat. (no clamping=False, clamping=True, default=True) |
| perpo_guidance_scaleopt | FLOAT | 0.300–2 | The strength of the perpo guidance scale. (no effect=0.0, strong effect=2.0, default=0.3) |
| skip_layers_percentageopt | INT | 11–100 | The skip_layers_percentage variable dictates the percentage of how many layers out of the total that should be skipped. (one=1, all=100, default=1) |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| model | MODEL | — |