- stt_core.py: Whisper-Engine (einmal laden, CPU-Fallback), Audio-Dekodierung jedes Formats, Halluzinationsfilter, Äußerungserkennung per Silero-VAD - stt_service.py: /health, /v1/audio/transcriptions (OpenAI), /transcribe (Rohdaten), WS /ws/stream; Inferenz im Worker-Thread, begrenzte Warteschlange (503) - stt_wyoming.py: Home-Assistant-Anbindung (TCP 10300) - stt_cli.py: Datei/Mikrofon über den Dienst oder lokal - Tests (Unit + Integration), README, requirements.txt, deploy/stt-service.service Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
54 lines
3.5 KiB
Markdown
54 lines
3.5 KiB
Markdown
# CLAUDE.md
|
||
|
||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||
|
||
> Sprache: Code-Kommentare, Doku und Commits auf Deutsch.
|
||
|
||
## Projektziel
|
||
|
||
Lokale, schnelle, zuverlässige Spracherkennung, nicht blockierend. Baustein für Smarthome
|
||
(Home Assistant via Wyoming, ESP32/Arduino als Audio-Clients) und **STT-Pendant zu `chatterbox-tts-cli`**
|
||
(`~/chatterbox-tts-cli`: CLI-Kern + FastAPI-Service + MCP-Adapter + systemd-User-Service, Port 9999).
|
||
Bewährtes STT-Vorbild: `~/my_voice_assistant_v3` (`app/providers/stt/faster_whisper.py`, `app/api/ws.py`).
|
||
Git-Remote auf kitux.de (Forgejo) geplant, noch nicht eingerichtet.
|
||
|
||
## Befehle
|
||
|
||
```bash
|
||
.venv/bin/python -m pytest # Unit-Tests, ohne Modell (~9 s)
|
||
.venv/bin/python -m pytest -m integration # echtes Whisper small/CPU + Silero, espeak-ng-Sprache (~20 s)
|
||
.venv/bin/python -m pytest tests/test_service.py::test_ws_stream_with_vad_emits_transcripts_per_utterance
|
||
|
||
CUDA_VISIBLE_DEVICES=GPU-83ba6d1f-ebbe-f8c8-1433-153e0ebc3866 .venv/bin/python stt_service.py # Port 9998, Wyoming 10300
|
||
.venv/bin/python stt_cli.py datei.wav | --once | --local --model small datei.wav
|
||
```
|
||
|
||
`.venv` ist mit `--system-site-packages` auf miniforge-Base angelegt (faster-whisper, fastapi, onnxruntime kommen
|
||
von dort); nur `wyoming` ist in der venv installiert. Tests immer mit `.venv/bin/python`, sonst fehlt `wyoming`.
|
||
|
||
## Architektur
|
||
|
||
- `stt_core.py` — reine Logik, kein print/sys.exit. `SttEngine` (Modell einmal laden, Lade-Versuche cuda→cpu mit
|
||
`cpu_model`, `_run_lock` serialisiert Inferenz, `condition_on_previous_text=False`, Halluzinationsfilter
|
||
`is_hallucination`), Audio-Hilfen (`decode_audio_bytes` via PyAV für jedes Format, `pcm16_to_float` mit
|
||
Kanalwahl, `StreamResampler` via soxr), `UtteranceSegmenter` (Streaming-Endpointing über 512-Sample-Fenster;
|
||
Wahrscheinlichkeitsfunktion injizierbar, Standard `SileroProb`).
|
||
- `stt_service.py` — `create_app(engine, settings, vad_config, prob_fn_factory)` als Fabrik (Tests injizieren
|
||
`FakeEngine`/`EnergyProb` aus `tests/conftest.py`). `TranscriptionWorker` = ThreadPoolExecutor(1) + Zähler
|
||
`pending` → `Overloaded`/503. Preload läuft als erster Worker-Job, ohne den Start zu blockieren.
|
||
`_StreamSession` = WebSocket-Protokoll (Empfangsschleife legt Äußerungen in eine Queue, `_consume` transkribiert
|
||
der Reihe nach; `send_lock`, weil zwei Tasks senden).
|
||
- `stt_wyoming.py` — Wyoming-Handler im selben Prozess/Worker; nimmt HA-Audio komplett an (externe VAD),
|
||
`transcript_names/terms` → Whisper-`hotwords`; Verbindung wird nach dem Transkript geschlossen (HA-Konvention).
|
||
- `stt_cli.py` — Client: Dateien per `POST /transcribe`, Mikrofon per `/ws/stream`; `--local` nutzt den Kern direkt.
|
||
stdout nur Transkripte, stderr Status. Default-Mikrofon über das ALSA-Gerät `pulse` (PortAudios Default ist hier
|
||
die falsche Onboard-Karte); ReSpeaker XVF3800 → automatisch Kanal 1 (ASR-Ausgang).
|
||
- `stt.py`, `stt_respeaker.py` — **historische** Einzelskripte, nicht weiterentwickeln.
|
||
|
||
Sprache: `language=None` → Config-Default, `"auto"` → Erkennung, `"de-DE"` → `"de"` (`SttEngine.resolve_language`).
|
||
|
||
## Umgebung
|
||
|
||
GPUs: T600 + 2× RTX 3090. `nvidia-smi` zählt in PCI-Reihenfolge, CUDA „fastest first“ → GPU immer per
|
||
`CUDA_VISIBLE_DEVICES=GPU-<uuid>` pinnen. GPU 1 belegt llama.cpp/ollama fast komplett; der Dienst läuft auf GPU 2
|
||
(`large-v3-turbo` ≈ 2,4 GB) neben chatterbox-tts und open-notebook-stt (:8902). HF-Modelle unter `$HF_HOME`.
|