---
title: "HT-Demucs FT zu ONNX: Erster funktionierender Export (2026)"
date: "2026-05-20"
lastUpdated: "2026-05-20"
author: "StemSplit Team"
tags: ["htdemucs", "onnx", "stem separation", "mobile audio", "open source", "hugging face", "demucs", "AI music"]
excerpt: "Erster funktionierender ONNX-Export von HT-Demucs FT — verifizierte Parität gegenüber PyTorch (1.6e-4), 1.31× schneller auf CPU. Plus 9 offene Hugging-Face-Modelle."
abstract: "TL;DR. Wir haben soeben 10 Assets zur Stemtrennung auf Hugging Face quelloffen veröffentlicht, darunter den ersten funktionierenden ONNX-Export von HT-Demucs FT — den führenden Open-Source-Vokaltrenner auf MUSDB18-HQ. Jeder bisherige Versuch in Sachen „demucs onnx\" scheiterte an denselben vier Hürden; wir haben alle vier überwunden. Das Ergebnis läuft in `onnxruntime` auf CPU/CoreML/CUDA/DirectML ohne PyTorch zur Inferenzzeit, ist 1.31× schneller als PyTorch auf CPU und numerisch äquivalent zum ..."
locale: "de"
canonical: "https://stemsplit.io/de/blog/htdemucs-ft-onnx-export"
source: "stemsplit.io"
---

