htdemucs β ONNX graphs for onnxruntime-web (WebGPU)
Hybrid Transformer Demucs, exported to ONNX and prepared for in-browser inference with onnxruntime-web on the WebGPU backend. Used by stemstudio.jp for local, upload-free stem separation.
Derived from facebookresearch/demucs
(MIT). See LICENSE β the upstream notice travels with these files.
Files
| File | Transfer (gzip) | Inflated | Stems |
|---|---|---|---|
htdemucs_ft.opt.fp16.istft.onnx.gzbin |
141,591,461 | 172,746,888 | vocals / instrumental (fine-tuned) |
htdemucs_4s.opt.fp16.istft.onnx.gzbin |
141,601,329 | 172,746,888 | vocals / drums / bass / other |
htdemucs_6s.opt.fp16.istft.onnx.gzbin |
114,203,693 | 142,573,723 | + guitar / piano |
Two things that are easy to get wrong
1. The .gzbin extension is deliberate. These are raw gzip streams stored
as ordinary files, and the browser inflates them with
DecompressionStream('gzip'). They are not named .gz, because some hosts
and dev servers see that extension and add content-encoding: gzip, at which
point the transport decompresses them and the application decompresses them
again β which fails with incorrect header check. Detect gzip by the leading
magic bytes (1f 8b), not by header or extension.
The compression is in the file rather than in the transport because model hosts
generally serve .onnx uncompressed regardless of Accept-Encoding.
2. Build order matters: optimize before fp16, not after. Running the
graph optimizer on an fp16 graph overflows folded constants to inf and every
output becomes NaN. Worse, nan > tolerance is false, so a naive comparison
reports "max diff 0.000e+00 / OK" on a completely broken model. The order used
here is: fp32 export β graph optimization β fp16 weights β inverse STFT folded
into the graph.
Why the optimized graph is WebGPU-only
Measured on one 7.8 s segment, same model, same host:
| wasm heap | wasm infer | WebGPU session build | |
|---|---|---|---|
| unoptimized | 1,223 MB | 16.8 s | 15.6 s |
| optimized | 3,251 MB | 18.1 s | 1.4 s |
On WebGPU, session build gets ~11Γ faster. On wasm, heap grows 2.7Γ and inference gets slower. "Ship the optimized one and everyone gets faster" is false β pick per execution provider.
Training data
The upstream weights were trained on MUSDB18-HQ and additional sources. The MIT license covers the code and these derived graphs; the dataset carries its own terms, which are worth checking for your own use.