Lightweight utilities for music source separation and transcription.
See the codeLightweight utilities for music source separation and transcription.
This library is a ground-up rewrite of the zfturbo's MSST repo, with a strong focus on robustness, simplicity and extensibility. We keep third-party dependencies to an absolute minimum to ease installation.
⚠️ This is pre-alpha software, expect significant breaking changes before v0.1.
Our default registry supports 110+ community-trained separation models.
More information about models and config can be found on the documentation.
There are three steps. You do not need to have Python installed.
Install uv if you haven't already. It is an awesome Python package and library manager with pip compatibility.
# Linux / MacOS
wget -qO- https://astral.sh/uv/install.sh | sh
# Windows
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
Open a new terminal and install the latest stable PyPI release as a tool. It will install the Python interpreter, all necessary packages and add the splifft executable to your PATH:
uv tool install "splifft[config,inference,cli,web]"
The core is kept as minimal as possible. Pick which ones you need:
config extra is used to parse the model configuration from JSON and discover the registry's default cache dir.inference extra is used to decode audio formats.cli extra provides you with the splifft command line toolweb extra is used to download models.This directly pulls from the main branch, which may be unstable:
uv tool install "git+https://github.com/undef13/splifft.git[config,inference,cli,web]"
We recommend using our built-in registry to manage model config and weights:
# list all available models, including those not yet available locally
splifft ls -a
# download model files and config to your user cache directory
# ~/.cache/splifft on linux
splifft pull bs_roformer-fruit-sw
# view information about the configuration
# modify the configuration, such as batch size according to your hardware
splifft info bs_roformer-fruit-sw
# run inference
splifft run data/audio/input/3BFTio5296w.flac --model bs_roformer-fruit-sw
Alternatively, for custom models, you can manage files manually. Go into a new directory and place the model checkpoint and configuration inside it. Assuming your current directory has this structure (doesn't have to be exactly this):
uv tool install yt-dlp
yt-dlp -f bestaudio -o data/audio/input/3BFTio5296w.flac 3BFTio5296w
wget -P data/models/ https://huggingface.co/undef13/splifft/resolve/main/roformer-fp16.pt?download=true
wget -P data/config/ https://raw.githubusercontent.com/undef13/splifft/refs/heads/main/src/splifft/data/config/bs_roformer-fruit-sw.json
.
└── data
├── audio
│ ├── input
│ │ └── 3BFTio5296w.flac
│ └── output
├── config
│ └── bs_roformer-fruit-sw.json
└── models
└── roformer-fp16.pt
Run:
splifft run data/audio/input/3BFTio5296w.flac --config data/config/bs_roformer-fruit-sw.json --checkpoint data/models/roformer-fp16.pt
[00:00:41] INFO using device=device(type='cuda') __main__.py:111
INFO loading configuration from __main__.py:113
config_path=PosixPath('data/config/bs_roformer.json')
INFO loading model metadata `BSRoformer` from module `splifft.models.bs_roformer` __main__.py:126
[00:00:42] INFO loading weights from checkpoint_path=PosixPath('data/models/roformer-fp16.pt') __main__.py:127
INFO processing audio file: __main__.py:135
mixture_path=PosixPath('data/audio/input/3BFTio5296w.flac')
⠙ processing chunks... ━━━━━━━━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 25% 0:00:10 (bs=4 • cuda • float16)
[00:00:56] INFO wrote stem `bass` to data/audio/output/3BFTio5296w/bass.flac __main__.py:158
INFO wrote stem `drums` to data/audio/output/3BFTio5296w/drums.flac __main__.py:158
INFO wrote stem `other` to data/audio/output/3BFTio5296w/other.flac __main__.py:158
[00:00:57] INFO wrote stem `vocals` to data/audio/output/3BFTio5296w/vocals.flac __main__.py:158
INFO wrote stem `guitar` to data/audio/output/3BFTio5296w/guitar.flac __main__.py:158
INFO wrote stem `piano` to data/audio/output/3BFTio5296w/piano.flac __main__.py:158
[00:00:58] INFO wrote stem `instrum` to data/audio/output/3BFTio5296w/instrum.flac __main__.py:158
INFO wrote stem `drums_and_bass` to data/audio/output/3BFTio5296w/drums_and_bass.flac __main__.py:158
To update the tool:
uv tool upgrade splifft --force-reinstall
Where is my
config.json, and which one is actually used?
Think of two locations:
src/splifft/data/config/*.json in this repo)splifft pull {model_id}splifft run --model {model_id} uses your cached copy:
~/.cache/splifft/{model_id}/config.json~/Library/Caches/splifft/{model_id}/config.json%LOCALAPPDATA%\splifft\Cache\{model_id}\config.jsonWhat is the difference between
--override-configand editingconfig.json?
--override-config "inference.batch_size=2" is temporary for that command only.config.json is persistent for all future runs.Use overrides to experiment quickly, then copy stable values into your config.
I hit
CUDA out of memory.
Reduce memory pressure first:
splifft run --override-config "inference.batch_size=2"
Then, if you have a GPU and want to use fp16 mixed precision:
splifft run --override-config 'inference.use_autocast_dtype="float16"'
Final stitching allocates memory on the GPU by default, so move the non-model work to CPU if needed:
splifft run --override-config 'inference.io_device="cpu"'
I only want some outputs (for example one stem).
Modify inference.requested_stems in the config.json or:
splifft run \
--model bs_roformer-fruit-sw \
--override-config 'inference.requested_stems=["piano"]'
My config suddenly fails validation after an upgrade.
Your cached config may be from an older schema. If you want the latest preset config without redownloading checkpoint weights:
splifft pull --force-overwrite-config bs_roformer-fruit-sw
Note that this discards your previous changes!
Where do I find the config contract?
splifft.config.Configsrc/splifft/data/config.schema.jsonFor example, runtime batch size is inference.batch_size.
How do I derive custom outputs (e.g. drumless)?
Use derived_stems in config (they will be executed in the order you define it), for example:
{
// ...
"derived_stems": {
"drumless": {
"operation": "subtract",
"stem_name": "vocals",
"by_stem_name": "mixture"
},
"drums_and_bass": {
"operation": "add",
"stem_names": ["drums", "bass"]
}
}
}
Add splifft to your project:
# latest pypi version
uv add splifft
# latest bleeding edge
uv add git+https://github.com/undef13/splifft.git
This will install the absolutely minimal core dependencies used under the src/splifft/models directory. Higher level components, e.g. inference, training or CLI components must be installed via optional dependencies, as specified in the project.optional-dependencies section of pyproject.toml, for example:
# enable the built-in configuration, inference and CLI
uv add "splifft[config,inference,cli,web]"
This will install splifft in your venv.
If you'd like to make local changes, it is recommended to enable all optional and developer group dependencies:
git clone https://github.com/undef13/splifft.git
cd splifft
uv venv
uv sync --all-extras --all-groups
You may also want to use --editable with sync. Check your code:
# lint & format
just fmt
# build & host documentation
just docs
Code style:
ConfigDict. This provides static type safety, runtime data validation, IDE autocompletion, and a single, clear source of truth for all parameters.splifft.types.ChunkSize) to convey intent. It reduces the needs of verbose docstrings.PRs are very welcome!
src/splifft/data/registry.jsonsrc/splifft/data/config/{config_id}.jsonuv run scripts/gen_schema.py.Registry.from_file, Config.from_file)If you would like to add a model to the splifft registry:
architecture, purpose, config_id, output, resources[]data/config, or auto-convert your MSST yaml with uv run scripts/community.py fix-registry-with-msstuv run scripts/community.py fix-registry to auto generate the created_at /model_size/digest fields using HF/GH metadata and sync outputs from configs.pnpm run fmt:json src/splifft/data/registry.jsonRight now, registry + configs are shipped in the package itself, with new model visibility inherently tied to package release/version bump. In the future, we may add a splifft update command.
splifft is currently optimised for inferencing and does not yet support training.
Near term:
torch.jit.scriptcoremltoolsLong term:
Lightweight utilities for music source separation and transcription.
See the codeLightweight utilities for music source separation and transcription.
This library is a ground-up rewrite of the zfturbo's MSST repo, with a strong focus on robustness, simplicity and extensibility. We keep third-party dependencies to an absolute minimum to ease installation.
⚠️ This is pre-alpha software, expect significant breaking changes before v0.1.
Our default registry supports 110+ community-trained separation models.
More information about models and config can be found on the documentation.
There are three steps. You do not need to have Python installed.
Install uv if you haven't already. It is an awesome Python package and library manager with pip compatibility.
# Linux / MacOS
wget -qO- https://astral.sh/uv/install.sh | sh
# Windows
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
Open a new terminal and install the latest stable PyPI release as a tool. It will install the Python interpreter, all necessary packages and add the splifft executable to your PATH:
uv tool install "splifft[config,inference,cli,web]"
The core is kept as minimal as possible. Pick which ones you need:
config extra is used to parse the model configuration from JSON and discover the registry's default cache dir.inference extra is used to decode audio formats.cli extra provides you with the splifft command line toolweb extra is used to download models.This directly pulls from the main branch, which may be unstable:
uv tool install "git+https://github.com/undef13/splifft.git[config,inference,cli,web]"
We recommend using our built-in registry to manage model config and weights:
# list all available models, including those not yet available locally
splifft ls -a
# download model files and config to your user cache directory
# ~/.cache/splifft on linux
splifft pull bs_roformer-fruit-sw
# view information about the configuration
# modify the configuration, such as batch size according to your hardware
splifft info bs_roformer-fruit-sw
# run inference
splifft run data/audio/input/3BFTio5296w.flac --model bs_roformer-fruit-sw
Alternatively, for custom models, you can manage files manually. Go into a new directory and place the model checkpoint and configuration inside it. Assuming your current directory has this structure (doesn't have to be exactly this):
uv tool install yt-dlp
yt-dlp -f bestaudio -o data/audio/input/3BFTio5296w.flac 3BFTio5296w
wget -P data/models/ https://huggingface.co/undef13/splifft/resolve/main/roformer-fp16.pt?download=true
wget -P data/config/ https://raw.githubusercontent.com/undef13/splifft/refs/heads/main/src/splifft/data/config/bs_roformer-fruit-sw.json
.
└── data
├── audio
│ ├── input
│ │ └── 3BFTio5296w.flac
│ └── output
├── config
│ └── bs_roformer-fruit-sw.json
└── models
└── roformer-fp16.pt
Run:
splifft run data/audio/input/3BFTio5296w.flac --config data/config/bs_roformer-fruit-sw.json --checkpoint data/models/roformer-fp16.pt
[00:00:41] INFO using device=device(type='cuda') __main__.py:111
INFO loading configuration from __main__.py:113
config_path=PosixPath('data/config/bs_roformer.json')
INFO loading model metadata `BSRoformer` from module `splifft.models.bs_roformer` __main__.py:126
[00:00:42] INFO loading weights from checkpoint_path=PosixPath('data/models/roformer-fp16.pt') __main__.py:127
INFO processing audio file: __main__.py:135
mixture_path=PosixPath('data/audio/input/3BFTio5296w.flac')
⠙ processing chunks... ━━━━━━━━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 25% 0:00:10 (bs=4 • cuda • float16)
[00:00:56] INFO wrote stem `bass` to data/audio/output/3BFTio5296w/bass.flac __main__.py:158
INFO wrote stem `drums` to data/audio/output/3BFTio5296w/drums.flac __main__.py:158
INFO wrote stem `other` to data/audio/output/3BFTio5296w/other.flac __main__.py:158
[00:00:57] INFO wrote stem `vocals` to data/audio/output/3BFTio5296w/vocals.flac __main__.py:158
INFO wrote stem `guitar` to data/audio/output/3BFTio5296w/guitar.flac __main__.py:158
INFO wrote stem `piano` to data/audio/output/3BFTio5296w/piano.flac __main__.py:158
[00:00:58] INFO wrote stem `instrum` to data/audio/output/3BFTio5296w/instrum.flac __main__.py:158
INFO wrote stem `drums_and_bass` to data/audio/output/3BFTio5296w/drums_and_bass.flac __main__.py:158
To update the tool:
uv tool upgrade splifft --force-reinstall
Where is my
config.json, and which one is actually used?
Think of two locations:
src/splifft/data/config/*.json in this repo)splifft pull {model_id}splifft run --model {model_id} uses your cached copy:
~/.cache/splifft/{model_id}/config.json~/Library/Caches/splifft/{model_id}/config.json%LOCALAPPDATA%\splifft\Cache\{model_id}\config.jsonWhat is the difference between
--override-configand editingconfig.json?
--override-config "inference.batch_size=2" is temporary for that command only.config.json is persistent for all future runs.Use overrides to experiment quickly, then copy stable values into your config.
I hit
CUDA out of memory.
Reduce memory pressure first:
splifft run --override-config "inference.batch_size=2"
Then, if you have a GPU and want to use fp16 mixed precision:
splifft run --override-config 'inference.use_autocast_dtype="float16"'
Final stitching allocates memory on the GPU by default, so move the non-model work to CPU if needed:
splifft run --override-config 'inference.io_device="cpu"'
I only want some outputs (for example one stem).
Modify inference.requested_stems in the config.json or:
splifft run \
--model bs_roformer-fruit-sw \
--override-config 'inference.requested_stems=["piano"]'
My config suddenly fails validation after an upgrade.
Your cached config may be from an older schema. If you want the latest preset config without redownloading checkpoint weights:
splifft pull --force-overwrite-config bs_roformer-fruit-sw
Note that this discards your previous changes!
Where do I find the config contract?
splifft.config.Configsrc/splifft/data/config.schema.jsonFor example, runtime batch size is inference.batch_size.
How do I derive custom outputs (e.g. drumless)?
Use derived_stems in config (they will be executed in the order you define it), for example:
{
// ...
"derived_stems": {
"drumless": {
"operation": "subtract",
"stem_name": "vocals",
"by_stem_name": "mixture"
},
"drums_and_bass": {
"operation": "add",
"stem_names": ["drums", "bass"]
}
}
}
Add splifft to your project:
# latest pypi version
uv add splifft
# latest bleeding edge
uv add git+https://github.com/undef13/splifft.git
This will install the absolutely minimal core dependencies used under the src/splifft/models directory. Higher level components, e.g. inference, training or CLI components must be installed via optional dependencies, as specified in the project.optional-dependencies section of pyproject.toml, for example:
# enable the built-in configuration, inference and CLI
uv add "splifft[config,inference,cli,web]"
This will install splifft in your venv.
If you'd like to make local changes, it is recommended to enable all optional and developer group dependencies:
git clone https://github.com/undef13/splifft.git
cd splifft
uv venv
uv sync --all-extras --all-groups
You may also want to use --editable with sync. Check your code:
# lint & format
just fmt
# build & host documentation
just docs
Code style:
ConfigDict. This provides static type safety, runtime data validation, IDE autocompletion, and a single, clear source of truth for all parameters.splifft.types.ChunkSize) to convey intent. It reduces the needs of verbose docstrings.PRs are very welcome!
src/splifft/data/registry.jsonsrc/splifft/data/config/{config_id}.jsonuv run scripts/gen_schema.py.Registry.from_file, Config.from_file)If you would like to add a model to the splifft registry:
architecture, purpose, config_id, output, resources[]data/config, or auto-convert your MSST yaml with uv run scripts/community.py fix-registry-with-msstuv run scripts/community.py fix-registry to auto generate the created_at /model_size/digest fields using HF/GH metadata and sync outputs from configs.pnpm run fmt:json src/splifft/data/registry.jsonRight now, registry + configs are shipped in the package itself, with new model visibility inherently tied to package release/version bump. In the future, we may add a splifft update command.
splifft is currently optimised for inferencing and does not yet support training.
Near term:
torch.jit.scriptcoremltoolsLong term:
401 followers · starred Aug 2025