DEV Community

voicute
voicute

Posted on

microWakeWord vs an online generator: custom wake words on the ESP32-S3

microWakeWord vs an online generator: custom wake words on the ESP32-S3

If you want wake-word detection on the device itself — an ESP32-S3, an ESPHome build, a Home Assistant Voice Preview Edition — microWakeWord is the community's answer. It's open source, its preset models are one YAML block away in ESPHome, and its INT8 TFLite models are genuinely tiny.

I run Voicute, an online wake-word generator, so I get asked how it compares. Since microWakeWord keeps coming up alongside openWakeWord as if they were one thing: they're two separate projects by different authors, from the same Home Assistant ecosystem. openWakeWord runs server-side; microWakeWord runs on the microcontroller. This post is only about the microcontroller side.

Where microWakeWord shines

For a supported preset wake word, it's hard to beat:

  • Official ESPHome micro_wake_word component — detection stays on-device, no audio streamed anywhere
  • Preset models already tuned for ESP32-S3-class hardware
  • INT8 TFLite models small enough for flash and RAM budgets on an MCU
  • An active community around Home Assistant Voice

If one of the preset words works for your product, use it. The rest of this post is about the case where it doesn't — your phrase isn't available, and you need a custom model.

What a custom microWakeWord model actually takes

The framework is open and the training docs are good. But "custom" means you assemble the whole data pipeline yourself:

  1. Generate synthetic positives with the Piper sample generator (free, open TTS)
  2. Collect real hard negatives — confusable phrases, TV, music, room noise from the target space
  3. Write the model config (JSON: features, architecture, quantization) by hand
  4. Train, export INT8 TFLite, flash, and evaluate on the actual microphone
  5. Iterate 1–4 until false accepts and recall both land where you need them

None of this is exotic — it's how wake-word models are built. It's just that every step is yours: every retrain cycle costs an afternoon of notebook-plus-desk time, and the quality ceiling is set by your data recipe.

Two recipe details decide most outcomes. First, synthetic positives only cover what TTS can say — Piper's voices have a recognizable character and a narrow accent range, and the gap between "Piper saying your phrase" and "a human saying it at 2 m through a MEMS mic" is where recall usually dies. Second, the negative set is what teaches rejection; generic background noise rarely contains the specific phrases your word actually gets confused with.

What an online generator changes

Again, full disclosure up front: I built Voicute, and its training platform is closed source. The inference engine and exported models are open (github.com/voicute/onnx-wakeword). Here's the honest side-by-side:

microWakeWord Voicute
Code fully open (framework + runtime) training closed; engine + models open
Target ESP32-S3-class MCUs (INT8 TFLite) ONNX + TFLite — MCU, Python, Android, web, HA
Sample TTS Piper (free) commercial neural TTS
Real recordings DIY — record, rebuild dataset, retrain upload in browser, retrain is one click
Hard-negative mining you curate the negative set re-mined automatically on retrain
Config model JSON written by hand none — phrase in, model out
Multi-keyword one model per phrase, stacked 2–10 words in one model (~128 KB, <5 ms)
Languages depends on available Piper voices/models Chinese, English, German, French, Japanese workflows
Time to first model hours–days (Colab ↔ device loop) minutes to a testable model

The three differences that matter in practice:

The record→retrain loop is minutes, not days. When the first model fails on real hardware — and a first model often fails — the microWakeWord path means rebuilding the dataset and running the training notebook again. In Voicute you record a small varied set of the real phrase, upload it, and retrain; hard negatives get re-mined for you. That loop speed is usually the difference between "we evaluated custom wake words" and "we shipped one."

Multi-keyword in one model. ESPHome-style runtimes load one model per phrase, so wake word plus a few commands means several models to train, manifest, and manage. Voicute trains 2–10 keywords into a single model, one inference pass, ~128 KB and under 5 ms on an ESP32-S3 — wake word and commands in the same budget as one standalone wake word.

TTS quality as a starting point. Piper is the right choice for a fully open pipeline; Voicute generates its synthetic positives with paid commercial-grade neural TTS instead. It's still synthetic audio — the synthetic-to-real gap exists for everyone — but starting closer to natural speech means fewer retrain cycles before the model survives a real room and a real accent.

When microWakeWord is still the right call

  • A preset model fits, and you want zero new dependencies — ESPHome makes this a one-block change.
  • The fully open stack (framework, runtime, training) is a hard requirement.
  • Your team already has the data pipeline built and enjoys operating it.

When the generator earns its keep

  • Your phrase isn't available as a preset, and non-English is often exactly this case.
  • You need wake word + commands in one model on the device.
  • The deadline is real and the person doing this is a firmware engineer, not an ML person.
  • You want the first model testable in minutes, then decide whether it needs real recordings.

One thing that doesn't change on either path: the exported model is only half the system. The microphone, gain, enclosure, and feature pipeline decide as much as the weights do — test on the target hardware, measure recall and false accepts per hour, and never trust a single confidence score.


Disclaimer: I'm the creator of Voicute. microWakeWord is a genuinely well-built project and the ESPHome integration is excellent; if I've mischaracterized anything, tell me and I'll correct it.

Top comments (0)