tts-voice-creator-clone-and.../architecture/vocal-isolation.md
mARTin-B78 91843e95e6 feat(voices): optional vocal isolation for URL imports
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 16:50:14 +02:00

3.2 KiB

Vocal isolation for URL/YouTube imports

Status: implemented behind a flag, default OFF. Goal: remove music/background from a downloaded clip before trimming and cloning (/api/download-yt -> /api/isolate-vocals -> trim -> quick-import-voice).

Findings (read-only inspection, 2026-10-04)

  • App image: python:3.11-slim-bookworm, requirements.txt has no torch/onnx/demucs. The live app container has no torch (import torch fails). It is read_only: true, cap_drop: ALL, 8 GB mem limit, no GPU reservation. Source dirs are bind-mounted read-only.
  • GPU/torch live in other service containers (tts-faster-qwen3-*, aligner, ...), not reusable: different images, no shared API for source separation.
  • There is no VAD, denoise or separation anywhere in the app today.

Options

Option Footprint Verdict
Demucs htdemucs (MIT code; weights MIT, ~80 MB, from dl.fbaipublicfiles.com via torch hub) in the main image torch + torchaudio on ARM64 ~ 2-3 GB image growth rejected: heavy, unconditional
Demucs in a separate sidecar container no growth of main image, GPU optional best long-term, but needs a new image, compose service and network contract
Optional external Demucs CLI, called as a subprocess, only when the flag is on and the binary + weights exist zero deps in the main image; the owner picks where Demucs lives (venv on a bind mount, or a derived image) chosen
Lighter: RNNoise/DeepFilterNet/spectral gating small, but removes noise only, not music/singing does not meet the goal

Why the CLI: demucs --two-stems=vocals -n htdemucs is the stable public interface; no import-time cost, no behaviour change when absent. ARM64: torch/torchaudio publish aarch64 wheels (CUDA wheels exist for DGX Spark / GB10; CPU wheels work everywhere), demucs itself is pure Python (pip install demucs). A sidecar can later expose the same CLI via VOCAL_ISOLATION_CMD (e.g. docker exec ... wrapper) without code changes.

Safety rules

  • VOCAL_ISOLATION=1 required; otherwise the feature reports unavailable and the API answers 503.
  • Available only if the command resolves AND the htdemucs weights file (955717e8-*.th) is already in $TORCH_HOME/hub/checkpoints (default ~/.cache/torch). The app never downloads weights: the owner installs them once (documented in Manual.md). This prevents Demucs' silent first-run download.
  • Input bounded to VOCAL_ISOLATION_MAX_SECONDS (default 900), runtime to VOCAL_ISOLATION_TIMEOUT (default 900 s), one job at a time (409 when busy), client disconnect cancels and kills the process.
  • Work happens in a private temp dir that is always removed; the result is converted to 24 kHz mono WAV and registered as a new temp id. The original id is untouched (compare / undo in the UI).
  • Subprocess started with an argument list (no shell); the path comes from the registry, never from the client.

Contract

  • GET /api/version gains features.vocal_isolation: bool.
  • POST /api/isolate-vocals {id} -> {id, duration}. Errors: 400 bad id, 404 unknown id, 413 too long, 409 busy, 503 disabled/unavailable, 504 timeout, 500 failed (message without internals).
  • Offline behaviour: fully local; no network access.