Lightweight utilities for music source separation.
Project description
SpliFFT
Lightweight 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.
Supported Models
- BS-Roformer (including unwa's HyperACE v1 and v2, Large Inst modifications)
- Mel-Roformer
- MDX23C TFC-TDF v3
- beat this! for beat tracking without DBN postprocessing
- PESTO for monophonic pitch estimation
- basic pitch for polyphonic pitch estimation (only frame-level onset, multipitch and posteriorgrams, no MIDI postprocessing)
Our default registry supports 110+ community-trained separation models.
Installation & Usage
More information about models and config can be found on the documentation.
CLI
There are three steps. You do not need to have Python installed.
-
Install
uvif 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
splifftexecutable to yourPATH:uv tool install "splifft[config,inference,cli,web]"
Explanation of feature flags
The core is kept as minimal as possible. Pick which ones you need:
- The
configextra is used to parse the model configuration from JSON and discover the registry's default cache dir. - The
inferenceextra is used to decode audio formats. - The
cliextra provides you with thesplifftcommand line tool - The
webextra is used to download models.
I want the latest bleeding-edge version
This directly pulls from the
mainbranch, which may be unstable:uv tool install "git+https://github.com/undef13/splifft.git[config,inference,cli,web]"
- The
-
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):
Minimal reproduction: with example audio from YouTube
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/data/config/bs_roformer.json
. └── data ├── audio │ ├── input │ │ └── 3BFTio5296w.flac │ └── output ├── config │ └── bs_roformer.json └── models └── roformer-fp16.ptRun:
splifft run data/audio/input/3BFTio5296w.flac --config data/config/bs_roformer.json --checkpoint data/models/roformer-fp16.pt
Console output
[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
FAQ
Where is my
config.json, and which one is actually used?
Think of two locations:
- Built-in templates bundled in the installed package (
src/splifft/data/config/*.jsonin this repo) - Your editable copy after
splifft pull {model_id}
splifft run --model {model_id} uses your cached copy:
- Linux:
~/.cache/splifft/{model_id}/config.json - macOS:
~/Library/Caches/splifft/{model_id}/config.json - Windows:
%LOCALAPPDATA%\splifft\Cache\{model_id}\config.json
What is the difference between
--override-configand editingconfig.json?
--override-config "inference.batch_size=2"is temporary for that command only.- editing
config.jsonis 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.batch_size=2" \
--override-config 'inference.use_autocast_dtype="float16"'
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?
- API docs:
splifft.config.Config - JSON schema:
src/splifft/data/config.schema.json
For 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"]
}
}
}
Library
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.
Development
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:
- Use stdlib dataclasses or pydantic BaseModels instead of untyped dictionaries or
ConfigDict. This provides static type safety, runtime data validation, IDE autocompletion, and a single, clear source of truth for all parameters. - Avoid complex class hierarchies and inheritance. Use plain data structures and pure, stateless functions.
- Leverage Python's type system and our built-in types (e.g.
splifft.types.ChunkSize) to convey intent. It reduces the needs of verbose docstrings. - The core should remain agnostic and not contain any model-specific code other than high-level pre/postprocessing archetypes.
PRs are very welcome!
Registry
- Source of truth:
src/splifft/data/registry.json - Per-model runtime config:
src/splifft/data/config/{config_id}.json - JSON Schema are generated with
uv run scripts/gen_schema.py. - Validation gate: pydantic (
Registry.from_file,Config.from_file)
If you would like to add a model to the splifft registry:
- upload checkpoint (ideally to huggingface), with optional MSST config
- add registry entry:
architecture,purpose,config_id,output,resources[] - write your own config JSON under
data/config, or auto-convert your MSST yaml withuv run scripts/community.py fix-registry-with-msst - optionally, run
uv run scripts/community.py fix-registryto auto generate thecreated_at/model_size/digestfields using HF/GH metadata and sync outputs from configs. - format registry JSON:
pnpm run fmt:json src/splifft/data/registry.json
Right 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.
Roadmap
splifft is currently optimised for inferencing and does not yet support training.
Near term:
torch.jit.script- ONNX export
coremltools- support streaming with ring buffer
- simple web-based GUI with FastAPI and SolidJS.
- Jupyter notebook
Long term:
- evals: SDR, bleedless, fullness, etc.
- datasets: MUSDB18-HQ, moises
- implement a complete, configurable training loop
- data augmentation
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file splifft-0.0.7.tar.gz.
File metadata
- Download URL: splifft-0.0.7.tar.gz
- Upload date:
- Size: 423.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
17efcde3fa70ca33a360b518bb5d5e414bda38d36c99e6c0ff1799308628291e
|
|
| MD5 |
e11b75ca96bb9a83d3ad320fd86a8912
|
|
| BLAKE2b-256 |
5683a23f601dda537866925745d55e90ade4a854571100ae5a684416f302e5db
|
Provenance
The following attestation bundles were made for splifft-0.0.7.tar.gz:
Publisher:
pypi.yml on undef13/splifft
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
splifft-0.0.7.tar.gz -
Subject digest:
17efcde3fa70ca33a360b518bb5d5e414bda38d36c99e6c0ff1799308628291e - Sigstore transparency entry: 1101911106
- Sigstore integration time:
-
Permalink:
undef13/splifft@73e37121969363ddd269469ea20a93e70c4ceef7 -
Branch / Tag:
refs/tags/v0.0.7 - Owner: https://github.com/undef13
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi.yml@73e37121969363ddd269469ea20a93e70c4ceef7 -
Trigger Event:
push
-
Statement type:
File details
Details for the file splifft-0.0.7-py3-none-any.whl.
File metadata
- Download URL: splifft-0.0.7-py3-none-any.whl
- Upload date:
- Size: 144.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0b4aa67a7eea32c80008e12545b9b98ee2a45e9469bb730d8cbc44773657e432
|
|
| MD5 |
21077312a15137bda1d55b738b08ef90
|
|
| BLAKE2b-256 |
7be1696060206d9e0261fe495b8beacd0fc227e56ff0af3486a80fa3bbfd4a13
|
Provenance
The following attestation bundles were made for splifft-0.0.7-py3-none-any.whl:
Publisher:
pypi.yml on undef13/splifft
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
splifft-0.0.7-py3-none-any.whl -
Subject digest:
0b4aa67a7eea32c80008e12545b9b98ee2a45e9469bb730d8cbc44773657e432 - Sigstore transparency entry: 1101911142
- Sigstore integration time:
-
Permalink:
undef13/splifft@73e37121969363ddd269469ea20a93e70c4ceef7 -
Branch / Tag:
refs/tags/v0.0.7 - Owner: https://github.com/undef13
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi.yml@73e37121969363ddd269469ea20a93e70c4ceef7 -
Trigger Event:
push
-
Statement type: