Advanced Curved ControlNet Scheduler
The node this whole pack is named after, on steroids
- prev_timestep_kf
- batch_images
- batch_masks
- TIMESTEP_KF
- curve_graph
- curve_stats
ControlNet's single most useful parameter is when it's active - start it at 0 and end it at 0.5 and the condition locks in composition early, then lets the model improvise detail. Most of the ecosystem gives you two fields for that. This node gives you a curve: ControlNet strength that fades, spikes, oscillates, or bell-curves across the whole generation, defined by presets, easing functions, custom math formulas, or even a mouse-drawn shape. It's the flagship of the curved_weight_schedule pack, and the one node the author clearly spent the most time on.
How it works
Underneath, it's a TimestepKeyframe generator for Kosinkadink's ComfyUI-Advanced-ControlNet. The node samples a strength curve across num_keyframes points between start_percent and end_percent, then emits a TIMESTEP_KEYFRAME object that Apply Advanced ControlNet consumes - each keyframe holding the curve's strength at that point in the schedule. Pick a preset (Fade Out, Fade In, Peak Control, Valley Control, Oscillating, and five more) and it fills in the strength and curve shape for you. Pick Custom and you're driving it manually.
The genuinely useful knobs:
preset- nine one-click shapes. If the UI isn't updating fields when you select one, the values still apply internally; the JS extension just makes it visible.mode/total_steps-percent(0–1) orsteps(absolute sampler steps).num_keyframes,start_percent,end_percent- the skeleton of the schedule.start_strength,end_strength,curve_type,curve_param- the manual curve.curve_paramcontrols steepness; higher is more extreme.custom_formula- math withtfrom 0 to 1:t**2,sin(t*3.14),1-exp(-5*t). Whitelisted functions only - no imports, no exec.batch_masks- the temporal-masking hook. Wire a mask batch here and keyframe i carries mask i.blend_curve_type/blend_amount,mirror_curve,repeat_curve,adaptive_keyframes- the curve-modulation toys. Fun, optional.comparison_curve- overlay a second curve on the graph for A/B testing.save_curve/curve_filenamedump the curve to CSV.
Outputs: TIMESTEP_KF (into Apply Advanced ControlNet's timestep_kf), curve_graph (an IMAGE - preview it and you'll see your schedule), and curve_stats (average, min, max, area under the curve as text).
Installing it - read this twice
This pack sits on top of Advanced ControlNet, and the temporal features need the modified fork, not the original:
cd ComfyUI/custom_nodes
git clone https://github.com/diffussy69/comfyui-curved_weight_schedule
git clone https://github.com/diffussy69/ComfyUI-Advanced-ControlNet
cd ComfyUI-Advanced-ControlNet && git checkout per-keyframe-images && cd ..
pip install matplotlib pillow numpy torch scipy
Restart, then hard-refresh (Ctrl+Shift+F5). Skip the fork and non-temporal scheduling still works - but batch_masks silently goes nowhere, which is the pack's headline feature.
Where people get burned
The Could not import TimestepKeyframe error means Advanced ControlNet isn't installed (or wasn't restarted). Keyframes "all starting at 0%" is expected behavior from many schedulers - chain the pack's Redistribute Keyframe Percents node after this to spread them. And honest take: this pack has essentially zero community footprint - nobody's sharing battle-tested workflows, so you're largely on your own tuning it. The graph preview and stats outputs are your allies; check them before you trust a curve. Start with the plain Curved ControlNet Scheduler first if you just want a simple fade - the Advanced version is a toolbox, and you'll only need half of it.
Inputs (26)
| Name | Type | Default | Description |
|---|---|---|---|
| preset | COMBO | Custom | Pre-configured curves (OVERRIDES strength/curve settings below when selected) |
| mode | COMBO | percent | Use percentage (0-1) or absolute steps |
| num_keyframes | INT | 102–100 | Number of keyframes to generate across the timestep range |
| start_percent | FLOAT | 0.0000–1 | Starting point in generation (0.0 = beginning) |
| end_percent | FLOAT | 1.0000–1 | Ending point in generation (1.0 = end) |
| start_strength | FLOAT | 1.000–10 | ControlNet strength at start (ignored if preset selected) |
| end_strength | FLOAT | 0.000–10 | ControlNet strength at end (ignored if preset selected) |
| curve_type | COMBO | Curve shape (ignored if preset selected) | |
| curve_param | FLOAT | 2.00.1–10 | Curve steepness (ignored if preset selected) |
| total_stepsopt | INT | 201–10000 | Total number of sampling steps (only used in 'steps' mode) |
| custom_formulaopt | STRING | t | Custom math formula using 't' (0 to 1). Examples: 'sin(t*3.14)', 't**2', '1-exp(-5*t)' |
| prev_timestep_kfopt | TIMESTEP_KEYFRAME | — | |
| batch_imagesopt | IMAGE | Optional: Batch of preprocessed images. Keyframe i will use image i. | |
| batch_masksopt | MASK | Optional: Batch of masks. Keyframe i will use mask i. | |
| invert_curveopt | BOOLEAN | false | Invert the curve shape |
| mirror_curveopt | BOOLEAN | false | Create symmetrical curve around midpoint |
| repeat_curveopt | INT | 11–10 | Repeat the curve pattern N times |
| adaptive_keyframesopt | BOOLEAN | false | Automatically place more keyframes where curve changes rapidly |
| blend_curve_typeopt | COMBO | none | Second curve to blend with primary curve |
| blend_amountopt | FLOAT | 0.000–1 | How much to blend with second curve (0=primary only, 1=blend only) |
| clamp_strengthsopt | BOOLEAN | true | Clamp strength values to valid range (0-10) |
| print_keyframesopt | BOOLEAN | false | Print generated keyframes for debugging |
| show_graphopt | BOOLEAN | true | Generate visual graph of the curve |
| comparison_curveopt | COMBO | none | Show comparison with another curve type |
| save_curveopt | BOOLEAN | false | Save curve data to CSV file |
| curve_filenameopt | STRING | curve_export | Filename for curve export (without extension) |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| TIMESTEP_KF | TIMESTEP_KEYFRAME | — |
| curve_graph | IMAGE | — |
| curve_stats | STRING | — |