microWakeWord — «Ирина» (Russian)
Quantized INT8 streaming TFLite wake-word model for the Russian «Ирина» (stress on the
2nd syllable: и-РИ-на), for ESP32-S3 / ESPHome and server-side
pymicro-wakeword. First openly published
Russian microWakeWord.
Files
irina.tflite— streaming quantized modelirina.json— v2 manifest (trained_languages: ["ru"],probability_cutoff0.97,sliding_window_size5)
Metrics (on real household recordings, not synthetic)
- Recall: 100% (16/16) real «Ирина» recordings at every cutoff through 0.97 (positive mean-prob 0.996) — including congested/child voices earlier models missed.
- FA/h on 3.13 h Russian ambient: 3.5 @0.90 · 1.9 @0.97 · ~1.0 @0.99 (thin sample — tune on device).
- Selected as the best of 15 random-subset runs on real recall (run 4; see repo).
Operating point — tune the cutoff on YOUR device
The manifest ships probability_cutoff = 0.97 — a deliberately recall-safe starting
point. Real utterances score ~0.996 (tightly bunched just under 1.0), well clear of 0.97, so
recall is 100% with comfortable margin. To trade a little of that margin for fewer false
accepts, raise the cutoff toward ~0.99 on your own device as your real ambient dictates:
| cutoff | recall (16 real) | FA/h* |
|---|---|---|
| 0.97 (shipped) | 100% | 1.9 |
| 0.98 | 100% | 1.3 |
| 0.99 | 100% | 1.0 |
| ≥0.995 | drops | — |
*FA/h is from a thin 3.13 h ambient sample — indicative only; measure on your device.
Above ~0.99 recall falls off a cliff, so don't exceed it. Secondary knob: raise
sliding_window_size (5 → 7) for extra smoothing if FA is stubborn.
Why it's alive on real voices (and the French cautionary tale)
No open Russian microWakeWord existed; the closest attempt (French: 3 Piper voices and a widened SNR) trained cleanly yet was dead on device. This one is alive — and publishable — because of choices each checked by a native-Russian ear, not assumed:
- Correct stress, verified per engine. Wrong stress ⇒ mispronounced positives ⇒ dead model.
Piper (espeak-ng) is fed plain Cyrillic; Silero is fed «Ир+ина» (
+before the stressed vowel,put_accent=False); Vosk's BERT accentizer handles it from plain text. - A deliberately diverse, license-clean voice mix. Piper
ruslan+ Silero (xenia/kseniya/eugene) + a female-leaning Vosk-TTS minority (all Apache/CC-BY-NC-SA). The Vosk female voices restore the female-speaker diversity that a non-redistributable Piper voice would otherwise have provided — so the model generalizes to female speakers without any CC-BY-NC-ND source. - Selected from a 15-run search, not one lucky run. Recall is stable run-to-run but false- accepts are a data-subset lottery; this artifact is the best of 15 random-subset runs, chosen on real recall/FA — not on the (misleading) synthetic eval.
- Curated hard-negatives — near-misses (Марина / Арина / Ирана / перина, diminutives, inflected forms) teach the model the boundary, not just the word.
- Battle-tested recipe, no heroics — SNR −5…+10 dB (not widened — widening is what broke the French run), negative class weight 20, 3 augmentation rounds, 12k steps.
Usage
from pymicro_wakeword import MicroWakeWord, MicroWakeWordFeatures
mww = MicroWakeWord.from_config("irina.json") # feed 16 kHz mono 16-bit audio via MicroWakeWordFeatures
Or in ESPHome via the micro_wake_word component.
Training & license
Voice mix above (Piper ruslan + Silero + female Vosk-TTS minority) → CC BY-NC-SA 4.0;
plus stock English negatives (kahrendt/microwakeword) and a Common Voice ru subset.
Full recipe, per-run log, and methodology: https://github.com/locveil/wakeword-training
(docs/recipe.md, EXPERIMENTS.md).
- Downloads last month
- 18