Zum Inhalt

Wake Word Service (Codewort-Training)

Lokales Wake-Word-Training und -Erkennung auf Basis von openWakeWord. Ermöglicht das Trainieren eines eigenen "hey xynap"-Codeworts mit TTS-generierten und manuell hochgeladenen Aufnahmen. Die Erkennung erfolgt per WebSocket direkt im Browser — ohne Google oder externe Dienste.

Architektur

Browser (AudioWorklet 48kHz → 16kHz PCM)
  └─► WebSocket wss://platform.xynap.tech/wakeword/ws
        └─► openWakeWord ONNX Inference
              └─► {event: "wake"} → Frontend-Callback

Wenn kein trainiertes Modell aktiv ist, fällt das System auf die Web Speech API (Chrome/Edge, sendet an Google) zurück.

Dienst-Infos

Container wakeword-service
Interner Port 5600
Netzwerk ai-network
API-Prefix /api/v1/wakeword/
WebSocket wss://platform.xynap.tech/wakeword/ws
Daten-Volume /data/ (Modelle, Samples)
Aktives Modell /data/active_model.txt

Training Pipeline

Das Training läuft vollautomatisch in 7 Phasen:

Phase Name Beschreibung
1 samples_tts TTS-Samples generieren (alle Stimmen × 5 Geschwindigkeiten)
2 samples_upload Hochgeladene eigene Aufnahmen prüfen
3 augment Noise-Augmentierung (–25 dB White Noise)
4 features openWakeWord Feature-Extraktion (Mel-Spektrogramm, 96-dim Embeddings)
5 train PyTorch DNN trainieren (FC-Layer + ReLU + LayerNorm + Sigmoid, Adam lr=0.001)
6 validate False-Positive-Rate messen
7 save ONNX-Modell speichern + Index aktualisieren

API-Endpoints

Alle Endpunkte sind über /api/v1/wakeword/ (Platform-API-Proxy) erreichbar.

Methode Pfad Beschreibung Permission
GET /status Aktives Modell + WebSocket-URL
WS /ws Binary PCM Stream → Wake-Event
GET /models Liste trainierter Modelle wakeword.read
POST /train Training starten wakeword.manage
GET /training/{job_id} Trainingsstatus + Phasen-Progress wakeword.read
POST /samples/upload WAV-Dateien hochladen wakeword.manage
GET /samples Alle Samples (gruppiert nach Wort) wakeword.read
DELETE /samples/{word} Samples eines Wortes löschen wakeword.manage
POST /models/{name}/activate Modell aktivieren wakeword.manage
DELETE /models/{name} Modell löschen wakeword.manage

WebSocket-Protokoll

Client → Server: Binary (Int16 PCM, 16kHz Mono, 256 samples = 16ms)
Server → Client: JSON {"event": "wake", "score": 0.87, "word": "hey xynap"}
                 JSON {"event": "ping"}

Admin-UI

Unter Einstellungen → Codewort-Training können Admins:

  1. Neues Modell trainieren — Wort eingeben, TTS-Samples aktivieren, Training starten
  2. Eigene Aufnahmen hochladen — WAV-Dateien (werden automatisch auf 16kHz mono resampled)
  3. Browser-Recording — Hold-to-Record (max. 3 Sekunden) direkt im Browser
  4. Modell aktivieren — Trainiertes Modell für alle User scharf schalten
  5. Trainingsfortschritt — Live-Anzeige der 7 Phasen per Polling

Browser-Integration

Das Composable useWakeWord.ts implementiert die clientseitige Erkennung:

  1. GET /api/v1/wakeword/status — prüft ob Modell aktiv, holt WebSocket-URL
  2. AudioContext + AudioWorklet (pcm-processor.js) — erfasst Mikrofon-Audio
  3. Dezimierung 48 kHz → 16 kHz + Float32 → Int16 im Worklet-Thread
  4. Binary PCM-Frames (256 Samples = 16 ms) per WebSocket an Service
  5. Bei {event:"wake"} → Intent-Callback auslösen

Reconnect-Logik: max. 5 Versuche mit exponentiellem Backoff.

Abhängigkeiten

Service Zweck
TTS-Gateway (Port 5200) Sample-Generierung beim Training
STT-Gateway (Port 5400) Validierung (optional)
openWakeWord 0.6.0 ONNX-Inferenz + Preprocessing
PyTorch ≥ 2.0 DNN-Training
onnxruntime 1.20.1 ONNX-Export + Inferenz

Konfiguration

Env-Variable Datei Wert
WAKEWORD_SERVICE_URL /etc/xynap/platform/backend.env http://wakeword-service:5600
DETECT_THRESHOLD Microservice server.py 0.5

Test-Tool

# Wake-Word-Erkennung über alle TTS-Stimmen testen
xynap-test-wakeword

# Anderes Codewort testen
xynap-test-wakeword --word "ok xynap"

# Nur bestimmte Stimmen
xynap-test-wakeword --voices qwen3|piper|all --out /tmp/

Dateipfade

Typ Pfad
Microservice /usr/local/xynap/wakeword-service/server.py
Dockerfile /usr/local/xynap/wakeword-service/Dockerfile
Platform-API Router /usr/local/xynap/platform/backend/app/core/wakeword/router.py
Admin-UI /usr/local/xynap/platform/frontend/src/shell/admin/WakeWordView.vue
Composable /usr/local/xynap/platform/frontend/src/shell/composables/useWakeWord.ts
AudioWorklet /usr/local/xynap/platform/frontend/src/shell/composables/pcm-processor.js
Service-Register /home/admin/docs/services/wakeword.md