Skip to main content

mlx-audio-separator

MLX-native stem separation for Apple Silicon Macs.

This project ports the inference paths from audio-separator (upstream repo: nomadkaraoke/python-audio-separator) to MLX so separation runs on Apple Silicon without requiring PyTorch or ONNX Runtime at inference time. Core runtime components are powered by mlx-audio-io (audio I/O) and mlx-spectro (spectral transforms).

Requirements

  • macOS 13+ (Ventura or later)
  • Apple Silicon (M1/M2/M3/M4)
  • Python 3.10+

Installation

pip install mlx-audio-separator

If you need first-run conversion from upstream checkpoints (.ckpt/.onnx/Demucs weights), install conversion extras:

pip install "mlx-audio-separator[convert]"

Quick Start

CLI

# Separate with default model
mlx-audio-separator song.mp3

# Use a specific model
mlx-audio-separator song.mp3 -m htdemucs_ft.yaml

# List supported models
mlx-audio-separator --list_models

Python

from mlx_audio_separator import Separator

sep = Separator()
sep.load_model()
outputs = sep.separate("song.mp3")
print(outputs)

Supported Architectures

  • Roformer (BS-Roformer and MelBand-Roformer families)
  • MDXC (including MDX23C-style checkpoints)
  • MDX
  • VR
  • Demucs

Demucs cache security and migration

Demucs conversion stores MLX weights as <model>.safetensors with a validated <model>_config.json sidecar. The loader verifies that the two files match before constructing a model. Legacy <model>_mlx.pkl caches are never deserialized. When automatic conversion is enabled they are left untouched and replaced by newly generated safe files from the official Demucs source.

To regenerate a cache explicitly:

pip install "mlx-audio-separator[convert]"
python -m mlx_audio_separator.demucs_mlx.mlx_convert htdemucs \
  --output-dir ~/.cache/mlx-audio-separator/demucs

Converted Demucs weights live in ~/.cache/mlx-audio-separator/demucs. MLX_AUDIO_SEPARATOR_DEMUCS_CACHE_DIR points that elsewhere. Caches left in the older ~/.cache/demucs-mlx by a release before 0.1.12 are still read, so upgrading does not cost a reconversion; nothing is written there any more, because the demucs-mlx package uses that directory for its own differently shaped cache.

Official Demucs downloads retain their filename hash checks and are loaded with PyTorch's restricted weight-only deserializer. This trusts the installed PyTorch, Demucs, NumPy, and optional DiffQ implementations plus the official model registry; arbitrary checkpoint globals and local pickle caches are not trusted.

Validation Snapshot

Release validation snapshot (2026-02-24 to 2026-02-26):

Check Result
Full-catalog benchmark gate 163/163 models ok (0 failures)
Unit tests 167 passed, 1 skipped
MLX vs audio-separator parity smoke 4/4 models passed (rel L2 <= 5e-2)

Scope: Apple Silicon (M4 mini), MUSDB18-HQ test subset, release gate + parity smoke model set.

Detailed evidence and provenance: docs/release-validation.md.

Performance Snapshot

MLX vs audio-separator (ABBA, 12-song MUSDB18-HQ test subset, M4 mini):

Model MLX speedup vs PAS
htdemucs_ft.yaml 1.40x
model_bs_roformer_ep_317_sdr_12.9755.ckpt 2.16x
mel_band_roformer_instrumental_instv7n_gabox.ckpt 2.50x
UVR-MDX-NET-Inst_HQ_3.onnx 1.53x

Median speedup across the 4-model overlap set: 1.847x.

These numbers are scoped to the benchmark settings above and are not universal guarantees for all machines, models, or audio inputs.

Stable Runtime Tuning

The defaults are the recommended configuration. Every inference option ships at the value that measured best for both quality and speed, so you should not need to set anything to get good results. See docs/tuning.md for what those values are, the measurements behind them, and the levers that remain for benchmarking or exact-parity work.

Release-facing stable controls:

  • --cache_clear_policy {aggressive,deferred} — defaults to deferred
  • --write_workers <int> — defaults to 2

Both already ship at the value that measured fastest, so the example that used to live here (passing them explicitly) is no longer needed.

--speed_mode is deprecated and ignored. Its latency_safe* profiles now resolve to the defaults, and it will be removed in the next major version.

Basic benchmark command:

mlx-audio-separator \
  --benchmark song.mp3 \
  --benchmark_warmup 1 \
  --benchmark_repeats 3 \
  --benchmark_profile

BS-Roformer-SW Performance (Opt-In)

For BS-Roformer-SW.ckpt, no extra flags are needed:

mlx-audio-separator song.mp3 \
  -m BS-Roformer-SW.ckpt \
  --output_format FLAC

What --speed_mode latency_safe_v3 used to enable -- deferred cache clearing plus async stem writes -- is now the default. Measured on a 195 s track to FLAC it runs ~6-17% faster than the old defaults with bit-identical output.

To avoid repeated checkpoint conversion overhead, pre-convert once to *.safetensors and exit:

mlx-audio-separator \
  -m BS-Roformer-SW.ckpt \
  --save_converted_safetensors \
  --preconvert_only

safetensors primarily improves model load/startup time. It is not expected to materially change per-file inference latency.

Validation command (latency + deterministic equivalence):

