diff --git a/server.py b/server.py index 6674a27..4c79eb1 100644 --- a/server.py +++ b/server.py @@ -48,7 +48,7 @@ _NVIDIA_CLONE_DEFAULT = os.environ.get("NVIDIA_TTS_CLONE_URL", "http://host.dock _NVIDIA_ZEROSHOT_DEFAULT = os.environ.get("NVIDIA_ZEROSHOT_TTS_URL", _NVIDIA_CLONE_DEFAULT) _NVIDIA_FLOW_DEFAULT = os.environ.get("NVIDIA_FLOW_TTS_URL", "http://host.docker.internal:8094") _FASTER_WHISPER_DEFAULT = os.environ.get("FASTER_WHISPER_URL", "http://host.docker.internal:8000") -_WHISPER_CPP_DEFAULT = os.environ.get("WHISPER_CPP_URL", "http://host.docker.internal:8080") +_WHISPER_CPP_DEFAULT = os.environ.get("WHISPER_CPP_URL", "http://host.docker.internal:8085") _GROQ_STT_ENDPOINT = "https://api.groq.com/openai/v1" _KOKORO_DEFAULT = os.environ.get("KOKORO_URL", "http://host.docker.internal:8880/v1") _VIBEVOICE_DEFAULT = os.environ.get("VIBEVOICE_URL", "http://192.168.178.8:8027") @@ -1903,15 +1903,15 @@ def _stt_backend_api_key(settings: dict, backend: str) -> str: return settings.get("whisper_api_key", "").strip() -def _make_minimal_wav() -> bytes: - """44-byte WAV header with 1 frame of silence — smallest valid WAV.""" - import struct - num_frames = 1 - data = b"\x00\x00" +def _make_minimal_wav(duration_ms: int = 500) -> bytes: + """Minimal WAV: mono 16-bit 16kHz silence of given duration.""" + sample_rate = 16000 + num_frames = sample_rate * duration_ms // 1000 + data = b"\x00\x00" * num_frames header = struct.pack( "<4sI4s4sIHHIIHH4sI", b"RIFF", 36 + len(data), b"WAVE", - b"fmt ", 16, 1, 1, 16000, 32000, 2, 16, + b"fmt ", 16, 1, 1, sample_rate, sample_rate * 2, 2, 16, b"data", len(data), ) return header + data @@ -1942,9 +1942,11 @@ def _stt_backend_health(url: str) -> tuple[bool, list[str]]: if not ok: return False, models # Verify the transcription endpoint actually works (catches broken builds like - # CTranslate2 containers compiled without CUDA that pass /health but fail on load) + # CTranslate2 containers compiled without CUDA that pass /health but fail on load, + # and LLM servers that expose /v1/models but no transcription endpoint) try: wav = _make_minimal_wav() + endpoint_found = False for path in ("/v1/audio/transcriptions", "/transcribe"): try: r = requests.post( @@ -1953,14 +1955,29 @@ def _stt_backend_health(url: str) -> tuple[bool, list[str]]: data={"model": "whisper-1", "response_format": "text"}, timeout=8, ) + if r.status_code in {404, 405}: + continue # try next path — endpoint missing or wrong method if r.status_code == 500: - ok = False # backend is broken (model load failed etc.) - break # 200, 400, 404, 422 all mean the endpoint exists and model loaded + # Distinguish backend crash from "couldn't process empty audio": + # a JSON detail that isn't the generic FastAPI text means the + # model loaded and responded — treat as ok (audio was just bad) + try: + detail = r.json().get("detail", "") + ok = bool(detail) and detail.lower() != "internal server error" + except Exception: + ok = False # non-JSON 500 → backend likely broken + else: + ok = True # 200, 400, 415, 422 → endpoint works + endpoint_found = True + break except requests.exceptions.ConnectionError: ok = False + endpoint_found = True break except Exception: - pass # timeout or other — don't mark as broken, just skip + pass # timeout — don't penalise slow model loads + if not endpoint_found: + ok = False # all paths returned 404/405 — not an STT backend except Exception: pass return ok, models diff --git a/static/sections/s-llms.html b/static/sections/s-llms.html index bf4ed6b..a09799f 100644 --- a/static/sections/s-llms.html +++ b/static/sections/s-llms.html @@ -350,7 +350,7 @@ Check "Enable CORS" for browser access

Minimal C++ Whisper with a built-in HTTP server. CPU or Metal/CUDA. Low memory, fast on consumer hardware.

URL - +
@@ -359,12 +359,12 @@ Check "Enable CORS" for browser access
Build & run - +
git clone https://github.com/ggml-org/whisper.cpp
 cd whisper.cpp && cmake -B build && cmake --build build -j
 ./build/bin/whisper-server \
-  -m models/ggml-large-v3.bin --port 8080
+ -m models/ggml-large-v3.bin --port 8085
github.com/ggml-org/whisper.cpp