12 KiB
Bedienungsanleitung — Voice Assistant
Inhaltsverzeichnis
- Voraussetzungen
- Installation der Abhängigkeiten
- Schnellstart
- Die fünf Zustände
- Steuer-Wörter
- Alle Kommandozeilenoptionen
- Mikrofon wählen
- Audio-Ausgang wählen
- LLM-Backend konfigurieren
- Sprache und Stimme
- Standalone-Werkzeuge
- Tipps und Fehlerbehebung
1. Voraussetzungen
Hardware
| Komponente | Empfehlung |
|---|---|
| Mikrofon | ReSpeaker XVF3800 (Hardware-AEC, 4 Mikrofone, 48 kHz) |
| GPU | NVIDIA RTX (CUDA) für Whisper-Transkription |
| Audio-System | PipeWire mit paplay |
Jedes USB-Mikrofon funktioniert. Das ReSpeaker XVF3800 ist empfohlen, weil es Hardware-seitig Echo cancellation (AEC) und Beamforming bietet — das verhindert, dass die TTS-Ausgabe als Spracheingabe erkannt wird.
Software
- Python 3.12+
- PipeWire als Audio-Server (
pactl,paplaymüssen verfügbar sein) - CUDA-Treiber für NVIDIA-GPU
2. Installation der Abhängigkeiten
pip install faster-whisper openwakeword piper-tts sounddevice scipy langdetect openai
Das Whisper-Modell (large-v3) wird beim ersten Start automatisch heruntergeladen (~3 GB).
Piper-Stimmen werden bei Bedarf automatisch heruntergeladen (~60–120 MB pro Sprache).
3. Schnellstart
# Standard: ReSpeaker-Mikrofon, llama.cpp auf localhost:8001, Deutsch
python3 assistant.py
# Ohne Wake-Word — sofort aufnahmebereit (gut zum Testen)
python3 assistant.py --no-wakeword
# Mit Ollama
python3 assistant.py --backend ollama --model llama3.2
# Mit OpenAI
export OPENAI_API_KEY=sk-...
python3 assistant.py --backend openai --model gpt-4o-mini
Beim ersten Start werden Modelle geladen (ca. 10–30 Sekunden). Danach erscheint:
Warte auf "Hey Jarvis" …
[LAUSCH] Warte auf "Hey Jarvis" …
4. Die fünf Zustände
Der Assistent durchläuft folgende Zustände. Der aktuelle Zustand wird in der
Statuszeile links in eckigen Klammern angezeigt: [ZUSTAND] Info
"Hey Jarvis"
LAUSCH ─────────────► AUFNAHME
▲ │
│ Timeout/Stopp Stille ≥5s
│ oder "over"
│ │
│ Stopp ▼
DIALOG ◄──────────── VORLESE ◄── GENERATOR
│ Vorlesen fertig Transkription
│ + LLM-Antwort
└── Sprache erkannt ──► AUFNAHME
LAUSCH
Wartet auf das Wake-Word „Hey Jarvis". Kein Quittungston, kein Feedback bis das Wake-Word erkannt wird. Ein kurzer Piepton signalisiert den Übergang zu AUFNAHME.
AUFNAHME
Nimmt die Sprache auf. Die Statuszeile zeigt die bisherige Aufnahmedauer und die aktuelle Stille-Dauer:
[AUFNAHME] 3.2s (Stille 1.1s)
Die Aufnahme endet wenn:
- Stille ≥
--silence-sec(Standard: 5 Sekunden) - Das Stop-Wort gesagt wird (Standard: „over")
- „Stopp" gesagt wird → direkt zurück zu LAUSCH (ohne Antwort)
- Maximaldauer von 60 Sekunden erreicht ist
GENERATOR
Der Assistent sagt den Quittungssatz (Standard: „Moment, ich antworte gleich."), während er die Transkription und den LLM-Aufruf durchführt. Auch hier ist „Stopp" aktiv und bricht den Vorgang ab.
VORLESE
Die Antwort wird vorgelesen. Alle Steuer-Wörter sind aktiv (→ Abschnitt 5). Mehrere Sätze werden parallel synthetisiert und nahtlos abgespielt.
DIALOG
Nach dem Vorlesen öffnet sich ein Zeitfenster (Standard: 5 Sekunden). Wird in dieser Zeit gesprochen, geht der Assistent direkt in AUFNAHME — ohne Wake-Word. So sind Rückfragen flüssig möglich. Nach Ablauf des Zeitfensters oder bei „Stopp" kehrt der Assistent zu LAUSCH zurück.
5. Steuer-Wörter
Das Wort „bitte" wird vor dem Abgleich immer ignoriert (z. B. „Stopp bitte" = „Stopp").
Während VORLESE
| Gesprochener Befehl | Wirkung |
|---|---|
| „Stopp" | Wiedergabe sofort abbrechen → DIALOG |
| „Pause" | Wiedergabe anhalten (bleibt pausiert) |
| „Weiter" | Nach Pause: aktuellen Satz von vorne abspielen |
| „Noch einmal" | Letzten Satz wiederholen |
| „Absatz noch einmal" | Zum Anfang des letzten Absatzes springen |
| „Alles von vorn" | Gesamte Antwort von Anfang an wiederholen |
In allen anderen aktiven Zuständen
| Zustand | Befehl | Wirkung |
|---|---|---|
| AUFNAHME | „Stopp" | Aufnahme abbrechen → LAUSCH |
| GENERATOR | „Stopp" | Verarbeitung abbrechen → LAUSCH |
| DIALOG | „Stopp" | Dialogfenster schließen → LAUSCH |
6. Alle Kommandozeilenoptionen
python3 assistant.py [OPTIONEN]
Eingabe
| Option | Standard | Beschreibung |
|---|---|---|
--mic NAME |
respeaker |
Mikrofon: respeaker | motu | camera | default | bluetooth | <Index> | <Substring> |
--list-mics |
— | Alle verfügbaren Mikrofone anzeigen und beenden |
--silence-sec N |
5.0 |
Stille-Dauer in Sekunden bis die Aufnahme endet |
--stop-word WORT |
over |
Codewort zum manuellen Beenden der Aufnahme |
--no-wakeword |
— | Wake-Word deaktivieren, sofort in AUFNAHME starten |
--wakeword-threshold N |
0.5 |
Empfindlichkeit Wake-Word-Erkennung (0.0–1.0) |
LLM-Backend
| Option | Standard | Beschreibung |
|---|---|---|
--backend NAME |
llama |
Backend: llama | ollama | openai |
--model NAME |
auto | Modellname (bei llama.cpp: automatisch vom Server) |
--system TEXT |
(eingebaut) | System-Prompt für den Assistenten |
--history N |
10 |
Maximale Anzahl gespeicherter Gesprächsrunden |
Spracherkennung (Whisper)
| Option | Standard | Beschreibung |
|---|---|---|
--whisper-model NAME |
large-v3 |
Whisper-Modell |
--gpu N |
1 |
CUDA-Index für Whisper (in CUDA_VISIBLE_DEVICES) |
--lang CODE |
de |
Sprache der Benutzereingabe (de, en, fr, …) |
Sprachausgabe (TTS)
| Option | Standard | Beschreibung |
|---|---|---|
--voice NAME |
de_DE-thorsten-high |
Standard-Piper-Stimme (Fallback) |
--en-variant |
us |
Englische Variante: us (Ryan) | gb (Alan) |
--out NAME |
default |
Ausgabe-Sink: default | respeaker | hdmi | motu | bluetooth | <Sink-Name> |
--ack-text TEXT |
Moment, ich antworte gleich. |
Quittungssatz im GENERATOR-Zustand |
--dialog-timeout N |
5.0 |
DIALOG-Fenster in Sekunden |
Typische Kombinationen
# Entwicklung / Debugging (kein Wake-Word, kurze Stille)
python3 assistant.py --no-wakeword --silence-sec 2.0
# MOTU M2 als Mikrofon und Ausgang
python3 assistant.py --mic motu --out motu
# Englisch mit britischer Stimme
python3 assistant.py --lang en --voice en_GB-alan-medium --en-variant gb
# Empfindlicheres Wake-Word
python3 assistant.py --wakeword-threshold 0.3
# Längeres Dialogfenster
python3 assistant.py --dialog-timeout 10.0
7. Mikrofon wählen
# Alle verfügbaren Mikrofone anzeigen
python3 assistant.py --list-mics
# oder
python3 mic.py
Vordefinierte Kurznamen:
| Kurzname | Gerät |
|---|---|
respeaker |
ReSpeaker XVF3800 (Standard) |
motu |
MOTU M2 Mikrofon-Eingang |
camera |
USB-Kamera-Mikrofon (VF0680) |
default |
System-Standard-Eingabe (PipeWire) |
bluetooth |
Erstes verbundenes Bluetooth-Gerät |
Alternativ kann ein numerischer Index (--mic 3) oder ein Substring des
Gerätenamens (--mic "USB Audio") angegeben werden.
8. Audio-Ausgang wählen
# Alle verfügbaren Ausgänge anzeigen
python3 speak.py --list
Vordefinierte Kurznamen:
| Kurzname | Gerät |
|---|---|
default |
PipeWire-Standard-Sink |
respeaker |
ReSpeaker XVF3800 3,5-mm-Klinke |
hdmi |
HDA NVidia HDMI |
motu |
MOTU M2 Ausgang |
bluetooth |
Erstes verbundenes Bluetooth-Gerät |
Vollständige Sink-Namen aus pactl list sinks short können direkt verwendet werden.
9. LLM-Backend konfigurieren
llama.cpp (Standard)
# llama.cpp muss auf Port 8001 laufen
python3 assistant.py --backend llama
Der Modellname wird automatisch vom Server abgefragt.
Ollama
# Ollama muss laufen: ollama serve
python3 assistant.py --backend ollama --model llama3.2
python3 assistant.py --backend ollama --model mistral
OpenAI
export OPENAI_API_KEY=sk-...
python3 assistant.py --backend openai --model gpt-4o-mini
python3 assistant.py --backend openai --model gpt-4o
10. Sprache und Stimme
Automatische Spracherkennung
Der Assistent erkennt automatisch die Sprache der LLM-Antwort und wählt die passende Piper-Stimme. Fehlende Stimmen werden beim ersten Bedarf automatisch heruntergeladen.
| Sprache | Stimme |
|---|---|
| Deutsch | de_DE-thorsten-high |
| Englisch (US) | en_US-ryan-high |
| Englisch (GB) | en_GB-alan-medium |
| Französisch | fr_FR-upmc-medium |
| Spanisch | es_ES-davefx-medium |
| Italienisch | it_IT-paola-medium |
| Niederländisch | nl_NL-mls-medium |
| Portugiesisch | pt_BR-faber-medium |
| Russisch | ru_RU-ruslan-medium |
| Polnisch | pl_PL-bass-high |
| Ukrainisch | uk_UA-lada-x_low |
| Tschechisch | cs_CZ-jirka-medium |
Englische Variante wählen
Da automatische Erkennung nicht zwischen en-US und en-GB unterscheiden kann, wird die Variante beim Start festgelegt:
python3 assistant.py --en-variant us # Standard: amerikanisches Englisch
python3 assistant.py --en-variant gb # britisches Englisch
Eigene Standardstimme
Die --voice-Option setzt die Fallback-Stimme (wenn Spracherkennung fehlschlägt
oder die erkannte Sprache nicht in der Tabelle ist):
python3 assistant.py --voice de_DE-kerstin-low
11. Standalone-Werkzeuge
speak.py — Sprachausgabe testen
# Text vorlesen
python3 speak.py --text "Hallo, ich bin dein Assistent."
# Mit bestimmter Stimme und Ausgang
python3 speak.py --text "Hello World" --voice en_US-ryan-high --out respeaker
# Text aus stdin
echo "Test" | python3 speak.py
# Alle Ausgänge anzeigen
python3 speak.py --list
# Alle verfügbaren Piper-Stimmen (Deutsch)
python3 speak.py --list-voices --voice-lang de
# Alle Stimmen aller Sprachen
python3 speak.py --list-voices --voice-lang ""
transcribe.py — Transkription testen
# Live-Transkription mit ReSpeaker
python3 transcribe.py
# Mit anderem Mikrofon
python3 transcribe.py --mic motu
# Alle Mikrofone anzeigen
python3 transcribe.py --list-mics
mic.py — Mikrofone anzeigen
python3 mic.py
12. Tipps und Fehlerbehebung
Wake-Word wird nicht erkannt
- Lautstärke des Mikrofons erhöhen:
pactl set-source-volume <Gerät> 150% - Schwellenwert senken:
--wakeword-threshold 0.3 - Zum Testen
--no-wakewordverwenden
Transkription ist ungenau
- Lautstärke erhöhen
- Hintergrundgeräusche reduzieren
- ReSpeaker XVF3800 verwenden (Hardware-AEC unterdrückt Lautsprecher-Echo)
--langkorrekt setzen (z. B.--lang defür Deutsch)
„Stopp" wird nicht erkannt
- Deutlich und mit normaler Lautstärke sprechen
- Latenz: ca. 0,5–1 Sekunde bis zur Reaktion (Whisper muss verarbeiten)
- In AUFNAHME:
--stop-wordist ein anderes Wort; „Stopp" wird separat erkannt
TTS-Stimme klingt falsch für die Sprache
- Stimme wurde mit falscher Sprache verwendet (z. B. Download fehlgeschlagen)
- Fehlermeldung erscheint im Terminal; nochmals versuchen (automatischer Retry 3×)
- Netzwerkverbindung prüfen (Stimmen werden von HuggingFace geladen)
Piper-Stimme fehlt / Download schlägt fehl
# Verfügbare Stimmen anzeigen
python3 speak.py --list-voices --voice-lang de
# Stimme manuell laden (wird dann gecacht)
python3 speak.py --text "Test" --voice ru_RU-ruslan-medium
audio: input overflow
Diese Meldung wird bewusst unterdrückt. Sie tritt auf wenn Whisper die Verarbeitung verzögert und der PortAudio-Puffer überläuft. Das ist normal und beeinflusst die Qualität nicht wesentlich.
llama.cpp antwortet nicht
# Prüfen ob der Server läuft
curl http://localhost:8001/v1/models
# Modell und Port in llama.cpp-Konfiguration prüfen