[cozdx1] Sigmas to Scheduler Func
Getting your hand-built curve into FaceDetailer
- sigmas
- scheduler_func
This node exists because of one annoying wall. You spend an evening dialing in a custom sigma curve in the Dynamic Sigma Scheduler, it fixes the flat look on your Anima or Qwen-Image renders, and then you want the same curve on your face detail pass - and there's nowhere to put it. FaceDetailer takes a scheduler name from a dropdown. That's it.
Sigmas to Scheduler Func is the adapter. It eats a finished SIGMAS tensor, hands back a callable SCHEDULER_FUNC, and you wire that into the detailer's scheduler_func_opt. Same curve, both passes.
What it actually does
Convert is the wrong word - nothing gets computed at graph build time. The node wraps your schedule in a small closure and returns it. When the receiving node runs, it calls that closure with (model, sampler_name, steps) and gets sigmas back. The parameters are ignored on purpose; the curve is the answer regardless of which sampler asks.
The interesting part is the steps mismatch. A detailer almost never wants the exact step count you built the curve at, so the wrapper resamples: a 1-D linear interpolation up or down to exactly steps + 1 values, then it force-writes your original first and last sigma back into position so the endpoints survive untouched. No smoothing, no renormalizing, no clever curve fitting. If the requested count already matches, you get a clone of your schedule unchanged.
That last detail matters more than it looks. The wrapper detaches and copies your sigmas once, and every call returns a fresh tensor, so nobody downstream can mutate your stored curve mid-run.
The input and output that matter
One input, one output. sigmas takes a SIGMAS - from [cozdx1] Dynamic Sigma Scheduler, Concat Sigmas, or honestly any node that emits the type, including core's BasicScheduler. It does validate: it wants a one-dimensional, finite, floating-point tensor with at least two values, and it throws [cozdx1] SIGMAS input must be one-dimensional or similar if you hand it something odd.
scheduler_func (type SCHEDULER_FUNC) is what you connect. Reach for scheduler_func_opt on anything that has it - Impact Pack's FaceDetailer, FaceDetailer (pipe), MaskDetailer (pipe), and the DetailerForEach variants are the ones the author names. Nothing else in the pack is required; Impact Pack is not imported or modified, so this works fine if you never install it.
Installing it
ComfyUI Manager: search ComfyUI-Dynamic-Sigmas in Custom Nodes Manager, install, restart. Manually:
cd ComfyUI/custom_nodes
git clone https://github.com/crom8505/ComfyUI-Dynamic-Sigmas.git
cd ComfyUI-Dynamic-Sigmas
pip install -r requirements.txt
No models, no API key, no downloads. The requirements file is one line - matplotlib, which the preview/graph parts of the pack need; the bridge itself only uses torch. Naming heads-up: the display names are all prefixed [cozdx1] and pyproject.toml lists cozdx1 as publisher, so in the node menu search cozdx1, not the repo name.
Where people get tripped up
The scheduler widget on the detailer stops doing anything. This is the big one, and it's by design. Once scheduler_func_opt is connected, the detailer's scheduler during sampling is your function - the dropdown stays visible in the UI and its value is ignored. Half the confusion around this node is people changing that dropdown, seeing zero difference, and concluding the node is broken. It isn't; that's the feature.
The step count the detailer asks for isn't the one in the widget. Impact Pack requests floor(detailer_steps / denoise) values from the scheduler function, so a 20-step pass at 0.5 denoise comes back asking for 40. Your curve gets linearly stretched to 41 values to answer it. The shape survives, the endpoints survive, but the per-step values in the middle are interpolated, not your authored ones. The README's own advice is to verify the effective denoise range when you replace an established Detailer scheduler - take that seriously, because a curve you tuned at 20 steps is not literally the curve being sampled at 40.
A curve that's wrong for the model family stays wrong. The bridge validates structure, not suitability. An SDXL-style schedule starting at 15.0 fed into a flow-matching detailer is nonsense, and the node will cheerfully pass it through. The pack's profiles are starting points, not auto-detection.
One opinion before you sink an afternoon into this: on SDXL and its finetunes, DPM++ 2M Karras is still correct and a hand-shaped detailer curve buys you very little. The payoff is real on flow-matching models - that's where a reshaped sigma schedule visibly changes output, and it's also where going too aggressive costs you. If you're at that stage, this node is the difference between a great main pass and a main pass that then gets a detail pass with a completely different, worse schedule.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| sigmas | SIGMAS | Sigma schedule to expose as a scheduler function. Its shape and endpoints are preserved when the receiving node requests a different step count. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| scheduler_func | SCHEDULER_FUNC | Connect to scheduler_func_opt. In Impact Pack, this overrides the receiving node's scheduler widget. |