docs: Aussprache-Pipeline aktualisieren (Normalizer/Chunker/Lexikon, piper echt)

- Architektur §5: Spoken-Adapter (Listen->Ordinalwoerter), Sentence-Chunker
  (keine Trennung nach Ziffer+Punkt/Abk.), TTS-Normalizer (Ordinalia/Einheiten/
  Abk./YAML-Lexikon, provider-abhaengige Stufen) + german_numbers im Baum.
- Architektur: piper als echtes lokales TTS (nicht mehr Stub); nur chatterbox Stub.
- README: Feature-Bullet Aussprache-Normalisierung + add_pronunciation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Dieter Schlüter 2026-06-17 23:28:52 +02:00
commit bef02a663a
2 changed files with 14 additions and 10 deletions

View file

@ -133,11 +133,13 @@ Stufen: `raw_transcript → cleaned_transcript → semantic_response → spoken_
- **Input Cleaner** (`pipeline/input_cleaner.py`) konservative Bereinigung des STT-Texts (Füllwörter, Whitespace). Verändert die Nutzerintention nicht.
- **Dialog-LLM** semantische Antwort; Persona/Sicherheitsregeln im System-Prompt (`providers/llm/openrouter.py`).
- **Spoken Response Adapter** (`pipeline/spoken_response_adapter.py`) macht die Antwort sprechbar/seniorengerecht (Markdown raus, Listen → Sätze, Uhrzeiten erhalten).
- **TTS Normalizer** (`pipeline/tts_normalizer.py`) Zahlen/Abkürzungen/Einheiten verbal ausformulieren, sprachabhängig (de/en).
- **Spoken Response Adapter** (`pipeline/spoken_response_adapter.py`) macht die Antwort sprechbar/seniorengerecht (Markdown raus, Aufzählungspunkte weg, **nummerierte Listen → Ordinalwörter** „1." → „erstens", Uhrzeiten/Verhältnisse erhalten).
- **Sentence Chunker** (`pipeline/sentence_chunker.py`) inkrementelle Satzsegmentierung für satzweises Streaming-TTS. Trennt bewusst **nicht** nach Ziffer+Punkt („1. Mai"), Einzelbuchstabe+Punkt („z. B.", Initialen) oder bekannten Abkürzungen.
- **TTS Normalizer** (`pipeline/tts_normalizer.py`) füllt gezielt die Lücken des Phonemizers (espeak-ng in piper), **ohne** zu duplizieren, was der schon gut kann (Kardinal-/Dezimalzahlen bleiben unangetastet): **Ordinalia** (Datum „1. Mai" → „erster Mai", Folgen „1. 2. 3." → „erstens, zweitens …"), **Einheiten nach Zahl** (kg/km/km-h/…), **Abkürzungen** (Dr./z. B./usw.) und ein **YAML-Aussprache-Lexikon** (`config/pronunciation.<lang>.yaml`, erweitert die eingebauten Defaults; case-insensitive Wort-Umschreibungen wie „strömt" → „ströhmt"). Stufe **provider-abhängig** (`TTS_NORMALIZE_LEVEL=auto|full|light|off`): piper → `full`, Cloud-TTS → `light` (Cloud spricht Zahlen/Abkürzungen selbst gut). Ordinalzahlen 1.31. in `pipeline/german_numbers.py`.
Empfehlung: nicht jede Zwischenstufe braucht ein großes LLM — Cleaner und
Empfehlung: nicht jede Zwischenstufe braucht ein großes LLM — Cleaner, Chunker und
Normalizer überwiegend regelbasiert (so heute umgesetzt), Adapter promptbasiert.
Lexikon pflegen: `python scripts/add_pronunciation.py "wort:aussprache" [--verify]`.
## 6. Orchestrator
@ -195,15 +197,16 @@ erkennung und Barge-in (`interrupt`)**; **Resilienz (Fallback-Ketten je Modul,
In-Memory-Metriken `/api/metrics`), Tageskontingent pro Nutzer und heuristische
Notfall-Eskalation**; automatisierte Tests.
**Echtes lokales STT:** `faster-whisper` (optionale Dependency `.[local]`,
CTranslate2) transkribiert real — damit ist ein Hybrid „STT+LLM lokal, TTS remote"
möglich (live verifiziert).
**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
remote" als auch eine **voll-lokale** Konstellation möglich (live verifiziert).
**Platzhalter (Gerüst):** Audio-Endpunkte (`local-default`, `bluetooth`,
`mobile-ws`, `mobile-webrtc`) liefern leere Chunks — nur Auswahl/Lifecycle sind
verdrahtet, kein echtes Hardware-I/O. Lokale TTS-Provider `piper`, `chatterbox`
sind noch Stubs. `transport_router.py` (Ebene 4) existiert, ist aber noch
nicht aktiv (lokal/remote trägt vorerst der Provider-Name).
verdrahtet, kein echtes Hardware-I/O. Der TTS-Provider `chatterbox` ist noch ein
Stub. `transport_router.py` (Ebene 4) existiert, ist aber noch nicht aktiv
(lokal/remote trägt vorerst der Provider-Name).
## 9. Roadmap / bewusste nächste Schritte
@ -240,7 +243,7 @@ voice-assistant-scaffold/
│ ├── api/ # health, chat, speak, transcribe, devices, sessions, config, admin, me, ws
│ ├── core/ # orchestrator
│ ├── audio/ # router, transport_router, vad, endpoints/input|output/*
│ ├── pipeline/ # input_cleaner, spoken_response_adapter, tts_normalizer, sentence_chunker
│ ├── pipeline/ # input_cleaner, spoken_response_adapter, tts_normalizer, sentence_chunker, german_numbers
│ └── providers/ # stt/ llm/ tts/ (openrouter + lokale Stubs) + fallback.py
├── config/ # voice-assistant.example.toml (+ lokale .toml, gitignored)
├── data/ # SQLite-DB (gitignored)