NRS
CFG Is a Bad Knob — NRS Replaces It With Three Better Ones
- model
- MODEL
Negative Rejection Steering (NRS) is one node that answers the complaint everyone eventually makes after cranking CFG past 7: the slider is a sledgehammer. It replaces classifier-free guidance's single "scale" number with three knobs - Skew, Stretch, Squash - that steer generation with actual vector math instead of a linear blend. You wire your model through it once, and the CFG box on your KSampler becomes a decoration. The name is honest: the whole trick is steering away from what your negative prompt rejects.
Why it exists
CFG runs two predictions per step - one conditioned on your prompt, one not - and mixes them as uncond + (cond − uncond) × scale. One scalar decides everything. Raise it for prompt adherence and you get burn, oversaturation, fried faces; lower it and the prompt quietly fades. Every architecture has its own sweet spot, and the community has spent years trying to replace the mechanism (CFG++, CFG-Ctrl, S2-Guidance all made the rounds). NRS is the version that actually shipped as a ComfyUI node. It takes that single cond-minus-uncond difference and decomposes it into perpendicular levers, so you stop trading adherence against artifacts on one axis. If negative prompts feel like they're fighting your positive prompt - scenes recomposing oddly, colors drifting - this is the tool that separates "steer away from the bad stuff" from "hold the line on the good stuff."
How it works
NRS is a model patcher. It clones your loaded model and installs a custom CFG function via set_model_sampler_cfg_function, so its math runs inside every sampler step. First it detects your model's prediction type - eps, v, or flow - by walking the object for a type flag. Eps models get converted into v-space for the geometry, then back before returning; flow models (Flux, Wan 2.1) are operated natively, no conversion. Then, per feature across every batch, width, and height position, it does three things:
- Skew pushes the sample away from the component of the uncond vector that's perpendicular to cond (the "rejection") - a lateral turn that changes composition and scene elements.
- Stretch amplifies the difference between cond and uncond's projection onto it - gas toward what the positive prompt likes, brake on what aligns with the negative. This is mostly color and texture.
- Squash rescales the result back toward cond's original length. It's the speed limiter: at 1.0 each step only travels the model's natural distance, at 0.0 it gets the full Skew/Stretch intensity.
The output is a patched MODEL you feed straight into your KSampler.
The knobs that matter
Only three inputs plus the model:
- skew (default 2, range −30 to 30) - the steering knob; start around half your usual CFG. Mainly affects composition.
- stretch (default 5, −30 to 30) - the accelerator; start at your full normal CFG. Mainly affects color and texture.
- squash (default 0.75, 0 to 1) - the limiter. Leave it low initially; it softens the other two and converts lost intensity into micro-detail.
Good starting points from the author: Skew = CFG/2, Stretch = full CFG, Squash = 0. Or skip the math and run the defaults (2/5/0.75), or 1/1/1 for a baseline. Tune one knob at a time on a fixed seed - same rule as CFG.
Install
ComfyUI Manager (search "Negative Rejection Steering") or clone it:
cd ComfyUI/custom_nodes
git clone https://github.com/Reithan/negative_rejection_steering
Then restart ComfyUI. There are no model downloads and no heavy dependencies - it's pure Python on top of torch, and needs Python ≥ 3.10. Same pack also ships a WebUI extension script and a StabilityMatrix-native module if you live in those.
Common issues
- "My CFG slider does nothing." Correct - that's the point. NRS ignores it entirely.
- Verify it's actually active: set CFG to something absurd like 30. If output looks normal, NRS is patching. If it looks "turbo fried," check your node wiring - the model should flow through the NRS node before the KSampler.
- Negative Skew/Stretch values are fine for learning how the model reads your negative - but don't use them if there's something in that negative you genuinely don't want to see. You'll steer straight into it.
- Flow models (Flux, Wan 2.1) got a dedicated operation space in v1.0.0; if you were on an older version, retune your three values.
- Video (MiniMax H3): disable caching accelerators like EasyCache or TeaCache - their thresholded caching skips model evaluations NRS needs, causing stutter. Skip multistep "m" samplers (
res_multistep,dpmpp_2m) since they extrapolate NRS's guidance across steps;euler_ancestralis the recommendation. And yes, NRS adds a second pass per step like CFG does, so expect roughly double the time on video.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | Input model to apply NRS to | |
| skew | FLOAT | 2.00-30–30 | Changes the 'direction' of generation, steering away from negative prompt elements. Start with CFG/2. |
| stretch | FLOAT | 5.00-30–30 | Intensifies positive prompt elements. Start with your normal CFG value. |
| squash | FLOAT | 0.750–1 | Softens Skew/Stretch effects, adding micro-detailing. Keep low initially. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| MODEL | MODEL | — |