From a0d6bf39f7663bf13559822aea3af39a63f7efc0 Mon Sep 17 00:00:00 2001 From: Ethanfel Date: Wed, 4 Mar 2026 18:00:57 +0100 Subject: [PATCH] Fix chattering: boundary layer SMC instead of hard sign() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The hard sign(s) creates a random +/-1 pattern in regions where the guidance error is near zero. When amplified by cond_scale (e.g. 12), this produces severe high-frequency noise artifacts, especially on SDXL which has smaller guidance magnitudes than SD3/FLUX. Replace sign(s) with sat(s/phi) — the standard boundary layer approach in practical sliding mode control. phi adapts to the guidance error std so the switching threshold is meaningful across different models. - |s| >> phi: correction = +/-K (same as paper) - |s| << phi: correction = K*s/phi (smooth, proportional) - Near-zero guidance regions get near-zero correction (no noise) Co-Authored-By: Claude Opus 4.6 --- nodes.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/nodes.py b/nodes.py index df849d5..f6cb69e 100644 --- a/nodes.py +++ b/nodes.py @@ -86,8 +86,14 @@ class SMCCFGCtrl: # Sliding surface: s_t = (e_t - e_{t-1}) + lambda * e_{t-1} s = (guidance_eps - prev_eps) + lam * prev_eps - # Switching control: u_sw = -K * sign(s_t) - u_sw = -K * torch.sign(s) + # Boundary layer SMC: replaces hard sign(s) with sat(s/phi). + # Hard sign() creates random ±1 in regions where |s| is near zero, + # which cond_scale amplifies into visible noise. The boundary layer + # uses a linear transition near zero (standard chattering prevention + # in practical SMC). phi adapts to the guidance magnitude so K stays + # meaningful across models with different guidance scales. + phi = guidance_eps.std().clamp(min=1e-6) + u_sw = -K * (s / phi).clamp(-1.0, 1.0) # Corrected guidance error (in normalized noise space) guidance_eps = guidance_eps + u_sw