Maskinöversättning · Engelskt original
Detektering av väckningsord / nyckelord
Den som SpeechWakeWord modulen driver en on-device keyword spotter: du registrerar en lista över fraser, trycker ljud chunks in och får detektioner. Baserat på isfalls streaming Zipformer-transducer (Icefalls strömmande Zipformers transducer)3.49M params, Apache-2.0), sammanställd till CoreML med INT8 palettisering.
Den skeppade kontrollpunkten är gigaspeech KWS finjustering. Icke-engelska sökord behöver en separat isfall finjustering och återexport.
Arkitektur
| Steg | Detaljer |
|---|---|
| Fbank | kaldi-kompatibel (25 ms / 10 ms, Povey fönster, 80 mel bins, high_freq=-400, ingen CMVN) |
| Encoder | 6-stegs kausal Zipformer2 (128-dim), 45 mel ramar i → 8 ramar ut (40 ms / ram) - 3,3 MB INT8 |
| Decoder | Statslös transducerare, BPE-500 vocab, kontextstorlek 2 - 525 KB FP16 |
| Joiner | Linear + tanh output projection - 160 KB INT8 |
| Decode | Modifierad strålsökning (beam=4) över en Aho-Corasick ContextGraph av användarnyckelord |
Sammanställd storlek på disken: 4 MB totalt (encoder.mlmodelc + decoder.mlmodelc + joiner.mlmodelcRuntime minne: ~ 6 MB inklusive kodare stat caches.
Prestanda
| Metric | Värde | Anmärkningar |
|---|---|---|
| RTF (CPU + Neural Engine) | 0.04 | 26× realtid på M-serien |
| Recall (12 sökord) | 88% | LibriSpeech test-clean, 158 positiva uttalanden |
| Falskt positivt/uttalande | 0.27 | 60 negativa uttalanden |
| CoreML INT8 vs PyTorch FP32 | 99% | Emissionsavtal |
Tuned standard: acThreshold=0.15, contextScore=0.5, numTrailingBlanks=1Per-keyword åsidosätter stöd.
CLI Användning
Plain-fras form (grönt BPE - fungerar bra för vanliga ord):
speech wake recording.wav --keywords "hey soniqo"
speech wake recording.wav --keywords "hey soniqo:0.15:0.5" "cancel"
Pre-tokenized form (sherpa-onnx stil - rekommenderas när du vet exakt nedbrytning modellen var utbildad på):
# Format: "phrase|piece1 piece2 ...:threshold:boost"
speech wake recording.wav \
--keywords "LIGHT UP|▁ L IGHT ▁UP:0.25:2.0"
# Multiple keywords + JSON output
speech 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
Eller en sökordsfil, en post per rad (# för kommentarer):
speech wake recording.wav --keywords-file keywords.txt
Swift API
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
| Fält | Betydelse |
|---|---|
phrase | Visa fras, t.ex. "hey soniqo". Används också som källa för giriga BPE-kodning när tokens är nil. |
acThreshold | Medel akustisk sannolikhet krävs över den matchade span. 0 → använd tuned standard (0.15). |
boost | Per-token kontext boost. Positiva värden gör frasen lättare att utlösa. 0 → använd tuned standard (0,5). |
tokens | Valfritt explicit BPE-styckelista. När icke-nil ser detektorn varje bit upp i modellens tokens.txt och kringgår den giriga BPE kodaren. |
tokensIcefall KWS vokabulär är uppercase BPE. Greedy tokenization of a phrase can pick a different BPE decomposition from the one the model was trained to emit -- "LIGHT UP" greedy-encodes to ▁LI GHT ▁UP men träningsdekompositionen är ▁ L IGHT ▁UP
Modell nedladdningar
| Modell | Params | Storlek | HuggingFace |
|---|---|---|---|
| KWS-Zipformer-3M | 3,49M | ~4 MB | aufklarer/KWS-Zipformer-3M-CoreML-INT8 |
Pipeline integration
Modulen exponerar en WakeWordProvider-protokoll som speglar StreamingVADProvider, så en röstpipeline kan gate aktivering på VAD, wake-word, eller båda. WakeWordStreamingAdapter wraps a loaded detector + a single session into a reusable provider object.
let adapter = try WakeWordStreamingAdapter(detector: detector)
// pipeline.configure(wakeWord: adapter)
Källa
- Källor/SpeechWakeWord -- Swift modul
- docs/models/kws-zipformer.md - arkitekturnoter
- docs/inference/wake-word.md -- inference pipeline
- Upstream: k2-fsa/icefall KWS recept/pkufool/keyword-spotting-models