On-device wake-word / keyword-spotting model based on icefall's streaming Zipformer2 encoder + stateless RNN-T transducer. CoreML export with INT8 palettization fits in under 4 MB of compiled weights and hits ~26× real-time on CPU + Neural Engine.
English only. The checkpoint is the gigaspeech KWS fine-tune. No multilingual variant is currently exported; keywords and test audio must be English. Other languages require a separate fine-tune + re-export.
- Source:
pkufool/keyword-spotting-models@v0.11/icefall-kws-zipformer-gigaspeech-20240219 - License: Apache-2.0
- Language: English only (gigaspeech fine-tune)
- CoreML bundle:
aufklarer/KWS-Zipformer-3M-CoreML-INT8on HuggingFace
The encoder maintains 38 cache tensors per stream: 36 per-layer attention and
convolution caches plus cached_embed_left_pad (Conv2dSubsampling state) and
processed_lens (int32 counter, used to build the attention mask).
Modified beam search over the transducer (beam=4) driven through an
Aho-Corasick ContextGraph that holds user-supplied keyword phrases. For
each encoder frame the decoder:
- Runs the decoder + joiner per beam hypothesis, softmaxes the logits.
- Picks top-
beam(hypothesis, token)pairs. - On non-blank / non-unk tokens advances the context-graph state and applies the phrase boost score. On blank/unk increments a tail-blank counter.
- Checks the most-probable hypothesis: if it lands on an
is_endnode, has at leastnum_tailing_blankstrailing blanks, and the mean acoustic probability over the matched span clears the per-keywordac_threshold, emits a detection and resets the beam. - Auto-resets the beam to root if no token has been emitted for
autoResetSecondsof audio (default 1.5 s).
The export defaults (ac_threshold = 0.15, context_score = 0.5,
num_tailing_blanks = 1) were tuned on LibriSpeech test-clean:
| Setting | Recall | FP/utt |
|---|---|---|
icefall defaults (0.25, 2.0, 1) |
62% | 0.43 |
| tuned (shipped) | 88% | 0.27 |
Per-keyword overrides are expressed in the keywords.txt file shipped
with the export and via KeywordSpec(phrase:, acThreshold:, boost:) in Swift.
The CoreML bundle ships three compiled models:
All three target CPU_AND_NE and iOS17 minimum. The encoder and joiner are
INT8 palettized; the decoder stays FP16 (it's tiny).
- Encoder chunk latency: ~12 ms on M-series CPU+NE for a 320 ms audio chunk.
- Real-time factor: ~0.04 (26× real-time) on the export's LibriSpeech benchmark.
- Total memory footprint at runtime: ~6 MB (weights + encoder state).
- Inference pipeline — fbank, streaming session, keyword file format.
