Use Qwen3-ASR as production speech recognizer

This commit is contained in:
Mikei386
2026-09-25 21:31:33 +02:00
parent 6378b50086
commit 8a323e5b9e
17 changed files with 294 additions and 66 deletions
+12 -7
View File
@@ -29,12 +29,11 @@ Sprachausgabe (Qwen3-TTS auf RTX 3060):
POST /v1/audio/speech (OpenAI-kompatibel)
GET /v1/audio/voices (verfügbare Stimmen)
Spracherkennung (whisper.cpp, deutsch, CPU-only):
Spracherkennung (Qwen3-ASR, deutsch, CPU-only):
POST /v1/audio/transcriptions (OpenAI-kompatibel)
GET /v1/audio/models (verfügbare Audio-Modelle)
Der TTS-Worker (mike-ai-xtts.service) und der STT-Worker
(mike-ai-whisper.service) laufen als separate, langlebige Prozesse.
TTS und Qwen3-ASR laufen als separate, langlebige Dienste.
Der Router leitet /v1/audio/speech und /v1/audio/transcriptions
per HTTP an die Worker weiter.
@@ -216,11 +215,11 @@ TTS_DEFAULT_VOICE = os.environ.get(
TTS_FORMATS = ("mp3", "wav", "pcm")
TTS_DEFAULT_FORMAT = "mp3"
# --- Spracherkennung (whisper.cpp, deutsch, CPU-only) ---
# --- Spracherkennung (Qwen3-ASR, deutsch, CPU-only) ---
STT_WORKER_URL = os.environ.get("STT_WORKER_URL", "http://127.0.0.1:8084")
STT_TIMEOUT = float(os.environ.get("STT_TIMEOUT", "120")) # s, pro Transkription
STT_CONNECT_TIMEOUT = float(os.environ.get("STT_CONNECT_TIMEOUT", "5"))
STT_MODEL = "whisper-1" # virtuelles Modell für /v1/audio/transcriptions
STT_MODEL = "whisper-1" # OpenClaw/OpenAI compatibility alias; Qwen3-ASR serves it
# Maximale Upload-Größe (Bytes) – verhindert unbegrenzten RAM-Verbrauch.
# 50 MB ist für Audio-Dateien (WebM/Opus, WAV, MP3) mehr als ausreichend.
@@ -2846,7 +2845,13 @@ class Handler(BaseHTTPRequestHandler):
models.append({
"id": STT_MODEL,
"object": "model",
"owned_by": "whisper.cpp",
"owned_by": "qwen3-asr",
"type": "transcription",
})
models.append({
"id": "qwen3-asr",
"object": "model",
"owned_by": "qwen3-asr",
"type": "transcription",
})
if tts.get("ready"):
@@ -2969,7 +2974,7 @@ class Handler(BaseHTTPRequestHandler):
# Modell-Validierung
model = fields.get("model", STT_MODEL)
if model not in (STT_MODEL, "whisper"):
if model not in (STT_MODEL, "whisper", "qwen3-asr"):
self._send_error(400, f"unbekanntes Modell: {model!r} "
f"(erwartet: {STT_MODEL})",
"invalid_request_error", "unknown_model")