Lightweight utilities for music source separation.
Project description
SpliFFT
Lightweight utilities for music source separation.
This library is a ground-up rewrite of the zfturbo's MSST repo, with a strong focus on robustness, simplicity and extensibility. While it is a fantastic collection of models and training scripts, this rewrite adopts a different architecture to address common pain points in research code.
Key principles:
- Configuration as code: pydantic models are used 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. - Data-oriented and functional core: complex class hierarchies and inheritance are avoided. the codebase is built on plain data structures (like
dataclasses) and pure, stateless functions. - Semantic typing as documentation: we leverage Python's type system to convey intent. types like
RawAudioTensorvs.NormalizedAudioTensormake function signatures self-documenting, reducing the need for verbose comments and ensuring correctness. - Extensibility without modification: new models can be integrated from external packages without altering the core library. the dynamic model loading system allows easy plug-and-play adhering to the open/closed principle.
⚠️ This is pre-alpha software, expect significant breaking changes.
Features and Roadmap
Short term (high priority)
- a robust, typed JSON configuration system powered by
pydantic - inferencing:
- normalization and denormalization
- chunk generation: vectorized with
unfold - chunk stitching: vectorized overlap-add with
fold - flexible ruleset for stem deriving: add/subtract model outputs or any intermediate output (e.g., creating an
instrumentaltrack by subtractingvocalsfrom themixture).
- web-based docs: generated with
mkdocswith excellent crossrefs. - simple CLI for inferencing on a directory of audio files
-
BS-Roformer: ensure bit-for-bit equivalence in pytorch and strive for max perf.- initial fp16 support
- support
coremltoolsandtorch.compile- handroll complex multiplication implementation
- handroll stft in forward pass
- port additional SOTA models from MSST (e.g. Mel Roformer, SCNet)
- model registry with simple file-based cache
- proper profiling (MFU, memory...)
- evals: SDR, bleedless, fullness, etc.
- datasets: MUSDB18-HQ, moises
Medium term
- simple web-based GUI with FastAPI and SolidJS.
- Jupyter notebook
Long term (low priority)
- data augmentation
- implement a complete, configurable training loop
-
maxkernels
Contributing: PRs are very welcome!
Installation & Usage
Documentation on the config (amongst other details) can be found here
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 comptability.# 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-based workflow 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
How do I find the config and override parts of it (e.g. change the batch size)?
splifft by default stores a list of configs under src/splifft/data/config/*.json of the project directory.
When installed as a uv tool (or pip library), they will be located under the your site packages directory.
When you do splifft pull {model_id}, the configuration will be copied from your site packages to a default cache directory:
- Linux:
~/.cache/splifft/{model_id}/config.json - MacOS:
~/Library/Caches/splifft/{model_id}/config.json - Windows:
%LOCALAPPDATA%\splifft\Cache\{model_id}\config.json
Modify these files to permanently change the configuration.
To setup your IDE intellisense, you can find the JSON Schema under src/splifft/data/config.schema.json.
I get the error
OutOfMemoryError: CUDA out of memory. Tried to allocate...
The default inference.batch_size values in the registry are tuned for running one job at a time on a ~12GB GPU.
If you hit CUDA out-of-memory, temporarily override the config:
# reduce memory pressure by lowering batch size
splifft run --override-config "inference.batch_size=2"
# if still OOM, also enable mixed precision
splifft run \
--override-config "inference.batch_size=2" \
--override-config 'inference.use_autocast_dtype="float16"'
Remember to commit your changes in your config.json.
The model outputs multiple stems, how do I only output a particular subset of it?
splifft run \
--model mdx23c-aufr33-drumsep_6stem \
--override-config 'inference.requested_stems=["kick", "snare"]'
splifft run \
--model bs_roformer-fruit-sw \
--override-config 'inference.requested_stems=["piano"]'
Again, remember to commit your changes to your config.json.
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 depedencies, 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
Format your code:
just fmt
This repo is no longer compatible with zfturbo's repo. The last version that does so is v0.0.1. To pin a specific version in uv, change your pyproject.toml:
[tool.uv.sources]
splifft = { git = "https://github.com/undef13/splifft.git", rev = "287235e520f3bb927b58f9f53749fe3ccc248fac" }
Mojo
While the primary goal is just to have minimalist PyTorch-based inference engine, I will be using this project as an opportunity to learn more about heterogenous computing, particularly with the Mojo language. The ultimate goal will be to understand to what extent can its compile-time metaprogramming and explicit memory layout control be used.
My approach will be incremental and bottom-up: I'll develop, test and benchmark small components against their PyTorch counterparts. The PyTorch implementation will always remain the "source of truth", the fully functional baseline and never be removed.
TODO:
- evaluate
pixiinpyproject.toml. - use
max.torch.CustomOpLibraryto provide a callable from the pytorch side - use
DeviceContextto interact with the GPU - attention
- use
LayoutTensorfor QKV
- use
- rotary embedding
- feedforward
- transformer
-
BandSplit&MaskEstimator - full graph compilation
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.5.tar.gz.
File metadata
- Download URL: splifft-0.0.5.tar.gz
- Upload date:
- Size: 407.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3900537b6257150e55e4e4b6db85b3cf8c930f138ccfc8bc48d7a9ede836c48b
|
|
| MD5 |
c912df5f497786055393105d68cdcd80
|
|
| BLAKE2b-256 |
92ccf2a6a7e729e3c3e85af49576fcfd62f3b33fa47d0527756d65394360fc25
|
Provenance
The following attestation bundles were made for splifft-0.0.5.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.5.tar.gz -
Subject digest:
3900537b6257150e55e4e4b6db85b3cf8c930f138ccfc8bc48d7a9ede836c48b - Sigstore transparency entry: 962211123
- Sigstore integration time:
-
Permalink:
undef13/splifft@7033b5eb0601d81f0952a26087ef15f8a0785574 -
Branch / Tag:
refs/tags/v0.0.5 - Owner: https://github.com/undef13
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi.yml@7033b5eb0601d81f0952a26087ef15f8a0785574 -
Trigger Event:
push
-
Statement type:
File details
Details for the file splifft-0.0.5-py3-none-any.whl.
File metadata
- Download URL: splifft-0.0.5-py3-none-any.whl
- Upload date:
- Size: 129.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 |
37b149d453dc36d361bbf59e28e14ae71215273f1cc1491132f4897b857d0681
|
|
| MD5 |
45c8f4d567ff5fefa61a88fd71ccdd53
|
|
| BLAKE2b-256 |
afd161ac4659549adc14feb33caa6c24f00ac88087781dd99689409841c4fab8
|
Provenance
The following attestation bundles were made for splifft-0.0.5-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.5-py3-none-any.whl -
Subject digest:
37b149d453dc36d361bbf59e28e14ae71215273f1cc1491132f4897b857d0681 - Sigstore transparency entry: 962211125
- Sigstore integration time:
-
Permalink:
undef13/splifft@7033b5eb0601d81f0952a26087ef15f8a0785574 -
Branch / Tag:
refs/tags/v0.0.5 - Owner: https://github.com/undef13
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi.yml@7033b5eb0601d81f0952a26087ef15f8a0785574 -
Trigger Event:
push
-
Statement type: