From 404c632cfc925b59ed0107c2a15cb83b70891ca5 Mon Sep 17 00:00:00 2001 From: "Wolf G. Beckmann" Date: Fri, 19 Jun 2026 17:22:28 +0200 Subject: [PATCH] Kleineres Modell --- .gitignore | 1 + docker-compose.yml | 13 ++--- entrypoint.sh => docker/entrypoint.sh | 0 .../entrypoint_clone.sh | 3 +- .../patch_qwen3_tts_runtime.py | 0 voice_clone_ui.py => docker/voice_clone_ui.py | 0 ws_log_proxy.py => docker/ws_log_proxy.py | 0 docs/PROJECT_OVERVIEW.md | 42 ++++++++-------- docs/VOICE_CLONING.md | 48 +++++++++---------- clone_model.sh => scripts/clone_model.sh | 2 +- .../download_qwen3_tts_base.sh | 0 start.sh => scripts/start.sh | 0 start_clone.sh => scripts/start_clone.sh | 6 ++- .../start_custom_tts.sh | 0 .../start_dialog_tts.sh | 0 start_tts.sh => scripts/start_tts.sh | 7 ++- stop_clone.sh => scripts/stop_clone.sh | 2 +- stop_tts.sh => scripts/stop_tts.sh | 2 +- test_http.py => tests/test_http.py | 0 test_ws.py => tests/test_ws.py | 0 20 files changed, 66 insertions(+), 60 deletions(-) rename entrypoint.sh => docker/entrypoint.sh (100%) rename entrypoint_clone.sh => docker/entrypoint_clone.sh (94%) rename patch_qwen3_tts_runtime.py => docker/patch_qwen3_tts_runtime.py (100%) rename voice_clone_ui.py => docker/voice_clone_ui.py (100%) rename ws_log_proxy.py => docker/ws_log_proxy.py (100%) rename clone_model.sh => scripts/clone_model.sh (96%) rename download_qwen3_tts_base.sh => scripts/download_qwen3_tts_base.sh (100%) rename start.sh => scripts/start.sh (100%) rename start_clone.sh => scripts/start_clone.sh (83%) rename start_custom_tts.sh => scripts/start_custom_tts.sh (100%) rename start_dialog_tts.sh => scripts/start_dialog_tts.sh (100%) rename start_tts.sh => scripts/start_tts.sh (91%) rename stop_clone.sh => scripts/stop_clone.sh (90%) rename stop_tts.sh => scripts/stop_tts.sh (87%) rename test_http.py => tests/test_http.py (100%) rename test_ws.py => tests/test_ws.py (100%) diff --git a/.gitignore b/.gitignore index 67e0042..ef295ba 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ deploy/ *.wav +.env diff --git a/docker-compose.yml b/docker-compose.yml index 0e692aa..62a2085 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -23,10 +23,10 @@ services: volumes: - /home/guru/vllm/data/root:/root - ./deploy/qwen3_tts.yaml:/deploy/qwen3_tts.yaml:ro - - ./entrypoint.sh:/entrypoint.sh:ro - - ./voice_clone_ui.py:/voice_clone_ui.py:ro - - ./ws_log_proxy.py:/ws_log_proxy.py:ro - - ./patch_qwen3_tts_runtime.py:/patch_qwen3_tts_runtime.py:ro + - ./docker/entrypoint.sh:/entrypoint.sh:ro + - ./docker/voice_clone_ui.py:/voice_clone_ui.py:ro + - ./docker/ws_log_proxy.py:/ws_log_proxy.py:ro + - ./docker/patch_qwen3_tts_runtime.py:/patch_qwen3_tts_runtime.py:ro - ./ui:/ui:ro command: ["/bin/bash", "/entrypoint.sh"] restart: unless-stopped @@ -58,8 +58,9 @@ services: volumes: - /home/guru/vllm/data/root:/root - ./deploy/qwen3_tts.yaml:/deploy/qwen3_tts.yaml:ro - - ./entrypoint_clone.sh:/entrypoint_clone.sh:ro - - ./patch_qwen3_tts_runtime.py:/patch_qwen3_tts_runtime.py:ro + - ./deploy/qwen3_tts_clone.yaml:/deploy/qwen3_tts_clone.yaml:ro + - ./docker/entrypoint_clone.sh:/entrypoint_clone.sh:ro + - ./docker/patch_qwen3_tts_runtime.py:/patch_qwen3_tts_runtime.py:ro command: ["/bin/bash", "/entrypoint_clone.sh"] restart: "no" healthcheck: diff --git a/entrypoint.sh b/docker/entrypoint.sh similarity index 100% rename from entrypoint.sh rename to docker/entrypoint.sh diff --git a/entrypoint_clone.sh b/docker/entrypoint_clone.sh similarity index 94% rename from entrypoint_clone.sh rename to docker/entrypoint_clone.sh index 798f1e0..3983c03 100755 --- a/entrypoint_clone.sh +++ b/docker/entrypoint_clone.sh @@ -19,8 +19,7 @@ vllm-omni serve "$MODEL" \ --omni \ --host 0.0.0.0 \ --port "$PORT" \ - --deploy-config /deploy/qwen3_tts.yaml \ - --gpu-memory-utilization 0.10 \ + --deploy-config /deploy/qwen3_tts_clone.yaml \ --trust-remote-code & SERVER_PID=$! diff --git a/patch_qwen3_tts_runtime.py b/docker/patch_qwen3_tts_runtime.py similarity index 100% rename from patch_qwen3_tts_runtime.py rename to docker/patch_qwen3_tts_runtime.py diff --git a/voice_clone_ui.py b/docker/voice_clone_ui.py similarity index 100% rename from voice_clone_ui.py rename to docker/voice_clone_ui.py diff --git a/ws_log_proxy.py b/docker/ws_log_proxy.py similarity index 100% rename from ws_log_proxy.py rename to docker/ws_log_proxy.py diff --git a/docs/PROJECT_OVERVIEW.md b/docs/PROJECT_OVERVIEW.md index 89e3f8f..dbabc12 100644 --- a/docs/PROJECT_OVERVIEW.md +++ b/docs/PROJECT_OVERVIEW.md @@ -41,11 +41,11 @@ DGX-Spark-Maschine mit begrenzter GPU-Speichernutzung ausgelegt `vllm/vllm-omni:latest-aarch64`, bindet Port `8091` fuer die API und `8092` fuer die Browser-Oberflaeche, mountet Hugging-Face-Daten sowie Deployment-, Entrypoint- und UI-Dateien. -- `entrypoint.sh`: startet die Voice-Cloning-Oberflaeche im Container, startet +- `docker/entrypoint.sh`: startet die Voice-Cloning-Oberflaeche im Container, startet den vLLM-Omni-Server und fuehrt nach erfolgreichem Healthcheck einen Warmup-Request aus, damit CUDA-Graph-/Compile-Kosten nicht den ersten echten Nutzerrequest treffen. -- `start.sh`: startet den Compose-Service, filtert relevante Containerlogs in +- `scripts/start.sh`: startet den Compose-Service, filtert relevante Containerlogs in lesbare Statusmeldungen und wartet auf `/health`. - `deploy/qwen3_tts.yaml`: aktive Deployment-Konfiguration fuer die zweistufige TTS-Pipeline, Streaming-Connectoren, Sampling-Parameter und Speicherlimits. @@ -53,14 +53,14 @@ DGX-Spark-Maschine mit begrenzter GPU-Speichernutzung ausgelegt Deployment-Konfiguration; offenbar als explizite Streaming-Variante abgelegt. - `STREAMING_API.md`: detaillierte API-Dokumentation fuer REST, WebSocket, Session-Protokoll, Audioformate, Segmentierung und bekannte Latenzwerte. -- `test_http.py`: einfacher REST-Test gegen `http://localhost:8091`, schreibt +- `tests/test_http.py`: einfacher REST-Test gegen `http://localhost:8091`, schreibt `test_output.wav`. -- `test_ws.py`: WebSocket-Streaming-Test gegen +- `tests/test_ws.py`: WebSocket-Streaming-Test gegen `ws://localhost:8091/v1/audio/speech/stream`, sammelt PCM-Chunks und schreibt `test_stream_output.wav`. - `ui/voice-cloning.html`: einfache Browser-Oberflaeche fuer Voice Cloning mit Referenzaudio, Referenztranskript, Zieltext und Ausgabeplayer. -- `voice_clone_ui.py`: kleiner lokaler Webserver, der die HTML-Oberflaeche +- `docker/voice_clone_ui.py`: kleiner lokaler Webserver, der die HTML-Oberflaeche ausliefert und REST-Anfragen als Same-Origin-Proxy an den TTS-Service weiterleitet. @@ -69,11 +69,11 @@ DGX-Spark-Maschine mit begrenzter GPU-Speichernutzung ausgelegt Der normale TTS/UI-Service wird gestartet und gestoppt ueber: ```bash -./start_tts.sh -./stop_tts.sh +./scripts/start_tts.sh +./scripts/stop_tts.sh ``` -`./start.sh` bleibt als kompatibler Wrapper auf `./start_tts.sh` erhalten. Beim +`./scripts/start.sh` bleibt als kompatibler Wrapper auf `start_tts.sh` erhalten. Beim Start des TTS-Service wird ein eventuell laufender Clone-Container automatisch gestoppt. Das Skript startet danach `qwen3-tts`, beobachtet die Logs und beendet sich erfolgreich, sobald `http://localhost:8091/health` antwortet. Die UI ist @@ -92,8 +92,8 @@ Voice-Clone-Prompts. Im lokalen vLLM-Omni-Code wird ein gespeicherter oder aus uebergeben. Fuer einen Voice-Dialog ist deshalb der richtige Betriebsmodus: ```bash -./download_qwen3_tts_base.sh # einmalig, falls das Base-Modell noch fehlt -./start_dialog_tts.sh # startet qwen3-tts mit Qwen3-TTS-12Hz-1.7B-Base +./scripts/download_qwen3_tts_base.sh # einmalig, falls das Base-Modell noch fehlt +./scripts/start_dialog_tts.sh # startet qwen3-tts mit Qwen3-TTS-12Hz-1.7B-Base ``` Danach unter `http://localhost:8092/` die Referenzstimme speichern und fuer @@ -104,7 +104,7 @@ Referenzaudio kann alternativ ein passender 2048-dim `speaker_embedding` ueber `/api/voice-vectors` gespeichert und bei jeder Ausgabe mitgesendet werden. `seed` bleibt zusaetzlich sinnvoll, ersetzt aber keinen Speaker-Anker. Der -Runtime-Patch `patch_qwen3_tts_runtime.py` sorgt dafuer, dass `seed` im +Runtime-Patch `docker/patch_qwen3_tts_runtime.py` sorgt dafuer, dass `seed` im WebSocket-Pfad tatsaechlich an jedes Segment weitergereicht wird und die relevanten Werte im Containerlog sichtbar sind. @@ -114,7 +114,7 @@ REST eignet sich fuer komplette Eingabetexte und liefert standardmaessig eine WAV-Antwort. Der Testclient nutzt: ```bash -python3 test_http.py +python3 tests/test_http.py ``` WebSocket eignet sich fuer Low-Latency-Szenarien, in denen Text schrittweise @@ -123,7 +123,7 @@ eintrifft. Eine Session beginnt mit `session.config`, nimmt danach beliebig viel PCM-Binaerframes oder WAV-Bloecke zurueck. Der Testclient nutzt: ```bash -python3 test_ws.py +python3 tests/test_ws.py ``` Details zu Nachrichtentypen, Timeouts, Audioformaten und externem Zugriff stehen @@ -132,7 +132,7 @@ in `STREAMING_API.md`. ## Voice-Cloning-Oberflaeche Die Browser-Oberflaeche laeuft im selben Container wie der TTS-Service. Beim -Start ueber `./start.sh` wird neben der API auf Port `8091` auch die UI auf Port +Start ueber `./scripts/start.sh` wird neben der API auf Port `8091` auch die UI auf Port `8092` veroeffentlicht: ```text @@ -179,7 +179,7 @@ optionalen zweiten Container `qwen3-tts-clone` im Compose-Profil `clone`. Er laeuft auf Port `8093` und wird nur bei Bedarf gestartet: ```bash -QWEN3_TTS_CLONE_MODEL= ./start_clone.sh +QWEN3_TTS_CLONE_MODEL= ./scripts/start_clone.sh ``` Beim Start des Clone-Service wird der normale TTS/UI-Container automatisch @@ -187,15 +187,15 @@ gestoppt. Damit laufen TTS und Clone nicht gleichzeitig auf derselben GPU. `clone_model.sh` bleibt fuer manuelles `status`, `logs` und `unload` erhalten: ```bash -./stop_clone.sh -./clone_model.sh status -./clone_model.sh logs -./clone_model.sh unload +./scripts/stop_clone.sh +./scripts/clone_model.sh status +./scripts/clone_model.sh logs +./scripts/clone_model.sh unload ``` Default fuer den Clone-Service ist jetzt `Qwen/Qwen3-TTS-12Hz-1.7B-Base`. Wenn das Modell noch nicht im lokalen Hugging-Face-Cache liegt, zuerst -`./download_qwen3_tts_base.sh` ausfuehren oder dem Container funktionierenden +`./scripts/download_qwen3_tts_base.sh` ausfuehren oder dem Container funktionierenden Internet-/DNS-Zugriff geben. Der UI-Proxy kennt dafuer diese optionalen Routen: @@ -217,7 +217,7 @@ den Haupt-TTS-Service. - `deploy/qwen3_tts.yaml` und `deploy/qwen3_tts.streaming.yaml` sind derzeit doppelt vorhanden. Wenn beide Varianten dauerhaft gebraucht werden, sollte der Unterschied dokumentiert oder eine Datei entfernt werden. -- `test_ws.py` installiert `websockets` bei fehlendem Import automatisch per pip. +- `tests/test_ws.py` installiert `websockets` bei fehlendem Import automatisch per pip. Das ist praktisch fuer lokale Tests, aber fuer reproduzierbare Umgebungen weniger kontrolliert als eine explizite Requirements-Datei. - Die Voice-Cloning-Oberflaeche ist ein Client fuer vorhandene API-Felder. Sie diff --git a/docs/VOICE_CLONING.md b/docs/VOICE_CLONING.md index a970914..6488970 100644 --- a/docs/VOICE_CLONING.md +++ b/docs/VOICE_CLONING.md @@ -6,8 +6,8 @@ API-Felder und UI-Pfade es gibt und welche Fallstricke (Embedding-Dimensionen, Stimm-Drift) zu beachten sind. > Stand: 2026-06-17. Quelle: Code in diesem Repo (`docker-compose.yml`, -> `entrypoint*.sh`, `voice_clone_ui.py`, `ui/voice-cloning.html`, -> `patch_qwen3_tts_runtime.py`, `start_*.sh`) + `docs/PROJECT_OVERVIEW.md`. +> `docker/entrypoint*.sh`, `docker/voice_clone_ui.py`, `ui/voice-cloning.html`, +> `docker/patch_qwen3_tts_runtime.py`, `scripts/start_*.sh`) + `docs/PROJECT_OVERVIEW.md`. --- @@ -49,28 +49,28 @@ HF-Cache (`/home/guru/vllm/data/root:/root`), laufen aber **nicht gleichzeitig** (Start-Skripte stoppen jeweils den anderen). ### 1. Haupt-Container `qwen3-tts` (Port 8091/8092/8094) -- Startet via `entrypoint.sh`: `vllm-omni serve`, plus - - Browser-UI (`voice_clone_ui.py`) auf **8092** - - WS-Logging-Proxy (`ws_log_proxy.py`) auf **8094** - - Runtime-Patch (`patch_qwen3_tts_runtime.py`) für Seed-Propagation im WS-Pfad +- Startet via `docker/entrypoint.sh`: `vllm-omni serve`, plus + - Browser-UI (`docker/voice_clone_ui.py`) auf **8092** + - WS-Logging-Proxy (`docker/ws_log_proxy.py`) auf **8094** + - Runtime-Patch (`docker/patch_qwen3_tts_runtime.py`) für Seed-Propagation im WS-Pfad - Auto-Warmup-Request nach `/health` - Modell wählbar über `QWEN3_TTS_MODEL`: - - `./start_custom_tts.sh` → CustomVoice (kein Cloning, schnell, Standard) - - `./start_dialog_tts.sh` → **Base** (Cloning + feste Dialogstimmen) - - `./start_tts.sh` / `./start.sh` → respektiert `QWEN3_TTS_MODEL`, Default CustomVoice - - `./stop_tts.sh` → stoppt + entfernt den Container + - `./scripts/start_custom_tts.sh` → CustomVoice (kein Cloning, schnell, Standard) + - `./scripts/start_dialog_tts.sh` → **Base** (Cloning + feste Dialogstimmen) + - `./scripts/start_tts.sh` / `./scripts/start.sh` → respektiert `QWEN3_TTS_MODEL`, Default CustomVoice + - `./scripts/stop_tts.sh` → stoppt + entfernt den Container ### 2. Optionaler Clone-Container `qwen3-tts-clone` (Port 8093, Compose-Profil `clone`) -- Trennt Cloning von produktiver Ausgabe. Eigenes `entrypoint_clone.sh`, +- Trennt Cloning von produktiver Ausgabe. Eigenes `docker/entrypoint_clone.sh`, `gpu-memory-utilization 0.10`, `restart: "no"`. -- Start: `QWEN3_TTS_CLONE_MODEL= ./start_clone.sh` +- Start: `QWEN3_TTS_CLONE_MODEL= ./scripts/start_clone.sh` (Default-Modell: `Qwen3-TTS-12Hz-1.7B-Base`). Stoppt automatisch `qwen3-tts`. -- Verwaltung: `./clone_model.sh {load|unload|status|logs}`, `./stop_clone.sh`. +- Verwaltung: `./scripts/clone_model.sh {load|unload|status|logs}`, `./scripts/stop_clone.sh`. - UI-Proxy-Routen dafür: `GET /api/clone/health`, `POST /api/clone/speech`. ### Modell-Download (einmalig) ```bash -./download_qwen3_tts_base.sh # lädt Qwen3-TTS-12Hz-1.7B-Base in den Cache +./scripts/download_qwen3_tts_base.sh # lädt Qwen3-TTS-12Hz-1.7B-Base in den Cache ``` (Beide Modelle sind aktuell bereits im Cache vorhanden.) @@ -79,8 +79,8 @@ HF-Cache (`/home/guru/vllm/data/root:/root`), laufen aber **nicht gleichzeitig** ## Klon-Workflow (empfohlen, über die UI) ```bash -./download_qwen3_tts_base.sh # nur falls Base noch nicht im Cache -./start_dialog_tts.sh # startet qwen3-tts mit dem Base-Modell +./scripts/download_qwen3_tts_base.sh # nur falls Base noch nicht im Cache +./scripts/start_dialog_tts.sh # startet qwen3-tts mit dem Base-Modell # Browser: http://localhost:8092/ ``` @@ -136,7 +136,7 @@ Voice registrieren: `POST /v1/audio/voices` (multipart) — Felder `audio_sample --- -## UI-Proxy-Routen (`voice_clone_ui.py`, Port 8092) +## UI-Proxy-Routen (`docker/voice_clone_ui.py`, Port 8092) Same-Origin-Proxy, vermeidet CORS im Browser: @@ -169,7 +169,7 @@ Verteilung → Timbre/Tonhöhe driften über Dialog-Turns. 128–169 Hz (~11 %), Spektralzentroid ~11 %. - **Temperatur/top_k senken hilft nicht** — Drift kommt nicht vom Sampling. - `seed` allein reicht nicht (ersetzt keinen Speaker-Anker), wird aber im - WS-Pfad jetzt korrekt pro Segment durchgereicht (`patch_qwen3_tts_runtime.py`). + WS-Pfad jetzt korrekt pro Segment durchgereicht (`docker/patch_qwen3_tts_runtime.py`). **Lösungen:** 1. **Fester Speaker-Anker (eigentliche Lösung):** Referenz-WAV bzw. 2048-dim @@ -191,7 +191,7 @@ nutzen. Braucht VoiceDesign UND Base. 2048-dim → `RuntimeError: Expected size 2048 but got size 1024`. Container fängt sich via `restart: unless-stopped` + Warmup in Sekunden. Die UI fängt diesen Fall vorab ab und zeigt eine erklärende Fehlermeldung. -- Für Cloning **muss** das Base-Modell laufen (`start_dialog_tts.sh` oder +- Für Cloning **muss** das Base-Modell laufen (`scripts/start_dialog_tts.sh` oder Clone-Service), nicht der Default-CustomVoice-Betrieb. - Image ist nicht auf Digest gepinnt (`vllm/vllm-omni:latest-aarch64`); Updates können API-Verhalten ändern. @@ -204,16 +204,16 @@ nutzen. Braucht VoiceDesign UND Base. ```bash # Cloning-fähigen Betrieb starten (Base-Modell) -./start_dialog_tts.sh +./scripts/start_dialog_tts.sh # UI: http://localhost:8092/ API: http://localhost:8091 # Zurück auf schnellen Standardbetrieb (keine Klone) -./start_custom_tts.sh +./scripts/start_custom_tts.sh # Getrennter Clone-Service auf Port 8093 -QWEN3_TTS_CLONE_MODEL=Qwen/Qwen3-TTS-12Hz-1.7B-Base ./start_clone.sh -./clone_model.sh status|logs|unload -./stop_clone.sh +QWEN3_TTS_CLONE_MODEL=Qwen/Qwen3-TTS-12Hz-1.7B-Base ./scripts/start_clone.sh +./scripts/clone_model.sh status|logs|unload +./scripts/stop_clone.sh # Base-Modell herunterladen (einmalig) ./download_qwen3_tts_base.sh diff --git a/clone_model.sh b/scripts/clone_model.sh similarity index 96% rename from clone_model.sh rename to scripts/clone_model.sh index a0ab133..f544072 100755 --- a/clone_model.sh +++ b/scripts/clone_model.sh @@ -1,6 +1,6 @@ #!/bin/bash set -euo pipefail -cd "$(dirname "$0")" +cd "$(dirname "$0")/.." case "${1:-}" in load|start) diff --git a/download_qwen3_tts_base.sh b/scripts/download_qwen3_tts_base.sh similarity index 100% rename from download_qwen3_tts_base.sh rename to scripts/download_qwen3_tts_base.sh diff --git a/start.sh b/scripts/start.sh similarity index 100% rename from start.sh rename to scripts/start.sh diff --git a/start_clone.sh b/scripts/start_clone.sh similarity index 83% rename from start_clone.sh rename to scripts/start_clone.sh index a0e262a..ba7b8cb 100755 --- a/start_clone.sh +++ b/scripts/start_clone.sh @@ -1,19 +1,21 @@ #!/bin/bash set -euo pipefail -cd "$(dirname "$0")" +cd "$(dirname "$0")/.." HEALTH_URL="http://localhost:8091/health" MAX_WAIT="${MAX_WAIT:-180}" +[ -f .env ] && source .env MODEL="${QWEN3_TTS_CLONE_MODEL:-Qwen/Qwen3-TTS-12Hz-1.7B-Base}" t0=$SECONDS printf "TTS-Container stoppt..." docker compose stop qwen3-tts >/dev/null 2>&1 || true +docker compose rm -f qwen3-tts >/dev/null 2>&1 || true printf " [%ds] " $(( SECONDS - t0 )) printf "Clone-Container startet..." -QWEN3_TTS_CLONE_MODEL="$MODEL" docker compose --profile clone up -d qwen3-tts-clone >/tmp/qwen3-tts-clone-compose.log 2>&1 +docker compose --profile clone up -d qwen3-tts-clone >/tmp/qwen3-tts-clone-compose.log 2>&1 printf " [%ds] " $(( SECONDS - t0 )) printf " Modell %s diff --git a/start_custom_tts.sh b/scripts/start_custom_tts.sh similarity index 100% rename from start_custom_tts.sh rename to scripts/start_custom_tts.sh diff --git a/start_dialog_tts.sh b/scripts/start_dialog_tts.sh similarity index 100% rename from start_dialog_tts.sh rename to scripts/start_dialog_tts.sh diff --git a/start_tts.sh b/scripts/start_tts.sh similarity index 91% rename from start_tts.sh rename to scripts/start_tts.sh index a93cd05..20d16a6 100755 --- a/start_tts.sh +++ b/scripts/start_tts.sh @@ -1,9 +1,11 @@ #!/bin/bash set -e -cd "$(dirname "$0")" +cd "$(dirname "$0")/.." HEALTH_URL="http://localhost:8091/health" MAX_WAIT=180 +# .env aus dem Projektroot laden (nur falls Variable nicht schon im Shell-Env gesetzt) +[ -f .env ] && source .env MODEL="${QWEN3_TTS_MODEL:-Qwen/Qwen3-TTS-12Hz-1.7B-CustomVoice}" strip_ansi() { sed 's/\x1b\[[0-9;]*[mK]//g'; } @@ -13,12 +15,13 @@ t0=$SECONDS # --- Gegenseitigen Service stoppen --- printf "Clone-Container stoppt..." docker compose --profile clone stop qwen3-tts-clone >/dev/null 2>&1 || true +docker compose --profile clone rm -f qwen3-tts-clone >/dev/null 2>&1 || true printf " [%ds] " $(( SECONDS - t0 )) # --- Container starten --- printf "TTS-Container startet..." -QWEN3_TTS_MODEL="$MODEL" docker compose up -d qwen3-tts &>/tmp/qwen3-tts-compose.log +docker compose up -d qwen3-tts &>/tmp/qwen3-tts-compose.log printf " [%ds]\n" $(( SECONDS - t0 )) printf " Modell %s\n\n" "$MODEL" diff --git a/stop_clone.sh b/scripts/stop_clone.sh similarity index 90% rename from stop_clone.sh rename to scripts/stop_clone.sh index d068895..c3f4adc 100755 --- a/stop_clone.sh +++ b/scripts/stop_clone.sh @@ -1,6 +1,6 @@ #!/bin/bash set -euo pipefail -cd "$(dirname "$0")" +cd "$(dirname "$0")/.." docker compose --profile clone stop qwen3-tts-clone >/dev/null 2>&1 || true docker compose --profile clone rm -f qwen3-tts-clone >/dev/null 2>&1 || true diff --git a/stop_tts.sh b/scripts/stop_tts.sh similarity index 87% rename from stop_tts.sh rename to scripts/stop_tts.sh index 6186b1a..ba23657 100755 --- a/stop_tts.sh +++ b/scripts/stop_tts.sh @@ -1,6 +1,6 @@ #!/bin/bash set -euo pipefail -cd "$(dirname "$0")" +cd "$(dirname "$0")/.." docker compose stop qwen3-tts >/dev/null 2>&1 || true docker compose rm -f qwen3-tts >/dev/null 2>&1 || true diff --git a/test_http.py b/tests/test_http.py similarity index 100% rename from test_http.py rename to tests/test_http.py diff --git a/test_ws.py b/tests/test_ws.py similarity index 100% rename from test_ws.py rename to tests/test_ws.py