whisper-stt-cli/CLAUDE.md
2026-09-13 21:05:18 +02:00

56 lines
3.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 (Umlaute in Code/Kommentaren bisher meist als ae/oe/ue).
## Projektziel
Lokale, schnelle, zuverlässige Spracherkennung (Sprache → Text), nicht blockierend. Soll später als
Baustein in Smarthome-Szenarien dienen (Home Assistant, Mikrocontroller wie ESP32/Arduino als
Audio-Clients) und das **STT-Pendant zum TTS-Projekt `chatterbox-tts-cli`** werden
(https://kitux.de/forgejo/dschlueter/chatterbox-tts-cli, lokaler Klon `~/chatterbox-tts-cli`:
CLI-Kern + FastAPI-Service mit Job-Queue/Worker-Thread + MCP-Adapter + systemd-User-Service).
Referenz für bewährtes STT: `~/my_voice_assistant_v3` (https://kitux.de/forgejo/dschlueter/my_voice_assistant_v3),
v. a. `app/providers/stt/faster_whisper.py` (Modell einmal laden + cachen, Inferenz via `asyncio.to_thread`,
CPU-Fallback), `app/audio/vad.py` (Äußerungsende per Stille), `app/api/ws.py` (`/ws/voice`), `app/core/warmup.py`.
## Dateien
- `stt.py` — **aktueller Stand**, eigenständige CLI (einzige relevante Datei).
- `stt_respeaker.py` — **historisch**, nicht weiterentwickeln und nicht als Vorlage nutzen.
Kein Build, keine Tests, keine Linter-Konfiguration. Git-Remote auf kitux.de (Forgejo) ist geplant, aber noch nicht eingerichtet.
## Befehle
```bash
pip install faster-whisper sounddevice numpy scipy requests # plus Systemtools: espeak-ng, ffmpeg, pactl/paplay, ollama
python3 stt.py --list-devices # Geräte inkl. nativer Sampleraten aus /proc/asound
python3 stt.py # Live-Aufnahme, Sprache de, Stoppwort "finito"
python3 stt.py en -i respeaker -m large-v3 # Positional-Arg = Sprache
python3 stt.py --file audio.wav --no-llm # Datei-Modus (nur int16-Mono-WAV korrekt)
python3 -m py_compile stt.py # Syntax-Check
```
Rauchtest ohne Mikrofon/GPU: `python3 stt.py --file <wav> --no-llm -m tiny --device cpu`.
## GPU-Umgebung
T600 + 2× RTX 3090. `nvidia-smi` zählt in PCI-Reihenfolge, CUDA/torch/ctranslate2 standardmäßig „fastest first“ —
Indizes stimmen nicht überein. Andere Dienste (llama.cpp, chatterbox, open-notebook-stt auf :8902) pinnen GPUs per
`CUDA_VISIBLE_DEVICES=GPU-<uuid>` (`nvidia-smi -L`); so auch hier verfahren statt per Index.
## Architektur `stt.py` (Ist-Zustand)
Ablauf in `main()`: `detect_compute()` → ein `WhisperModel` (für Stoppwort-Chunks **und** finale Transkription) →
`resolve_device()` (Default via `pactl` → `alsa.card` → sounddevice-Index `hw:N`) → `play_announcement()`
(espeak-ng → ffmpeg → `sd.play`, Fallback `paplay`) → `record_until_stopword()` (Callback-Stream schreibt
2-s-Blöcke in Queue; Hauptthread: Mono → 16 kHz → RMS-Gate → Whisper-Stoppwortprüfung) → Peak-Normalisierung →
WAV in `/tmp/stt_*.wav` → `transcribe()` → `llm_correct()` (Ollama `/api/chat`, `localhost:11434`).
- `stereo_to_mono()`: ReSpeaker XVF3800 → nur rechter Kanal (ASR-Output); Mischen verschlechtert die Erkennung.
- Stoppwort-Entfernung aus dem Text übernimmt nur der LLM-Prompt (`LLM_SYSTEM_PROMPT`, nur de/en).
- Alle Ausgaben per `print`; das Endergebnis steht nach der Zeile `FINALES ERGEBNIS` auf stdout.