Siren (Music Sampler) π§
Siren is the sampler dials ACE-Step actually needs, plus a retake button
- model
- positive
- negative
- latent_audio
- section
- sampler
- sigmas
- latent
- report
- gen_extra_info
- time
- seconds
Siren is the music sampler for ACE-Step latents, and its whole reason to exist is that it knows how ACE-Step's schedule actually behaves. A stock KSampler treats audio like an image and gets it subtly wrong; this node puts the dials that matter on the face - a two-stage schedule, a proper retake mechanism, and honest reporting of the curve - so "generate a song, keep the good take, fix the bad verse" stops being guesswork.
The two-stage schedule
ACE-Step is flow-based, with a heavily top-loaded schedule: with shift 3.0, the halfway step is still at sigma 0.750 - the arrangement is still being decided halfway through. That's why stage_b_steps exists: it carves a number of steps off the tail of the whole steps schedule (50 is the shipped default for acestep_v1.5_xl_base/_sft; the turbo variants want 8), so stage A can run a high cfg while the lyrics and structure are decided, and stage B can run a lower stage_b_cfg (4.5 vs 6.0) while the sound is finished. The boundary has to be late to land in polishing territory - out of 50 steps, 10 puts it at sigma 0.429 and 15 at 0.562. One schedule is built for the whole run, so scheduler applies to every stage; if you want a different shape on the tail, stage_b_scheduler re-builds one over the same length, pins its first sigma to what the latent actually carries (the classic refiner-seam artifact lives exactly there), and forces it monotonic.
cfg on ACE-Step is a trade, not a quality dial: high locks the lyrics and structure but squeezes the sound; low lets the timbre breathe but slurs the words. At exactly 1.0 the unconditional pass is skipped and the negative input stops doing anything at all.
The retake dial
resume_from_sigma is the star. 0 = off, a fresh take. Above 0, it resumes an existing take from that noise level and derives the step count itself - so a retake walks exactly the tail of the native schedule and costs proportionally less. On a 50-step curve at shift 3.0: 0.43 tidies up the performance (10 steps), 0.56 is a noticeably different take (14), 1.00 is completely new (50). Wire a Siren Section latent in and the retake applies to just that stretch of the track. The scale isn't linear in how much survives - the report prints the step it landed on, and the node warns if you point it at an empty latent.
One rule follows from the masked math and the node enforces it: with a section, exactly one stage can run - a masked run has to finish at sigma 0 so the frozen region's reference is the clean latent, so set stage_b_steps to 0 for retakes. And note seed here is the noise seed; the musical idea comes from the audio-codes LLM inside the text encoder (Siren Cast's seed). Hold both fixed when comparing settings, or you're comparing two different tracks.
Inputs and outputs
model, positive, negative, latent_audio (from Empty Ace Step 1.5 Latent Audio, or through a Siren Section), seed, steps, cfg, sampler_name (euler is what every shipped template uses), scheduler (simple), plus eta / s_noise / s_churn / solver_type for the ancestral/SDE crowd. An ancestral sampler on stage A adds variety but its tail noise is audible as hiss - finish on a deterministic stage_b_sampler if you go that way. The optional sampler input takes a Sampler Settings bundle (or a chain, or a recipe from the model library's Settings Select) and replaces the widgets outright while wired - that's how a stored per-model recipe drives this node.
Outputs: latent, report (curve landmarks, per-stage times, section coverage, every warning), gen_extra_info (for Generation Info's extra input), time and seconds (measured around the sampling calls - the honest cost).
Installing it
Part of Kinburg/Kinburg-Nodes - Manager search "Kinburg-Nodes", or git clone https://github.com/Kinburg/Kinburg-Nodes into custom_nodes, restart. No extra pip deps for the sampler itself. The real downloads are ACE-Step 1.5 and the two Qwen text encoders - and for a model that fits on ~4 GB, that's a bargain.
Inputs (23)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | β | |
| positive | CONDITIONING | β | |
| negative | CONDITIONING | β | |
| latent_audio | LATENT | The audio latent to sample. Straight from 'Empty Ace Step 1.5 Latent Audio' for a fresh track, or through a 'Siren Section' node to regenerate only part of an existing take. | |
| seed | INT | 00β18446744073709550000 | Noise seed. NOTE this is NOT the seed that decides the song: the musical idea comes from the audio-codes LLM inside TextEncodeAceStepAudio1.5, which has its OWN seed. Change that one for a different piece; change this one for a different noise draw of the same piece. When comparing settings, hold both fixed β otherwise you're comparing two different tracks. |
| steps | INT | 501β10000 | Length of the WHOLE schedule. 50 is the shipped default for acestep_v1.5_xl_base / _sft; the turbo variants want 8. 'stage_b_steps' is carved out of this number, not added to it β 50 with stage_b_steps 10 means 40 + 10, so you never add the stages up by hand. |
| cfg | FLOAT | 6.00β100 | Guidance for stage A. Shipped defaults: 6.0 for xl_base, 7.0 for xl_sft, and 1.0 for the turbo variants. On AceStep this is a trade, not a quality dial: high cfg locks the lyrics and the structure but squeezes the sound, low cfg lets the timbre breathe but slurs the words. At exactly 1.0 the unconditional pass is skipped entirely, so the negative input stops doing anything at all. |
| sampler_name | COMBO | euler | 'euler' is what every shipped AceStep 1.5 template uses. An ancestral / SDE sampler adds variety, but its extra noise on the tail is audible as hiss β if you want one, put it on stage A and finish on a deterministic sampler via 'stage_b_sampler'. |
| scheduler | COMBO | simple | 'simple' is the shipped default for AceStep 1.5. One schedule is built for the whole run, so this applies to every stage. |
| stage_b_steps | INT | 00β10000 | How many of the 'steps' the SECOND stage takes, off the tail. 0 = a single stage (start here). Two stages exist for one reason: cfg can be high while the lyrics and structure are being decided and lower while the sound is being finished. AceStep's schedule is heavily top-loaded (with shift 3.0 the halfway step is still at sigma 0.750), so the boundary has to be LATE to land in polishing territory β out of 50 steps, 10 puts it at sigma 0.429 and 15 at 0.562. Much earlier and the second stage starts rewriting the arrangement instead. Ignored when a section is marked β see the tooltip on 'resume_from_sigma'. |
| stage_b_cfg | FLOAT | 4.50β100 | Guidance for the second stage. Lower than 'cfg' is the point β try 4.5 against a stage-A 6.0. Ignored when 'stage_b_steps' is 0. |
| resume_from_sigma | FLOAT | 0.0000β1 | 0 = off: start from pure noise, i.e. a fresh take. Above 0: RESUME an existing take from this noise level instead β the whole track, or only the marked stretch when a Siren Section is wired. This is the retake dial, and it replaces fiddling with 'denoise': the step count is derived for you, so the run walks exactly the tail of the native schedule and takes proportionally less time. On a 50-step curve at shift 3.0: 0.43 β tidy up the performance, groove intact (10 steps) 0.51 β same musical idea, different performance (12) 0.56 β noticeably different take (14) 0.71 β almost a new section (22) 1.00 β completely new (50) The scale is not linear in how much survives β the report prints the step it landed on. Needs something to resume FROM: on an empty latent it only weakens the start, which the node warns about. |
| eta | FLOAT | 1.000β100 | Stochasticity for ancestral / SDE samplers. NO effect on 'euler' or other deterministic samplers, which is what AceStep normally runs. |
| s_noise | FLOAT | 1.000β100 | Multiplier on the noise added at stochastic steps. Ancestral / SDE / churn samplers only. |
| s_churn | FLOAT | 0.000β100 | Re-injects noise into otherwise deterministic samplers (euler, heun, dpm_2). 0 = off, which is what the AceStep templates use. |
| solver_type | COMBO | midpoint | Solver variant for the samplers that have one. A value from the wrong family is ignored (noted in the console) rather than breaking the run, so this can't hurt. |
| stage_b_sampler | COMBO | Let the second stage use a different sampler. The useful case: an ancestral sampler on stage A for variety, then a deterministic one here so the tail doesn't come out hissy. | |
| stage_b_scheduler | COMBO | Let the second stage walk a different scheduler's shape over its part of the run β e.g. 'simple' to lay down the structure and 'beta' to spend the tail differently. One curve is still shared, so this can't just be swapped in: the alternate scheduler is rebuilt over the same length, its tail sliced out, and its first sigma PINNED to the level the latent actually carries at the handoff (a mismatch there is what produces classic 'refiner seam' artifacts), then forced monotonic. Same splice Chimera does. The report says when it happened. | |
| stage_b_seed | INT | -1-1β18446744073709550000 | Separate noise seed for the second stage. -1 = use stage A's. It only does something when 'stage_b_sampler' is ancestral or SDE: a continuing stage adds NO fresh noise to the latent, so the seed reaches nothing but the stochastic samplers' own internal noise generator. With euler it is inert. In a RETAKE (a section mask) the rule is different β there only one stage runs anyway, and it draws its own noise from stage A's seed. |
| verbose | BOOLEAN | true | Print the report (curve landmarks, stages, section coverage, warnings) to the console. The same text is always on the 'report' output. |
| sectionopt | KINBURG_SIREN_SECTION | Output of a 'Siren Section' node β informational here (it feeds the report and 'gen_extra_info'). What actually drives the sampling is the mask that node writes into the LATENT, so the input that matters is 'latent_audio'. Wiring this while forgetting the latent is a mistake the node warns about. | |
| sampleropt | KINBURG_SAMPLER_CFG | Optional 'Sampler Settings' bundle (or a chain of them, or a recipe out of the model library's Settings Select / Model Select). While wired it REPLACES this node's own sampling widgets β steps, cfg, samplers, scheduler and the stage split all come from the bundle, and the report says so. Use it to drive Siren from a stored per-model recipe. For everything else the widgets are simpler: they can't disagree with themselves, and they drop the dials that do nothing here ('seed_mode' / 'seed_step' are Ouroboros loop controls, and a later stage's 'denoise' and 'scheduler' are ignored because one schedule is shared). | |
| sigmasopt | SIGMAS | External noise schedule, replacing the one this node builds: 'steps', 'scheduler' and any stage denoise are then ignored, though the stages' step counts still decide how the curve is split between them. 'resume_from_sigma' still applies on top. |
Outputs (5)
| Name | Type | Description |
|---|---|---|
| latent | LATENT | β |
| report | STRING | β |
| gen_extra_info | GEN_INFO | β |
| time | STRING | β |
| seconds | FLOAT | β |