2026-06-16 00:47:53 +02:00
|
|
|
# Voice Assistant
|
|
|
|
|
|
|
|
|
|
Lokaler, vollständig offline-fähiger Sprachassistent mit Wake-Word-Erkennung,
|
|
|
|
|
GPU-Transkription, LLM-Antwortgenerierung und mehrsprachiger Sprachausgabe.
|
|
|
|
|
|
|
|
|
|
## Features
|
|
|
|
|
|
|
|
|
|
- **Wake-Word** „Hey Jarvis" via [openwakeword](https://github.com/dscripka/openWakeWord)
|
|
|
|
|
- **Spracherkennung** via [faster-whisper](https://github.com/SYSTRAN/faster-whisper) (`large-v3`, CUDA)
|
|
|
|
|
- **LLM-Backends**: llama.cpp (lokal), Ollama, OpenAI-kompatible APIs
|
|
|
|
|
- **Text-to-Speech** via [Piper](https://github.com/rhasspy/piper) mit automatischer Spracherkennung
|
|
|
|
|
- **11 TTS-Sprachen** (de/en/fr/es/it/nl/pt/ru/pl/uk/cs), Stimmen werden bei Bedarf automatisch heruntergeladen
|
|
|
|
|
- **5-Zustands-Maschine** (LAUSCH → AUFNAHME → GENERATOR → VORLESE → DIALOG)
|
|
|
|
|
- **Steuer-Wörter** während der Wiedergabe: Stopp, Pause, Weiter, Noch einmal, …
|
|
|
|
|
- **„Stopp"** funktioniert in allen aktiven Zuständen (AUFNAHME, GENERATOR, VORLESE, DIALOG)
|
|
|
|
|
- **Wählbares Mikrofon**: ReSpeaker XVF3800, MOTU M2, Kamera-Mikrofon, Bluetooth, Index
|
|
|
|
|
- **Wählbarer Ausgang**: beliebiger PipeWire-Sink
|
|
|
|
|
|
|
|
|
|
## Voraussetzungen
|
|
|
|
|
|
|
|
|
|
### Hardware
|
|
|
|
|
- Mikrofon (empfohlen: [ReSpeaker XVF3800](https://wiki.seeedstudio.com/ReSpeaker_XVF3800/) mit Hardware-AEC)
|
|
|
|
|
- NVIDIA GPU mit CUDA (für Whisper; llama.cpp kann separat konfiguriert werden)
|
|
|
|
|
|
|
|
|
|
### Software
|
|
|
|
|
```
|
|
|
|
|
Python >= 3.12
|
|
|
|
|
faster-whisper
|
|
|
|
|
openwakeword
|
|
|
|
|
piper-tts
|
|
|
|
|
sounddevice
|
|
|
|
|
scipy
|
|
|
|
|
langdetect
|
|
|
|
|
openai # Python-Client (auch für lokale Backends)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
PipeWire + paplay müssen als Audio-Backend aktiv sein.
|
|
|
|
|
|
|
|
|
|
## Schnellstart
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
# Verfügbare Mikrofone anzeigen
|
|
|
|
|
python3 assistant.py --list-mics
|
|
|
|
|
|
|
|
|
|
# Starten mit Standard-Einstellungen (ReSpeaker, llama.cpp lokal)
|
|
|
|
|
python3 assistant.py
|
|
|
|
|
|
|
|
|
|
# Ohne Wake-Word (direkt in Aufnahme-Modus)
|
|
|
|
|
python3 assistant.py --no-wakeword
|
|
|
|
|
|
|
|
|
|
# Mit Ollama-Backend
|
|
|
|
|
python3 assistant.py --backend ollama --model llama3.2
|
|
|
|
|
|
|
|
|
|
# Britisches Englisch als TTS-Variante
|
|
|
|
|
python3 assistant.py --en-variant gb
|
|
|
|
|
```
|
|
|
|
|
|
2026-06-16 02:21:26 +02:00
|
|
|
## LLM-Backends
|
|
|
|
|
|
|
|
|
|
Der Assistent unterstützt jeden OpenAI-kompatiblen Endpunkt über `--api-url` und `--api-key`.
|
|
|
|
|
|
|
|
|
|
| Ziel | Befehl |
|
|
|
|
|
|---|---|
|
|
|
|
|
| llama.cpp lokal (Standard, Port 8001) | `python3 assistant.py` |
|
|
|
|
|
| llama.cpp auf anderem Port/Host | `--backend llama --api-url http://host:8080/v1` |
|
|
|
|
|
| Ollama lokal | `--backend ollama --model llama3.2` |
|
|
|
|
|
| Ollama remote | `--backend ollama --api-url http://server:11434/v1 --model llama3.2` |
|
|
|
|
|
| OpenAI | `--backend openai --model gpt-4o-mini` + `OPENAI_API_KEY` setzen |
|
|
|
|
|
| OpenRouter | `--backend openai --api-url https://openrouter.ai/api/v1 --model mistralai/mistral-7b-instruct --api-key $OPENROUTER_API_KEY` |
|
|
|
|
|
| Groq | `--backend openai --api-url https://api.groq.com/openai/v1 --model llama-3.1-70b-versatile --api-key $GROQ_API_KEY` |
|
|
|
|
|
| LM Studio | `--backend llama --api-url http://localhost:1234/v1` |
|
|
|
|
|
| Together AI | `--backend openai --api-url https://api.together.xyz/v1 --model meta-llama/Llama-3-8b-chat-hf --api-key $TOGETHER_API_KEY` |
|
|
|
|
|
|
|
|
|
|
Alle Provider, die die OpenAI Chat-Completions API implementieren, funktionieren mit `--backend openai --api-url <endpoint>`.
|
|
|
|
|
|
2026-06-16 00:47:53 +02:00
|
|
|
## Dateien
|
|
|
|
|
|
|
|
|
|
| Datei | Beschreibung |
|
|
|
|
|
|---|---|
|
|
|
|
|
| `assistant.py` | Hauptprogramm — Zustands-Maschine, LLM-Integration |
|
|
|
|
|
| `speak.py` | TTS-Modul — Piper-Wrapper, Spracherkennung, Sink-Auswahl |
|
|
|
|
|
| `mic.py` | Mikrofon-Modul — Geräteauflösung, Alias-Tabelle |
|
|
|
|
|
| `transcribe.py` | Standalone-Transkription zum Testen |
|
|
|
|
|
|
|
|
|
|
## Architektur
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
Mikrofon (PortAudio)
|
|
|
|
|
│
|
|
|
|
|
▼
|
|
|
|
|
audio_q
|
|
|
|
|
│
|
|
|
|
|
├─► LAUSCH: openwakeword → "Hey Jarvis" → AUFNAHME
|
|
|
|
|
├─► AUFNAHME: Stille/Stop-Wort/Stopp → record_buffer
|
|
|
|
|
├─► GENERATOR: whisper.transcribe → LLM-Stream → VORLESE
|
|
|
|
|
├─► VORLESE: piper-synth (Thread) + paplay + ctrl_monitor
|
|
|
|
|
└─► DIALOG: 5s-Fenster für Rückfrage ohne Wake-Word
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Separate Tools
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
# Sprachausgabe testen
|
|
|
|
|
python3 speak.py --text "Hallo Welt" --out respeaker
|
|
|
|
|
|
|
|
|
|
# Verfügbare Ausgänge anzeigen
|
|
|
|
|
python3 speak.py --list
|
|
|
|
|
|
|
|
|
|
# Live-Transkription testen
|
|
|
|
|
python3 transcribe.py --mic respeaker
|
|
|
|
|
|
|
|
|
|
# Verfügbare Mikrofone anzeigen
|
|
|
|
|
python3 mic.py
|
|
|
|
|
```
|