
Stems · 8 October 2026 · 11 min
Demucs vs MDX-Net: what each separator gets wrong, and why
Demucs and MDX-Net each fail in their own way. In the published 2021 Music Demixing Challenge numbers, Hybrid Demucs led on drums and bass, and KUIELab-MDX-Net led on vocals and the catch-all “other” stem. The reason is representation. A model that thinks in long spectrogram windows resolves pitch beautifully and smears attacks. A model that thinks in waveforms keeps the hit and fights with sustained harmony. Choose by the stem you need, and judge the result with your ears and a null test, not with a single score.
Every forum thread on this question ends the same way. Someone posts “Demucs for drums, MDX for vocals,” someone else says the opposite, and nobody shows their work. The truth is more interesting than a tier list. These two families are two answers to one hard trade-off, and once you can hear that trade-off, you can choose a model per stem instead of picking a team.
Two families, and how they blurred
The original Demucs from Meta’s research team was a waveform model. It was a U-Net that took raw samples in and put raw samples out, with a recurrent layer in the middle for longer context. Spectrogram models came at the problem from the other side. They look at a time-frequency picture of the mix and predict how much of each tile belongs to each source.
That neat split didn’t last. Hybrid Demucs (Défossez, 2021) runs a waveform branch and a spectrogram branch side by side, shares a core between them, and sums their outputs. The paper reports that it won the Sony-organized Music Demixing Challenge 2021. Hybrid Transformer Demucs (Rouard, Massa and Défossez, 2022), the “htdemucs” you see in most tools today, swaps the innermost layers for a cross-domain Transformer. With extra training data and per-source fine-tuning it reached 9.0 dB SDR on MUSDB HQ, and 9.2 dB with sparse attention.
KUIELab-MDX-Net (Kim, Choi and colleagues), the model behind the “MDX” name, was blended from the start. It uses four spectrogram U-Nets, one per source, plus a small mixer network, and blends the result with a pretrained Demucs for the time-domain side. Per the authors, it placed second on leaderboard A and third on leaderboard B of the same challenge. So “Demucs versus MDX” really means “a waveform-first hybrid versus a spectrogram-first blend.”
What the published numbers say
Here are the MDX 2021 hidden-test results for Track A (MUSDB-only training), as reported in the Hybrid Demucs paper. The scores are in the challenge’s SDR, higher is better:
| Model (MDX 2021, Track A) | Overall | Drums | Bass | Other | Vocals |
|---|---|---|---|---|---|
| Hybrid Demucs | 7.33 | 8.04 | 8.12 | 5.19 | 7.97 |
| KUIELab-MDX-Net | 7.24 | 7.17 | 7.23 | 5.63 | 8.90 |
Almost a dB apart on drums and bass, almost a dB the other way on vocals, and nearly tied overall. The same paper ran a listening test on MUSDB. Listeners rated KUIELab-MDX-Net best for vocal quality, and rated Hybrid Demucs much better for low bleed across sources. Défossez also names each family’s signature flaw plainly: phase inconsistency in spectrogram methods can make attacks sound hollow, and waveform Demucs vocals can carry a crunchy static.
That’s the whole forum argument, settled by the people who built the models. The rest of this essay is about why it happens, and how to check it on your own material.
The trade-off you can run
Any time-frequency method has to choose a window. Long windows separate close pitches, like a 48 Hz kick tail and a 55 Hz bass note, but they spread each event across their whole length. Short windows pin events in time but blur pitch. MDX-Net leans into this openly: the paper lists a different FFT size per source, 6144 for vocals, 4096 for drums, 16384 for bass and 8192 for other.
To isolate the effect of the window from any model’s mistakes, this script uses oracle masks. They’re built from the true stems of a synthetic mix, so they’re the best a mask can ever do at each window size. It also measures kick pre-echo, the energy that leaks into the 20 ms before each hit, and shows why researchers moved to scale-invariant SDR.
#!/usr/bin/env python3
"""window_tradeoff.py: why spectrogram separators and waveform separators fail
differently, shown with oracle masks on a SYNTHETIC mix (lab.py).
For each STFT size we build the best possible soft mask from the true stems
and score every stem. Short windows keep the kick's attack; long windows
resolve the bass and pad harmonics. Then we measure kick pre-echo (energy
smeared into the 20 ms before each hit) and show why SI-SDR exists.
Usage: python3 window_tradeoff.py (numpy + lab.py)
"""
import numpy as np
import lab
stems = lab.synth_stems(seed=7)
mix, stems = lab.mixdown(stems)
names = list(stems)
sizes = [512, 1024, 2048, 4096, 8192, 16384]
best = {n: (-99, None, None) for n in names}
print("oracle soft-mask SDR (dB) by STFT size, SYNTHETIC 92 BPM mix")
print(f"{'n_fft':>6s} {'ms':>6s} " + " ".join(f"{n:>6s}" for n in names) + f" {'mean':>6s}")
for nf in sizes:
est = lab.separate_with_masks(mix, lab.ratio_masks(stems, nf), nf)
s = [lab.sdr(stems[n], est[n]) for n in names]
for n, v in zip(names, s):
if v > best[n][0]:
best[n] = (v, nf, est[n])
print(f"{nf:6d} {1000*nf/lab.SR:6.1f} " + " ".join(f"{v:6.1f}" for v in s) + f" {np.mean(s):6.1f}")
print("\nper-stem best window (the MDX-Net idea: a different n_fft per source)")
for n in names:
print(f" {n:5s} best at n_fft={best[n][1]:5d} SDR {best[n][0]:5.1f} dB")
print(f" mean of per-stem bests: {np.mean([best[n][0] for n in names]):.1f} dB")
# kick pre-echo: energy in the 20 ms before each onset, relative to the 20 ms after
k = stems["kick"]
on = np.where((np.abs(k[1:]) > 0.05) & (np.abs(k[:-1]) <= 0.05))[0]
on = [o for i, o in enumerate(on) if i == 0 or o - on[i - 1] > lab.SR // 4]
w = int(0.02 * lab.SR)
def pre_echo(x):
pre = sum(np.sum(x[o - w:o] ** 2) for o in on if o > w)
post = sum(np.sum(x[o:o + w] ** 2) for o in on)
return 10 * np.log10(pre / post + 1e-12)
print("\nkick pre-echo (20 ms before hit vs 20 ms after; lower is cleaner)")
print(f" true kick stem : {pre_echo(k):6.1f} dB")
for nf in (512, 4096, 16384):
e = lab.separate_with_masks(mix, lab.ratio_masks(stems, nf), nf)["kick"]
print(f" oracle mask n_fft={nf:5d} : {pre_echo(e):6.1f} dB")
# SDR vs SI-SDR: turn a good estimate down 6 dB
e = best["lead"][2]
print("\nscale check on the lead estimate")
print(f" as is : SDR {lab.sdr(stems['lead'], e):5.1f} dB SI-SDR {lab.si_sdr(stems['lead'], e):5.1f} dB")
print(f" -6 dB gain : SDR {lab.sdr(stems['lead'], 0.5*e):5.1f} dB SI-SDR {lab.si_sdr(stems['lead'], 0.5*e):5.1f} dB")
Real output, synthetic audio (the groove from lab.py: kick, bass, pad, vowel-like lead, hats):
oracle soft-mask SDR (dB) by STFT size, SYNTHETIC 92 BPM mix
n_fft ms kick bass pad lead hats mean
512 11.6 7.8 7.9 8.7 13.5 18.0 11.2
1024 23.2 7.8 7.7 8.9 15.5 18.1 11.6
2048 46.4 8.5 8.2 8.8 16.3 18.1 12.0
4096 92.9 9.6 9.1 9.1 16.9 18.1 12.6
8192 185.8 10.5 9.7 9.3 16.9 18.1 12.9
16384 371.5 10.8 10.0 9.5 16.7 17.7 12.9
per-stem best window (the MDX-Net idea: a different n_fft per source)
kick best at n_fft=16384 SDR 10.8 dB
bass best at n_fft=16384 SDR 10.0 dB
pad best at n_fft=16384 SDR 9.5 dB
lead best at n_fft= 8192 SDR 16.9 dB
hats best at n_fft= 4096 SDR 18.1 dB
mean of per-stem bests: 13.1 dB
kick pre-echo (20 ms before hit vs 20 ms after; lower is cleaner)
true kick stem : -120.0 dB
oracle mask n_fft= 512 : -22.8 dB
oracle mask n_fft= 4096 : -18.2 dB
oracle mask n_fft=16384 : -17.2 dB
scale check on the lead estimate
as is : SDR 16.9 dB SI-SDR 16.9 dB
-6 dB gain : SDR 5.8 dB SI-SDR 16.9 dB
What that tells you
SDR loves long windows, even for the kick. Kick SDR climbs from 7.8 dB at 512 points to 10.8 dB at 16384. That’s because most of a kick’s energy is its low sine tail, and a long window is what pulls that tail apart from the bass. Bass and pad follow the same curve. The hats don’t care at all, about 18 dB everywhere.
Your ears hear the other column. The true kick has no energy before the hit (the −120 dB is just our floor). A 512-point mask leaks a ghost at −22.8 dB, and a 16384-point mask leaks one at −17.2 dB. That’s the soft “fff-THUMP” pre-echo on separated drums, and the window that won on SDR made it worse. A score that sums error energy over the whole file will happily trade a smeared transient for a cleaner tail.
Choosing per stem helps. Taking the best window for each stem raises the mean from 12.9 dB, the best single size, to 13.1 dB. It’s a small gain with oracle masks. With real models it’s the logic behind per-source FFT sizes and blending.
Watch how a score is defined. Turning a perfectly good lead estimate down 6 dB drops plain SDR from 16.9 dB to 5.8 dB, while SI-SDR stays at 16.9 dB. Le Roux and colleagues argue the case in “SDR – half-baked or well done?”. If a tool’s marketing quotes an SDR, ask which one, and on what test set.
A caveat that should keep everyone humble. Oracle masks are a ceiling for masking, not for models. The HT Demucs paper lists an ideal-ratio-mask oracle at 8.22 dB on MUSDB HQ, and its best model at 9.20 dB. Hybrid models that predict complex spectra or waveforms can beat a magnitude mask. Our synthetic groove shows you the trade-off. It doesn’t rank real models.
Choosing by stem, in practice
| You need | Lean toward | Listen for | Quick fix |
|---|---|---|---|
| Acapella, vocal for a remix | MDX-style vocal model | Snare ghosts, hollow “s” sounds | Gate between phrases, de-ess gently |
| Drum loop or breaks | htdemucs | Pre-echo before hits, cymbal swirl | Transient shaper, short fade-in on each chop |
| Bassline | htdemucs | Kick thump riding the bass | Sidechain-style ducking keyed from the drum stem |
| Instrumental or karaoke | Either; blend if you can | Reverb tails left behind from the vocal | Null test, then decide if the leftover matters |
| Pads, keys, “other” | MDX-style | Watery, phasey sustain | Accept a little bleed; it often glues |
None of this replaces your ears. Separators are trained on particular data, and a dense trap mix, a jazz trio and a live rock room will each surprise you. Treat the table as a place to start.
Decoding the model names in a menu
Stem tools tend to show you a menu of names that sound like firmware versions, so here’s a quick translation. “htdemucs” is Hybrid Transformer Demucs, the v4 release. “htdemucs_ft” is the per-source fine-tuned version: four models, one per stem, slower and usually a bit cleaner. “htdemucs_6s” adds guitar and piano stems. The Demucs README calls that six-source model experimental and warns of a lot of bleeding in the piano stem, so treat it that way. “MDX” on its own usually means a model descended from the KUIELab challenge work. “MDX23C” is a later, community-trained successor, and “Roformer” names usually point to band-split Transformer designs, the line of work that grew out of Band-Split RNN, which the HT Demucs paper itself names as its strongest competitor.
Two practical rules come out of that. More stems doesn’t mean better stems. Each extra source is another chance for two similar timbres to trade energy, so start with four and only go wider when you actually need the guitar on its own. And the newest name isn’t automatically the best one for your record. The benchmarks are averages over pop and rock multitracks. A sparse 808 record or a bowed-string arrangement can rank models differently, and that’s exactly why the five-minute audition below beats any chart.
How to audition two models without fooling yourself
- Use the same source. Same WAV, same sample rate, no re-encode between runs. A lossy source takes away more than the model difference adds back.
- Level-match the stems. A stem that’s 1 dB louder sounds “better.” Match by RMS or LUFS before you compare. This is the SI-SDR lesson in practice.
- Solo the transients first. Loop two bars of drums and listen right before each hit. Pre-echo is the fastest tell between the families.
- Then listen in the mix. A stem that sounds rough soloed can sit perfectly once the rest of the track is playing.
- Null-test. Add all the stems up, flip polarity, sum with the original. A loud residual means the model dropped or invented something.
If you’d rather not wire this up by hand, DeepSplit runs htdemucs-, MDX23C- and Roformer-class models locally, so you can split the same file several ways on your own machine and compare the results without any upload in between.
Once a rebuild is done, the transient you were fighting is still what the limiter sees. Crest factor is not loudness covers what a softened attack does to your master, and checking the summed stems in mono with a phase-correlation pass catches the phasey sustain that spectrogram bleed leaves behind.
- Is Demucs or MDX-Net better?
- Neither wins everywhere. In the MDX 2021 challenge results, Hybrid Demucs scored higher on drums and bass, and KUIELab-MDX-Net scored higher on vocals and the ‘other’ stem. Choose by the stem you need.
- Is Demucs a waveform model or a spectrogram model?
- Both, these days. The original Demucs worked on waveforms. Hybrid Demucs (v3) and Hybrid Transformer Demucs (v4) run a waveform branch and a spectrogram branch together and add their outputs.
- What does SDR actually measure?
- It compares the energy of the true stem with the energy of the error, in dB. Higher is better. It doesn’t weight errors by how audible they are, so a transient smeared before the hit can hide inside a good score.
- Why do separated drums sound hollow?
- Spectrogram masking smears energy across the analysis window, and estimating phase is hard. The Hybrid Demucs paper notes that phase inconsistency in spectrogram methods can make attacks sound hollow.
- Should I ensemble two models?
- Blending is a sound idea, and it’s what KUIELab-MDX-Net itself does with Demucs for drums and bass. Null-test the blend against the mix and listen to transients before you trust it.