UVR MDX-Net β†’ LiteRT

Three UVR MDX-Net models converted to LiteRT (.tflite) in fp16 for on-device music stem separation on Android. Each one splits a stereo mix into vocals and instrumental.

This repo ships the models, a runnable Python reference (separate.py), and the export script that produced them.

Models

Model Predicts Params dim_f n_fft hop
UVR_MDXNET_9482 vocals 7.4 M 2048 4096 1024
UVR-MDX-NET-Voc_FT vocals 16.7 M 3072 6144 1024
UVR-MDX-NET-Inst_HQ_3 instrumental 16.7 M 3072 6144 1024
  • 9482 β€” smallest and fastest. A good default.
  • Voc FT β€” higher-quality vocals.
  • Inst HQ 3 β€” cleaner instrumental.

Each model predicts one stem; the other is the residual (mix βˆ’ predicted). Inst HQ 3 predicts the instrumental, so its residual is inverted relative to the other two. separate.py handles this per model.

Two builds of each

Every model ships in two forms β€” same graph, same input and output, different weight storage:

Suffix Weights 9482 Voc FT / Inst HQ 3
.fp16acc.tflite fp32 28 MB 64 MB
.fp16w.tflite fp16 15 MB 34 MB

.fp16acc is the default and the more conservative choice. .fp16w halves the download and the APK at a small, measured cost in precision:

Model vocals instrumental largest sample difference
9482 65.7 dB 59.4 dB βˆ’64.8 dBFS
Voc FT 71.7 dB 65.2 dB βˆ’69.0 dBFS
Inst HQ 3 69.4 dB 62.4 dB βˆ’62.1 dBFS

(SNR of the .fp16w output against the .fp16acc output on the same audio β€” well below the level of MDX's own separation artifacts.) Both builds carry the fp16accfp16 metadata flag, so either can run its arithmetic in fp16 on ARMv8.2 cores; only the stored weights differ. The .fp16w builds have not yet been validated on-device β€” prefer .fp16acc for production until you have.

Quickstart

pip install -r requirements.txt

# input must be WAV
ffmpeg -i example.mp3 example.wav

python separate.py example.wav                    # β†’ example_vocals.wav + example_instrumental.wav
python separate.py example.wav --model voc_ft
python separate.py example.wav --model inst_hq3
python separate.py example.wav --fp16-weights     # use the half-size .fp16w build

Options: --out-dir DIR, --denoise. Use 44.1 kHz stereo input for best results.

Model input and output

The .tflite is the neural network only β€” the STFT and inverse STFT run in your own code.

input = output = float32 [1, 4, dim_f, 256]   (NCHW)

The 4 channels are the real and imaginary STFT planes in the order [L_re, L_im, R_re, R_im], at flat index ((plane Β· dim_f) + bin) Β· 256 + frame. Use a periodic Hann window, centered with reflect padding, unnormalized, keeping bins [0, dim_f) β€” the Nyquist bin is dropped. One pass covers 256 frames (about 5.9 seconds at 44.1 kHz); longer audio is processed in overlapping chunks.

separate.py is a complete reference implementation of the above.

Android

implementation("com.google.ai.edge.litert:litert:2.1.6")
val model = CompiledModel.create(
    tflitePath,
    CompiledModel.Options(Accelerator.GPU, Accelerator.CPU).apply {
        cpuOptions = CompiledModel.CpuOptions(numThreads = bigCoreCount)
    },
)
val inputs = model.createInputBuffers()
val outputs = model.createOutputBuffers()

inputs[0].writeFloat(chunkFloats)
model.run(inputs, outputs)
val stem = outputs[0].readFloat()

Two things to watch: copy the model to a file path and pass that, since loading from assets holds the whole model on the heap; and set numThreads, which defaults to 1.

Either build loads through the same call. Start with .fp16acc; the .fp16w files are the same graph at half the size, but confirm they load and delegate on your target devices before shipping them β€” check logcat for Replacing N out of M node(s) with delegate.

Reproducing the export

pip install torch==2.9.1 --index-url https://download.pytorch.org/whl/cpu
pip install -r export/requirements.txt

python export/export_mdx_litert.py UVR_MDXNET_9482.onnx        UVR_MDXNET_9482.fp16acc.tflite
python export/export_mdx_litert.py UVR-MDX-NET-Voc_FT.onnx     UVR-MDX-NET-Voc_FT.fp16acc.tflite
python export/export_mdx_litert.py UVR-MDX-NET-Inst_HQ_3.onnx  UVR-MDX-NET-Inst_HQ_3.fp16acc.tflite --min-snr 90

# add --fp16-weights for the .fp16w builds
python export/export_mdx_litert.py UVR_MDXNET_9482.onnx  UVR_MDXNET_9482.fp16w.tflite --fp16-weights

The export is deterministic and checks each model against the ONNX reference before writing it. Inst HQ 3 uses a slightly lower fidelity threshold (--min-snr 90); it converts to 95 dB where the other two reach 109–112 dB.

With --fp16-weights the graph is converted twice: once at fp32 to run the full correctness check, then again with fp16 weights as the output. The strict check has to run on the fp32 graph, because fp16 weights put a floor of roughly 30–50 dB under any random-input measurement β€” low enough to hide a genuine conversion fault. The fp16 pass additionally verifies that no int8 tensors appeared and that the file actually halved.

Source ONNX files come from the UVR MDX-Net releases at TRvlvr/model_repo, mirrored on the Hub at Politrees/UVR_resources.

License

MIT, matching the upstream models. The weights are from the Ultimate Vocal Remover project and its contributors; this repo redistributes them converted from ONNX to LiteRT fp16. See LICENSE.

Downloads last month
699
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support

Model tree for gyoom-sa/UVR-MDX-LiteRT

Quantized
(2)
this model