Downloads · 30 days
0
monteslu/htdemucs-web-onnx
htdemucs-web-onnx is a audio-to-audio model from monteslu. Use it for the audio-to-audio task on the model card, and read the license before you ship it in a product. The card lists the license as mit.
htdemucs (Hybrid Transformer Demucs) 4-stem music source separation (drums / bass / other / vocals), exported to ONNX for onnxruntime-web on WebGPU, in a form designed to run while the same GPU is rendering a UI the u…
Downloads · 30 days
0
Access
Public
Updated Jul 7, 2026
Repo size
126 MB
Likes
0
Public
Click a slice to open those files.
.onnx126 MB · 100%
From the Hugging Face model README
htdemucs (Hybrid Transformer Demucs) 4-stem music source separation (drums / bass / other / vocals), exported to ONNX for onnxruntime-web on WebGPU, in a form designed to run while the same GPU is rendering a UI the user is watching.
Running htdemucs as one ONNX session makes each inference a ~200-330ms monolithic GPU burst. The browser compositor cannot interleave frames with a submitted burst, so any UI sharing the GPU freezes for the duration, and pacing between runs cannot shorten a single burst. This export solves both cost and burst length:
Conv/ConvTranspose (full fp16 degrades the
drums and bass stems badly; with convolutions kept fp32 every stem stays at correlation
= 0.9998 against the fp32 reference). Constants are folded before conversion. ~2.4x faster than fp32 and 126MB total instead of 173MB.
htdemucs_p00.onnx ... htdemucs_p20.onnx), cut at encoder /
transformer-layer / decoder sub-block boundaries so each piece is a ~10-30ms GPU
submission. Draining the queue between pieces lets a 30-60Hz UI keep every frame while
separation runs. The fp32 piece chain reproduces the monolithic model bit-exactly;
the shipped fp16 chain measures per-stem correlation >= 0.9998 on real music.Measured on a Radeon RX 7600 with a WebGPU app actively rendering: 30Hz display holds a steady 30fps through the entire separation (a monolithic session managed 12-18fps with 330ms freezes). Throughput ~22x realtime run back-to-back, ~8x with compositor-friendly pacing.
htdemucs_split_manifest.json: ordered piece list. Each entry: {file, inputs, outputs}
(ONNX tensor names). Top level also has outputs: {"freq": "x", "time": "xt"}.htdemucs_p00.onnx ... htdemucs_p20.onnx: the pieces. Run strictly in manifest order.mix [1, 2, 343980] fp32 waveform segment (44.1kHz stereo),
mag [1, 4, 2048, 336] fp32 spectrogram (STFT real/imag interleaved per channel,
matching the standard demucs-web preprocessing). Final outputs: x
[1, 4, 4, 2048, 336] (frequency branch) and xt [1, 4, 2, 343980] (time branch),
combined by the usual demucs post-processing (mask/iSTFT + overlap-add).mix/mag, run pieces in order,
merge each piece's outputs back into the map. All boundary tensors are fp32
(keep_io_types). With preferredOutputLocation: 'gpu-buffer' the boundaries never leave
the GPU; dispose them after each segment.const CPU_NODES = ['/ReduceMean','/Sub','/Pow','/ReduceMean_1','/Clip','/Sqrt','/Add','/Div',
'/ReduceMean_2','/Sub_1','/Pow_1','/ReduceMean_3','/Clip_1','/Sqrt_1','/Add_1','/Div_1'];
const session0 = await ort.InferenceSession.create(piece0, {
executionProviders: [{ name: 'webgpu', forceCpuNodeNames: CPU_NODES }],
graphOptimizationLevel: 'all',
preferredOutputLocation: 'gpu-buffer',
});
// pieces 1..20: executionProviders: ['webgpu'], NO forceCpuNodeNames
If you feed mix/mag as GPU buffers, create those buffers with COPY_SRC usage
(the CPU-pinned nodes read them back host-side).
await device.queue.onSubmittedWorkDone() plus a few ms of
sleep after each piece. For maximum throughput: run pieces back to back (~7% overhead vs
a monolithic session). Never have two run() calls in flight at once.Exported from the official facebookresearch/demucs
htdemucs weights (single model, not the ft ensemble) via torch.onnx with an fp16-safe
normalization wrapper; the fp32 export is bit-identical in output to
timcsy/demucs-web-onnx htdemucs_embedded.onnx.
Then: ONNX Runtime offline BASIC optimization while still fp32 (constant folding),
convert_float_to_float16(op_block_list=['Conv','ConvTranspose']) per piece, and a
dependency-bounded graph cut into 21 pieces validated bit-exact against the monolith in fp32.
License: MIT, matching demucs. Credit for htdemucs goes to Alexandre Défossez et al. (Meta AI); see the demucs repository for the papers.