#!/bin/bash # Container-Entrypoint: startet den vLLM-Omni TTS-Server und feuert nach # Erreichen von /health einmalig einen Warmup-Request ab. Dieser absorbiert # die einmalige torch.compile/CUDA-Graph-Kompilierung (~38 s), damit kein # echter Nutzer-Request sie je trifft. Läuft bei JEDEM Containerstart # (Reboot, Crash-Restart, manuell). set -e MODEL="${QWEN3_TTS_MODEL:-Qwen/Qwen3-TTS-12Hz-1.7B-CustomVoice}" PORT=8091 # external-facing proxy port (clients connect here) VLLM_PORT=8095 # internal vllm-omni port UI_PORT=8092 # --- Runtime-Patches fuer Qwen3-TTS anwenden --- if [ -f /patch_qwen3_tts_runtime.py ]; then python3 /patch_qwen3_tts_runtime.py fi # --- Browser-UI im Container starten --- if [ -f /voice_clone_ui.py ]; then python3 /voice_clone_ui.py \ --host 0.0.0.0 \ --port "$UI_PORT" \ --api-base "http://localhost:${VLLM_PORT}" \ --clone-api-base "http://qwen3-tts-clone:8093" \ --model "$MODEL" & UI_PID=$! echo "[ui] Voice-Cloning-UI laeuft auf Port ${UI_PORT}" fi # --- WebSocket-Proxy auf dem client-facing PORT starten --- # Proxy sitzt vor vllm-omni und fuegt Stille-Fuellen zwischen Saetzen ein. if [ -f /ws_log_proxy.py ]; then python3 /ws_log_proxy.py \ --host 0.0.0.0 \ --port "$PORT" \ --upstream "ws://localhost:${VLLM_PORT}/v1/audio/speech/stream" & WS_PROXY_PID=$! echo "[ws-proxy] Proxy laeuft auf Port ${PORT} -> vllm-omni Port ${VLLM_PORT}" fi # --- vllm-omni Server intern auf VLLM_PORT starten --- vllm-omni serve "$MODEL" \ --omni \ --host 0.0.0.0 \ --port "$VLLM_PORT" \ --deploy-config /deploy/qwen3_tts.yaml \ --gpu-memory-utilization 0.10 \ --trust-remote-code & SERVER_PID=$! # --- Warmup im Hintergrund, sobald der Server gesund ist --- ( for _ in $(seq 1 150); do if curl -sf "http://localhost:${VLLM_PORT}/health" >/dev/null 2>&1; then echo "[warmup] Server gesund — sende Warmup-Request (kompiliert CUDA-Graphen)..." t0=$SECONDS curl -sf -X POST "http://localhost:${VLLM_PORT}/v1/audio/speech" \ -H 'Content-Type: application/json' \ -d "{\"model\":\"${MODEL}\",\"input\":\"System wird aufgewärmt.\",\"voice\":\"Ryan\",\"language\":\"German\",\"response_format\":\"wav\"}" \ -o /dev/null \ && echo "[warmup] fertig nach $(( SECONDS - t0 ))s — Server ist jetzt heiß." \ || echo "[warmup] fehlgeschlagen (Server läuft trotzdem)." break fi sleep 2 done ) & # --- Auf den Server-Prozess warten (PID 1 Signalweiterleitung) --- trap 'kill "$SERVER_PID" "${UI_PID:-}" "${WS_PROXY_PID:-}" 2>/dev/null || true' TERM INT wait "$SERVER_PID"