StemSplitio/htdemucs-ft-vocals-onnx
HT-Demucs FT — Vocals Specialist, ONNX
The #1 open-source vocal separator on MUSDB18-HQ, exported to ONNX. No PyTorch required at inference. Runs on CPU / CoreML / CUDA / DirectML.
This repo packages sub-model 3 of the `htdemucs_ft` 4-bag ensemble as a single 316 MB .onnx file plus a ~150-line numpy reference inference script. Verified to be numerically equivalent to the original PyTorch model.
Want all 4 stems in one drop-in package? Use the full bag repo: `StemSplitio/htdemucs-ft-onnx`.
TL;DR
pip install onnxruntime numpy soundfile
python infer.py your-song.mp3 ./out/
# writes ./out/vocals.wav at 44.1 kHz stereoThat's it. No PyTorch, no CUDA setup, no GPU server.
Quality
Performance
Real-time factor on M4 Pro CPU: 0.20. Roughly 1.31× faster than PyTorch CPU on the same hardware.
Tooling — demucs-onnx Python package
This model can also be run (and re-exported) via the open-source `demucs-onnx` Python package on PyPI. It auto-downloads from this repo on first use.
pip install demucs-onnx
# Single specialist (this repo)
demucs-onnx separate song.mp3 stems/ --stem vocals
# Or via the Python API
python -c "from demucs_onnx import separate_stem; \
audio = separate_stem('song.mp3', 'vocals')"The same package is also the canonical tool for exporting htdemucs to ONNX yourself — it bundles all four blocker fixes (complex STFT, fractions.Fraction, random.randrange, aten::_native_multi_head_attention) so vanilla torch.onnx.export works on your own checkpoints.
pip install "demucs-onnx[export]"
demucs-onnx export htdemucs_ft vocals.onnx --stem vocalsCommon use cases
- Karaoke maker — extract clean instrumental + acapella in one pass (pair with the
otherONNX) - Acapella extraction — harvest isolated vocals for sampling, remixing, vocal-coach feedback
- Vocal removal — build a vocal-remover app on iOS / Android / web without a GPU server
- Speech-from-music — isolate spoken-word from background music for transcription
Quick start
Python — minimal
import infer
vocals = infer.separate_vocals("your-song.mp3")
# vocals: numpy array (2, samples) at 44.1 kHzPython — full control
import soundfile as sf
import infer
# Optional execution providers — CPU is the default and most portable.
# Swap to "coreml" on macOS, "cuda" on NVIDIA, "dml" on Windows DX12.
audio, sr = sf.read("your-song.mp3", dtype="float32", always_2d=True)
stems = infer.separate(audio.T, sr, providers=["CPUExecutionProvider"])
sf.write("vocals.wav", stems[infer.SOURCES.index("vocals")].T, sr)CLI
python infer.py your-song.mp3 ./out/
python infer.py your-song.mp3 ./out/ --providers cuda # NVIDIA
python infer.py your-song.mp3 ./out/ --providers coreml # macOS
python infer.py your-song.mp3 ./out/ --providers dml # WindowsMobile (iOS / Swift)
import onnxruntime_objc
let env = try ORTEnv(loggingLevel: .warning)
let opts = try ORTSessionOptions()
try opts.appendCoreMLExecutionProvider(with: ORTCoreMLExecutionProviderOptions())
let session = try ORTSession(env: env,
modelPath: Bundle.main.path(forResource: "htdemucs_ft_vocals", ofType: "onnx")!,
sessionOptions: opts)
// audio: 1 × 2 × 343980 Float32 buffer, then session.run(...).Mobile (Android / Kotlin)
import ai.onnxruntime.OrtEnvironment
import ai.onnxruntime.OrtSession
val env = OrtEnvironment.getEnvironment()
val opts = OrtSession.SessionOptions().apply { addNnapi() }
val session = env.createSession(modelPath, opts)Web (onnxruntime-web)
import * as ort from "onnxruntime-web";
const session = await ort.InferenceSession.create("htdemucs_ft_vocals.onnx", {
executionProviders: ["wasm"],
graphOptimizationLevel: "all",
});
const tensor = new ort.Tensor("float32", audioBuffer, [1, 2, 343980]);
const out = await session.run({ mix: tensor });
// out.stems.data is a Float32Array (1, 4, 2, 343980); use row 3 for vocals.Input / output spec
For longer audio, chunk with overlap-add — see infer.py::separate for a working ~60-line implementation.
Related repos
Sibling stem-specialist ONNX repos from the same export:
PyTorch versions for HF Inference Endpoints: `htdemucs-ft-pytorch`, `htdemucs-ft-vocals-pytorch`.
Full benchmark across every popular open-source separator: StemSplitio/stem-separation-benchmark-2026.
Skip the infrastructure — use the StemSplit API
Don't want to ship a 316 MB model in your app, manage a GPU pool, or write overlap-add chunking? Use the [StemSplit API](https://stemsplit.io/developers) instead — same model under the hood, hosted for you, with credits and a dashboard.
Or use the no-code tools that ship the same model family:
Files in this repo
License & attribution
This repo is MIT-licensed, matching the original HT-Demucs.
@inproceedings{rouard2023hybrid,
title = {Hybrid Transformers for Music Source Separation},
author = {Rouard, Simon and Massa, Francisco and D{\'e}fossez, Alexandre},
booktitle = {ICASSP},
year = {2023}
}- Original PyTorch model: `facebookresearch/demucs`
- ONNX export, parity verification, and packaging by StemSplit
- Search keywords: vocal remover onnx, karaoke maker, acapella extractor, htdemucs vocals onnx, vocal separation ios
