CFG Sculptor Advanced
Stop picking a CFG number, draw a curve instead
- noise
- model
- positive
- negative
- sampler
- sigmas
- latent_image
- vae
- Snapshot 1
- Snapshot 2
- Snapshot 3
- Final Image
Every sampler you've ever used treats CFG as one number. You type 7, you get 7, at every step, from pure noise to finished image. CFG Sculptor Advanced makes it a function of the step instead - and it's not a patch sitting in front of a KSampler, it is the sampler. It takes the whole stack, runs the denoise loop itself with a different CFG at each step, decodes with the VAE you hand it, and gives you pixels.
Why you'd reach for it
Because the old hand-tuned trick is annoying to do twice. High CFG early (so the composition actually obeys your prompt) and low CFG at the end (so the last few steps don't deep-fry the image) is a known fix - "not enough steps for too high CFG" is the single most common explanation for images falling apart at the end of a render. Normally you do that with two passes, or by lowering CFG and eating weaker adherence. Here it's one curve, one pass.
It's also a good way to see what CFG does. CFG is one line of arithmetic run every step - uncond + (cond - uncond) * scale. Letting the scale slide instead of holding it flat is close to what the CFG++ samplers do internally: they pick a scale per step from the sigma schedule and step size. This node lets you pick it yourself, and draws you the result.
The thing it will not do is make a guidance-distilled model obey harder. Flux Dev, Z-Image Turbo and Klein distilled have guidance baked into the weights and want CFG 1. Cranking cfg_start to 8 on Z-Image Turbo with a beautiful envelope is still applying the correction twice: slower, and burned above about 3.
The knobs that matter
Most of the schema is the sampler contract (model, positive, negative, sampler, sigmas, noise, latent_image, vae) - the experimental half is text fields you'll actually touch:
cfg_start/cfg_end- default2.0and1.0, which is the whole idea in two numbers: strong start, gentle finish. They're strings, so type a number and don't get clever.preset- ten built-ins; the defaultcustommeans your values win. Start on a preset, then move one field.envelope_mode+use_envelope- the shape of the start→end ramp:linear,sigmoid,gaussian,rise_fall,fall_rise,mid_peak,mid_valley,fibonacci.waveform,wave_amplitude,wave_periods,wave_decay- oscillation riding on top of that ramp: sine, triangle, square, sawtooth, fibonacci, with amplitude, how many periods across the run, and how it decays.hysteresis_enabled+hysteresis_factor(default 1.5) - damps fast swings in the curve. This is the one that makes an aggressive waveform usable; without smoothing, a square wave or a Fibonacci envelope can hand adjacent steps wildly different guidance.snap1_enabled/snap1_step(and 2, 3 - defaults 5, 10, 15) - decodes intermediate latents.node_id_hiddenyou leave alone; it's the frontend's bookkeeping.
Outputs
Four IMAGEs: Snapshot 1, Snapshot 2, Snapshot 3 and Final Image. There's no LATENT out - it decodes for you, which is why vae is a required input - and it isn't an output node, so wire Final Image into Preview Image or Save Image or you'll get nothing. Snapshots are the useful part for tuning: if step 5 is already fried, your start is too high; if only the finish is wrecked, your curve isn't dropping fast enough.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/Rimor-dev/ComfyUI-CFG-Sculptor
# restart ComfyUI
The README's own clone line says Rimor/ComfyUI-CFG-Sculptor - that's a typo in the doc, use Rimor-dev. Or search "ComfyUI-CFG-Sculptor" in ComfyUI Manager. Dependencies are just torch and numpy, and there are no model downloads. It does need a recent ComfyUI with comfy_api support, because the pack is written against the newer backend node API - if you open the source and find no NODE_CLASS_MAPPINGS, that's expected, not broken. The README recommends installing via AKA, a shell manager; ignore that if you already use Manager.
Where people get burned
There's no community thread to fall back on. This is an experimental pack with essentially no footprint in the usual places, so nobody has posted your exact edge case. That makes discipline mandatory: fix your seed, change one widget per run, and compare several generations rather than two. Same seed plus different CFG values produces dramatically different images, so a single-image A/B proves nothing about whether your curve helped.
The live CFG graph is a custom frontend widget. Third-party node widgets are exactly what ComfyUI's Nodes 2.0 canvas rewrite has been breaking across the ecosystem. If the graph doesn't draw or you can't open the node's properties, switch back to the legacy canvas before concluding the pack is faulty.
Snapshots aren't free - each is a full VAE decode at that step. And on flow-matching models, treat the whole curve as an experiment rather than a fix: they like conservative, balanced schedules, and aggressive reshaping is where they fall apart.
Inputs (26)
| Name | Type | Default | Description |
|---|---|---|---|
| noise | NOISE | — | |
| model | MODEL | — | |
| positive | CONDITIONING | — | |
| negative | CONDITIONING | — | |
| sampler | SAMPLER | — | |
| sigmas | SIGMAS | — | |
| latent_image | LATENT | — | |
| vae | VAE | — | |
| node_id_hidden | STRING | 0 | — |
| preset | STRING | custom | — |
| cfg_start | STRING | 2.0 | — |
| cfg_end | STRING | 1.0 | — |
| envelope_mode | STRING | linear | — |
| use_envelope | STRING | true | — |
| waveform | STRING | sine | — |
| wave_amplitude | STRING | 0.3 | — |
| wave_periods | STRING | 2.0 | — |
| wave_decay | STRING | linear | — |
| hysteresis_enabled | STRING | false | — |
| hysteresis_factor | STRING | 1.5 | — |
| snap1_enabled | STRING | false | — |
| snap1_step | STRING | 5 | — |
| snap2_enabled | STRING | false | — |
| snap2_step | STRING | 10 | — |
| snap3_enabled | STRING | false | — |
| snap3_step | STRING | 15 | — |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| Snapshot 1 | IMAGE | — |
| Snapshot 2 | IMAGE | — |
| Snapshot 3 | IMAGE | — |
| Final Image | IMAGE | — |