From 1899663308c8f2938f16b4b86caa536bcf787d6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dieter=20Schl=C3=BCter?= Date: Thu, 18 Jun 2026 08:32:05 +0200 Subject: [PATCH] docs: lokales TTS (piper in-process) + Start-Warm-up dokumentieren README/BEDIENUNGSANLEITUNG/Architektur: piper laeuft in-process (gecachtes Stimmmodell, kein Subprozess pro Satz), In-Process-Resampling, lokale Modelle werden beim Start vorgeladen. .[local] installiert jetzt faster-whisper UND piper-tts. Latenz-Hinweis erster Ton 5,8 s -> ~1,6 s. Co-Authored-By: Claude Opus 4.8 --- BEDIENUNGSANLEITUNG.md | 11 ++++++----- Docs/voice-assistant-architecture.md | 7 ++++--- README.md | 10 ++++++++-- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/BEDIENUNGSANLEITUNG.md b/BEDIENUNGSANLEITUNG.md index 28533cd..0047442 100644 --- a/BEDIENUNGSANLEITUNG.md +++ b/BEDIENUNGSANLEITUNG.md @@ -237,19 +237,20 @@ python scripts/voice_loop.py --recorder arecord --device plughw:5,0 --session hy --llm-provider local-openai-compatible \ --tts-provider openrouter ``` -Erster Turn ist langsamer (Whisper-Modell lädt; das LLM-Modell ist nach `make llm-up` -bereits geladen), danach zügig. STT-Modell +Die lokalen Modelle (faster-whisper, piper) werden **beim Serverstart vorgeladen** +(Warm-up im Hintergrund) — der erste Turn ist daher nicht mehr spürbar langsamer. STT-Modell und Gerät steuern `FASTER_WHISPER_MODEL`/`FASTER_WHISPER_DEVICE` in `.env`. Satzweises Vorlesen ist Standard (früher Ton); `--stream-text` zeigt den Text live dazu. **Voll-lokal-Beispiel** (STT + LLM + TTS **alles lokal** — kein API-Geld, maximaler -Datenschutz). TTS läuft hier über **piper** (lokales, CPU-freundliches Neural-TTS): +Datenschutz). TTS läuft hier über **piper** (lokales Neural-TTS, **in-process**: das +Stimmmodell wird einmal geladen und gecacht, kein Subprozess-Start pro Satz): ```bash -# einmalig: lokales STT installieren +# einmalig: lokales STT + TTS installieren (faster-whisper + piper-tts) pip install -e .[local] # lokalen llama.cpp-Server starten (großes, unzensiertes Modell): make llm-up # mit make llm-status auf "HTTP OK" warten -# piper-Binary + Stimme bereitstellen: die Stimm-Dateien (.onnx + .onnx.json) +# piper-Stimme bereitstellen: die Stimm-Dateien (.onnx + .onnx.json) # liegen im PIPER_VOICES_DIR (Default ~/.local/share/piper/voices). Deutsche Stimmen z. B. # von huggingface 'rhasspy/piper-voices' (de_DE-thorsten-high, de_DE-kerstin-low). # Verfügbare Stimmen prüfen: ls ~/.local/share/piper/voices/*.onnx diff --git a/Docs/voice-assistant-architecture.md b/Docs/voice-assistant-architecture.md index 20c6fa7..4ccb46f 100644 --- a/Docs/voice-assistant-architecture.md +++ b/Docs/voice-assistant-architecture.md @@ -198,8 +198,9 @@ In-Memory-Metriken `/api/metrics`), Tageskontingent pro Nutzer und heuristische Notfall-Eskalation**; automatisierte Tests. **Echtes lokales STT & TTS:** `faster-whisper` (optionale Dependency `.[local]`, -CTranslate2) transkribiert real; `piper` (Binary + Stimmmodell, ffmpeg-Resampling -auf 24000 Hz) synthetisiert real. Damit ist sowohl ein Hybrid „STT+LLM lokal, TTS +CTranslate2) transkribiert real; `piper` (in-process via piper-Python-API, Stimmmodell +einmal geladen + gecacht, In-Process-Resampling auf 24000 Hz) synthetisiert real. Lokale +Modelle werden beim Serverstart vorgeladen (Warm-up). Damit ist sowohl ein Hybrid „STT+LLM lokal, TTS remote" als auch eine **voll-lokale** Konstellation möglich (live verifiziert). **Platzhalter (Gerüst):** Audio-Endpunkte (`local-default`, `bluetooth`, @@ -218,7 +219,7 @@ Reihenfolge der Weiterentwicklung: 4. **(weitgehend erledigt)** Echtzeit: WebSocket-Streaming-Chat (`/ws/chat`), **Token-Level-LLM-Streaming (SSE, `stream:true`)**, **Audio-Streaming (chunked TTS satzweise, `audio_stream:true`)**, **Audio-Eingang (`/ws/voice`)**, **Barge-in/Turn-Manager (`interrupt` bricht laufende Antwort ab)** und **VAD-Aeusserungserkennung (energie-basiert, opt-in)** sind umgesetzt. Offen: **echte partielle Live-Transkripte (Streaming-STT-Dienst, wortweise)** und **WebRTC (aiortc)** — beide brauchen schwere Abhaengigkeiten/Dienste. Heute laeuft STT pro Aeusserung. 5. **(weitgehend erledigt)** Resilienz: Fallback-Ketten je Modul (`*_FALLBACK`, Provider faellt aus → naechster) und In-Memory-Metriken (`/api/metrics`: Request/Latenz, Pipeline-Stufen, Fallback/Fehler; JSON + Prometheus). Offen: verteiltes Tracing, Alerting. 6. **(weitgehend erledigt)** Betrieb: Tageskontingent pro Nutzer (`DAILY_REQUEST_LIMIT`, 429) und **zweistufige** Notfall-Eskalation: (1) schnelle Stichwort-Heuristik im Hot-Path (0 Latenz) + (2) **LLM-Klassifikation** (`app/safety/llm_classifier.py`) als Hintergrund-Task, der laeuft, wenn die Heuristik nichts fand — faengt verpasste Formulierungen (z. B. metaphorisch geaeusserte Suizidalitaet, Schlaganfall-Symptome ohne Stichwort) mit Konfidenz-Schwelle, ohne die Antwortlatenz zu erhoehen. Eskalation jeweils -> Log + Metrik (`source`: keyword/llm) + optionaler Webhook + Event. Offen: Telefon-/Angehoerigen-Integration, Abrechnung. -7. **(weitgehend erledigt)** Lokale Provider: STT via `faster-whisper` (`.[local]`) und **TTS via `piper`** (lokales Neural-TTS, ffmpeg-Resampling auf 24000 Hz) sind echt — eine **voll-lokale Konstellation** (STT+LLM+TTS lokal, keine API-Kosten, max. Datenschutz) ist damit möglich. Offen: `chatterbox`-TTS (noch Stub), höhere Sprachqualität als piper. +7. **(weitgehend erledigt)** Lokale Provider: STT via `faster-whisper` (`.[local]`) und **TTS via `piper`** (lokales Neural-TTS, **in-process** mit gecachtem Stimmmodell, In-Process-Resampling auf 24000 Hz; lokale Modelle werden beim Start vorgeladen) sind echt — eine **voll-lokale Konstellation** (STT+LLM+TTS lokal, keine API-Kosten, max. Datenschutz) ist damit möglich. Offen: `chatterbox`-TTS (noch Stub), höhere Sprachqualität als piper. 8. **TransportRouter** als eigene lokal/remote-Achse aktivieren; echte Geräte-Endpunkte (PipeWire/Bluetooth) — heute OS-Ebene. **Datenschutz (querschnittlich, ab sofort mitdenken):** Senioren-Sprachdaten sind diff --git a/README.md b/README.md index b8da58f..d7cafc5 100644 --- a/README.md +++ b/README.md @@ -148,6 +148,12 @@ Markdown/Emojis — schlecht zum Vorlesen und spürbar träge. Der Provider Modell `base`. Auf einer RTX 3090 lohnt `FASTER_WHISPER_DEVICE=cuda` + `FASTER_WHISPER_COMPUTE_TYPE=float16`; das verkürzt die Transkriptionszeit pro Turn. +**Dritter Hebel — lokales TTS (piper):** piper läuft **in-process** über die piper-Python-API +(im `.[local]`-Extra). Das Stimmmodell wird **einmal** geladen und prozessweit gecacht — +früher startete piper als Subprozess **pro Satz** und zahlte jedes Mal ~2 s Modell-Ladezeit. +Zusätzlich werden lokale Modelle **beim Serverstart vorgeladen** (Warm-up), sodass auch der +erste Nutzer keinen Kaltstart spürt. Messung (lokales Setup): erster Ton **5,8 s → ~1,6 s**. + ### Komplett lokal: Profil `local-dev` `VA_PROFILE=local-dev` betreibt **alle** KI-Module ohne Cloud. Die Route löst auf zu: @@ -160,8 +166,8 @@ Modell `base`. Auf einer RTX 3090 lohnt `FASTER_WHISPER_DEVICE=cuda` + **Voraussetzungen:** - **LLM:** llama.cpp-Container läuft (`make llm-up`) -- **STT:** faster-whisper installiert (`pip install -e .[local]`) -- **TTS:** piper-Binary + Stimme vorhanden (siehe `PIPER_*` in `.env.example`) +- **STT + TTS:** `pip install -e .[local]` (installiert faster-whisper **und** piper-tts); + ein piper-Stimmmodell (`.onnx` + `.onnx.json`) im `PIPER_VOICES_DIR` (siehe `PIPER_*`) **Start (Reihenfolge):**