Lokaler Spracherkennungs-Dienst (faster-whisper): HTTP, WebSocket, Wyoming/Home Assistant, CLI
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
dschlueter 7a4d0e2885 Alte Einzelskripte stt.py und stt_respeaker.py nach legacy/ verschoben
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-13 21:34:23 +02:00
deploy STT-Dienst: Kern, HTTP/WebSocket/Wyoming-Service, CLI, Tests, systemd-Unit 2026-09-13 21:34:03 +02:00
legacy Alte Einzelskripte stt.py und stt_respeaker.py nach legacy/ verschoben 2026-09-13 21:34:23 +02:00
tests STT-Dienst: Kern, HTTP/WebSocket/Wyoming-Service, CLI, Tests, systemd-Unit 2026-09-13 21:34:03 +02:00
.gitignore Initiales Repository: stt.py, historisches stt_respeaker.py, CLAUDE.md, .gitignore 2026-09-13 21:05:18 +02:00
CLAUDE.md Alte Einzelskripte stt.py und stt_respeaker.py nach legacy/ verschoben 2026-09-13 21:34:23 +02:00
pytest.ini STT-Dienst: Kern, HTTP/WebSocket/Wyoming-Service, CLI, Tests, systemd-Unit 2026-09-13 21:34:03 +02:00
README.md Alte Einzelskripte stt.py und stt_respeaker.py nach legacy/ verschoben 2026-09-13 21:34:23 +02:00
requirements.txt STT-Dienst: Kern, HTTP/WebSocket/Wyoming-Service, CLI, Tests, systemd-Unit 2026-09-13 21:34:03 +02:00
stt_cli.py STT-Dienst: Kern, HTTP/WebSocket/Wyoming-Service, CLI, Tests, systemd-Unit 2026-09-13 21:34:03 +02:00
stt_core.py Alte Einzelskripte stt.py und stt_respeaker.py nach legacy/ verschoben 2026-09-13 21:34:23 +02:00
stt_service.py STT-Dienst: Kern, HTTP/WebSocket/Wyoming-Service, CLI, Tests, systemd-Unit 2026-09-13 21:34:03 +02:00
stt_wyoming.py STT-Dienst: Kern, HTTP/WebSocket/Wyoming-Service, CLI, Tests, systemd-Unit 2026-09-13 21:34:03 +02:00

SpeechToText

Lokaler, schneller Spracherkennungs-Dienst (Sprache → Text) auf Basis von faster-whisper — das STT-Gegenstück zu chatterbox-tts-cli.

Gedacht als Baustein für Sprachassistenten und Smarthome: Home Assistant (Wyoming), Mikrocontroller wie ESP32 (HTTP/WebSocket), Skripte (CLI) und OpenAI-kompatible Tools.

  • Schnell: Modell bleibt geladen. Gemessen auf RTX 3090 mit large-v3-turbo: 5,8 s Audio → 0,2 s, 35 s Audio → 0,7 s Rechenzeit; ~2,4 GB VRAM.
  • Nicht blockierend: Inferenz in einem Worker-Thread, Warteschlange begrenzt (503 statt Stau).
  • Äußerungsende per VAD (Silero) statt Stoppwort; Transkript ca. 1 s nach Sprechende.
  • Robust: GPU-Fehler → automatischer CPU-Fallback; beliebige Audioformate; Halluzinationsfilter („Untertitel im Auftrag des ZDF“ …).

Installation

python3 -m venv --system-site-packages .venv   # nutzt vorhandenes faster-whisper/torch-Umfeld
.venv/bin/pip install -r requirements.txt

Dienst starten

# Manuell (GPU per UUID pinnen: nvidia-smi -L)
CUDA_VISIBLE_DEVICES=GPU-<uuid> .venv/bin/uvicorn stt_service:app --host 0.0.0.0 --port 9998

# Als systemd-User-Service (Autostart)
cp deploy/stt-service.service ~/.config/systemd/user/
systemctl --user daemon-reload && systemctl --user enable --now stt-service
journalctl --user -u stt-service -f

curl http://127.0.0.1:9998/health

Beim ersten Start wird das Modell heruntergeladen (large-v3-turbo ≈ 1,6 GB). Der Dienst ist sofort erreichbar; /health meldet loading, bis das Modell bereit ist.

Konfiguration (Umgebungsvariablen)

