Hangover Sigmas Function
Build your own noise schedule, and the three traps in it
- sigmas
The scheduler dropdown is a black box with 16 names you didn't choose - normal, karras, sgm_uniform, beta, linear_quadratic, and whatever a workflow from Reddit demanded. Hangover Sigmas Function replaces the dropdown with a formula. You pick a curve (or write your own expression in x and p), pick a step count, and get a SIGMAS list you feed straight into a custom sampler.
Is that a good idea? Depends entirely on your model. On SD 1.5 and SDXL checkpoints - including Illustrious/Pony-style anime finetunes, still DDPM-style no matter what year they were merged - reshaping the noise curve is a genuine correction, which is the whole reason "Karras" got glued onto so many sampler names. On flow-matching models the trajectory is already near-straight, so a reshaped curve doesn't correct anything, it distorts: the community's 62-sampler × 16-scheduler sweeps keep finding Karras and exponential-style curves failing across the board there. Same node, opposite verdicts.
How it works
Under the hood it's almost embarrassingly simple, which is good: it builds a linspace, runs a function over it, and rounds every value to five decimals.
Exponential (x^p)-linspace(1.0, 0.0, steps+1) ** p. The label oversells it;x**pis a power curve, not an exponential.p = 1is straight linear.p > 1front-loads the work: you plunge through the high-noise steps fast, then crawl through a long low-sigma tail.p < 1lingers up high and drops hard at the end.Cosine (from 0 to pi/2)- acosarc from 1 to 0. Rounder than linear, gentler in the middle. Note thatpis ignored here; the widget is just along for the ride.Gauss (e^-x^2 from 0 to p)-exp(-x²)sampled from 0 top, sopis the range, not a strength. More below, because this is the trap.Custom function (use x and p)- your expression, evaluated at everyxbetweenx_fromandx_to, withpas a variable. Parsing is sympy, so real expressions work; a typo throws instead of silently doing something odd.
Inputs: function, steps (INT, default 8, minimum 2), p (FLOAT), custom_function (STRING, default x**p), x_from and x_to (FLOAT). Outputs: sigmas (SIGMAS) - wire it into SamplerCustom/SamplerCustomAdvanced, or anything else that eats a SIGMAS, like FlipSigmas or SplitSigmas - and steps (INT), the same number as an integer, so a downstream node that wants a step count can take it from here.
The catch: the sampler walks the list, so the list is the step count. You're getting steps + 1 values, and that's what actually sets how many denoising steps run.
The three traps
- The default Custom expression points the wrong way.
x**pwithx_from = 0andx_to = 1gives you 0 → 1: from no noise to full noise. Sigmas must run high-to-low - either flip the range (x_from = 1,x_to = 0) or write the curve backwards with(1-x)**p. - Gauss with
p = 1never reaches zero. The last sigma isexp(-p²), so at the defaultp = 1your schedule ends at about 0.368, and residual noise stays in the latent. Pushpto about 3.5 or higher and the last value rounds to exactly 0.0; below 3.4 it doesn't. - The built-in curves are baked on a 1 → 0 scale. That matches flow-matching models, but not SD 1.5/SDXL, whose schedules start around 14.6 - hand an SDXL checkpoint a 0–1 schedule and you've described a late refinement, not a generation. Use Custom mode:
p*(1-x)withx_from = 0,x_to = 1,p ≈ 14.6is a plain linear SDXL-scale ramp.
Install
Manager: search ComfyUI_Hangover-Utils, install, restart. Manual:
cd ComfyUI/custom_nodes
git clone https://github.com/Hangover3832/ComfyUI_Hangover-Utils
pip install -r ComfyUI_Hangover-Utils/requirements.txt
That pip line isn't in the README and it isn't optional. This module imports sympy (for custom_function parsing) and matplotlib at the top, and __init__.py imports it unguarded - a missing sympy takes out the whole pack, not just this node. The pack also uses ComfyUI's newer comfy_api.latest node API, so a stale install fails at import. Update first, then debug.
Should you reach for it
For a flow-matching model, treat it as a teaching tool: hand-reshaped curves are mostly where you lose quality there, and the useful knob has moved to the model's timestep shift. For SDXL-family models at low step counts it's worth an afternoon - build x**0.5, plot it, run it, compare against Karras. Pair it with Plot Sigmas from the same pack: plot before you sample, or you're guessing with extra steps.
Inputs (9)
| Name | Type | Default | Description |
|---|---|---|---|
| function | COMBO | 9 options: Exponential {x^p}, Cosine {cos(x), x from 0 to pi/2 }, Gauss {e^-x^2 from 0 to p}, Polynomial regression {least squares fit(points)}, Linear interpolation {points}, Custom function (use x, p and s), +3 | |
| steps | INT | 8 | — |
| p | FLOAT | 0.500 | parameter p |
| scale | FLOAT | 1.000 | scale factor (after clipping) |
| points | STRING | (0.0,1.0), (0.5,0.25), (1.0,0.0) | points in pairs (x0, y0), (x1, y1), ..., where x should range from 0.0 to 1.0, parameter p is availabe |
| custom_function | STRING | 1-(x**p) | parameters x, p and s (scale) are abvailabe |
| x_from | FLOAT | 0.000 | — |
| x_to | FLOAT | 1.000 | — |
| clip | BOOLEAN | true | clip the output between [0..1] |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| sigmas | SIGMAS | — |