Audio Ensemble
Average three models and the artefacts mostly cancel
- audio_1
- audio_2
- audio_3
- audio_4
- audio_5
- audio_6
- audio_7
- audio_8
- audio_9
- audio_10
- audio
What it is, and the trick behind it
Ensembling is the oldest quality hack in source separation: run the same input through several models (or the same model with different settings) and combine the results. Each model makes different mistakes, so averaging their errors leaves the part they agree on - the actual signal - standing. It's how UVR's karaoke community has been squeezing the last dB out of their vocal removal for years, and Audio Ensemble is that idea as a node, with pymss's ensemble implementations underneath.
It's also the honest way to answer "which of these two models is better for my track": run both, listen to the average, and compare. And if you feed the same audio in twice with weights 1 and -0.999, you get a difference signal - near silence if they match, which is how you confirm a separation is a true null rather than just sounding clean. (Exactly 1 and -1 is refused: a zero weight sum raises an error, which is why you nudge one of them.)
Inputs
input_count-2to10. This is a live control: the frontend adds and removes the matching audio inputs and weight widgets as you change it, so you only ever see the sockets you're using.ensemble_type- eight algorithms, described below.audio_1…audio_10- the audio inputs (the firstinput_countof them are the live ones). All must be connected; a missing one is a hard error naming the socket.weight_1…weight_10- per-input weights, as strings, defaulting to"1". They're parsed as floats, an empty value counts as 1.0, and anything non-numeric raisesweight_N must be a number.Weights only affect theavg_*algorithms.
Output: a single audio socket.
What the algorithms actually do
From pymss's own ensemble implementation:
avg_wave(default) - weighted average of the waveforms. Weights must not sum to zero - the underlying function raises rather than dividing by zero, so a1/-1pair is rejected and1/-0.999is the way to ask for a difference signal. This is the one you want most of the time, and it's where the weights earn their keep: give the model you trust2and the other1.median_wave- per-sample median across inputs. With three or more sources this is the artefact killer: a glitch that only one model produced gets voted out. Weights are ignored.min_wave/max_wave- per-sample minimum/maximum magnitude. Blunt instruments: they don't blend, they select, so expect a harder sound. Useful as a diagnostic, rarely as a finish.avg_fft,median_fft,min_fft,max_fft- the same operations in the STFT domain (2048-point window, 1024 hop), converted back with an inverse STFT. FFT averaging can be cleaner where models disagree on phase; the min/max FFT variants are the spectral equivalent of the blunt ones above.
Whatever you pick, inputs are aligned first: everything is resampled to the first input's sample rate, then truncated to the shortest length, with the channel and batch counts reduced to the smallest of the set. So mixing a 48kHz stem with a 44.1kHz one works, but you're silently downsampling the higher one, and a slightly different-length stem just loses its tail.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/pymss-project/comfy-mss
python -m pip install pymss # into ComfyUI's Python env
ComfyUI Manager → Comfy-MSS is the same thing with fewer keystrokes. Restart. This node needs torchaudio for resampling, which ships with ComfyUI's standard torch stack; the ensemble maths itself is numpy inside pymss.
Gotchas
- The first input sets the rules. Its sample rate wins and everything else conforms. If you're mixing rates, put your highest-rate source first.
- Unconnected inputs error out loudly -
Missing required audio inputs: audio_2. Setinput_countto what you actually wired. - Weights do nothing for median/min/max. Not a bug; the docs on the underlying function say so explicitly.
- Don't ensemble blind. Averaging a good model with a bad one drags the result toward the middle. Ensembling shines when you're combining models that are each decent and different - a roformer and an MDX23C, say.
- This doesn't create anything. It combines audio you already separated; the separation itself is the expensive part, and you'll be paying for it once per model.
Inputs (22)
| Name | Type | Default | Description |
|---|---|---|---|
| input_count | COMBO | 2 | 9 options: 2, 3, 4, 5, 6, 7, +3 |
| ensemble_type | COMBO | avg_wave | 8 options: avg_wave, median_wave, min_wave, max_wave, avg_fft, median_fft, +2 |
| weight_1 | STRING | 1 | — |
| weight_2 | STRING | 1 | — |
| weight_3 | STRING | 1 | — |
| weight_4 | STRING | 1 | — |
| weight_5 | STRING | 1 | — |
| weight_6 | STRING | 1 | — |
| weight_7 | STRING | 1 | — |
| weight_8 | STRING | 1 | — |
| weight_9 | STRING | 1 | — |
| weight_10 | STRING | 1 | — |
| audio_1opt | AUDIO | — | |
| audio_2opt | AUDIO | — | |
| audio_3opt | AUDIO | — | |
| audio_4opt | AUDIO | — | |
| audio_5opt | AUDIO | — | |
| audio_6opt | AUDIO | — | |
| audio_7opt | AUDIO | — | |
| audio_8opt | AUDIO | — | |
| audio_9opt | AUDIO | — | |
| audio_10opt | AUDIO | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| audio | AUDIO | — |