my_voice_assistant/BEDIENUNGSANLEITUNG.md
2026-06-16 02:21:26 +02:00

14 KiB
Raw Blame History

Bedienungsanleitung — Voice Assistant

Inhaltsverzeichnis

  1. Voraussetzungen
  2. Installation der Abhängigkeiten
  3. Schnellstart
  4. Die fünf Zustände
  5. Steuer-Wörter
  6. Alle Kommandozeilenoptionen
  7. Mikrofon wählen
  8. Audio-Ausgang wählen
  9. LLM-Backend konfigurieren
  10. Sprache und Stimme
  11. Standalone-Werkzeuge
  12. 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, paplay mü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 (~60120 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. 1030 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.01.0)

LLM-Backend

Option Standard Beschreibung
--backend NAME llama Backend: llama | ollama | openai
--model NAME auto Modellname (bei llama.cpp: automatisch vom Server)
--api-url URL Überschreibt die Backend-URL (beliebiger OpenAI-kompatibler Endpunkt)
--api-key KEY API-Key (überschreibt OPENAI_API_KEY / Backend-Default)
--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

Der Assistent spricht mit jedem LLM, das die OpenAI Chat-Completions API implementiert. Mit --api-url und --api-key kann der Endpunkt frei überschrieben werden — das --backend-Flag wählt nur den Verbindungs-Default.

llama.cpp (Standard)

# llama.cpp muss auf Port 8001 laufen
python3 assistant.py --backend llama

Der Modellname wird automatisch vom Server abgefragt. Anderen Port oder Host angeben:

python3 assistant.py --backend llama --api-url http://192.168.1.10:8001/v1

Ollama (lokal)

# Ollama muss laufen: ollama serve
python3 assistant.py --backend ollama --model llama3.2
python3 assistant.py --backend ollama --model mistral

Ollama (remote / anderer Rechner)

python3 assistant.py --backend ollama \
  --api-url http://mein-server:11434/v1 \
  --model llama3.2

OpenAI

export OPENAI_API_KEY=sk-...
python3 assistant.py --backend openai --model gpt-4o-mini
python3 assistant.py --backend openai --model gpt-4o

OpenRouter (viele Modelle über eine API)

OpenRouter bietet Zugang zu hunderten Modellen (Mistral, Llama, Gemma, Claude, GPT-4 u. v. m.) über eine einheitliche API.

export OPENROUTER_API_KEY=sk-or-...
python3 assistant.py \
  --backend openai \
  --api-url https://openrouter.ai/api/v1 \
  --model mistralai/mistral-7b-instruct

Andere beliebte OpenRouter-Modelle:

  • meta-llama/llama-3.1-8b-instruct:free (kostenlos)
  • google/gemma-3-27b-it
  • anthropic/claude-3.5-haiku

Den API-Key unter https://openrouter.ai/keys erstellen.

Groq (sehr schnelle Inferenz)

export GROQ_API_KEY=gsk_...
python3 assistant.py \
  --backend openai \
  --api-url https://api.groq.com/openai/v1 \
  --model llama-3.1-70b-versatile

LM Studio

# LM Studio muss mit aktiviertem lokalen Server laufen (Port 1234)
python3 assistant.py --backend llama --api-url http://localhost:1234/v1

Together AI

export TOGETHER_API_KEY=...
python3 assistant.py \
  --backend openai \
  --api-url https://api.together.xyz/v1 \
  --model meta-llama/Llama-3-8b-chat-hf

Allgemeines Prinzip

Jeder Provider, der /v1/chat/completions mit stream=true unterstützt, funktioniert mit:

python3 assistant.py \
  --backend openai \
  --api-url https://<provider>/v1 \
  --model <modellname> \
  --api-key <api-key>

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-wakeword verwenden

Transkription ist ungenau

  • Lautstärke erhöhen
  • Hintergrundgeräusche reduzieren
  • ReSpeaker XVF3800 verwenden (Hardware-AEC unterdrückt Lautsprecher-Echo)
  • --lang korrekt setzen (z. B. --lang de für Deutsch)

„Stopp" wird nicht erkannt

  • Deutlich und mit normaler Lautstärke sprechen
  • Latenz: ca. 0,51 Sekunde bis zur Reaktion (Whisper muss verarbeiten)
  • In AUFNAHME: --stop-word ist 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