uv run --with torch python scripts/perf/compare_latency.py \
  --corpus-file /tmp/corpus_one.txt \
  --baseline-config scripts/perf/configs/bs_roformer_sw_default_baseline.json \
  --candidate-config scripts/perf/configs/bs_roformer_sw_latency_safe_v3_candidate.json \
  --model-file-dir ~/.cache/mlx-audio-separator/models \
  --allow-speed-mode-mismatch \
  --target-improvement-demucs-mdxc 10.0 \
  --equivalence-check \
  --equivalence-threshold-rel-l2 1e-6 \
  --output-json /tmp/bs_roformer_sw_latency_safe_v3_compare.json \
  --output-markdown /tmp/bs_roformer_sw_latency_safe_v3_compare.md

BS-Roformer-SW Optimization Program (Opt-In Tracks)

As of 0.1.8, what latency_safe_v3 promoted -- deferred cache clearing and async stem writes -- is the default for every model, and --speed_mode is deprecated and ignored. Measure candidates against the defaults. All experimental tracks below remain parked pending new evidence.

Candidate configs for staged exploration live under scripts/perf/configs/:

  • bs_roformer_sw_cand_grouped_bandmask.json
  • bs_roformer_sw_cand_fused_ola.json
  • bs_roformer_sw_cand_stream_pipeline.json
  • bs_roformer_sw_cand_compile_fullgraph.json
  • bs_roformer_sw_cand_flac_fastwrite.json

Corpus manifest templates:

  • Quick gate (3 files): scripts/perf/corpora/bs_roformer_sw_quick.txt
  • Full gate (12 files): scripts/perf/corpora/bs_roformer_sw_full.txt

Quick-gate example:

uv run --with torch python scripts/perf/compare_latency.py \
  --corpus-file scripts/perf/corpora/bs_roformer_sw_quick.txt \
  --baseline-config scripts/perf/configs/bs_roformer_sw_latency_safe_v3_baseline.json \
  --candidate-config scripts/perf/configs/bs_roformer_sw_cand_grouped_bandmask.json \
  --model-file-dir ~/.cache/mlx-audio-separator/models \
  --target-improvement-demucs-mdxc 3.0 \
  --equivalence-check \
  --equivalence-threshold-rel-l2 1e-6 \
  --equivalence-max-files 1 \
  --output-json /tmp/bs_roformer_sw_quick_gate.json \
  --output-markdown /tmp/bs_roformer_sw_quick_gate.md

Full-gate example:

uv run --with torch python scripts/perf/compare_latency.py \
  --corpus-file scripts/perf/corpora/bs_roformer_sw_full.txt \
  --baseline-config scripts/perf/configs/bs_roformer_sw_latency_safe_v3_baseline.json \
  --candidate-config scripts/perf/configs/bs_roformer_sw_cand_grouped_bandmask.json \
  --model-file-dir ~/.cache/mlx-audio-separator/models \
  --target-improvement-demucs-mdxc 5.0 \
  --equivalence-check \
  --equivalence-threshold-rel-l2 1e-6 \
  --equivalence-max-files 0 \
  --output-json /tmp/bs_roformer_sw_full_gate.json \
  --output-markdown /tmp/bs_roformer_sw_full_gate.md

Documentation

Document Description
docs/release-validation.md Release evidence snapshot
docs/release-first.md Release execution playbook
docs/reproducibility.md Reproducibility guide
docs/wave4-opt-in.md Wave 4 opt-in/experimental roadmap
docs/bs-roformer-sw-optimization-program.md BS-Roformer-SW candidate gating and promotion table
CHANGELOG.md Changelog
THIRD_PARTY_NOTICES.md Third-party attribution and license notices

License

This project is MIT licensed.

Acknowledgments

mlx-audio-separator is derived from audio-separator (upstream repo: nomadkaraoke/python-audio-separator, MIT) by beveradb and the nomadkaraoke community. Substantial portions of the architecture, model loading, and separation logic are adapted from that project. If you find this package useful, please also star and support the upstream project.

The models used by this project were trained by the Ultimate Vocal Remover community, primarily @Anjok07 and @aufr33. See THIRD_PARTY_NOTICES.md for full attribution and license details.

Additional references:

Metadata

Release files for mlx-audio-separator 0.1.13

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mlx-audio-separator 0.1.13
File Size Uploaded
mlx_audio_separator-0.1.13.tar.gz 354.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for mlx-audio-separator 0.1.13
File Interpreter ABI Platform
mlx_audio_separator-0.1.13-py3-none-any.whl Python 3 none any Details

Total release size: 711.9 kB

Release files / mlx_audio_separator-0.1.13.tar.gz

Download URL mlx_audio_separator-0.1.13.tar.gz
Size 354.5 kB
Tags Source
SHA-256 checksum
How to use checksums
1c8b0e9e59f7ad6a0a793f35d5684d826ece417cf49e8b6ca0f1d3a10b8b95d5
BLAKE2b-256 checksum
How to use checksums
2f4281edf01e40ccd8600dea953838cfb417c3c712de703d77dc036d3db51240
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

Release files / mlx_audio_separator-0.1.13-py3-none-any.whl

Download URL mlx_audio_separator-0.1.13-py3-none-any.whl
Size 357.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c39565e966e60dad1774b803829d5aa999f00f8ca08871194e389bdbc91ba87e
BLAKE2b-256 checksum
How to use checksums
d30d196bc29a432a2767cb2adfb9420dd55b5fc5eea987a7ce9c6f752c1b2974
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

Release history Release notifications | RSS feed

0.1.18

2 release files

0.1.17

2 release files

0.1.16

2 release files

0.1.15

2 release files

0.1.14

2 release files

This release

0.1.13 This release

2 release files

0.1.12

2 release files

0.1.11

2 release files

0.1.10

2 release files

0.1.9

2 release files

0.1.8

2 release files

0.1.7

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page