Skip to main content

OVOS wake-word plugin wrapping microWakeWord TFLite streaming models (ESPHome ecosystem)

Project description

ovos-ww-plugin-microwakeword

OVOS wake-word plugin wrapping microWakeWord TFLite streaming models from the ESPHome ecosystem.

Supported models

Models published at https://github.com/esphome/micro-wake-word-models:

model_name Phrase v1 v2
okay_nabu Okay Nabu
hey_jarvis Hey Jarvis
alexa Alexa
hey_mycroft Hey Mycroft
vad Voice activity

Any community-provided .tflite model that follows the microWakeWord input convention (1×1×40 int8 log-mel features) is compatible.

Installation

pip install ovos-ww-plugin-microwakeword

The package declares ai-edge-litert (Linux x86_64) or tflite-runtime (other platforms) as a runtime dependency alongside pymicro-features (the TFLite Micro audio frontend wrapper).

Configuration

In ~/.config/mycroft/mycroft.conf (or ovos.conf), under the hotwords section for your chosen keyword:

{
  "hotwords": {
    "okay nabu": {
      "module": "ovos-ww-plugin-microwakeword",
      "model_name": "okay_nabu",
      "model_version": 1,
      "probability_cutoff": 0.5,
      "sliding_window_size": 10,
      "refractory_frames": 40
    }
  }
}

Configuration reference

Key Type Default Description
model str (auto) Absolute path to a .tflite file, or an https:// URL. Takes precedence over model_name.
model_name str okay_nabu Short name of an official ESPHome model. Auto-downloads on first use.
model_version int 1 1 or 2 — selects the model subdirectory in the ESPHome repository.
probability_cutoff float 0.5 Dequantized probability threshold in [0, 1]. Higher → fewer false positives, lower → fewer missed detections.
sliding_window_size int 10 Number of consecutive 10 ms frames whose average must exceed probability_cutoff before a detection fires. Mirrors ESPHome sliding_window_average_size.
refractory_frames int 40 Frames to ignore after a detection (≈ 400 ms) to prevent double-fires.

Technical details

Audio pipeline

16 kHz int16 PCM  →  pymicro-features (TFLite Micro audio frontend)
                  →  40-dim log-mel feature slice per 10 ms frame
                  →  quantize to int8 (scale 0.102, zero-point −128)
                  →  TFLite interpreter (1×1×40 → 1×1 uint8)
                  →  dequantize → float probability
                  →  sliding window average ≥ cutoff → detection

Model input signature

Inspected from okay_nabu.tflite (v1):

Input  tensor: serving_default_input_audio:0  shape=[1, 1, 40]  dtype=int8
               quantization: scale=0.10196, zero_point=-128
Output tensor: StatefulPartitionedCall:0      shape=[1, 1]       dtype=uint8
               quantization: scale=0.00390625, zero_point=0

The model embeds its streaming RNN/convolution state as TFLite resource variables. Each sequential interpreter.invoke() call advances the internal state automatically — no external state tensor management is needed. interpreter.allocate_tensors() resets the streaming state (called by reset()).

ESPHome model compatibility notes

  • v1 models use the original microWakeWord architecture; quantized int8 input with the TFLite Micro audio frontend.
  • v2 models use the same input convention — the plugin supports both transparently.
  • Models must accept [1, 1, 40] int8 input; any model with a different input shape will raise ValueError at load time.
  • The audio frontend (pymicro-features) is the exact same C implementation used by ESPHome's on-device inference.

How to test

Unit tests (no model required)

pytest tests/test_unit.py -v

All 16 unit tests use a mocked interpreter and pass without network access.

End-to-end tests (downloads okay_nabu.tflite, requires edge-tts + ffmpeg)

pip install edge-tts
pytest tests/test_e2e.py -v -s

Expected output:

tests/test_e2e.py::TestE2EReal::test_negative_no_detection PASSED
[positive test] DETECTION FIRED on 'okay nabu' TTS audio.   ← or SKIPPED with max_prob info
tests/test_e2e.py::TestE2EReal::test_positive_detection PASSED

The positive test soft-fails (SKIP) rather than hard-fails when TTS audio does not trigger the model, because the model is trained on human voice. The negative test ("hello world") is a hard assertion.


Credits

Developed by TigreGótico for OpenVoiceOS.

NGI0 Commons Fund

This project was funded through the NGI0 Commons Fund, a fund established by NLnet with financial support from the European Commission's Next Generation Internet programme, under the aegis of DG Communications Networks, Content and Technology under grant agreement No 101135429.


License

Apache-2.0

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ovos_ww_plugin_microwakeword-0.0.1a2.tar.gz (14.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

File details

Details for the file ovos_ww_plugin_microwakeword-0.0.1a2.tar.gz.

File metadata

File hashes

Hashes for ovos_ww_plugin_microwakeword-0.0.1a2.tar.gz
Algorithm Hash digest
SHA256 0d9e7606d2a69b6faf7255c21b50a7830c5d450065437452c4bdb50d684126fa
MD5 458044040fcd82126189b7dfc3bd402f
BLAKE2b-256 c7b6de5a4f187f430bd9fa174ed692157c16c1b04e44f91abb91de2291e09105

See more details on using hashes here.

File details

Details for the file ovos_ww_plugin_microwakeword-0.0.1a2-py3-none-any.whl.

File metadata

File hashes

Hashes for ovos_ww_plugin_microwakeword-0.0.1a2-py3-none-any.whl
Algorithm Hash digest
SHA256 91210c3ccd01959e8f538eb9f544625dfed4231278071d55260e4742e2423b0a
MD5 b2fb950557f2417621fde501990b47a9
BLAKE2b-256 0eeacf6171f8762411b2d9c13ec919f76d7c07c5233d89d56ed52fa66bc49b90

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page