Variable Standard Bedeutung
STT_MODEL large-v3-turbo Whisper-Modell (tiny … large-v3, large-v3-turbo, Pfad)
STT_DEVICE auto auto / cuda / cpu
STT_COMPUTE_TYPE auto float16 (GPU) / int8 (CPU) automatisch
STT_CPU_MODEL small Modell beim Ausweichen auf CPU
STT_LANGUAGE de Default-Sprache, auto = Erkennung
STT_BEAM_SIZE 5 Beam-Search-Breite (1 = schneller)
STT_INITIAL_PROMPT – Kontext/Eigennamen für Whisper
STT_MAX_QUEUE 8 max. wartende Aufträge, darüber HTTP 503
STT_MAX_UPLOAD_MB 50 max. Uploadgröße
STT_PRELOAD 1 Modell beim Start laden + aufwärmen
STT_VAD_SILENCE_MS 700 Stille bis Äußerungsende (Streaming)
STT_VAD_THRESHOLD 0.5 Silero-Sprachschwelle
STT_VAD_MAX_UTTERANCE_S 30 max. Äußerungslänge
STT_WYOMING_HOST / STT_WYOMING_PORT 0.0.0.0 / 10300 Wyoming-Server, Port leer = aus
STT_LOG_LEVEL INFO Log-Level

Schnittstellen

HTTP

# OpenAI-kompatibel (multipart) — response_format: json | text | verbose_json
curl -F file=@aufnahme.mp3 -F language=de http://127.0.0.1:9998/v1/audio/transcriptions

# Rohdaten im Body — ideal für Mikrocontroller (kein multipart nötig)
curl --data-binary @aufnahme.wav http://127.0.0.1:9998/transcribe
curl --data-binary @roh.pcm "http://127.0.0.1:9998/transcribe?format=pcm&sample_rate=16000&channels=1"

/transcribe liefert text, language, duration, processing_s, segments.

WebSocket /ws/stream (Live-Streaming)

Client schickt s16le-PCM in beliebig großen Stücken; der Dienst erkennt Äußerungen selbst.

→ {"type":"start","sample_rate":16000,"channels":1,"channel":null,"language":"de","vad":true,"silence_ms":700}
→ <binär: PCM> …
← {"type":"speech_start","t":1.31}
← {"type":"transcript","text":"Schalte das Licht ein.","language":"de","duration":2.4,"processing_s":0.21,"reason":"silence","t":3.9}
→ {"type":"end"}      # laufende Äußerung abschließen → danach {"type":"done"}
→ {"type":"close"}    # ausstehende Transkripte senden, dann schließen

Ohne VAD ("vad":false) wird alles bis end gesammelt und als Ganzes transkribiert (Push-to-Talk). Für ESP32: I²S-Mikrofon mit 16 kHz mono lesen und die Puffer direkt als Binär-Frames senden.

Home Assistant (Wyoming)

Einstellungen → Geräte & Dienste → Integration hinzufügen → Wyoming Protocol → Host = dieser Rechner, Port 10300. Danach in der Sprachassistenten-Pipeline als Spracherkennung auswählen. ESPHome-Satelliten nutzen den Dienst dann automatisch.

CLI

Nur Transkripte auf stdout, Status auf stderr → skriptfähig.

.venv/bin/python stt_cli.py aufnahme.wav            # Datei über den Dienst
.venv/bin/python stt_cli.py *.mp3 --json            # JSON-Zeilen
.venv/bin/python stt_cli.py                         # Mikrofon (System-Default), fortlaufend
text=$(.venv/bin/python stt_cli.py --once)          # eine Äußerung → Variable
.venv/bin/python stt_cli.py -d respeaker -v         # bestimmtes Gerät (ReSpeaker: ASR-Kanal automatisch)
.venv/bin/python stt_cli.py --local --model small aufnahme.wav   # ohne Dienst
.venv/bin/python stt_cli.py --list-devices

Exit-Codes: 0 ok, 1 Fehler, 2 keine Sprache erkannt.

Tests

.venv/bin/python -m pytest                    # schnell, ohne Modell (Fake-Engine)
.venv/bin/python -m pytest -m integration     # echtes Whisper (small, CPU) + Silero mit espeak-ng-Sprache
.venv/bin/python -m pytest tests/test_core.py::test_segmenter_detects_two_utterances

Bekannte Grenzen

  • Wörtlich wiederholte Sätze innerhalb eines 30-s-Fensters fasst Whisper teils zusammen (bei natürlicher Sprache selten).
  • Keine wortweisen Zwischenergebnisse während des Sprechens — Transkript kommt pro Äußerung.
  • legacy/stt.py und legacy/stt_respeaker.py sind die alten Einzelskripte (historisch, nicht gepflegt).