router: deutsche Spracherkennung mit whisper.cpp (CPU-only)
- STT-Worker (stt_worker.py): langlebiger HTTP-Service auf Port 8084 - whisper-cli als Subprozess (CPU-only, 8 Threads) - Audio-Vorbereitung via ffmpeg (WebM/Opus/M4A → 16 kHz WAV) - Nativ: WAV, MP3, OGG, FLAC - Health-Endpunkt: GET /status - Transkription: POST /transcribe (Multipart-Form-Data) - Router-Integration: - POST /v1/audio/transcriptions (OpenAI-kompatibel) - GET /v1/audio/models (whisper-1, kokoro-german) - GET /v1/audio/voices (martin, victoria) - /status mit stt-Section - model=whisper-1 akzeptiert - response_format: json, verbose_json - systemd-Service: mike-ai-whisper.service - Boot-Start, Restart on failure, journald - CPU-only, kein GPU-Lock - Deploy-Dateien aktualisiert (deploy.sh, install.sh) - Mock-STT-Worker für lokale Tests (dev/mock_stt_worker.py) - Tests ergänzt: STT Status, WAV, language=de, unbekanntes Modell, Worker down, Recovery, Audio-Modelle, Audio-Voices, STT+Qwen parallel, STT+TTS parallel - README.md: STT-Section mit Endpunkten, Benchmarks, Doku Benchmarks (CPU-only, 8 Threads): 7.3 s Audio → 8.9 s (RTF 1.22×) 30 s Audio → 16.8 s (RTF 0.56×) 50 s Audio → 18.5 s (RTF 0.37×) RAM: ~1.7 GB (Modell), Worker: ~20 MB
This commit is contained in:
@@ -19,6 +19,7 @@ Sprachausgabe bereit (Kokoro-82M, CPU-only, OpenAI-kompatibel).
|
||||
| Router-Port | **8081** |
|
||||
| Router-Service | `mike-ai-profile-router.service` |
|
||||
| TTS-Worker | `http://127.0.0.1:8082` (Service `mike-ai-kokoro.service`) |
|
||||
| STT-Worker | `http://127.0.0.1:8084` (Service `mike-ai-whisper.service`) |
|
||||
|
||||
## Profile / virtuelle Modelle
|
||||
|
||||
@@ -40,6 +41,9 @@ Sprachausgabe bereit (Kokoro-82M, CPU-only, OpenAI-kompatibel).
|
||||
| `GET /images` | Liste der gespeicherten Bilder (max. 200) |
|
||||
| `GET /images/<datei>` | PNG-Download (nur `images/`-Verzeichnis, validiert) |
|
||||
| `POST /v1/audio/speech` | Deutsche Sprachausgabe (Kokoro-82M, OpenAI-kompatibel) |
|
||||
| `POST /v1/audio/transcriptions` | Deutsche Spracherkennung (whisper.cpp, OpenAI-kompatibel) |
|
||||
| `GET /v1/audio/models` | Verfügbare Audio-Modelle (STT + TTS) |
|
||||
| `GET /v1/audio/voices` | Verfügbare TTS-Stimmen |
|
||||
| alles andere | Transparente Weiterleitung an llama.cpp |
|
||||
|
||||
### Verhalten
|
||||
@@ -280,14 +284,106 @@ Pfad `phonemizer-fork` + `espeakng-loader` (kein spacy-curated-transformers,
|
||||
kein thinc 9.x). `spacy` wird nur für den `misaki.en`-Import benötigt
|
||||
(Englisch), nicht für den deutschen Pfad.
|
||||
|
||||
## Spracherkennung (whisper.cpp, deutsch, CPU-only)
|
||||
|
||||
Der Router stellt lokale deutsche Spracherkennung bereit. Die Transkription
|
||||
läuft in einem **separaten, langlebigen Worker** (`mike-ai-whisper.service`),
|
||||
der `whisper-cli` als Subprozess aufruft. Der Worker ist CPU-only und
|
||||
blockiert weder Qwen/llama.cpp noch FLUX/GPU – er teilt sich nur den
|
||||
Prozessor.
|
||||
|
||||
- **Modell:** Whisper large-v3-turbo (ggml, ~1.6 GB, Vollpräzision)
|
||||
- **Build:** whisper.cpp CPU-only (AVX2+FMA, 8 Threads)
|
||||
- **Audio-Vorbereitung:** ffmpeg konvertiert WebM/Opus/M4A/AAC → 16 kHz mono WAV
|
||||
- **Nativ unterstützt:** WAV, MP3, OGG, FLAC
|
||||
- **Kein GPU-Lock:** STT läuft vollständig auf CPU, parallel zu Qwen (GPU)
|
||||
und TTS (CPU)
|
||||
|
||||
### Endpunkt `POST /v1/audio/transcriptions`
|
||||
|
||||
OpenAI-kompatibel (Multipart-Form-Data). Unterstützt `file`, `model`,
|
||||
`language`, `prompt`, `temperature`, `response_format`.
|
||||
|
||||
| Parameter | Werte | Default |
|
||||
|---|---|---|
|
||||
| `file` | Audio-Datei (Pflicht: webm, wav, mp3, m4a, ogg, flac) | – |
|
||||
| `model` | `whisper-1` (oder `whisper`) | `whisper-1` |
|
||||
| `language` | `de`, `en`, … (optional) | Auto-Detektion |
|
||||
| `prompt` | Kontext-Hinweis (optional) | – |
|
||||
| `temperature` | 0.0–1.0 (optional) | 0.0 |
|
||||
| `response_format` | `json` (Default), `verbose_json` | `json` |
|
||||
|
||||
Die Antwort ist **JSON** mit `text` (und optional `language`, `duration`
|
||||
bei `verbose_json`).
|
||||
|
||||
Beispiele:
|
||||
|
||||
```bash
|
||||
# WebM/Opus (z.B. aus Open WebUI-Mikrofon)
|
||||
curl -s http://192.168.1.196:8081/v1/audio/transcriptions \
|
||||
-F "file=@aufnahme.webm" \
|
||||
-F "model=whisper-1"
|
||||
|
||||
# WAV mit expliziter Sprache
|
||||
curl -s http://192.168.1.196:8081/v1/audio/transcriptions \
|
||||
-F "file=@aufnahme.wav" \
|
||||
-F "model=whisper-1" \
|
||||
-F "language=de"
|
||||
|
||||
# Verbose-Format
|
||||
curl -s http://192.168.1.196:8081/v1/audio/transcriptions \
|
||||
-F "file=@aufnahme.wav" \
|
||||
-F "model=whisper-1" \
|
||||
-F "response_format=verbose_json"
|
||||
```
|
||||
|
||||
### Discovery-Endpunkte
|
||||
|
||||
- `GET /v1/audio/models` – listet verfügbare Audio-Modelle
|
||||
(`whisper-1` für STT, `kokoro-german` für TTS)
|
||||
- `GET /v1/audio/voices` – listet verfügbare TTS-Stimmen
|
||||
(`martin`, `victoria`)
|
||||
|
||||
### Verhalten
|
||||
|
||||
- **Kein GPU-Lock:** STT läuft CPU-only und greift nicht in den
|
||||
GPU-Hotswap (Bild) oder Profilwechsel (Qwen) ein. STT-Requests können
|
||||
parallel zu Chats, TTS und Bildgenerierung laufen.
|
||||
- **Serialisierte Transkription:** Der Worker transkribiert nacheinander
|
||||
(CPU-bound), parallele Requests werden intern gewartet.
|
||||
- **`/status`** zeigt `stt.reachable`, `stt.ready`, `stt.model`,
|
||||
`stt.threads`, `stt.language`, `stt.ffmpeg_exists`.
|
||||
- **Fehler:** Worker down → `503` (`stt_failed`); ungültige Parameter →
|
||||
`400`. OpenAI-kompatibles Fehlerformat.
|
||||
|
||||
### Benchmark (CPU-only, gemessen)
|
||||
|
||||
| Audio-Dauer | Transkription | RTF |
|
||||
|---|---|---|
|
||||
| 7.3 s | 8.9 s | 1.22× |
|
||||
| 30 s | 16.8 s | 0.56× |
|
||||
| 50 s | 18.5 s | 0.37× |
|
||||
|
||||
RTF < 1.0 bedeutet: Transkription ist schneller als Echtzeit.
|
||||
RAM-Belegung des Workers: ~1.7 GB (inkl. Modell).
|
||||
|
||||
### Erforderliche Komponenten
|
||||
|
||||
- `whisper.cpp` (CPU-only Build, `/opt/mike-ai/whisper.cpp/build-cpu/`)
|
||||
- `ggml-large-v3-turbo.bin` (`/opt/mike-ai/models/whisper/`)
|
||||
- `ffmpeg` (für WebM/Opus/M4A/AAC-Konvertierung)
|
||||
- Python 3.13 (nur Standardbibliothek, kein Venv nötig)
|
||||
|
||||
## Repository-Struktur
|
||||
|
||||
```
|
||||
router/ai_profile_router.py # der Router (einzige Laufzeit-Datei)
|
||||
router/image_worker.py # FLUX-Worker (eigener Prozess, JSON-Protokoll)
|
||||
router/tts_worker.py # Kokoro-TTS-Worker (eigener Prozess, HTTP-API)
|
||||
router/stt_worker.py # Whisper-STT-Worker (eigener Prozess, HTTP-API)
|
||||
deploy/mike-ai-profile-router.service # systemd-Unit (Router)
|
||||
deploy/mike-ai-kokoro.service # systemd-Unit (TTS-Worker)
|
||||
deploy/mike-ai-whisper.service # systemd-Unit (STT-Worker)
|
||||
deploy/install.sh # läuft auf dem Zielsystem (per SSH)
|
||||
deploy/deploy.sh # läuft lokal: SCP + SSH
|
||||
dev/ # lokale Tests (Mock-llama.cpp, Mock-Worker, Benchmarks)
|
||||
|
||||
Reference in New Issue
Block a user