blog: microWakeWord on OVOS (draft)#71
Conversation
📝 WalkthroughWalkthroughA new blog post documents the ChangesmicroWakeWord OVOS documentation
Estimated code review effort: 1 (Trivial) | ~5 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…eaming-state detail, real-voice caveat, WakeForge cross-link Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
f1552ed to
96734e5
Compare
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@_posts/2026-08-19-microwakeword-on-ovos.md`:
- Line 99: Update the streaming-model explanation to state that session state is
cleared explicitly with the interpreter’s reset API, `reset_all_variables()` or
`ResetVariableTensors()`, rather than by `allocate_tensors()`. Describe
`allocate_tensors()` only as tensor allocation and clarify that reset is
required between sessions.
- Line 35: Update the custom-model compatibility statement near the
microWakeWord input-signature description: do not claim that any `.tflite` with
`[1, 1, 40]` int8 input works. Either narrow the claim or document the complete
contract, including the expected wake-word output tensor and required
streaming/state behavior.
- Line 45: Update the package description to accurately state the
wheel-supported platforms: ai-edge-litert provides Linux and macOS wheels, while
tflite-runtime provides Linux-only manylinux wheels; remove the broader “other
platforms” wording.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 819f53ac-5283-44af-9df5-d75f9194489e
📒 Files selected for processing (1)
_posts/2026-08-19-microwakeword-on-ovos.md
|
|
||
| `hey_mycroft` and the `vad` (voice-activity) model exist only as v2. Everything else is available as both v1 and v2; set `model_version` to choose. | ||
|
|
||
| Beyond the catalogue, any community-trained or custom `.tflite` model is compatible as long as it follows the microWakeWord input signature — `[1, 1, 40]` int8 log-mel features. Point the `model` key at an absolute file path or an `https://` URL and the plugin loads it directly; a model with any other input shape raises `ValueError` at load time rather than misbehaving silently. |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
rg -n -S "get_input_details|get_output_details|quantization|dtype|shape|resource|reset" .Repository: OpenVoiceOS/ovos-blogs
Length of output: 6421
🌐 Web query:
microWakeWord TFLite custom model input output state contract uint8 probability resource variables documentation
💡 Result:
microWakeWord models are specialized TensorFlow Lite (TFLite) models designed for streaming wake word detection on resource-constrained devices, such as those using ESPHome [1][2][3]. ### Model Input and Output Contract To function within the microWakeWord ecosystem, a custom TFLite model must strictly adhere to the following input and output specifications [4]: - Input: The model expects an input tensor with a shape of [1], using INT8 (quantized) data [4]. These 40 features represent a Mel-frequency spectrogram slice generated by the microWakeWord preprocessor [1][4]. - Output: The model returns an output tensor with a shape of [1], using UINT8 data [4]. The value represents the probability of the wake word being present, typically scaled as an integer from 0 to 255 [5][4]. A threshold (e.g., ~200/255) is applied to this raw output to determine detection [4]. ### Streaming and State Management microWakeWord models are stateful, meaning they maintain temporal context across inference windows [4]. Internally, these models utilize TFLite variable tensors (resource variables) to pass state from one inference execution to the next [4]. When training custom models, it is essential to ensure the model architecture supports this streaming behavior—often by converting a non-streaming training model into a streaming-compatible TFLite model that updates based only on the newest spectrogram features [1][3]. ### Integration Requirements A functional custom model requires a corresponding model manifest file (a JSON file) to work with ESPHome [6][7]. This file must include: - micro: An object containing configuration parameters, specifically: - probability_cutoff: The float threshold applied to the UINT8 output [7]. - sliding_window_size: The number of inference steps over which probabilities are averaged [8][7]. - tensor_arena_size: The memory allocation required for the model's tensor arena (in bytes) [7]. Training these models is complex and requires specialized experimentation [1][6]. The standard training workflow involves the microWakeWord repository's notebooks, which guide users through generating a quantized TFLite file compatible with these constraints [6][3]. Standard models from other frameworks (like openWakeWord) are not directly compatible with the microWakeWord component [9].
Citations:
- 1: https://github.com/OHF-Voice/micro-wake-word/blob/main/README.md
- 2: https://esphome.io/components/micro_wake_word/
- 3: https://github.com/kahrendt/microWakeWord/
- 4: https://github.com/VarunChopra11/WakeWord
- 5: https://github.com/OpenVoiceOS/ovos-ww-plugin-microwakeword
- 6: https://github.com/kahrendt/microWakeWord/blob/1c2d8666497543361f9fde059afa5f21b409cf0e/notebooks/basic%5Ftraining%5Fnotebook.ipynb
- 7: https://www.ncnynl.com/docs/en/esphome/components/micro_wake_word.html
- 8: https://deepwiki.com/esphome/home-assistant-voice-pe/3.1-wake-word-detection
- 9: Custom wake word isn't working - wake word component is marked as failed esphome/issues#5743
Document the full custom-model contract.
Matching the [1, 1, 40] int8 input isn’t enough for compatibility; the model also needs the expected wake-word output tensor and streaming/state behavior. Narrow the claim or spell out those requirements instead of saying any matching .tflite works.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@_posts/2026-08-19-microwakeword-on-ovos.md` at line 35, Update the
custom-model compatibility statement near the microWakeWord input-signature
description: do not claim that any `.tflite` with `[1, 1, 40]` int8 input works.
Either narrow the claim or document the complete contract, including the
expected wake-word output tensor and required streaming/state behavior.
| pip install ovos-ww-plugin-microwakeword | ||
| ``` | ||
|
|
||
| The package declares `ai-edge-litert` on Linux x86_64 and `tflite-runtime` on other platforms as the interpreter runtime, alongside `pymicro-features` — a wrapper around the exact same C audio frontend that ESPHome uses for on-device inference. |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
rg -n -S "ai-edge-litert|tflite-runtime|platform_system|platform_machine|sys_platform" .Repository: OpenVoiceOS/ovos-blogs
Length of output: 864
🌐 Web query:
ai-edge-litert PyPI wheel supported platforms tflite-runtime PyPI Linux manylinux supported platforms
💡 Result:
LiteRT (formerly known as TensorFlow Lite) is the official successor to the tflite-runtime library [1][2]. While legacy TensorFlow Lite packages remain functional, LiteRT is the primary runtime for Google's on-device AI moving forward [1]. Regarding platform support: ai-edge-litert: The ai-edge-litert PyPI package provides pre-built wheels for Linux and macOS [3][4]. For Linux specifically, it supports common architectures such as x86_64 and aarch64 [4]. It is intended to serve as the functional replacement for tflite-runtime [4]. tflite-runtime: The tflite-runtime package historically distributed wheels on PyPI that utilized manylinux tags (e.g., manylinux2014, manylinux_2_34) to provide compatibility across various Linux distributions [5][6]. However, users have previously encountered issues where these wheels were not fully compliant with their claimed manylinux tags, leading to installation or compatibility challenges [7]. Migration note: Developers are encouraged to migrate from tflite-runtime to ai-edge-litert to receive future feature updates and performance enhancements [1]. Official documentation for LiteRT now provides guidance for Linux-based devices (such as Raspberry Pi) using the ai-edge-litert package [8].
Citations:
- 1: https://developers.google.com/edge/litert/migration
- 2: https://developers.googleblog.com/en/tensorflow-lite-is-now-litert/
- 3: Could not find a version that satisfies the requirement ai-edge-litert ultralytics/ultralytics#19805
- 4: LiteRT runtime build not working for Linux+Aarch64 google-ai-edge/LiteRT#5
- 5: https://socket.dev/pypi/package/tflite-runtime/versions
- 6: https://github.com/pypa/manylinux?tab=readme-ov-file
- 7: AArch64 tflite_runtime manylinux2014 prebuilt wheels distributed on PYPI are not manylinux2014 compliant tensorflow/tensorflow#60738
- 8: https://developers.google.com/edge/litert/microcontrollers/python
Narrow this to the actual wheel tags. ai-edge-litert ships Linux/macOS wheels, while tflite-runtime is Linux-only manylinux; “other platforms” overstates the supported matrix.
🧰 Tools
🪛 LanguageTool
[style] ~45-~45: ‘exact same’ might be wordy. Consider a shorter alternative.
Context: ...ymicro-features` — a wrapper around the exact same C audio frontend that ESPHome uses for ...
(EN_WORDINESS_PREMIUM_EXACT_SAME)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@_posts/2026-08-19-microwakeword-on-ovos.md` at line 45, Update the package
description to accurately state the wheel-supported platforms: ai-edge-litert
provides Linux and macOS wheels, while tflite-runtime provides Linux-only
manylinux wheels; remove the broader “other platforms” wording.
|
|
||
| Audio arrives as 16 kHz int16 PCM. `pymicro-features` turns each 10 ms frame into a 40-dimensional log-mel feature slice and quantizes it to int8. That slice — shape `[1, 1, 40]` — goes into the TFLite interpreter, which returns a uint8 value the plugin dequantizes into a probability. | ||
|
|
||
| The interesting part is that these are *streaming* models. The recurrent and convolutional state lives inside the graph as TFLite resource variables, so each successive `invoke()` advances the internal state on its own — there is no external state tensor to thread through, and no buffering of a fixed window of audio. Resetting is just `allocate_tensors()`, which clears that state. |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
rg -n -S "allocate_tensors|reset_all_variables|ResetVariableTensors|refractory|state" .Repository: OpenVoiceOS/ovos-blogs
Length of output: 3573
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== file size =="
wc -l _posts/2026-08-19-microwakeword-on-ovos.md
echo
echo "== surrounding lines =="
sed -n '80,110p' _posts/2026-08-19-microwakeword-on-ovos.md | cat -n
echo
echo "== search for relevant API wording in repo =="
rg -n -S "reset_all_variables|ResetVariableTensors|allocate_tensors|streaming models|resource variables" _posts README.md .github . || trueRepository: OpenVoiceOS/ovos-blogs
Length of output: 3721
🌐 Web query:
TensorFlow Lite Interpreter allocate_tensors reset_all_variables resource variables state reset documentation
💡 Result:
In TensorFlow Lite, the Interpreter provides specific methods to manage model memory and state, particularly for stateful operations like LSTMs [1][2]. allocate_tensors This method is required to pre-plan and allocate memory for all tensors in the model before inference can occur [3][4][5]. Because TensorFlow Lite optimizes inference by pre-planning memory, you must call allocate_tensors after creating the interpreter and before invoking it [3][4][5]. You must also call it again if you modify the input tensor sizes (e.g., via resize_tensor_input) [6]. reset_all_variables This method is used to reset all variable tensors to their default values [4][5][7]. If a variable tensor does not have an associated buffer, it is reset to zero [6][7]. This is primarily needed for stateful models (such as those containing LSTM layers), where the internal state (e.g., hidden states or cell states) persists across multiple inferences [1][2]. Calling this function ensures that the model state is cleared, allowing for a fresh start in subsequent inferences [1][2]. Note: The C++ implementation of this functionality is often labeled as ResetVariableTensors [6]. While it is exposed in the Python and Java APIs as reset_all_variables, it has historically been marked as experimental and subject to change [6][8]. Additionally, in specialized environments like TensorFlow Lite Micro, managing state may involve more granular use of Resource Variables (VAR_HANDLE, ASSIGN_RESOURCE, READ_RESOURCE) [9].
Citations:
- 1: Tensorflow lite lstm/bilstm reset variables why needed ? Can we avoid reset variables. tensorflow/tensorflow#47813
- 2: Add reset function into the python wrapper tensorflow/tflite-micro#1389
- 3: https://www.tensorflow.org/api_docs/python/tf/lite/Interpreter
- 4: https://developers.google.com/edge/api/tflite/python/tf/lite/Interpreter
- 5: https://ai.google.dev/edge/api/tflite/python/tf/lite/Interpreter
- 6: https://android.googlesource.com/platform/external/tensorflow/+/e5acacf7284/tensorflow/lite/interpreter.h
- 7: https://developers.google.com/edge/api/tflite/java/org/tensorflow/lite/Interpreter
- 8: https://github.com/tensorflow/tensorflow/blob/7145fc0e49be01ef6943f4df386ce38567e37797/tensorflow/lite/python/interpreter.py
- 9: https://github.com/tensorflow/tflite-micro/blob/main/tensorflow/lite/micro/docs/resource_variables.md
Call out the reset API explicitly.
allocate_tensors() is for tensor allocation; state reset is exposed separately via reset_all_variables() / ResetVariableTensors(). If this model relies on clearing streaming state between sessions, describe that directly instead of attributing it to allocation.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@_posts/2026-08-19-microwakeword-on-ovos.md` at line 99, Update the
streaming-model explanation to state that session state is cleared explicitly
with the interpreter’s reset API, `reset_all_variables()` or
`ResetVariableTensors()`, rather than by `allocate_tensors()`. Describe
`allocate_tensors()` only as tensor allocation and clarify that reset is
required between sessions.
Companion post for ovos-ww-plugin-microwakeword. Code-validated: supported-models table (okay_nabu/hey_jarvis/alexa v1+v2; hey_mycroft/vad v2-only), config keys + defaults, 1x1x40 int8 streaming inference, ai-edge-litert/tflite-runtime deps, real-voice testing caveat, WakeForge cross-link for phrases outside the ESPHome catalogue. No monetary values.
Summary by CodeRabbit