- CHANGELOG.md neu (0.1.0, 0.2.0) - Bedienungsanleitung: LLM-Korrektur in Überblick, Voraussetzungen, Installation, Deinstallation - Entwicklerdoku: Output-Klasse, STT_LLM_*-Konfiguration, Nebenläufigkeitsregel für Ausgaben, Erweitern (LLM/Prompt), Grenzen und nächste Schritte - README, CLAUDE.md: Verweise und Befehle ergänzt - stt_core.__version__ = 0.2.0 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
64 lines
4.3 KiB
Markdown
64 lines
4.3 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.
|
||
|
||
## Dokumentation
|
||
|
||
`README.md` (Überblick) · `BEDIENUNGSANLEITUNG.md` (Anwender, vollständige Tabelle der `STT_*`-Variablen) ·
|
||
`docs/API.md` (HTTP/WebSocket/Wyoming-Protokoll) · `docs/ENTWICKLER.md` (Architektur, Nebenläufigkeitsregeln,
|
||
Tests, Erweitern). Bei Änderungen an Schnittstellen, Optionen oder Umgebungsvariablen die betroffenen Dokumente
|
||
mitpflegen; bei neuer Version `stt_core.__version__` erhöhen und `CHANGELOG.md` ergänzen.
|
||
|
||
## Befehle
|
||
|
||
```bash
|
||
.venv/bin/python -m pytest # Unit-Tests, ohne Modell/LLM (~9 s)
|
||
.venv/bin/python -m pytest -m integration # echtes Whisper small/CPU + Silero (~20 s), LLM über Ollama (bis ~75 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 | --until-enter [--llm-correct] | --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_llm.py` — optionale LLM-Nachkorrektur, nur über `Output` in `stt_cli.py` (`--llm-correct`); Kern und Dienst kennen
|
||
sie nicht. Ollama nativ (`num_ctx`/`keep_alive`/`think:false` pro Anfrage, weil Ollama global 131k Kontext hat) oder
|
||
OpenAI-kompatibel; `_accept` verwirft Antworten mit Ähnlichkeit < 0,75 oder ±30 % Länge → Rohtext.
|
||
- `legacy/stt.py`, `legacy/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`.
|