whisper-stt-cli/BEDIENUNGSANLEITUNG.md
dschlueter 6ebea4b745 CLI: --until-enter und optionale LLM-Korrektur (--llm-correct)
- --until-enter: Aufnahme mit beliebig langen Pausen, Enter beendet, Ausgabe als ein Text
- stt_llm.py: Nachkorrektur per lokalem LLM (Standard gemma4:12b über Ollama nativ mit
  kleinem Kontext; OpenAI-kompatible Server möglich), strenger Prompt mit Beispielen,
  Ähnlichkeitsprüfung und Fehler-Fallback auf den Rohtext
- Output-Klasse in der CLI: Korrektur in eigenem Thread, Reihenfolge bleibt erhalten
- Tests für die LLM-Korrektur (13 Unit, 1 Integration)
- Doku: Bedienungsanleitung, README, Entwicklerdoku (inkl. Modellvergleich), CLAUDE.md

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 00:48:02 +02:00

505 lines
23 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.

# Bedienungsanleitung SpeechToText
Diese Anleitung richtet sich an **Anwender**: Installieren, Starten, Benutzen, Einrichten mit Home
Assistant, Probleme lösen. Für Programmierer: [docs/API.md](docs/API.md) (Schnittstellen) und
[docs/ENTWICKLER.md](docs/ENTWICKLER.md) (Aufbau des Codes).
## Inhalt
1. [Was macht das Programm?](#1-was-macht-das-programm)
2. [Voraussetzungen](#2-voraussetzungen)
3. [Installation](#3-installation)
4. [Dienst starten und prüfen](#4-dienst-starten-und-prüfen)
5. [Benutzung mit der Kommandozeile (CLI)](#5-benutzung-mit-der-kommandozeile-cli)
6. [Das richtige Mikrofon](#6-das-richtige-mikrofon)
7. [Home Assistant anbinden](#7-home-assistant-anbinden)
8. [Andere Geräte im Netzwerk](#8-andere-geräte-im-netzwerk)
9. [Einstellungen](#9-einstellungen)
10. [Welches Whisper-Modell?](#10-welches-whisper-modell)
11. [Tipps für gute Erkennung](#11-tipps-für-gute-erkennung)
12. [Fehlerbehebung](#12-fehlerbehebung)
13. [Datenschutz](#13-datenschutz)
14. [Deinstallation](#14-deinstallation)
---
## 1. Was macht das Programm?
SpeechToText wandelt **gesprochene Sprache in Text** um — vollständig **lokal** auf dem eigenen Rechner,
ohne Cloud. Grundlage ist das Spracherkennungsmodell *Whisper* in der schnellen Umsetzung
*faster-whisper*.
Es besteht aus zwei Teilen:
- **Dem Dienst** (`stt_service.py`): läuft im Hintergrund, hält das Sprachmodell im Speicher und nimmt
Aufträge entgegen — von Home Assistant, von Mikrocontrollern, von Skripten oder von der CLI.
- **Der Kommandozeile** (`stt_cli.py`): schickt Audiodateien oder das Mikrofon an den Dienst und gibt den
erkannten Text aus.
```mermaid
flowchart LR
MIC[Mikrofon] --> CLI[stt_cli.py]
FILE[Audiodatei] --> CLI
HA[Home Assistant] -- Wyoming :10300 --> SVC
ESP[ESP32 / Skripte / Apps] -- HTTP / WebSocket :9998 --> SVC
CLI -- HTTP / WebSocket :9998 --> SVC[STT-Dienst<br/>Whisper-Modell auf GPU]
SVC --> TXT[Text]
```
**Wie schnell?** Auf einer RTX 3090 mit dem Modell `large-v3-turbo`: ein Satz von 6 Sekunden ist in
0,2 Sekunden erkannt, 35 Sekunden Sprache in 0,7 Sekunden. Beim freien Sprechen erscheint der Text etwa
eine Sekunde, nachdem man aufgehört hat zu sprechen.
**Wie merkt das Programm, dass ich fertig bin?** Es erkennt eine **Sprechpause** (Standard: 0,7 s Stille
nach Sprache). Ein Stoppwort ist nicht nötig.
---
## 2. Voraussetzungen
| | Minimum | Empfohlen |
|---|---|---|
| Betriebssystem | Linux (getestet: Ubuntu mit PipeWire) | |
| Python | 3.11 | 3.12 (getestet) |
| Grafikkarte | keine (läuft auch auf CPU, dann langsamer) | NVIDIA mit ≥ 4 GB freiem Speicher, CUDA 12 |
| Arbeitsspeicher | 4 GB frei | 8 GB frei |
| Festplatte | 0,5 GB (Modell `small`) | 2 GB (Modell `large-v3-turbo`) |
| Mikrofon | beliebig (nur für Live-Betrieb) | ReSpeaker XVF3800 oder gutes USB-Mikrofon |
Systemprogramme: `ffmpeg` ist hilfreich (Formatumwandlung), `pactl` (PipeWire/PulseAudio) für die
Mikrofonwahl, `espeak-ng` nur für die automatischen Tests.
---
## 3. Installation
```bash
cd ~/Python_Programs
git clone <repository-url> SpeechToText # bzw. vorhandenen Ordner nutzen
cd SpeechToText
python3 -m venv --system-site-packages .venv
.venv/bin/pip install -r requirements.txt
```
`--system-site-packages` nutzt bereits installierte Pakete (z. B. faster-whisper, CUDA-Bibliotheken)
mit. Ohne vorhandene Installation lädt `pip` alles herunter.
**Installation prüfen** (dauert ca. 10 Sekunden, braucht kein Modell):
```bash
.venv/bin/python -m pytest
# … 49 passed
```
> Beim **ersten Start des Dienstes** wird das Whisper-Modell aus dem Internet geladen
> (`large-v3-turbo` ≈ 1,6 GB). Danach arbeitet alles offline.
---
## 4. Dienst starten und prüfen
### Manuell starten
```bash
cd ~/Python_Programs/SpeechToText
.venv/bin/python stt_service.py
```
Auf Rechnern mit **mehreren Grafikkarten** die gewünschte Karte fest angeben. Die Kennung (UUID) zeigt
`nvidia-smi -L`:
```bash
CUDA_VISIBLE_DEVICES=GPU-83ba6d1f-ebbe-f8c8-1433-153e0ebc3866 .venv/bin/python stt_service.py
```
> Warum UUID statt Nummer? `nvidia-smi` und CUDA nummerieren die Karten unterschiedlich. Mit der UUID
> landet der Dienst sicher auf der richtigen Karte.
Im Terminal erscheint u. a.:
```
INFO stt.service: Wyoming-Server auf tcp://0.0.0.0:10300
INFO stt: Lade Whisper-Modell large-v3-turbo (cuda, float16)
INFO stt: Modell bereit nach 2.3s
```
Das Fenster offen lassen. **Beenden** mit `Strg+C`.
### Prüfen
In einem zweiten Terminal:
```bash
curl http://127.0.0.1:9998/health
```
`"status":"ok"` = bereit. `"status":"loading"` = Modell lädt noch (kurz warten).
`"device":"cuda"` = läuft auf der Grafikkarte, `"cpu"` = auf dem Prozessor.
Im Browser zeigt **http://127.0.0.1:9998/docs** alle Schnittstellen zum Ausprobieren.
### Optional: automatisch starten (systemd)
Soll der Dienst dauerhaft laufen (nötig z. B. für Home Assistant nach einem Neustart):
```bash
cp deploy/stt-service.service ~/.config/systemd/user/
# ggf. CUDA_VISIBLE_DEVICES und Einstellungen in der Datei anpassen
systemctl --user daemon-reload
systemctl --user enable --now stt-service
```
| Aufgabe | Befehl |
|---|---|
| Status | `systemctl --user status stt-service` |
| Neustart (nach Änderungen) | `systemctl --user restart stt-service` |
| Anhalten | `systemctl --user stop stt-service` |
| Autostart abschalten | `systemctl --user disable --now stt-service` |
| Live-Log | `journalctl --user -u stt-service -f` |
Vorher einen manuell gestarteten Dienst beenden — beide wollen Port 9998.
---
## 5. Benutzung mit der Kommandozeile (CLI)
Die CLI gibt **nur den erkannten Text** aus (Standardausgabe). Statusmeldungen stehen getrennt davon
(Fehlerausgabe). Deshalb lässt sie sich direkt in Skripten verwenden.
Alle Beispiele im Projektordner: `cd ~/Python_Programs/SpeechToText`
### Audiodateien
```bash
.venv/bin/python stt_cli.py aufnahme.wav
.venv/bin/python stt_cli.py interview.mp3 notiz.ogg # mehrere Dateien, eine Zeile je Datei
.venv/bin/python stt_cli.py aufnahme.wav --json # mit Details
.venv/bin/python stt_cli.py aufnahme.wav > text.txt # in Datei speichern
```
Unterstützt: WAV, MP3, OGG, FLAC, M4A, WebM und praktisch alle anderen Audioformate.
### Mikrofon
```bash
.venv/bin/python stt_cli.py -v
```
Nach **„Bereit — sprich.“** einfach sprechen und kurz Pause machen. Jeder Satz erscheint als eigene
Zeile. Beenden mit `Strg+C`.
### Mit Pausen sprechen, selbst beenden
```bash
.venv/bin/python stt_cli.py --until-enter -v
```
Die Aufnahme läuft, bis **Enter** gedrückt wird — Denk- und Sprechpausen beliebiger Länge beenden sie
nicht. Mit `-v` erscheinen die erkannten Abschnitte schon während des Sprechens (mit `+` markiert).
Nach Enter wird der letzte Abschnitt fertig transkribiert und der **gesamte Text als eine Zeile**
ausgegeben. Mit `--timeout SEK` endet die Aufnahme spätestens nach SEK Sekunden.
```
Mikrofon: pulse → alsa_input.usb-Seeed_Studio_reSpeaker_XVF3800_… (16000 Hz, 2 Kanäle, Kanal 1)
Bereit — sprich. (Strg+C beendet)
… Sprache erkannt (2.3s)
(3.1s Audio, 0.21s Rechenzeit)
Schalte das Licht im Wohnzimmer ein.
```
### Alle Optionen
| Option | Bedeutung |
|---|---|
| `DATEI …` | Audiodateien transkribieren; ohne Datei wird das Mikrofon benutzt |
| `-v`, `--verbose` | Statusdetails anzeigen (Sprachbeginn, Dauer, Rechenzeit) |
| `--json` | Ergebnis als JSON-Zeile (Text, Sprache, Dauer, Rechenzeit …) |
| `-l`, `--language` | Sprache: `de`, `en`, `fr` … oder `auto` (automatisch erkennen) |
| `--prompt "…"` | Eigennamen/Fachbegriffe vorgeben, z. B. `--prompt "Bredelar, Marsberg"` |
| `--once` | nach dem ersten erkannten Satz beenden |
| `--until-enter` | Aufnahme mit **beliebig langen Pausen**, bis Enter gedrückt wird; Ergebnis als **ein** Text |
| `--timeout SEK` | Mikrofon nach SEK Sekunden beenden |
| `--silence-ms MS` | Pausenlänge, die einen Satz beendet (Standard 700; für Denkpausen 1200–2000) |
| `-d`, `--device` | Mikrofon wählen: Nummer oder Namensteil, z. B. `-d respeaker` |
| `--channel N` | Mikrofonkanal wählen (ReSpeaker: automatisch 1) |
| `--list-devices` | verfügbare Mikrofone anzeigen (`*` = Standard von PortAudio) |
| `--url URL` | anderer Dienst, z. B. `--url http://192.168.1.10:9998` (auch per `STT_URL`) |
| `--local` | **ohne Dienst**: Modell direkt laden (Start dauert länger) |
| `--model NAME` | nur mit `--local`: Whisper-Modell, z. B. `small`, `large-v3-turbo` |
| `--compute-device` | nur mit `--local`: `auto`, `cuda` oder `cpu` |
| `--http-timeout SEK` | max. Wartezeit bei Dateien (Standard 300) |
| `--llm-correct` | Ergebnis zusätzlich von einem lokalen LLM korrigieren lassen, siehe [LLM-Korrektur](#llm-korrektur-optional) |
| `--llm-model NAME` | LLM für die Korrektur (Standard `gemma4:12b`) |
| `--llm-url URL` | LLM-Server (Standard Ollama `http://127.0.0.1:11434`; OpenAI-kompatibel mit `…/v1`) |
### Rückgabewerte (für Skripte)
| Code | Bedeutung |
|---|---|
| `0` | Text erkannt |
| `1` | Fehler (Dienst nicht erreichbar, Datei fehlt …) |
| `2` | keine Sprache erkannt (nur Stille/Geräusche, Zeitlimit abgelaufen) |
| `130` | mit `Strg+C` abgebrochen, bevor ein Ergebnis vorlag (z. B. während einer Dateiübertragung) |
### Beispiele für Skripte
```bash
# Einen Satz sprechen und in einer Variablen weiterverarbeiten
text=$(.venv/bin/python stt_cli.py --once --timeout 15)
[ $? -eq 0 ] && echo "Du hast gesagt: $text"
# Alle MP3s eines Ordners in Textdateien umwandeln
for f in aufnahmen/*.mp3; do
.venv/bin/python stt_cli.py "$f" > "${f%.mp3}.txt"
done
# Längere Notiz mit Pausen sprechen, Enter beendet, Text in Variable
notiz=$(.venv/bin/python stt_cli.py --until-enter)
# Diktat mit Denkpausen fortlaufend in eine Datei schreiben
.venv/bin/python stt_cli.py --silence-ms 1500 >> notizen.txt
```
### LLM-Korrektur (optional)
Mit `--llm-correct` wird der erkannte Text zusätzlich von einem **lokalen Sprachmodell** (Standard:
`gemma4:12b` über Ollama) geprüft. Es korrigiert nur offensichtliche Erkennungsfehler — falsch
verstandene Wörter, Rechtschreibung, Groß-/Kleinschreibung, Satzzeichen — und lässt Bedeutung, Zahlen,
Namen und Verneinungen unangetastet.
```bash
.venv/bin/python stt_cli.py --until-enter --llm-correct -v
.venv/bin/python stt_cli.py notiz.mp3 --llm-correct --json
```
```
LLM: korrigiert (1.21s)
roh: Heute ist ein schöner Tag. Die Lonne scheint und die Rögel singen im Garten.
Heute ist ein schöner Tag. Die Sonne scheint und die Vögel singen im Garten.
```
**Sicherungen:** Weicht die Antwort des LLM zu stark vom erkannten Text ab (z. B. weil es etwas erfindet
oder einer „Anweisung“ im Diktat folgt), wird sie verworfen und der **Rohtext** ausgegeben. Ist das LLM
nicht erreichbar, erscheint eine Meldung und ebenfalls der Rohtext. Mit `--json` stehen Rohtext
(`raw_text`) und Details (`llm`: Status, Dauer, Modell) immer mit im Ergebnis.
**Wann sinnvoll?** Für Notizen, Diktate und längere Texte. Für kurze Befehle („Licht an“) nicht nötig —
Whisper erkennt sie meist fehlerfrei, und die Korrektur kostet rund 1 Sekunde pro Text.
**Voraussetzungen und Hinweise:**
- Ollama läuft und das Modell ist installiert: `ollama pull gemma4:12b`.
- Das **erste Laden** dauert je nach Rechner rund eine Minute; im Mikrofon-Modus beginnt es schon beim
Start im Hintergrund. Danach bleibt das Modell 30 Minuten geladen (`STT_LLM_KEEP_ALIVE`).
- Das Modell belegt dabei ca. 10 GB Grafikspeicher.
- Anderes Modell oder anderer Server: `--llm-model mistral-nemo` bzw.
`--llm-url http://127.0.0.1:8011/v1` (llama.cpp, LM Studio …).
### Ohne laufenden Dienst
```bash
.venv/bin/python stt_cli.py --local --model large-v3-turbo aufnahme.wav
.venv/bin/python stt_cli.py --local --model small --compute-device cpu -v # Mikrofon auf CPU
```
Praktisch für gelegentliche Nutzung; jeder Aufruf lädt das Modell aber neu (Sekunden bis Minuten).
---
## 6. Das richtige Mikrofon
**Standard:** Ohne `-d` benutzt die CLI das Mikrofon, das in den **Systemeinstellungen** (Ubuntu:
Einstellungen → Ton → Eingabe) ausgewählt ist. Die erste Statuszeile zeigt, welches:
```
Mikrofon: pulse → alsa_input.usb-Seeed_Studio_reSpeaker_XVF3800_…
```
**Anderes Mikrofon:**
```bash
.venv/bin/python stt_cli.py --list-devices # Liste mit Nummern
.venv/bin/python stt_cli.py -d 15 -v # per Nummer
.venv/bin/python stt_cli.py -d respeaker -v # per Namensteil
```
**ReSpeaker XVF3800:** Das Gerät liefert zwei Kanäle. Der **rechte Kanal (1)** ist speziell für
Spracherkennung aufbereitet (Echo- und Rauschunterdrückung). Die CLI erkennt den ReSpeaker am Namen und
wählt Kanal 1 automatisch. Andere Mikrofone: beide Kanäle werden gemischt; mit `--channel 0`/`1` lässt
sich ein Kanal erzwingen.
**Pegel prüfen:** In den Toneinstellungen muss der Eingangspegel beim Sprechen ausschlagen. Wird nie
„Sprache erkannt“ angezeigt, ist das Mikrofon meist falsch gewählt, stumm oder zu leise.
---
## 7. Home Assistant anbinden
Der Dienst spricht das **Wyoming-Protokoll**, mit dem Home Assistant lokale Spracherkennung einbindet.
1. Dienst dauerhaft laufen lassen ([systemd](#optional-automatisch-starten-systemd)), sonst fehlt die
Spracherkennung nach einem Neustart.
2. Port 10300 im Netzwerk erreichbar machen (siehe [Abschnitt 8](#8-andere-geräte-im-netzwerk)).
3. In Home Assistant: **Einstellungen → Geräte & Dienste → Integration hinzufügen → „Wyoming Protocol“**
4. **Host:** IP-Adresse des STT-Rechners, **Port:** `10300` → Absenden. Es erscheint „speech-to-text“.
5. **Einstellungen → Sprachassistenten** → Assistent öffnen → **Spracherkennung:** „speech-to-text“,
Sprache „Deutsch“.
6. Testen, z. B. über das Mikrofon-Symbol in der Home-Assistant-App oder einen ESPHome-Satelliten
(z. B. ESP32-S3-Box, M5Stack Atom Echo).
Home Assistant bzw. der Satellit erkennt das Satzende selbst und schickt die komplette Aufnahme. Im Log
des Dienstes erscheint pro Befehl eine Zeile `Wyoming-Transkript (…)`.
---
## 8. Andere Geräte im Netzwerk
Der Dienst ist im ganzen Netzwerk erreichbar unter `http://<IP-des-Rechners>:9998` (HTTP/WebSocket) und
`<IP>:10300` (Wyoming). Die IP zeigt `hostname -I`.
Ist eine Firewall aktiv, die Ports für das Heimnetz freigeben:
```bash
sudo ufw allow from 192.168.1.0/24 to any port 9998 proto tcp comment 'SpeechToText HTTP'
sudo ufw allow from 192.168.1.0/24 to any port 10300 proto tcp comment 'SpeechToText Wyoming'
```
(`192.168.1.0/24` an das eigene Netz anpassen.)
> **Wichtig:** Der Dienst hat **kein Passwort**. Jeder im Netzwerk kann Audio schicken. Die Ports daher
> **nicht ins Internet** freigeben (keine Portweiterleitung im Router).
Wie Mikrocontroller (ESP32), Web-Apps oder eigene Programme den Dienst ansprechen, beschreibt
[docs/API.md](docs/API.md) mit Beispielen.
---
## 9. Einstellungen
Der Dienst wird über **Umgebungsvariablen** eingestellt:
- **manuell:** vor den Startbefehl schreiben, z. B.
`STT_MODEL=small STT_LANGUAGE=en .venv/bin/python stt_service.py`
- **systemd:** in `~/.config/systemd/user/stt-service.service` als `Environment="STT_MODEL=small"`,
danach `systemctl --user daemon-reload && systemctl --user restart stt-service`
| Variable | Standard | Bedeutung |
|---|---|---|
| `STT_MODEL` | `large-v3-turbo` | Whisper-Modell, siehe [Abschnitt 10](#10-welches-whisper-modell) |
| `STT_LANGUAGE` | `de` | Standardsprache; `auto` = automatisch erkennen |
| `STT_DEVICE` | `auto` | `auto` (GPU wenn vorhanden), `cuda` oder `cpu` |
| `STT_COMPUTE_TYPE` | `auto` | Rechengenauigkeit; `auto` = `float16` auf GPU, `int8` auf CPU |
| `STT_CPU_MODEL` | `small` | Modell, falls die GPU nicht nutzbar ist und auf CPU ausgewichen wird |
| `STT_CPU_THREADS` | `0` | CPU-Threads (0 = automatisch) |
| `STT_BEAM_SIZE` | `5` | Suchbreite; `1` ist schneller, `5` genauer |
| `STT_INITIAL_PROMPT` | – | Eigennamen/Fachbegriffe für alle Anfragen |
| `STT_PRELOAD` | `1` | Modell sofort beim Start laden (`0` = erst bei der ersten Anfrage) |
| `STT_MAX_QUEUE` | `8` | max. gleichzeitig wartende Aufträge, darüber Ablehnung („beschäftigt“) |
| `STT_MAX_UPLOAD_MB` | `50` | größte erlaubte Audiodatei |
| `STT_VAD_SILENCE_MS` | `700` | Pause, die beim Live-Streaming einen Satz beendet |
| `STT_VAD_THRESHOLD` | `0.5` | Empfindlichkeit der Spracherkennung (höher = weniger Fehlauslösung durch Geräusche) |
| `STT_VAD_MIN_SPEECH_MS` | `200` | Mindestlänge von Sprache (filtert Klicks und Klopfen) |
| `STT_VAD_PRE_ROLL_MS` | `300` | Audio vor dem erkannten Sprachbeginn mitnehmen |
| `STT_VAD_MAX_UTTERANCE_S` | `30` | längster Satz; längere Abschnitte werden geteilt |
| `STT_WYOMING_PORT` | `10300` | Port für Home Assistant; leer = aus |
| `STT_WYOMING_HOST` | `0.0.0.0` | Netzwerkschnittstelle für Wyoming |
| `STT_HOST` / `STT_PORT` | `0.0.0.0` / `9998` | Adresse des HTTP-Dienstes (nur bei `python stt_service.py`) |
| `STT_LOG_LEVEL` | `INFO` | `DEBUG`, `INFO`, `WARNING`, `ERROR` |
| `STT_DOWNLOAD_ROOT` | – | eigener Ordner für Modelle (sonst Hugging-Face-Cache) |
| `CUDA_VISIBLE_DEVICES` | – | Grafikkarte festlegen (UUID aus `nvidia-smi -L`) |
**LLM-Korrektur** (nur `stt_cli.py --llm-correct`):
| Variable | Standard | Bedeutung |
|---|---|---|
| `STT_LLM_MODEL` | `gemma4:12b` | Modell für die Korrektur |
| `STT_LLM_URL` | `http://127.0.0.1:11434` | Ollama; OpenAI-kompatible Server mit `…/v1` |
| `STT_LLM_API` | `auto` | `auto`, `ollama` oder `openai` |
| `STT_LLM_KEEP_ALIVE` | `30m` | nur Ollama: wie lange das Modell nach Gebrauch geladen bleibt |
| `STT_LLM_NUM_CTX` | `4096` | nur Ollama: Kontextgröße (klein halten, sonst läuft das Modell auf der CPU) |
| `STT_LLM_TIMEOUT` | `120` | max. Wartezeit in Sekunden (inkl. Laden) |
| `STT_LLM_MIN_SIMILARITY` | `0.75` | Mindestähnlichkeit zum Rohtext, sonst wird die Korrektur verworfen |
---
## 10. Welches Whisper-Modell?
| Modell | Qualität Deutsch | Geschwindigkeit | Grafikspeicher | Einsatz |
|---|---|---|---|---|
| `tiny` | mäßig | sehr schnell | < 1 GB | nur Tests |
| `base` | ausreichend für kurze Befehle | sehr schnell | ~1 GB | schwache Hardware |
| `small` | gut | schnell, auch auf CPU brauchbar | ~1 GB | **CPU-Betrieb** |
| `medium` | sehr gut | mittel | ~2–3 GB | |
| `large-v3` | ausgezeichnet | langsamer | ~4 GB | höchste Genauigkeit bei langen Texten |
| **`large-v3-turbo`** | ausgezeichnet | **schnell** | **~2,4 GB** | **Standard mit GPU** |
Gemessen wurde in diesem Projekt nur `large-v3-turbo` (RTX 3090); `small` auf CPU ist durch die Tests
erprobt. Die übrigen Angaben sind Richtwerte. Jedes Modell wird beim ersten Gebrauch einmalig heruntergeladen.
---
## 11. Tipps für gute Erkennung
- **Abstand:** 30 cm bis 1 m zum Mikrofon, deutlich, aber normal sprechen.
- **Pause am Satzende:** Nach dem Satz kurz innehalten — das signalisiert „fertig“.
- **Denkpausen:** Wird ein Satz mitten drin abgeschnitten, `--silence-ms 1200` (oder mehr) verwenden.
- **Eigennamen:** Werden Namen falsch geschrieben, mit `--prompt "Name1, Name2"` vorgeben.
- **Hintergrundgeräusche:** Radio/Fernseher leiser; bei vielen Fehlauslösungen `STT_VAD_THRESHOLD=0.6`.
- **Sprache fest einstellen:** `-l de` ist schneller und zuverlässiger als `auto`, besonders bei kurzen
Sätzen.
---
## 12. Fehlerbehebung
| Problem | Ursache | Lösung |
|---|---|---|
| `Fehler: … Connection refused` / „Läuft der Dienst?“ | Dienst nicht gestartet | Dienst starten ([Abschnitt 4](#4-dienst-starten-und-prüfen)) oder `--local` nutzen |
| `/health` zeigt lange `loading` | erster Start: Modell wird heruntergeladen | Internetverbindung prüfen, warten; Fortschritt im Log |
| `/health` zeigt `"device":"cpu"`, obwohl eine GPU da ist | GPU belegt/zu wenig Speicher/CUDA-Problem | Log lesen (`Laden auf cuda fehlgeschlagen: …`), `nvidia-smi` prüfen, andere Karte per `CUDA_VISIBLE_DEVICES` |
| `/health` zeigt `error` | Modell nicht ladbar | Meldung im Feld `error`; Modellname und Speicherplatz prüfen |
| Nie „Sprache erkannt“ | falsches/stummes Mikrofon | [Abschnitt 6](#6-das-richtige-mikrofon); Pegel in den Toneinstellungen prüfen |
| Sätze werden mittendrin geteilt / Aufnahme endet bei Pausen | Pausen zu lang für die Einstellung | `--silence-ms 1200` oder `--until-enter` (Enter beendet) |
| Text kommt erst sehr spät | Pausenerkennung sehr lang eingestellt oder CPU-Betrieb | `--silence-ms` verringern; GPU nutzen |
| Wörter/Namen falsch | Aussprache, unbekannte Namen | `--prompt` mit Namen; größeres Modell; deutlicher sprechen |
| „Untertitel im Auftrag des ZDF“ o. Ä. | Whisper-Halluzination bei Stille | wird normalerweise gefiltert; tritt es trotzdem auf, bitte Beispiel melden |
| Wiederholte gleiche Sätze fehlen teilweise | Whisper fasst wörtliche Wiederholungen zusammen | bekannte Grenze; bei natürlicher Sprache selten |
| `Warteschlange voll` / HTTP 503 | zu viele Aufträge gleichzeitig | kurz warten; `STT_MAX_QUEUE` erhöhen |
| `Address already in use` beim Start | Port 9998/10300 belegt (zweiter Dienst läuft) | anderen Dienst beenden (`systemctl --user stop stt-service`) |
| Home Assistant findet den Dienst nicht | Firewall, falsche IP, Dienst aus | `curl http://<IP>:9998/health` vom HA-Rechner; [Abschnitt 8](#8-andere-geräte-im-netzwerk) |
| `LLM: Fehler, Rohtext behalten — ConnectionError` | Ollama läuft nicht / falsche `--llm-url` | `systemctl status ollama`; `curl http://127.0.0.1:11434/api/version` |
| `LLM: verworfen, Rohtext behalten` | LLM-Antwort wich zu stark ab | gewollte Sicherung; bei Bedarf anderes Modell probieren |
| LLM-Korrektur dauert beim ersten Mal ~1 Minute | Modell wird geladen | normal; danach ~1 s pro Text |
| LLM-Korrektur dauert immer mehrere Sekunden | Modell läuft auf der CPU (zu großer Kontext/kein GPU-Speicher) | `ollama ps` prüfen: `PROCESSOR` sollte `100% GPU` zeigen |
| `Warnung: … Audioblöcke verworfen` | Netzwerk/Dienst zu langsam für das Mikrofon | Verbindung prüfen; lokal testen |
**Log ansehen:** manuell gestartet → im Terminal; als systemd-Dienst →
`journalctl --user -u stt-service -n 100`. Mehr Details mit `STT_LOG_LEVEL=DEBUG`.
---
## 13. Datenschutz
- Die gesamte Spracherkennung läuft **lokal**. Audio und Text verlassen den Rechner nicht.
- Internetzugriff nur beim **ersten Herunterladen** eines Modells (Hugging Face).
- Die optionale LLM-Korrektur nutzt ein **lokales** LLM (Ollama). Nur wer `--llm-url` auf einen fremden
Server setzt, schickt Text dorthin.
- Der Dienst **speichert keine Aufnahmen** und keine Texte auf der Festplatte.
- **Ausnahme Log:** Bei Home-Assistant-Anfragen (Wyoming) wird der erkannte Text im Log protokolliert
(Stufe `INFO`). Wer das nicht möchte: `STT_LOG_LEVEL=WARNING`.
- Der Dienst hat keine Zugangskontrolle → nur im eigenen Netz betreiben ([Abschnitt 8](#8-andere-geräte-im-netzwerk)).
---
## 14. Deinstallation
```bash
systemctl --user disable --now stt-service 2>/dev/null
rm -f ~/.config/systemd/user/stt-service.service && systemctl --user daemon-reload
rm -rf ~/Python_Programs/SpeechToText
```
Heruntergeladene Modelle liegen im Hugging-Face-Cache (`$HF_HOME/hub` bzw. `~/.cache/huggingface/hub`,
Ordner `models--*faster-whisper*`) und werden eventuell auch von anderen Programmen genutzt — nur löschen,
wenn sicher ist, dass sie nicht mehr gebraucht werden.