Mot de réveil / Détection de mots-clés

Le module SpeechWakeWord exécute un détecteur de mots-clés sur appareil : vous enregistrez une liste de phrases, poussez des fragments audio et recevez les détections. Basé sur le transducteur Zipformer en streaming d'icefall (3,49 M paramètres, Apache-2.0), compilé en CoreML avec palettisation INT8.

Anglais uniquement

Le checkpoint livré est le fine-tuning KWS sur gigaspeech. Les mots-clés non anglais nécessitent un fine-tuning icefall distinct et une ré-exportation.

Architecture

ÉtapeDétails
fbankcompatible kaldi (25 ms / 10 ms, fenêtre Povey, 80 bins mel, high_freq=-400, pas de CMVN)
EncodeurZipformer2 causal à 6 étages (128-dim), entrée 45 trames mel → 8 trames de sortie (40 ms / trame) — 3,3 Mo INT8
DécodeurTransducteur sans état, vocabulaire BPE-500, taille de contexte 2 — 525 Ko FP16
JoinerProjection linéaire + tanh — 160 Ko INT8
DécodageBeam search modifié (beam=4) sur un ContextGraph Aho-Corasick des mots-clés utilisateur

Taille compilée sur disque : ~4 Mo au total (encoder.mlmodelc + decoder.mlmodelc + joiner.mlmodelc). Mémoire d'exécution : ~6 Mo incluant les caches de l'encodeur.

Performance

MétriqueValeurRemarques
RTF (CPU + Neural Engine)0,0426× temps réel sur série M
Rappel (12 mots-clés)88 %LibriSpeech test-clean, 158 énoncés positifs
Faux positifs / énoncé0,2760 énoncés négatifs
CoreML INT8 vs PyTorch FP3299 %Accord des émissions

Valeurs par défaut calibrées : acThreshold=0,15, contextScore=0,5, numTrailingBlanks=1. Les surcharges par mot-clé sont prises en charge.

Utilisation CLI

Forme à phrase simple (BPE glouton — fonctionne bien pour les mots courants) :

audio wake recording.wav --keywords "hey soniqo"

audio wake recording.wav --keywords "hey soniqo:0.15:0.5" "cancel"

Forme pré-tokenisée (style sherpa-onnx — recommandée lorsque vous connaissez la décomposition exacte sur laquelle le modèle a été entraîné) :

# Format: "phrase|piece1 piece2 ...:threshold:boost"
audio wake recording.wav \
    --keywords "LIGHT UP|▁ L IGHT ▁UP:0.25:2.0"

# Multiple keywords + JSON output
audio wake recording.wav \
    --keywords "LIGHT UP|▁ L IGHT ▁UP:0.25:2.0" \
               "LOVELY CHILD|▁LOVE LY ▁CHI L D:0.25:2.0" \
    --json

Ou un fichier de mots-clés, une entrée par ligne (# pour les commentaires) :

audio wake recording.wav --keywords-file keywords.txt

API Swift

import SpeechWakeWord

// Load the model with your keyword list.
let detector = try await WakeWordDetector.fromPretrained(
    keywords: [
        KeywordSpec(phrase: "hey soniqo", acThreshold: 0.15, boost: 0.5),
        KeywordSpec(phrase: "cancel")
    ]
)

// Streaming: push chunks, consume detections as they fire.
let session = try detector.createSession()
for chunk in micAudioChunks {                   // Float32 @ 16 kHz
    for detection in try session.pushAudio(chunk) {
        print("[\(detection.time(frameShiftSeconds: 0.04))s] \(detection.phrase)")
    }
}

// Batch: single shot over a full buffer.
let detections = try detector.detect(audio: samples, sampleRate: 16000)

KeywordSpec

ChampSignification
phrasePhrase d'affichage, p. ex. "hey soniqo". Sert aussi de source pour le codage BPE glouton lorsque tokens est nil.
acThresholdProbabilité acoustique moyenne requise sur la plage correspondante. 0 → utilise la valeur par défaut calibrée (0,15).
boostBoost de contexte par token. Les valeurs positives facilitent le déclenchement de la phrase. 0 → valeur par défaut calibrée (0,5).
tokensListe explicite optionnelle de pièces BPE. Quand elle n'est pas nil, le détecteur recherche chaque pièce dans le tokens.txt du modèle et contourne l'encodeur BPE glouton.
Quand utiliser tokens pré-tokenisé

Le vocabulaire KWS d'icefall est BPE en majuscules. La tokenisation gloutonne d'une phrase peut choisir une décomposition BPE différente de celle sur laquelle le modèle a été entraîné — "LIGHT UP" se code gloutonnement en ▁LI GHT ▁UP mais la décomposition d'entraînement est ▁ L IGHT ▁UP. Quand la détection sur audio synthétisé par TTS ou parole lue propre manque des correspondances évidentes, essayez la forme pré-tokenisée style sherpa-onnx.

Téléchargements du modèle

ModèleParamètresTailleHuggingFace
KWS-Zipformer-3M3.49M~4 MBaufklarer/KWS-Zipformer-3M-CoreML-INT8

Intégration dans la pipeline

Le module expose un protocole WakeWordProvider qui reflète StreamingVADProvider, permettant à une pipeline vocale de contrôler l'activation via VAD, mot de réveil, ou les deux. WakeWordStreamingAdapter encapsule un détecteur chargé + une session unique dans un objet provider réutilisable.

let adapter = try WakeWordStreamingAdapter(detector: detector)
// pipeline.configure(wakeWord: adapter)

Sources