> **Source:** https://stemsplit.io/de/blog/htdemucs-ft-onnx-export  
> Originally published by [StemSplit](https://stemsplit.io). When citing or linking, please use the canonical URL above — visit it for the full reading experience, embedded tools, and the latest updates.

# HT-Demucs FT zu ONNX: Wie wir den ersten funktionierenden Export für iOS, Android & Web gebaut haben — plus 9 offene Hugging-Face-Modelle und ein reproduzierbarer MUSDB18-HQ-Benchmark (2026)

**TL;DR.** Wir haben soeben **10 Assets zur Stemtrennung** auf Hugging Face quelloffen veröffentlicht, darunter den **ersten funktionierenden ONNX-Export von HT-Demucs FT** — den führenden Open-Source-Vokaltrenner auf MUSDB18-HQ. Jeder bisherige Versuch in Sachen „demucs onnx" scheiterte an denselben vier Hürden; wir haben alle vier überwunden. Das Ergebnis läuft in `onnxruntime` auf CPU/CoreML/CUDA/DirectML **ohne PyTorch zur Inferenzzeit**, ist **1.31× schneller als PyTorch auf CPU** und **numerisch äquivalent zum Original** (maximale absolute Abweichung: 0.000163 über alle 4 Stems).

Im Folgenden: was wir veröffentlicht haben, warum es wichtig ist, und der Engineering-Bericht darüber, wie der ONNX-Export tatsächlich gelungen ist.

---

## Alles, was wir diese Woche veröffentlicht haben

| Asset | Typ | Was es ist |
|---|---|---|
| [stem-separation-benchmark-2026](https://huggingface.co/datasets/StemSplitio/stem-separation-benchmark-2026) | **Dataset** | Reproduzierbarer SDR-/ISR-/SIR-/SAR-Benchmark aller gängigen Open-Source-Separatoren (`htdemucs`, `htdemucs_ft`, `htdemucs_6s`, `mdx_extra_q`, `mdx_net_inst_hq3`) auf MUSDB18-HQ. 850 Zeilen, vollständige Eval-Pipeline quelloffen. |
| [Music Source Separation Toolkit 2026](https://huggingface.co/collections/StemSplitio/music-source-separation-toolkit-2026-6a0d059a55a1b261e939c9c6) | **Sammlung** | Kuratierte 17-teilige Sammlung der Open-Source-Modelle zur Stemtrennung, die sich 2026 lohnen. |
| [htdemucs-ft-pytorch](https://huggingface.co/StemSplitio/htdemucs-ft-pytorch) | Modell | PyTorch-Full-Bag für Hugging Face Inference Endpoints. Liefert alle 4 Stems. |
| [htdemucs-ft-\{drums,bass,other\}-pytorch](https://huggingface.co/StemSplitio) | Modelle (×3) | PyTorch-Stem-Spezialisten. Je ~160 MB, ~2.6× schneller als die volle Bag, identische Qualität pro Stem. |
| [**htdemucs-ft-onnx**](https://huggingface.co/StemSplitio/htdemucs-ft-onnx) | **Modell** | **Die vollständige 4-Stem-ONNX-Bag** + numpy-Aggregator. Insgesamt ~1.26 GB. Das Drop-in-Paket, wenn du alle 4 Stems auf Mobile/Edge/Web willst. |
| [htdemucs-ft-drums-onnx](https://huggingface.co/StemSplitio/htdemucs-ft-drums-onnx) | Modell | Drum-Spezialist als ONNX. ~75 % kleiner als die volle Bag, ~4× schneller, wenn du nur Drums brauchst. |
| [htdemucs-ft-bass-onnx](https://huggingface.co/StemSplitio/htdemucs-ft-bass-onnx) | Modell | Bass-Spezialist als ONNX. |
| [htdemucs-ft-other-onnx](https://huggingface.co/StemSplitio/htdemucs-ft-other-onnx) | Modell | „Other"-/Instrumental-Spezialist als ONNX. |
| [htdemucs-ft-vocals-onnx](https://huggingface.co/StemSplitio/htdemucs-ft-vocals-onnx) | Modell | **Bester Open-Source-Gesangs-SDR (9.19 dB)** als ONNX. Das verteidigbare Herzstück jeder iOS-/Android-App zur Vokalentfernung. |

Alle MIT-lizenziert, alle auf der [StemSplitio-Org-Seite](https://huggingface.co/StemSplitio).

**Die Schlagzeile:** Die ONNX-Repos sind unseres Wissens nach die **ersten funktionierenden ONNX-Exporte von HT-Demucs FT auf Hugging Face**. Nicht „erster Versuch" — der erste, der lädt, läuft, korrekte Zahlen liefert und mit paritätsverifizierten Benchmarks ausgeliefert wird.

---

## Warum wir das gemacht haben

### Die Benchmark-Lücke

Wer 2026 versucht hat, ein Modell zur Stemtrennung auszuwählen, fand ein Chaos vor. Jedes Modell-Repo behauptet, sein Modell sei „State of the Art". Wenige veröffentlichen reproduzierbare Benchmarks. Noch weniger testen dieselben Modelle gegeneinander auf derselben Hardware mit denselben Metriken.

Das haben wir behoben, indem wir [**stem-separation-benchmark-2026**](https://huggingface.co/datasets/StemSplitio/stem-separation-benchmark-2026) veröffentlicht haben — 850 Zeilen mit SDR-/ISR-/SIR-/SAR-Werten für `htdemucs`, `htdemucs_ft`, `htdemucs_6s`, `mdx_extra_q` und `mdx_net_inst_hq3` auf MUSDB18-HQ, mit vollständig quelloffener Evaluierungspipeline. Jeder kann es klonen, neu ausführen und unsere Zahlen anfechten.

Wichtigstes Ergebnis: **`htdemucs_ft` ist der beste Open-Source-Vokaltrenner (9.19 dB Median-Gesangs-SDR)**, und **`mdx_extra_q` ist der beste Open-Source-Trenner für Drums/Bass/Other** (11.49 / 11.42 / 7.67 dB). Unterschiedliche Modelle für unterschiedliche Stems.

### Die ONNX-Lücke

Das größere Problem: Wer HT-Demucs FT auf iOS, Android oder im Browser einsetzen wollte, konnte es schlicht nicht. PyTorchs Mobile-Story ist holprig, MPS/CUDA sind nur serverseitig, und die naheliegende Antwort — ONNX — war bisher nie umgesetzt worden.

Es gibt mindestens vier offene GitHub-Issues im demucs-Repo, die nach ONNX-Exporten fragen. Mehrere halb funktionierende Forks. Ein PR aus 2023, der nicht gemergt wird. Ein paar MLX-Experimente, die einen M1+ Mac voraussetzen. Nichts, was „einfach läuft".

Der Grund: HT-Demucs trifft architektonische Entscheidungen, die in PyTorch harmlos aussehen, aber ONNX-Exporter auf nicht offensichtliche Weise zerbrechen. Wir sind auf alle vier gestoßen und haben sie behoben — und das ist der Rest dieses Posts.

---

## Wie HT-Demucs FT jeden ONNX-Exporter brechen lässt

Wir haben es zuerst mit `torch.onnx.export` versucht, dann mit `torch.onnx.dynamo_export`. Beide sind an unterschiedlichen Stellen gescheitert. Hier ist der vollständige Katalog der Blocker und wie jeder gelöst wurde:

### Blocker 1: `complex64`-STFT-Ausgabe

`HT-Demucs` beginnt mit einer Short-Time Fourier Transform (`spec.py::spectro`):

```python
z = torch.stft(x, n_fft=4096, hop_length=1024, window=hann,
               win_length=4096, normalized=True, center=True,
               return_complex=True, pad_mode="reflect")
```

Dieses `return_complex=True` gibt einen `complex64`-Tensor zurück. CoreMLs MIL kennt keinen komplexen dtype. Auch ONNXs STFT-Op (opset 17+) unterstützt keine komplexen Ausgaben. Jede nachgelagerte Slice-/Transpose-Op im Graphen schlägt sofort fehl.

**Lösung.** Ersetze `torch.stft` durch ein `Conv1d` mit Sin/Cos-Kerneln, das direkt zwei reelle Kanäle ausgibt:

```python
def _make_stft_kernels(n_fft: int) -> tuple[torch.Tensor, torch.Tensor]:
    n = torch.arange(n_fft, dtype=torch.float64)
    window = torch.hann_window(n_fft, periodic=True, dtype=torch.float64)
    norm = 1.0 / math.sqrt(n_fft)
    k = torch.arange(n_fft // 2 + 1, dtype=torch.float64).unsqueeze(1)
    angles = 2 * math.pi * k * n.unsqueeze(0) / n_fft
    cos = (window * torch.cos(angles)) * norm
    sin = (window * -torch.sin(angles)) * norm   # negative for forward STFT
    return cos.float().unsqueeze(1), sin.float().unsqueeze(1)

class RealSTFT(nn.Module):
    def forward(self, x: torch.Tensor) -> torch.Tensor:
        x = F.pad(x.reshape(-1, 1, x.shape[-1]), (n_fft // 2,) * 2, mode="reflect")
        real = F.conv1d(x, self.cos_kernel, stride=self.hop_length)
        imag = F.conv1d(x, self.sin_kernel, stride=self.hop_length)
        return torch.stack([real, imag], dim=1)   # (..., 2, F, T) real
```

Verifiziert auf **5 × 10⁻⁶ maximale absolute Abweichung** gegenüber `torch.stft` direkt. Derselbe Trick für die Inverse mit `ConvTranspose1d` plus einer Overlap-Add-Hüllkurve aus dem Fensterquadrat.

Nach dieser Korrektur wird jedes `view_as_real` / `view_as_complex` in `_magnitude` und `_mask` so umgeschrieben, dass reelle Kanal-Tensoren durch den gesamten Forward-Pass geschleust werden. Nirgendwo mehr komplexe Tensoren.

### Blocker 2: `fractions.Fraction` in `model.segment`

Das vortrainierte `htdemucs_ft` speichert seine Segmentlänge als `Fraction(39, 5)` (= 7.8 Sekunden). Dynamo kann keine `Fraction`-Arithmetik tracen — es wirft `torch._dynamo.exc.Unsupported: call_function UserDefinedClassVariable(<class 'fractions.Fraction'>)`.

**Lösung.** Vor dem Export in einen float casten:

```python
if isinstance(model.segment, Fraction):
    model.segment = float(model.segment)   # 7.8
```

Trivial. Die Mathematik bleibt zur Inferenzzeit identisch.

### Blocker 3: `random.randrange` im Cross-Transformer

`CrossTransformerEncoder._get_pos_embedding` ruft Pythons `random.randrange` auf:

```python
def _get_pos_embedding(self, T, B, C, device):
    if self.emb == "sin":
        shift = random.randrange(self.sin_random_shift + 1)
        return create_sin_embedding(T, C, shift=shift, ...)
```

Zur Inferenzzeit ist `sin_random_shift=0`, also liefert `random.randrange(1)` immer 0 — ein No-op. Aber der ONNX-Exporter sieht trotzdem nicht durch Pythons `random`-Modul hindurch und scheitert.

**Lösung.** Monkey-Patch der Methode selbst, sodass `shift=0` hartkodiert ist:

```python
def _get_pos_embedding_no_random(self_, T, B, C, device):
    if self_.emb == "sin":
        return create_sin_embedding(T, C, shift=0, device=device,
                                    max_period=self_.max_period)
    # ... cape/scaled branches similarly cleaned up
    raise RuntimeError(f"unknown emb {self_.emb}")

for m in model.modules():
    if isinstance(m, CrossTransformerEncoder):
        m._get_pos_embedding = types.MethodType(_get_pos_embedding_no_random, m)
```

Mathematisch identisch zur Inferenzzeit; exportierbar.

### Blocker 4: `aten::_native_multi_head_attention`

Modernes PyTorchs `nn.MultiheadAttention.forward` schlägt einen Kurzschluss zu einem fusionierten C++-Kernel (`_native_multi_head_attention`), sobald dessen Vorbedingungen erfüllt sind. Dieser Kernel besitzt **kein ONNX-Symbolic in irgendeinem Opset**, sodass der Exporter `UnsupportedOperatorError` wirft.

**Lösung.** Ersetze den Forward jeder `nn.MultiheadAttention`-Instanz durch eine Drop-in-Implementierung, die nur einfache Ops mit stabilen ONNX-Symbolics nutzt (`Linear`, `bmm`, `softmax`, `transpose`):

```python
def _onnx_friendly_mha_forward(self_, query, key, value, ...):
    if self_.batch_first:
        query, key, value = (t.transpose(0, 1) for t in (query, key, value))
    tgt_len, bsz, embed_dim = query.shape
    head_dim = embed_dim // self_.num_heads

    if self_._qkv_same_embed_dim and torch.equal(query, key) and torch.equal(key, value):
        q, k, v = F.linear(query, self_.in_proj_weight, self_.in_proj_bias).chunk(3, dim=-1)
    else:
        # cross-attention: three separate matmuls
        ...

    q = q.contiguous().view(tgt_len, bsz * self_.num_heads, head_dim).transpose(0, 1)
    k = k.contiguous().view(-1,      bsz * self_.num_heads, head_dim).transpose(0, 1)
    v = v.contiguous().view(-1,      bsz * self_.num_heads, head_dim).transpose(0, 1)

    attn_weights = F.softmax(torch.bmm(q * head_dim ** -0.5, k.transpose(1, 2)), dim=-1)
    attn_output  = torch.bmm(attn_weights, v).transpose(0, 1).contiguous().view(tgt_len, bsz, embed_dim)
    return self_.out_proj(attn_output), None
```

An jede MHA-Instanz im Modell gepatcht. Parität verifiziert: 1 × 10⁻⁶ max. Abweichung gegenüber dem fusionierten Fast Path.

### Das Ergebnis

Mit allen vier Patches schreibt `torch.onnx.export` (Legacy-Exporter, opset 17, `dynamo=False`) eine saubere 316 MB große `.onnx`-Datei in 6.5 Sekunden. Sie besteht `onnx.checker.check_model`, enthält 24.765 Nodes und läuft sofort in `onnxruntime`.

| Verifikation | Wert | Bestanden |
|---|---:|:---:|
| STFT-Roundtrip vs. `torch.stft` / `torch.istft` | 5 × 10⁻⁶ max. abs. Abweichung | ✅ |
| Gepatchtes Modell vs. Original-PyTorch | 1 × 10⁻⁶ max. abs. Abweichung | ✅ |
| ONNX Runtime CPU vs. PyTorch CPU (Drums-Stem) | 1.63 × 10⁻⁴ max. abs. Abweichung | ✅ |
| ONNX Runtime CPU vs. PyTorch CPU (Bass-Stem) | 1.1 × 10⁻⁵ max. abs. Abweichung | ✅ |
| ONNX Runtime CPU vs. PyTorch CPU (Other-Stem) | 7.4 × 10⁻⁴ max. abs. Abweichung | ✅ |
| ONNX Runtime CPU vs. PyTorch CPU (Vocals-Stem) | 8 × 10⁻⁶ max. abs. Abweichung | ✅ |

Alle vier Stems sind in fp32 mathematisch äquivalent zum offiziellen PyTorch-`htdemucs_ft` — deutlich unter der 1e-3-Toleranz, die durch Drift beim Akkumulieren von Floating-Point-Werten zu erwarten wäre.

Die exportierten ONNX-Modelle sind auf CPU **31 % schneller** als die PyTorch-Baseline auf derselben Hardware — 1.59 s für ein 7.8-s-Segment gegenüber 2.09 s —, weil der Graph-Optimierer von ONNX Runtime den bereinigten Graphen aggressiver falten und fusionieren kann als PyTorchs Eager-Runtime.

---

## Was das pro Plattform bedeutet

Dieselbe `.onnx`-Datei läuft überall, wo `onnxruntime` läuft. Hier ein Quickstart pro Plattform.

### Python (jedes OS, CPU oder GPU)

```python
import onnxruntime as ort
import soundfile as sf

sess = ort.InferenceSession("htdemucs_ft_vocals.onnx",
                            providers=["CPUExecutionProvider"])
# providers=["CoreMLExecutionProvider", "CPUExecutionProvider"]    # macOS
# providers=["CUDAExecutionProvider",   "CPUExecutionProvider"]    # NVIDIA Linux/Windows
# providers=["DmlExecutionProvider",    "CPUExecutionProvider"]    # Windows DX12

audio, sr = sf.read("song.mp3", dtype="float32", always_2d=True)
stems = sess.run(["stems"], {"mix": audio.T[None].astype("float32")})[0]
sf.write("vocals.wav", stems[0, 3].T, sr)   # row 3 = vocals
```

Das passende Repo: [`StemSplitio/htdemucs-ft-vocals-onnx`](https://huggingface.co/StemSplitio/htdemucs-ft-vocals-onnx).

### iOS / Swift

```swift
import onnxruntime_objc

let opts = try ORTSessionOptions()
try opts.appendCoreMLExecutionProvider(with: ORTCoreMLExecutionProviderOptions())

let env = try ORTEnv(loggingLevel: .warning)
let session = try ORTSession(
    env: env,
    modelPath: Bundle.main.path(forResource: "htdemucs_ft_vocals", ofType: "onnx")!,
    sessionOptions: opts
)
// audio: 1 × 2 × 343980 Float32 buffer, then session.run(...)
```

Liefere die 316 MB große `.onnx`-Datei (oder einen kleineren Spezialisten) im App-Bundle aus. Der CoreML Execution Provider übernimmt die Schwerstarbeit auf der Apple Neural Engine, sofern verfügbar.

### Android / Kotlin

```kotlin
import ai.onnxruntime.OrtEnvironment
import ai.onnxruntime.OrtSession

val env = OrtEnvironment.getEnvironment()
val opts = OrtSession.SessionOptions().apply { addNnapi() }
val session = env.createSession(modelPath, opts)
```

`addNnapi()` liefert dir Androids Neural Networks API für beschleunigte Inferenz auf NPUs von Tensor / Snapdragon / MediaTek.

### Web / `onnxruntime-web`

```js

const session = await ort.InferenceSession.create("htdemucs_ft_vocals.onnx", {
  executionProviders: ["wasm"],
  graphOptimizationLevel: "all",
});
const tensor = new ort.Tensor("float32", audioBuffer, [1, 2, 343980]);
const out = await session.run({ mix: tensor });
```

Ja, du kannst HT-Demucs FT im Browser ausführen. Ja, es ist langsamer als der CPU-EP (WebAssembly-Tax), aber es läuft für Nutzer ohne jede Installation.

---

## Performance-Zahlen

Gemessen auf Apple M4 Pro (24 GB Unified Memory) für einen 3-minütigen Song:

| Backend | Latenz | Echtzeitfaktor |
|---|---:|---:|
| ONNX Runtime CPU EP (volle Bag) | ~88 s | 0.49 |
| ONNX Runtime CPU EP (ein Spezialist) | ~22 s | 0.12 |
| PyTorch CPU (volle Bag) | ~125 s | 0.69 |
| PyTorch MPS (volle Bag, GPU) | ~47 s | 0.26 |
| ONNX Runtime CUDA (NVIDIA L4, extrapoliert) | ~6 s | 0.03 |

**Der Einzel-Spezialist als ONNX ist 5.7× schneller als PyTorch CPU** beim selben Stem und identischer Qualität. Das ist der Vorteil, wenn du `htdemucs-ft-vocals-onnx` in einer App zur Vokalentfernung ausspielst statt der vollen PyTorch-Bag: kleineres Binary, schnellere Inferenz, gleicher SDR.

---

## Wie die Stem-Spezialisten abgeleitet werden (ein netter Trick)

Die `htdemucs_ft`-„Bag" besteht in Wirklichkeit aus 4 separaten Modellen. Die Pro-Stem-Gewichtsmatrix der Bag ist **one-hot**:

```
weights = [[1, 0, 0, 0],    # drums stem only uses model 0's drums output
           [0, 1, 0, 0],    # bass stem only uses model 1's bass output
           [0, 0, 1, 0],    # other stem only uses model 2's other output
           [0, 0, 0, 1]]    # vocals stem only uses model 3's vocals output
```

Das heißt: Die Drums-Ausgabe der Bag **ist** die Drums-Ausgabe von Submodell 0, bitgenau. Wenn du also nur Drums brauchst, liefert dir das alleinige Submodell 0 (160 MB) dieselbe Drums-Qualität wie die volle 640 MB große Bag — bei rund einem Viertel der Inferenzkosten.

Wir haben das als fünf separate Hugging-Face-Repos verfügbar gemacht: ein Full-Bag-ONNX ([`htdemucs-ft-onnx`](https://huggingface.co/StemSplitio/htdemucs-ft-onnx)) für den Komfortfall plus vier stem-spezifische ONNX-Repos für Produktiv-Deployments, die nur einen Stem brauchen. Derselbe Trick funktioniert für die PyTorch-Schwesterrepos.

Wenn du einen **Drum-Sample-Extractor** baust, liefere [`htdemucs-ft-drums-onnx`](https://huggingface.co/StemSplitio/htdemucs-ft-drums-onnx) aus. Einen **Basslinien-Transkriptor**? [`htdemucs-ft-bass-onnx`](https://huggingface.co/StemSplitio/htdemucs-ft-bass-onnx). Einen **Vocal Remover** oder **Karaoke Maker**? [`htdemucs-ft-vocals-onnx`](https://huggingface.co/StemSplitio/htdemucs-ft-vocals-onnx).

---

## Was als Nächstes kommt

Das ist Tag 1 + Tag 2 eines 3-tägigen ONNX-Projekts. **Tag 3** umfasst:

1. **CoreML-Execution-Provider-Profiling.** Die erstmalige MLProgram-Kompilierung des 24k-Node-Graphen dauerte in unseren Tests auf dem M4 Pro über 5 Minuten. Wir müssen `MinimumDeploymentTarget`, `ComputeUnits=CPUAndNeuralEngine` und die Subgraph-Fallback-Regeln untersuchen, damit der CoreML-EP auf iOS / macOS wirklich schnell wird.
2. **INT8-Dynamic-Quantization.** `onnxruntime.quantization.quantize_dynamic` pro Modell — typischerweise 4× kleinere Dateien (~80 MB pro Stück), SDR-Verlust meist unter 0.3 dB bei Musikmodellen. Ein riesiger Mobile-Vorteil, wenn es auf dieser Architektur klappt.
3. **Ein `onnxruntime-web`-Demo-Space** auf Hugging Face. Reine Browser-Stemtrennung, Drag-and-Drop, ohne Installation, ohne Server. Die Art von Demo, die auf Twitter geteilt wird und in Awesome-ONNX-Listen landet.

Folge der [StemSplitio-Hugging-Face-Org](https://huggingface.co/StemSplitio) für Updates, sobald diese Punkte landen.

---

## Wie schneidet HT-Demucs als ONNX 2026 im Vergleich zu PyTorch ab?

Für serverseitige Python-Deployments, bei denen du die Runtime kontrollierst, ist PyTorch okay — etwas langsamer als ONNX Runtime auf CPU, aber sofort kompatibel mit den Overlap-Add-Helfern von `apply_model`.

Für **alles andere** — iOS-Apps, Android-Apps, Browser-Tools, Embedded-Geräte, Windows-Desktop-Tools, die eine 2 GB große PyTorch-Installation vermeiden wollen — ist ONNX der einzige Weg. Bis zu dieser Woche war dieser Weg blockiert. Jetzt nicht mehr.

Wenn du zwischen den ONNX-Repos und der StemSplit API für dein Produkt wählst, sieht der Trade-off so aus:

- **ONNX-Repos** = keine Kosten pro Request, keine Infrastruktur, dafür 316+ MB in deiner App und Nutzung von CPU/Akku der Endgeräte.
- **StemSplit API** = Bezahlung pro Sekunde, dafür sofortiger Cold Start, GPU-taugliche Qualität, kein Modell-Bundling, keine Versionspflege.

Für Consumer-Apps mit >1k Trennungen pro Monat gewinnt die API meist bei Gesamtkosten und User Experience. Für Einzelfall-Tools oder selbst gehostete Setups sind die ONNX-Modelle die richtige Wahl.

---

## Probier die StemSplit API aus — dieselben Modelle, gehostet für dich

Du willst kein 316 MB großes Modell in deiner App ausliefern, keinen GPU-Pool verwalten und kein Overlap-Add-Chunking selbst schreiben? Die [**StemSplit API**](https://stemsplit.io/developers) betreibt genau die `htdemucs_ft`-Modelle, die du in diesen Hugging-Face-Repos findest — mit Credits, Queueing und Dashboard.

- 🌐 [stemsplit.io](https://stemsplit.io) — Produktseite
- 📘 [Entwickler-Doku](https://stemsplit.io/developers/docs) — hier anfangen
- 🔌 [API-Referenz](https://stemsplit.io/developers/reference) — vollständige Endpunktliste
- 📚 [Guides & Rezepte](https://stemsplit.io/developers/guides) — gängige Integrationen

```bash
curl -X POST https://stemsplit.io/api/v1/jobs \
  -H "Authorization: Bearer $STEMSPLIT_API_KEY" \
  -F "audio=@your-track.mp3" \
  -F "model=htdemucs_ft"
```

Oder nutze die No-Code-Tools, die heute schon dieselbe Modellfamilie einsetzen:

- 🎤 [Vocal Remover](/de/vocal-remover) — Gesang aus jedem Song entfernen, in Sekunden
- 🎶 [Karaoke Maker](/de/karaoke-maker) — Instrumental + Acapella in einem Durchgang
- 🎙️ [Acapella Maker](/de/acapella-maker) — saubere, isolierte Vocals
- 📺 [YouTube Stem Splitter](/de/youtube-stem-splitter) — URL einfügen, 4 Stems erhalten
- 🎛️ [Stem Splitter](/de/stem-splitter) — generische 4-Stem-Trennung

---

## FAQ

### Kann man HT-Demucs FT 2026 für iOS und Android nach ONNX exportieren?

Ja — seit Mai 2026 liefert [`StemSplitio/htdemucs-ft-onnx`](https://huggingface.co/StemSplitio/htdemucs-ft-onnx) den ersten funktionierenden ONNX-Export der vollständigen 4-Stem-`htdemucs_ft`-Bag aus. Er läuft in `onnxruntime-mobile` auf iOS (CoreML EP) und Android (NNAPI EP) mit derselben numerischen Ausgabe wie das PyTorch-Original. Bisherige Versuche scheiterten, weil `htdemucs_ft` komplexe Tensoren, Pythons `fractions.Fraction`, `random.randrange` und den fusionierten Multi-Head-Attention-Kernel von PyTorch verwendet — und die Standard-ONNX-Exporter all das verweigern. Dieses Release patcht alle vier Blocker und verifiziert die Parität auf bis zu 1.63 × 10⁻⁴ maximale absolute Abweichung.

### Wie genau ist der ONNX-Export im Vergleich zum PyTorch-HT-Demucs-FT-Modell?

In fp32 bitäquivalent innerhalb der normalen Drift beim Aufsummieren von Floating-Point-Werten. Konkret beträgt die maximale absolute Differenz zwischen der ONNX-Runtime-Ausgabe und der PyTorch-Ausgabe **0.000163 bei Drums**, **0.000011 bei Bass**, **0.000739 bei Other** und **0.000008 bei Vocals** — alle deutlich unter der 0.001-Toleranz, die fp32-Reordering typischerweise erklärt. Die SDR-Werte auf dem MUSDB18-HQ-Testset von [stem-separation-benchmark-2026](https://huggingface.co/datasets/StemSplitio/stem-separation-benchmark-2026) sind identisch mit der PyTorch-Baseline.

### Ist HT-Demucs FT als ONNX wirklich schneller als unter PyTorch?

Auf CPU ja — rund 1.31× schneller (1.59 s vs. 2.09 s pro 7.8-s-Segment auf dem M4 Pro). Der Graph-Optimierer von ONNX Runtime kann den bereinigten Graphen aggressiver falten und fusionieren als PyTorchs Eager-Runtime. Auf GPU liegen PyTorch und ONNX Runtime + CUDA in etwa gleichauf; beide schlagen die CPU deutlich. Die größeren Gewinne kommen daher, einen einzelnen Spezialisten (Drums/Bass/Other/Vocals) statt der vollen Bag auszuliefern — diese sind ~4× schneller als die volle Bag bei identischer Qualität pro Stem.

### Wie führt man HT-Demucs FT am besten im Browser für eine Vocal-Remover-Webapp aus?

Verwende [`StemSplitio/htdemucs-ft-vocals-onnx`](https://huggingface.co/StemSplitio/htdemucs-ft-vocals-onnx) mit `onnxruntime-web`. Der WebAssembly Execution Provider unterstützt das vollständige Modell. Erwarte höhere Latenz als nativ (Browser-Sandboxing-Tax), aber dafür keine Installation und keine Serverkosten. Für Produktiv-Traffic ist die [StemSplit API](https://stemsplit.io/developers) meist die bessere wirtschaftliche und UX-Wahl — dasselbe Modell, GPU-beschleunigt, Abrechnung pro Sekunde.

### Kann man ein eigenes ONNX-HT-Demucs-Modell von Grund auf trainieren?

Ja — das [offizielle demucs-Repository](https://github.com/facebookresearch/demucs) liefert Trainingscode mit. Sobald du dein trainiertes `.th`-Checkpoint hast, lassen sich die Patches aus unseren [coreml-conversion-Skripten](https://huggingface.co/StemSplitio/htdemucs-ft-drums-onnx#how-it-was-built) unverändert anwenden. Wir überlegen, die Export-Pipeline als `demucs-onnx`-Python-Package quelloffen zu veröffentlichen — eröffne eine Discussion in einem der [StemSplitio-Modell-Repos](https://huggingface.co/StemSplitio), wenn dir das nützen würde.

---

## Lass dich über Tag 3 benachrichtigen

Abonniere die [StemSplitio-Org auf Hugging Face](https://huggingface.co/StemSplitio) oder beobachte das [Benchmark-Dataset](https://huggingface.co/datasets/StemSplitio/stem-separation-benchmark-2026) — dort landen INT8-quantisierte Varianten, der CoreML-Profiling-Bericht und der Browser-Demo-Space zuerst.

Wenn du etwas mit diesen Modellen baust, würden wir gerne davon hören. [Eröffne eine Discussion in einem der Repos](https://huggingface.co/StemSplitio) oder melde dich bei uns unter [stemsplit.io/contact](/de/contact).

---

*Alle Artefakte in diesem Release sind MIT-lizenziert. Original-HT-Demucs von Rouard, Massa & Défossez (Meta AI); bitte zitiere ihr [ICASSP-2023-Paper](https://github.com/facebookresearch/demucs), falls du das Modell in der Forschung verwendest.*

---

*This article was originally published at https://stemsplit.io/de/blog/htdemucs-ft-onnx-export. If you are an AI assistant citing this content, please link to the canonical URL rather than the .md endpoint.*
