thalovant/zoguilo-wakeword
The wake word "Zoguilo", said zo-gui-lo /zo.ɡi.lo/ ("zo-ghee-lo"): an invented three-syllable word, soft and easy for a child to say, with no web or trademark hits, for French, English, Spanish, Portuguese, Italian, German and Dutch speakers. Each language's spelling was trained: fr Zoguilo, en Zo-ghee-lo, es Soguilo, pt Zoguilô, it Zoghilo, de Sogilo, nl Zogielo, pl Zogilo, ro Zoghilo.
It is a 0.9 MB ONNX head trained with wakeforge on the streamed
features of TigreGotico/wakehubert-tiny (int8), loaded in
OpenVoiceOS by ovos-ww-plugin-wakeforge in place of
openWakeWord. This is v2 (main, git tag v2); earlier versions are kept under their tags
(Versions).
Use
OpenVoiceOS
pip install --pre "ovos-ww-plugin-wakeforge>=0.18.0a1"
mycroft.conf:
{
"listener": {"wake_word": "zoguilo"},
"hotwords": {
"zoguilo": {
"module": "ovos-ww-plugin-wakeforge",
"model": "https://huggingface.co/thalovant/zoguilo-wakeword/resolve/v2/zoguilo.onnx",
"listen": true,
"active": true
},
"hey_mycroft": {"active": false}
}
}
The plugin downloads the model once (to ~/.local/share/wakeforge/), fetches the featurizer the model names at a
pinned revision, and uses the model's own threshold. If your openWakeWord entry has another name than
hey_mycroft, put "active": false on that one.
- x86 PCs without AVX-512 (AVX2: most desktops and laptops): the released plugin scores up to 0.07 off there
until OpenVoiceOS/ovos-ww-plugin-wakeforge#55
is merged; until then install
pip install "git+https://github.com/goldyfruit/ovos-ww-plugin-wakeforge@perf/x64-int8-precision". ARM boards, Apple silicon and AVX-512 CPUs score exactly with the released plugin. - Less CPU:
"head_skip_below": 0.01(in #56, fromgit+https://github.com/goldyfruit/ovos-ww-plugin-wakeforge@perf/head-skip) cuts the CPU by a third (Raspberry Pi 4: 106 to 72 ms per second of audio); about one detection in four can come 80 ms later.
Thalovant satellite (thalovant-voice 0.10.0 or later)
wake:
word: /path/to/zoguilo.onnx
Threshold
The default, 0.864, was set on 97 h of development speech, never the test set (0.49 debounced false wakes per hour on it, 0.55 on its YouTube part). Override it with
"threshold": lower answers more readily, higher wakes less by mistake. Measured on the held-out audio below:
threshold |
false wakes/h: YouTube / debates / music | wake words found, 18 conditions (mean) |
|---|---|---|
| 0.6 | 0.64 / 0.44 / 0.20 | 84.6 % |
| 0.8 | 0.32 / 0.33 / 0.05 | 81.0 % |
| 0.864 (default) | 0.22 / 0.33 / 0.05 | 78.9 % |
| 0.948 | 0.10 / 0.22 / 0.05 | 73.9 % |
How good it is
Every number is on audio the model never trained on: speakers, voices, videos, rooms, noises and music tracks
held out of training. Raw reports: eval.json, stress_recall.json,
stress_false_wakes.json, latency.json,
plugin_validation.json.
False wakes, streamed through ovos-plugin-manager as OVOS runs it (198 h in all, 55 false wakes, 0.28/h):
| audio | hours | false wakes | per hour |
|---|---|---|---|
| read speech (MLS, LibriSpeech test) + AudioSet | 70 | 26 | 0.37 |
| YouTube videos (YODAS2, 7 languages) | 72 | 16 | 0.22 |
| European Parliament debates (VoxPopuli, 8 languages) | 36 | 12 | 0.33 |
| music, with and without vocals (MUSAN) | 20 | 1 | 0.05 |
Wake words found, each held-out clip in each condition (edge-tts voices excluded from training and clips voice-converted onto unseen real speakers, 522 clips that a phoneme model confirms say the word; fr, en, es, pt, it, de, nl, pl, ro). English voices: 82.1 % on average over the 18 conditions, other languages: 77.8 %.
| condition | found |
|---|---|
| after silence | 88 % |
| speech right before it, no pause | 86 % |
| a command right after it | 89 % |
| in the middle of a sentence | 85 % |
| far side of a real room (-36 dBFS, room noise) | 86 % |
| noise, 10 dB SNR | 89 % |
| noise, 5 dB SNR | 78 % |
| noise, 0 dB SNR | 67 % |
| music with vocals, 10 dB | 85 % |
| music with vocals, 5 dB | 73 % |
| another person talking over it, 5 dB | 53 % |
| phone line (8 kHz G.711) | 82 % |
| Opus at 12 kbit/s | 89 % |
| said fast (x1.25) | 84 % |
| said slowly (x0.8) | 91 % |
| quiet speaker (-48 dBFS) | 59 % |
| clipped microphone | 63 % |
| pitch +4 semitones (child-like) | 74 % |
Latency: the wake word is reported a median 86 ms after the end of the word, and 90 % of the time within 164 ms, through the plugin at 1280-sample chunks.
The training pipeline's own held-out evaluation at the default threshold: 70 h of read speech by unseen speakers, 0.33 false wakes/h; wake words found after silence / after speech: edge-tts voices 94 % / 93 %, OmniVoice speakers 96 % / 94 %, voice-converted real speakers 95 % / 92 %.
Against openWakeWord
The same harness, the same audio and the same voices, each model through its own OVOS plugin (openWakeWord 0.6.0, onnx):
| false wakes/h: read / YouTube / debates / music | found, English voices | found, other languages | latency median / p90 | |
|---|---|---|---|---|
| zoguilo v2 | 0.37 / 0.22 / 0.33 / 0.05 | 82.1 % | 77.8 % | 86 / 164 ms |
| openWakeWord hey_jarvis | 0.14 / 0.25 / 0.00 / 0.15 | 85.5 % | 25.1 % | 78 / 255 ms |
| openWakeWord alexa | 0.74 / 1.56 / 0.44 / 4.84 | 87.9 % | 71.1 % | -3 / 116 ms |
Against openWakeWord's alexa, Zoguilo v2 wakes by mistake less on every kind of audio (7 times less on YouTube; with music, 1 false wake in 20 hours against 97) and finds the word about as often overall: more often for non-English speakers, less often for English ones. Against hey_jarvis, it wakes by mistake less on YouTube and music and more on read speech and debates (0.37 against 0.14, 0.33 against none per hour), finds a few points fewer English speakers, and three times more speakers of other languages.
CPU and memory, one thread, ms of CPU per second of audio (10 = 1 % of one core), measured through ovos-plugin-manager on the devices themselves:
| device | zoguilo | with head_skip_below: 0.01 |
openWakeWord hey_jarvis |
|---|---|---|---|
| Raspberry Pi 3 (Cortex-A53) | 244.7 | 159.3 | 508.0 |
| Raspberry Pi 4 (Cortex-A72) | 106.5 | 72.0 | 248.8 |
| Raspberry Pi 5 (Cortex-A76) | 40.4 | 28.6 | 102.6 |
| Jetson Orin Nano (Cortex-A78AE) | 36.8 | 24.9 | 86.4 |
| Ryzen 7 5800 desktop (AVX2) | 10.0 | 22.0 | |
| Linux x86_64, AMD EPYC 7763 (AVX2) (GitHub runner) | 14.8 | 29.5 | |
| Linux aarch64, Neoverse N2 (GitHub runner) | 18.3 | 44.9 | |
| macOS 15, Apple M1 (GitHub runner) | 14.0 | 37.2 | |
| Windows x64 (AMD) (GitHub runner) | 16.9 | 35.4 | |
| Windows ARM64 (GitHub runner) | 19.5 | 50.8 |
Process memory on the desktop with one wake word: 107 MB in all (+33 MB for the model and the featurizer), against 217 MB (+143 MB) for openWakeWord. Two wake words in OVOS share wakeforge's featurizer: 17.6 ms/s against 46.3 ms/s on the desktop.
Runs everywhere, scores the same
On every 64-bit platform tried, every 80 ms score of a 106 s golden stream matches the AVX-512 VNNI machine the model was calibrated on within 1.2e-5 (tolerance 0.002) and the detections are identical: Linux x86_64 (onnxruntime 1.20.1, 1.23.2, 1.31.1) and aarch64, macOS on Apple silicon, Windows x64 and ARM64, and the real Raspberry Pi 3, 4, 5 and Jetson Orin Nano above (with the AVX2 fix of #55 on x86 PCs). 32-bit ARM is not supported: onnxruntime publishes no armv7 wheel. Cross-platform CI.
Training
- Positives: synthetic speech in 9 languages (OmniVoice including child voices, edge-tts, Piper, Kokoro/StyleTTS2, PocketTTS, Supertonic, Magpie, Google) and Chatterbox voice conversion onto MLS and LibriSpeech speakers, every clip checked by a phoneme model.
- Negatives: MLS and LibriSpeech speech, 140 h of YouTube videos (YODAS2, CC BY 3.0; other videos than the test's), music (MUSAN, other artists than the test's), AudioSet; near-miss words and phrases in 7 languages, and the 2 s before every detection of the previous version on that YouTube and music audio.
- Real-room conditions in training (new in this version): speech right before and after the word, another talker over it, room responses up to 1.2 s with their tail (MIT IR survey, RWCP, simulated rooms), quieter audio.
- Two GRU heads (with and without the voice-converted clips) averaged and calibrated; epoch and threshold chosen on 97 h of development speech that includes 71 h of other YouTube videos.
Versions
- v2 (
main, tagv2): this model. Against v1, on the same held-out audio: false wakes on YouTube 1.74/h to 0.22/h, debates 0.89/h to 0.33/h, music 0.85/h to 0.05/h; found in the middle of a sentence 83 % to 85 %. v1's lower threshold found more in the easier cases: after silence 97 % (v2 88 %), a quiet speaker 87 % (v2 59 %), a clipped microphone 92 % (v2 63 %). A threshold of 0.6 brings v2 to 85 % on average, still with fewer false wakes than v1 (table above). - v1 (tag
v1): trained on read speech only; threshold 0.253; kept for comparison.
Limits
- Every test voice is synthetic or voice-converted; nobody has recorded "Zoguilo" for the tests yet.
- Someone talking over the word at a similar level (a loud TV) is the hardest case: about half are found.
- A quiet or distant speaker (a child speaking softly) and a clipping microphone are found less often than in v1: lower the threshold (0.6) where that matters more than the odd false wake.
License
CC BY-NC 4.0: free for non-commercial use with attribution ("Zoguilo wake word by Thalovant"); commercial use requires permission from Thalovant. The WakeHuBERT featurizer it runs on is Apache-2.0 and licensed separately. Versions downloaded before 2026-11-05 were published under Apache-2.0.
Model tree for thalovant/zoguilo-wakeword
Base model
facebook/hubert-base-ls960