π΅ ACE-Step 1.5XL Reference Latent
Attach a reference voice when you already have the latent
- conditioning
- reference_latent
- conditioning
- reference_latent
- negative_conditioning
Reference Latent is the same trick as Reference Audio, but one step earlier in the graph: instead of taking a raw audio clip and encoding it for you, it accepts a latent you've already produced. If you've got a LATENT from Audio to Latent, or from an earlier reference pass, or you're caching encoded samples across runs - this is the node that stamps that voice into your conditioning.
Use it when you want to skip the per-run VAE encode. The classic pattern: encode your voice sample once with ACE-Step 1.5XL Audio to Latent, save it or wire it around, and reuse that latent across many generations with this node. It's the difference between "encode a reference every time" and "encode once, steer forever." It also composes - you can chain a latent that's already been cropped or strength-blended through it, which the audio version can't do as cleanly.
How it works
The logic is identical to Reference Audio's second half, and it's worth knowing because it's the part most people mis-assemble:
- It builds negative_conditioning by zeroing your input conditioning and stripping the
reference_audio_timbre_latentsandaudio_codespayloads. This is the sanctioned way to get a negative; the pack README warns that runningConditioningZeroOutafter the reference can leave the reference payload attached and weaken the effect. - It crops the reference latent using
reference_start_secondsandreference_max_seconds(0 = no crop / whole clip). Ifstartruns past the end, it raises a clear error rather than silently emitting garbage. - It blends the latent toward ACE silence by
reference_strength, then appends it to your conditioning asreference_audio_timbre_latents- the exact key the ACE-Step sampler reads for voice steering.
The inputs and outputs
- conditioning - positive conditioning from Text Encode.
- reference_latent - a
LATENTwith 64 channels (ACE-Step format); get it from Audio to Latent. - reference_strength - 0β1, how hard the reference pushes. 1 is full send; back off if the voice takes over.
- reference_start_seconds / reference_max_seconds - crop the reference region.
Outputs: conditioning (positive β KSampler), reference_latent (cropped/blended copy, handy for previewing what you fed in), and negative_conditioning (β KSampler negative).
Install
ComfyUI Manager ("ComfyUI-ACEStep") or:
cd ComfyUI/custom_nodes
git clone https://github.com/starsFriday/ComfyUI-ACEStep.git
then restart. No pip deps of its own - ComfyUI's built-in ACE-Step support and torchaudio cover it. Models (acestep_v1.5_xl_turbo_bf16.safetensors, a Qwen ACE CLIP, ace_1.5_vae.safetensors) come from the ACE-Step 1.5 repo; this is the XL tier at ~12GB+ VRAM.
Gotchas
The channel-count check is your friend here: this node validates that the reference latent has the 64 channels ACE-Step 1.5 uses, so feeding it a latent from the wrong VAE fails loudly. And remember the reference workflow rules apply exactly as they do for Reference Audio - keep generate_audio_codes off on the text encoder when the reference should lead, and don't zero out conditioning downstream. The subtle one: because this node takes an already-encoded latent, you own the encoding quality. If your Audio to Latent got a noisy or misaligned clip, the reference will faithfully pass that along - garbage in, timbre out.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| conditioning | CONDITIONING | β | |
| reference_latent | LATENT | β | |
| reference_strength | FLOAT | 1.000β1 | β |
| reference_start_seconds | FLOAT | 0.000β10000 | β |
| reference_max_seconds | FLOAT | 0.000β10000 | β |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| conditioning | CONDITIONING | β |
| reference_latent | LATENT | β |
| negative_conditioning | CONDITIONING | β |