Production-ready, inference-only toolkit for Band-Split RoPE Transformer audio source separation
BS-RoFormer-Infer provides a clean, lightweight API for running music source separation inference using Band-Split RoFormer models with automatic checkpoint management.
Two independent choices:
| Argument | Values | Meaning |
|---|---|---|
backend |
torch (default), mlx, auto |
which framework computes |
device |
None, auto, cpu, cuda, cuda:N, mps |
where Torch computes |
from bs_roformer import BSRoformerSession
with BSRoformerSession(device="mps") as session: # Apple GPU, Torch
session.infer("songs/", store_dir="stems/")bs-roformer-infer --input_folder songs --device mps
bs-roformer-infer --input_folder songs --backend autobackend defaults to torch, so nothing changes unless you ask. auto picks an
accelerated backend only when one is genuinely installed and falls back to Torch
otherwise. Requesting a backend that cannot run here raises immediately — before
any checkpoint is downloaded — rather than quietly using a different one.
backend="mlx" owns its own Apple Silicon execution and accepts only device
of auto/mps (or none), refusing anything else rather than ignoring it.
Native Apple Silicon execution through MLX. Install it with the extra, which is never part of the core install:
pip install "bs-roformer-infer[mlx]"BSRoformerSession(backend="mlx").load()Measured on an M2 against the default checkpoint: about 2.5x faster than Torch
on MPS at roughly half the memory (10.5 s versus 26.6 s per 13.35 s chunk;
2.7 GB versus 5.3 GB), agreeing with the Torch path to 3.4e-07 maximum absolute
error across all six stems. It reads the same sha256-verified checkpoint and
config as the Torch path — there is no second catalog and no separate
converted-weight cache.
All 34 registry models are supported, including checkpoints that use the
non-standard mask-estimator heads — hyperace, hyperace_v1, fno, and
large_inst — or the non-standard trunks — siamese and value_residual.
The MLX heads and trunks share the package registry and refuse unsupported
variations before downloading a checkpoint.
Speed varies by head — fno runs 3.7x faster than Torch on MPS and hyperace
2.8x, while large_inst is currently about 2x slower. That one is a known
performance gap, not a correctness one.
It refuses, rather than gets wrong, a config whose chunk_size is not a multiple
of its STFT hop — an alignment the chunked path silently assumes.
MPS and MLX both need an arm64 Python interpreter. Under Rosetta/x86_64
they report as unavailable rather than failing loudly — an x86_64 interpreter
makes torch.backends.mps.is_available() return False, and MLX ships no
macOS x86_64 wheel at all, so it cannot even be installed there. Either way,
an accelerated path just looks absent rather than misconfigured. This is easy
to hit without noticing: an x86_64 uv resolves
x86_64 interpreters, so uv sync can silently produce an environment where
the accelerated paths structurally cannot exist. Check with
python -c "import platform; print(platform.machine())" — it must print
arm64.
Legacy None and explicit auto select CUDA when available, otherwise CPU.
Explicit cpu, cuda, cuda:N, and mps are supported; an explicitly requested
accelerator that is unavailable raises rather than being silently downgraded.
Apple Silicon. Pass device="mps" (or --device mps) to run on the Mac GPU.
It is opt-in on purpose: auto keeps its long-standing CUDA-else-CPU meaning, so
upgrading does not move an existing Mac caller onto a different compute path.
Measured on an M2 against the default checkpoint, MPS agrees with CPU to within
1.1e-07 maximum absolute error across all six stems, and processes a 13.35 s
chunk in 26.6 s versus 90.7 s on CPU.
BSRoformerSession.release() permits a later reload, while close() is terminal.
Loading and cache_info() use the same checkpoint resolver; its package-owned
config/checkpoints.toml remains the authoritative URL/integrity metadata.
Legacy JSON files remain only as transition compatibility fixtures and are not
read by production registry/download resolution.
BS-RoFormer (Band-Split RoPE Transformer) is a strong architecture for music
source separation, introduced by Lu, Wang, Kong, and Hung (2023). The
reference implementation, lucidrains/BS-RoFormer,
provides the model architecture only -- no checkpoint management, no CLI, no
packaging for downstream use. Trained checkpoints are typically distributed
through python-audio-separator
(which pulls in the full Ultimate Vocal Remover GUI stack) or through
individual community members' personal Hugging Face/Google Drive accounts --
hosts that can and do vanish without warning. This project's own history
includes exactly that: the original jarredou Hugging Face account behind
the default BS-RoFormer-SW checkpoint was deleted (discovered 2026-06), and
9 of the other 10 registry models' fallback URLs (the dead upstream
TRvlvr/model_repo GitHub repo) were found 404ing in a 2026-07-12 audit.
BS-RoFormer-Infer reprovides the architecture as a clean, pip-installable, inference-only package: no training code, no GUI dependency, a versioned model registry that can be repointed at a new host by editing one JSON file (no code change), and sha256-verified auto-download so a corrupted or tampered checkpoint is never silently loaded.
This project builds upon the excellent work of several open-source projects:
- BS-RoFormer by Phil Wang (lucidrains) -- Clean PyTorch implementation of the Band-Split RoPE Transformer architecture
- python-audio-separator by Andrew Beveridge (nomadkaraoke) -- Pre-trained checkpoints and model configurations
- Original Research -- Wei-Tsung Lu, Ju-Chiang Wang, Qiuqiang Kong, and Yun-Ning Hung for the Band-Split RoPE Transformer paper
- Politrees/UVR_resources on Hugging Face -- current mirror host for 9 of the 10 registry checkpoints, after the original TRvlvr source went dead (see Model Weights)
- anvuew/dereverb_bs_roformer on Hugging Face -- author-hosted config for the De-Reverb model
- enerjazzer/BS-ROFO-SW-Fixed on Hugging Face -- current host for the default BS-RoFormer-SW checkpoint, after the original jarredou account was deleted
If you use BS-RoFormer-Infer in your research, please cite the original paper:
@inproceedings{lu2024music,
title = {Music Source Separation with Band-Split RoPE Transformer},
author = {Lu, Wei-Tsung and Wang, Ju-Chiang and Kong, Qiuqiang and Hung, Yun-Ning},
booktitle = {ICASSP 2024 - 2024 IEEE International Conference on Acoustics, Speech and Signal Processing (ICASSP)},
pages = {481--485},
year = {2024},
publisher = {IEEE},
doi = {10.1109/ICASSP48485.2024.10446843}
}Also available as a preprint: arXiv:2309.02612.
- Inference Only: Lightweight package focused on production inference
- Auto-Download: the default model is fetched on first use and sha256-verified against recorded checksums
- CLI Tools:
bs-roformer-inferandbs-roformer-downloadcommands - Python API: Clean programmatic interface
- Model Registry: Easy model discovery with search and category filtering
In scope: inference (forward pass) with the BS-RoFormer architecture; a 34-entry registry spanning multi-stem, 53-stem mega, four-stem, vocals, karaoke, instrumental, and de-reverb checkpoints; automatic, manual, and configurable-directory checkpoint management with sha256 verification; a standalone download CLI.
Out of scope, forever:
- Training or fine-tuning code -- this package only ever runs a forward pass.
- The Ultimate Vocal Remover GUI itself, or any GUI.
- Bundling or committing checkpoint bytes to this repository's git history (see What This Project Will NEVER Bundle).
# Using pip
pip install bs-roformer-infer
# Using UV (recommended)
uv pip install bs-roformer-infer# First run auto-downloads the recommended BS-RoFormer-SW model (~700 MB,
# sha256-verified) into ~/.cache/bs-roformer-infer/ -- no separate download step needed
bs-roformer-infer --input_folder ./songs --store_dir ./outputsEvery WAV inside input_folder produces separated stems (vocals, drums, bass, guitar, piano, other) plus *_instrumental.wav. Explicit --config_path/--model_path arguments still work and skip auto-resolution entirely.
from ml_collections import ConfigDict
import torch
import yaml
from bs_roformer import DEFAULT_MODEL, ensure_model_assets, get_model_from_config
from bs_roformer.inference import SafeLoaderWithTuple
# Resolves local copies, or downloads (sha256-verified) on first use
ckpt_path, config_path = ensure_model_assets(DEFAULT_MODEL)
with open(config_path) as f:
config = ConfigDict(yaml.load(f, Loader=SafeLoaderWithTuple))
model = get_model_from_config("bs_roformer", config)
model.load_state_dict(torch.load(ckpt_path, map_location="cpu"))BS-RoFormer-SW (roformer-model-bs-roformer-sw-by-jarredou) by jarredou is the recommended default model for audio source separation. It supports 6-stem separation (vocals, drums, bass, guitar, piano, other) and provides excellent quality for production workflows.
from bs_roformer import DEFAULT_MODEL
print(DEFAULT_MODEL) # "roformer-model-bs-roformer-sw-by-jarredou"| Model | Category | Description |
|---|---|---|
roformer-model-bs-roformer-sw-by-jarredou |
multi-stem | Recommended - 6-stem separation (vocals, drums, bass, guitar, piano, other) |
roformer-model-bs-roformer-mvsep-mega-53-stems |
mega-stem | MVSep Mega 53-stem model by ZFTurbo; memory-heavy, upstream recommends at least 16GB VRAM |
roformer-model-bs-roformer-musdb18hq-by-zfturbo |
four-stem | MUSDB18HQ 4-stem model from ZFTurbo's v1.0.12 release |
roformer-model-bs-roformer-fno-instrumental-by-pcunwa |
instrumental | FNO instrumental checkpoint; uses a bundled minimal FNO1d mask-estimator variation |
roformer-model-bs-roformer-large-inst-by-pcunwa |
instrumental | Large-Inst instrumental checkpoint; adds four Transformer pairs inside the mask-estimator head |
roformer-model-bs-roformer-hyperace-v2-instrumental-by-pcunwa |
instrumental | HyperACE v2 instrumental checkpoint; uses the HyperACE mask-estimator variation |
roformer-model-bs-roformer-hyperace-v2-vocals-by-pcunwa |
vocals | HyperACE v2 vocals checkpoint; uses the HyperACE mask-estimator variation |
roformer-model-bs-roformer-leap-vocals-by-pcunwa |
vocals | Leap vocals checkpoint by pcunwa |
roformer-model-bs-roformer-leap-instrumental-by-pcunwa |
instrumental | Leap instrumental checkpoint by pcunwa |
roformer-model-bs-roformer-leap-xe-vocals-by-pcunwa |
vocals | Leap Xe vocals checkpoint; standard BS trunk |
roformer-model-bs-roformer-leap-xe-instrumental-by-pcunwa |
instrumental | Leap Xe instrumental checkpoint; standard BS trunk |
roformer-model-bs-roformer-siamese-vocals-by-pcunwa |
vocals | Experimental two-stream Siamese RoFormer trunk |
roformer-model-bs-roformer-hyperace-v1-instrumental-by-pcunwa |
instrumental | HyperACE v1 segmentation head |
roformer-model-bs-roformer-value-residual-instrumental-by-pcunwa |
instrumental | Experimental learned value-residual trunk |
pcunwa-bs-roformer-resurrection-instrumental / pcunwa-bs-roformer-resurrection-vocals |
instrumental / vocals | Direct pcunwa Resurrection checkpoints |
pcunwa-bs-roformer-revive-v1 / pcunwa-bs-roformer-revive-v2 / pcunwa-bs-roformer-revive-v3e |
vocals | Direct pcunwa Revive checkpoint variants |
roformer-model-bs-roformer-karaoke-by-anvuew |
karaoke | Karaoke vocals checkpoint by anvuew |
roformer-model-bs-roformer-karaoke-by-becruily |
karaoke | Karaoke vocals checkpoint by becruily |
roformer-model-bs-roformer-dereverb-by-anvuew-sdr-22-5050 |
dereverb | anvuew de-reverberation checkpoint |
roformer-model-bs-roformer-mag-vocals-by-anvuew |
vocals | anvuew MAG vocals checkpoint |
roformer-model-bs-roformer-vocals-ft1-by-anvuew |
vocals | anvuew FT1 vocals checkpoint |
roformer-model-bs-roformer-vocals-by-anvuew |
vocals | anvuew vocals checkpoint |
roformer-model-bs-roformer-vocals-resurrection-by-unwa |
vocals | Vocals Resurrection by unwa |
roformer-model-bs-roformer-vocals-revive-v3e-by-unwa |
vocals | Vocals Revive V3e by unwa |
roformer-model-bs-roformer-vocals-revive-v2-by-unwa |
vocals | Vocals Revive V2 by unwa |
roformer-model-bs-roformer-vocals-revive-by-unwa |
vocals | Vocals Revive by unwa |
roformer-model-bs-roformer-vocals-by-gabox |
vocals | Vocals by Gabox |
roformer-model-bs-roformer-instrumental-resurrection-by-unwa |
instrumental | Instrumental Resurrection by unwa |
roformer-model-bs-roformer-de-reverb |
dereverb | De-reverberation model |
| ... | ... | See --list-models for full list |
Categories: multi-stem, mega-stem, four-stem, vocals, karaoke, instrumental, dereverb
The MVSep Mega entry exposes 53 raw stems from one BS-RoFormer checkpoint. It is useful for broad stem discovery, but it is much larger than the default model and the upstream release notes warn that individual stems may be weaker than specialized models.
HyperACE v1/v2, FNO, and Large-Inst checkpoints use model variations: the
RoFormer trunk is the same, but the mask estimator head is different. Siamese
and Value Residual checkpoints use distinct trunk variations. Registry-selected
models load these variations automatically. The FNO variation is a bundled
minimal FNO1d inference implementation, so installing this package does not pull
in the full neuraloperator research framework. The Large-Inst variation adds
four alternating time/frequency Transformer pairs before the mask MLP.
As of the 2026-07-12 re-audit, all registry entries have a live download URL (see the availability note in What This Project Will NEVER Bundle).
from bs_roformer import MODEL_REGISTRY
# List all categories
print(MODEL_REGISTRY.categories())
# List models by category
for model in MODEL_REGISTRY.list("vocals"):
print(model.name, model.checkpoint)
# Search models
results = MODEL_REGISTRY.search("unwa")
for m in results:
print(m.slug)
# Pretty-print all models
print(MODEL_REGISTRY.as_table())Model weights are never bundled or committed to this repository. Every
checkpoint is downloaded at runtime from its registry-recorded source,
sha256-verified against src/bs_roformer/config/checkpoints.toml, and cached
locally -- a mismatch deletes the file and retries instead of silently
keeping a corrupt checkpoint.
Downloads default to ~/.cache/bs-roformer-infer/<model-slug>/. The location is
configurable, resolved in this order:
- Explicit argument:
--models_dir(inference CLI),--output-dir(download CLI), orensure_model_assets(..., models_dir=...)(API) - The
BS_ROFORMER_MODELS_PATHenvironment variable - The default
~/.cache/bs-roformer-infer/
A relative ./models directory (the pre-0.1.4 default) is still searched as a
read fallback, so existing downloads keep working without re-fetching.
When bs-roformer-infer runs without --model_path/--config_path, the
requested registry model (default: BS-RoFormer-SW) is looked up in the
directories above and downloaded on first use. Downloads are verified against
the sha256 checksums recorded in src/bs_roformer/config/checkpoints.toml; a
mismatch deletes the file and retries instead of keeping a corrupt checkpoint.
The recommended BS-RoFormer-SW model needs one file (its config ships inside the package):
| File | URL | sha256 |
|---|---|---|
BS-Rofo-SW-Fixed.ckpt (699,412,152 bytes) |
https://huggingface.co/enerjazzer/BS-ROFO-SW-Fixed/resolve/main/BS-Rofo-SW-Fixed.ckpt | 24e7d35ee9c64415673d3fd33e06a67cac2c103c5df6267ba1576459c775916e |
Place it at
~/.cache/bs-roformer-infer/roformer-model-bs-roformer-sw-by-jarredou/BS-Rofo-SW-Fixed.ckpt
(or the equivalent path under your BS_ROFORMER_MODELS_PATH), and inference
will pick it up without network access.
Additional registry assets (see CHANGELOG for full provenance) download from these mirrors:
| Model | File | URL | sha256 |
|---|---|---|---|
| De-Reverb | deverb_bs_roformer_8_384dim_10depth.ckpt (361,499,604 bytes) |
https://huggingface.co/Politrees/UVR_resources/resolve/main/models/Roformer/BandSplit/deverb_bs_roformer_8_384dim_10depth.ckpt | 9c38653aaa5e49f2f7b84dd3be2b6b679e0cbea23978e6b48389ee6f0a914768 |
| De-Reverb (config) | deverb_bs_roformer_8_384dim_10depth_config.yaml (2,358 bytes) |
https://huggingface.co/anvuew/dereverb_bs_roformer/resolve/main/archive/deverb_bs_roformer_8_384dim_10depth.yaml (author's file — NOT Politrees' similarly-named copy, which silently uses the wrong stft_hop_length; see CHANGELOG) |
a87cf93b36b9a20d25a9cc4f78a2541ea0033988e7b6c38dcf0029e9290af816 |
| Chorus Male-Female by Sucial | model_chorus_bs_roformer_ep_267_sdr_24.1275.ckpt (527,121,477 bytes) |
https://huggingface.co/Politrees/UVR_resources/resolve/main/models/Roformer/BandSplit/model_chorus_bs_roformer_ep_267_sdr_24.1275.ckpt | 123c00786bdbc6bd462dddb35cd21fd6ae99ab8319f93f63a8abc1012e593d94 |
| Instrumental Resurrection by unwa | bs_roformer_instrumental_resurrection_unwa.ckpt (204,483,033 bytes) |
https://huggingface.co/Politrees/UVR_resources/resolve/main/models/Roformer/BandSplit/model_BandSplit-Roformer_Resurrection_Instrumental_by-Unwa.ckpt | 16311025a5133ae6411760ccfe9e3e66b31a01d9d8bec0a03fa7ec4bedac7a15 |
| Male-Female by aufr33 | bs_roformer_male_female_by_aufr33_sdr_7.2889.ckpt (527,119,779 bytes) |
https://huggingface.co/Politrees/UVR_resources/resolve/main/models/Roformer/BandSplit/bs_roformer_male_female_by_aufr33_sdr_7.2889.ckpt | 3cf11736d1b42a11ae55d8299316585921477dd2a671b24b663660846ca9861b |
| Vocals by Gabox | bs_roformer_vocals_gabox.ckpt (639,254,584 bytes) |
https://huggingface.co/Politrees/UVR_resources/resolve/main/models/Roformer/BandSplit/bs_roformer_voc_gabox.ckpt | 18d58efe5e949e70fab11b875329af6d06ef11ccc29574bfe943fb57cc827f38 |
| Vocals Resurrection by unwa | bs_roformer_vocals_resurrection_unwa.ckpt (204,510,749 bytes) |
https://huggingface.co/Politrees/UVR_resources/resolve/main/models/Roformer/BandSplit/model_BandSplit-Roformer_Resurrection_Vocals_by-Unwa.ckpt | 9dbfe5cb572e4ed32a15ec727d7bd06c8d7aba97509e6fda5bc008bb1e0b2dd5 |
| Vocals Revive by unwa | bs_roformer_vocals_revive_unwa.ckpt (639,326,600 bytes) |
https://huggingface.co/Politrees/UVR_resources/resolve/main/models/Roformer/BandSplit/bs_roformer_revive_by_unwa.ckpt | f1d7e4bfdfef07c6b2bc1d65283a7d03c3c38f8c7dbc8d729b785f93c8b8699a |
| Vocals Revive V2 by unwa | bs_roformer_vocals_revive_v2_unwa.ckpt (639,326,600 bytes) |
https://huggingface.co/Politrees/UVR_resources/resolve/main/models/Roformer/BandSplit/bs_roformer_revive_v2_by_unwa.ckpt | 58098850c882a7472dad39f99fb8040ce6eaafe671cfe9881d89aea276bbb5f5 |
| Vocals Revive V3e by unwa | bs_roformer_vocals_revive_v3e_unwa.ckpt (639,326,600 bytes) |
https://huggingface.co/Politrees/UVR_resources/resolve/main/models/Roformer/BandSplit/bs_roformer_revive_v3_by_unwa.ckpt (hosted there without the trailing "e" — same file) | 1b0751b9a15c591407c3b77f08eb4ad3005e42e96051f3f2b39760f1130c467b |
| Large-Inst by pcunwa | bs_large_v2_inst.ckpt (238,214,371 bytes) |
https://huggingface.co/pcunwa/BS-Roformer-Large-Inst/resolve/main/bs_large_v2_inst.ckpt | 09251ab8b5bb892414a6ab8aa80a1be30c17852d5e7f4e76943610de049e4bc4 |
| Large-Inst by pcunwa (config) | bs_large_v2_inst_config.yaml (1,973 bytes) |
https://huggingface.co/pcunwa/BS-Roformer-Large-Inst/resolve/main/config.yaml | 85d10906007df21ee48dbb86faa09205609274eb38ea224dce767e2844d0a934 |
The Chorus/Male-Female-aufr33 config
(config_chorus_male_female_bs_roformer.yaml) and the three Revive
checkpoints' shared config (config_bs_roformer_vocals_revive_unwa.yaml) are
also fetched from Politrees/UVR_resources — see config/checkpoints.toml for
the exact URLs and hashes.
# List available models
bs-roformer-download --list-models
# Download the recommended model into the cache dir
bs-roformer-download --model roformer-model-bs-roformer-sw-by-jarredou
# Download into a custom directory
bs-roformer-download --model roformer-model-bs-roformer-sw-by-jarredou --output-dir ./modelsNote on download availability (re-audited 2026-07-23): all registry models now have live download sources. The 9 that fell back to the dead upstream TRvlvr repository were re-hosted to Politrees/UVR_resources (with the De-Reverb config sourced from the author's anvuew/dereverb_bs_roformer repo instead — see CHANGELOG for why). Run
python tools/check_weights_liveness.py(needs network) to re-check.
# Clone repository
git clone https://github.com/openmirlab/bs-roformer-infer.git
cd bs-roformer-infer
# Install with UV
uv sync --extra dev
# Install with pip
pip install -e ".[dev]"uv run pytest -q # unit tests (network- and realweights-marked tests deselected by
# default -- the latter need real hardware and real checkpoints)
uv run ruff check . # lintMIT License - see LICENSE for details.
This project includes code and configurations adapted from:
- BS-RoFormer (MIT) - Phil Wang
- python-audio-separator (MIT) - Andrew Beveridge
For issues and questions:
- GitHub Issues: github.com/openmirlab/bs-roformer-infer/issues
For applications that need controlled model lifetime, use BSRoformerSession:
from bs_roformer import BSRoformerSession
with BSRoformerSession() as session:
session.infer("input_folder", store_dir="outputs")load() downloads and verifies weights, infer() requires a ready session,
release() frees memory while retaining the disk cache, and cache_info()
reports the selected checkpoint. Existing CLI and downloader entry points remain
available and lazy. Checkpoint URLs and SHA-256 metadata live in the package-owned
config/checkpoints.toml and can be overridden with explicit paths or metadata.
This package is inference-only. The public clean facade exposes an explicit lifecycle session (load, ready-only infer, release, close, status, cache_info, and context-manager support) while retaining the legacy one-shot API for compatibility. Checkpoint URLs and integrity metadata are package-owned in config/checkpoints.toml; callers may provide a generic checkpoint override without changing package code.