Coupled Initialization
Stop your 4-image batch from giving you the same idea 4 times
- noise
Queue a batch of four with a fixed prompt and seed and you rarely get four ideas. You get siblings - same composition, same light, a hand moved half an inch. Coupled Initialization exists to fix that: it replaces RandomNoise, rearranges the starting noise across the batch, and pushes the K images apart.
The price tag is the interesting part: the pack's pyproject.toml declares dependencies = [], so a batch of 4 costs what it always cost and you get four more distinct attempts at your prompt.
Why the batch looks so samey, and what coupling does about it
This is a starting-noise problem, not a model problem. At fixed prompt and settings the initial noise is the only thing varying across the batch, and the sampler is a deterministic walk from it - two noise maps that land close together finish as two similar images. Independence doesn't save you: K independent draws are uncorrelated, but they aren't spread out.
So the node forces the batch anti-correlated: any two samples end up with correlation ρ = −strength / (K − 1). At strength 1 and K = 2, ρ = −1 and the pair is literally (ε, −ε) - the second image starts from the negative of the first; for larger K, −1/(K − 1) is the most negative correlation K jointly Gaussian variables can carry without the covariance going non-positive-definite. It's the Monte Carlo antithetic-variates trick, aimed the other way: pair a draw with its mirror and you spread the batch instead of shrinking the variance.
From the shipped source (coupled_initialization/noise.py): every row keeps a standard Gaussian marginal, so this rearranges the batch rather than distorting it. The first row passes through untouched and the rest are rebuilt from row 1 plus the original rows' deviations; half-precision batches are upcast to float32 for the reduction and cast back, so fp16 doesn't cost you precision here.
That untouched first row is the handy part: image #1 is exactly what RandomNoise with the same seed would have produced, so a coupled batch is a known reference plus K − 1 repelled alternatives - and the README's K = 2 number (starting-noise mean squared distance 2.01 → 3.96) is that effect and nothing else.
The two inputs, and the one output
There's not much to set, which is the point.
seed- one seed for the whole batch. The usualcontrol_after_generatedropdown rides along, so set it to fixed before comparing coupled against IID or the box gets overwritten after the run.strength- 0 to 1, step 0.05, default 1.0. 0 is native IID noise, 1 is maximum repulsion, and 0.5 is what I'd reach for if full strength feels like the batch is fighting the prompt. The author marks it advanced in the schema, so if you only see the seed field, look for the advanced toggle.
The output is a single noise (NOISE) - the same object type RandomNoise emits - and it wires into one place: the noise input of SamplerCustomAdvanced.
K, the thing you actually tune, isn't an input. K is the latent's batch size: set EmptyLatentImage to 2 or 3 and start there, because K = 1 has nothing to couple. Plain KSampler makes its own noise internally and can't take this node at all, so this is your excuse to move to the custom-sampling stack (SamplerCustomAdvanced + CFGGuider + KSamplerSelect + BasicScheduler). The pack ships coupled-vs-IID examples in examples/ for SD1.5, SDXL and FLUX.1-schnell.
Installing it
No dependencies, no models to download. From ComfyUI Manager, search "coupled initialization" - or do it by hand, which is what the README documents:
cd ComfyUI/custom_nodes
git clone https://github.com/jjia131/ComfyUI-CoupledInitialization
Restart ComfyUI; it lands under sampling → custom_sampling → noise, and canvas search finds it as coupledInitialization, coupled noise or antithetic. The SD1.5 example wants Comfy-Org's FP16 SD1.5 checkpoint in models/checkpoints.
Where it bites
Nothing changed. Check strength > 0, latent batch size > 1, and that the node actually feeds SamplerCustomAdvanced's noise input rather than a RandomNoise you forgot to delete. And stop judging the batch by image #1.
Video and nested latents are out. The source rejects anything that isn't a strided 4D floating-point image latent shaped [batch, channels, height, width], so 5D Wan/LTX latents don't work in v0.1.
A latent with repeated batch_index values throws - the node can't give each image a distinct base noise, and the error tells you to build a fresh empty latent with batch_size=K.
Changing K changes the coupling. ρ depends on K, so 2 → 3 alters the second image as well as adding a third.
It changes the joint distribution, and it can't outvote your guidance. Sampling to measure rather than to look? Wrong tool. And a very high CFG drags every image back toward the same prompt-saturated answer - an over-constrained prompt lands in the same place however you rearrange the starting noise.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| seed | INT | 00–18446744073709550000 | Seed for the whole gallery. Keep fixed for reproducible comparisons. |
| strength | FLOAT | 1.000–1 | 0: native noise. 1: maximum repulsion. Each image retains a standard Gaussian noise marginal. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| noise | NOISE | — |