- BEDIENUNGSANLEITUNG.md: Installation, Betrieb, CLI, Mikrofon, Home Assistant, Einstellungen, Modellwahl, Fehlerbehebung, Datenschutz - docs/API.md: HTTP, WebSocket-Protokoll, Wyoming, Fehlercodes, geprüfte Beispiele - docs/ENTWICKLER.md: Architektur, Module, Nebenläufigkeit, Tests, Erweitern, Designentscheidungen - CLAUDE.md: Verweis auf die Dokumentation Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
19 KiB
Bedienungsanleitung SpeechToText
Diese Anleitung richtet sich an Anwender: Installieren, Starten, Benutzen, Einrichten mit Home Assistant, Probleme lösen. Für Programmierer: docs/API.md (Schnittstellen) und docs/ENTWICKLER.md (Aufbau des Codes).
Inhalt
- Was macht das Programm?
- Voraussetzungen
- Installation
- Dienst starten und prüfen
- Benutzung mit der Kommandozeile (CLI)
- Das richtige Mikrofon
- Home Assistant anbinden
- Andere Geräte im Netzwerk
- Einstellungen
- Welches Whisper-Modell?
- Tipps für gute Erkennung
- Fehlerbehebung
- Datenschutz
- 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.
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
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):
.venv/bin/python -m pytest
# … 36 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
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:
CUDA_VISIBLE_DEVICES=GPU-83ba6d1f-ebbe-f8c8-1433-153e0ebc3866 .venv/bin/python stt_service.py
Warum UUID statt Nummer?
nvidia-smiund 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:
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):
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
.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
.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.
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 |
--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) |
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
# 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
# Diktat mit Denkpausen fortlaufend in eine Datei schreiben
.venv/bin/python stt_cli.py --silence-ms 1500 >> notizen.txt
Ohne laufenden Dienst
.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:
.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.
- Dienst dauerhaft laufen lassen (systemd), sonst fehlt die Spracherkennung nach einem Neustart.
- Port 10300 im Netzwerk erreichbar machen (siehe Abschnitt 8).
- In Home Assistant: Einstellungen → Geräte & Dienste → Integration hinzufügen → „Wyoming Protocol“
- Host: IP-Adresse des STT-Rechners, Port:
10300→ Absenden. Es erscheint „speech-to-text“. - Einstellungen → Sprachassistenten → Assistent öffnen → Spracherkennung: „speech-to-text“, Sprache „Deutsch“.
- 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:
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 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.servicealsEnvironment="STT_MODEL=small", danachsystemctl --user daemon-reload && systemctl --user restart stt-service
| Variable | Standard | Bedeutung |
|---|---|---|
STT_MODEL |
large-v3-turbo |
Whisper-Modell, siehe Abschnitt 10 |
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) |
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 deist schneller und zuverlässiger alsauto, 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) 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; Pegel in den Toneinstellungen prüfen |
| Sätze werden mittendrin geteilt | Pausen zu lang für die Einstellung | --silence-ms 1200 |
| 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 |
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).
- 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).
14. Deinstallation
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.