TTS: Kokoro → XTTS-v2 (CPU-only, Claribel Dervla)

- Neues xtts_worker.py: Coqui XTTS-v2, HTTP-API auf Port 8085
- Router: TTS_WORKER_URL → 8085, TTS_MODEL → xtts-v2, TTS_VOICES → claribel
- deploy: mike-ai-xtts.service, install.sh + deploy.sh aktualisiert
- Tests: 54/54 bestanden (mock_tts_worker + test_local.sh auf XTTS umgestellt)
- README: TTS-Section auf XTTS-v2 aktualisiert
- Kokoro-Service gestoppt und deaktiviert (Dateien bleiben als Backup)
This commit is contained in:
Mikei386
2026-08-19 22:01:58 +02:00
parent ed471196d4
commit d399d2b4f7
9 changed files with 451 additions and 171 deletions
+11 -11
View File
@@ -20,7 +20,7 @@ Bildgenerierung (FLUX.2 [klein] 4B Base):
GET /images (Liste)
GET /images/<datei> (PNG-Download)
Sprachausgabe (Kokoro-82M, deutsch, CPU-only):
Sprachausgabe (XTTS-v2, multilingual, CPU-only):
POST /v1/audio/speech (OpenAI-kompatibel)
GET /v1/audio/voices (verfügbare Stimmen)
@@ -28,7 +28,7 @@ Spracherkennung (whisper.cpp, deutsch, CPU-only):
POST /v1/audio/transcriptions (OpenAI-kompatibel)
GET /v1/audio/models (verfügbare Audio-Modelle)
Der TTS-Worker (mike-ai-kokoro.service) und der STT-Worker
Der TTS-Worker (mike-ai-xtts.service) und der STT-Worker
(mike-ai-whisper.service) laufen als separate, langlebige Prozesse.
Der Router leitet /v1/audio/speech und /v1/audio/transcriptions
per HTTP an die Worker weiter.
@@ -108,14 +108,14 @@ IMAGE_QUALITY = {"standard": 30, "high": 50}
IMAGE_DEFAULT_QUALITY = "standard"
IMAGE_MAX_N = 4
# --- Sprachausgabe (Kokoro-82M, deutsch, CPU-only) ---
TTS_WORKER_URL = os.environ.get("TTS_WORKER_URL", "http://127.0.0.1:8082")
# --- Sprachausgabe (XTTS-v2, multilingual, CPU-only) ---
TTS_WORKER_URL = os.environ.get("TTS_WORKER_URL", "http://127.0.0.1:8085")
TTS_TIMEOUT = float(os.environ.get("TTS_TIMEOUT", "300")) # s, pro Synthese
TTS_CONNECT_TIMEOUT = float(os.environ.get("TTS_CONNECT_TIMEOUT", "5"))
TTS_MODEL = "kokoro-german" # virtuelles Modell für /v1/audio/speech
TTS_VOICES = ("martin", "victoria")
TTS_DEFAULT_VOICE = "martin"
TTS_FORMATS = ("mp3", "wav", "flac", "pcm")
TTS_MODEL = "xtts-v2" # virtuelles Modell für /v1/audio/speech
TTS_VOICES = ("claribel",)
TTS_DEFAULT_VOICE = "claribel"
TTS_FORMATS = ("mp3", "wav")
TTS_DEFAULT_FORMAT = "mp3"
# --- Spracherkennung (whisper.cpp, deutsch, CPU-only) ---
@@ -1124,7 +1124,7 @@ class Handler(BaseHTTPRequestHandler):
self.end_headers()
self.wfile.write(data)
# ---------- Sprachausgabe (Kokoro) ----------
# ---------- Sprachausgabe (XTTS-v2) ----------
def _speech(self) -> None:
try:
@@ -1183,7 +1183,7 @@ class Handler(BaseHTTPRequestHandler):
"invalid_request_error", "invalid_speed")
return
# Modell-Name optional; falls angegeben, muss es kokoro-german sein.
# Modell-Name optional; falls angegeben, muss es xtts-v2 sein.
model = data.get("model")
if model is not None and model != TTS_MODEL:
self._send_error(400, f"unbekanntes Modell: {model!r} "
@@ -1225,7 +1225,7 @@ class Handler(BaseHTTPRequestHandler):
models.append({
"id": TTS_MODEL,
"object": "model",
"owned_by": "kokoro",
"owned_by": "coqui-xtts",
"type": "speech",
})
return {"object": "list", "data": models}