<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: voicute</title>
    <description>The latest articles on DEV Community by voicute (@buguatec).</description>
    <link>https://dev.to/buguatec</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4072257%2F541cd7b4-4417-4970-86b8-58dcfc9cf307.png</url>
      <title>DEV Community: voicute</title>
      <link>https://dev.to/buguatec</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/buguatec"/>
    <language>en</language>
    <item>
      <title>microWakeWord vs an online generator: custom wake words on the ESP32-S3</title>
      <dc:creator>voicute</dc:creator>
      <pubDate>Sat, 31 Oct 2026 04:07:39 +0000</pubDate>
      <link>https://dev.to/buguatec/microwakeword-vs-an-online-generator-custom-wake-words-on-the-esp32-s3-g77</link>
      <guid>https://dev.to/buguatec/microwakeword-vs-an-online-generator-custom-wake-words-on-the-esp32-s3-g77</guid>
      <description>&lt;h1&gt;
  
  
  microWakeWord vs an online generator: custom wake words on the ESP32-S3
&lt;/h1&gt;

&lt;p&gt;If you want wake-word detection &lt;strong&gt;on the device itself&lt;/strong&gt; — 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.&lt;/p&gt;

&lt;p&gt;I run &lt;a href="https://www.voicute.com" rel="noopener noreferrer"&gt;Voicute&lt;/a&gt;, 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.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where microWakeWord shines
&lt;/h2&gt;

&lt;p&gt;For a supported preset wake word, it's hard to beat:&lt;/p&gt;

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

&lt;p&gt;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 — &lt;strong&gt;your phrase isn't available&lt;/strong&gt;, and you need a custom model.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a custom microWakeWord model actually takes
&lt;/h2&gt;

&lt;p&gt;The framework is open and the training docs are good. But "custom" means you assemble the whole data pipeline yourself:&lt;/p&gt;

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

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  What an online generator changes
&lt;/h2&gt;

&lt;p&gt;Again, full disclosure up front: &lt;strong&gt;I built Voicute, and its training platform is closed source.&lt;/strong&gt; The inference engine and exported models are open (&lt;a href="https://github.com/voicute/onnx-wakeword" rel="noopener noreferrer"&gt;github.com/voicute/onnx-wakeword&lt;/a&gt;). Here's the honest side-by-side:&lt;/p&gt;

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

&lt;p&gt;The three differences that matter in practice:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The record→retrain loop is minutes, not days.&lt;/strong&gt; 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."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Multi-keyword in one model.&lt;/strong&gt; 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.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TTS quality as a starting point.&lt;/strong&gt; 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.&lt;/p&gt;

&lt;h2&gt;
  
  
  When microWakeWord is still the right call
&lt;/h2&gt;

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

&lt;h2&gt;
  
  
  When the generator earns its keep
&lt;/h2&gt;

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

&lt;p&gt;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 &lt;em&gt;and&lt;/em&gt; false accepts per hour, and never trust a single confidence score.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Disclaimer: I'm the creator of Voicute.&lt;/strong&gt; 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.&lt;/p&gt;

</description>
      <category>esp32</category>
      <category>esphome</category>
      <category>homeassistant</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>openWakeWord vs an online wake word generator: two paths to a custom model</title>
      <dc:creator>voicute</dc:creator>
      <pubDate>Sat, 31 Oct 2026 03:54:59 +0000</pubDate>
      <link>https://dev.to/buguatec/openwakeword-vs-an-online-wake-word-generator-two-paths-to-a-custom-model-57o6</link>
      <guid>https://dev.to/buguatec/openwakeword-vs-an-online-wake-word-generator-two-paths-to-a-custom-model-57o6</guid>
      <description>&lt;h1&gt;
  
  
  openWakeWord vs an online wake word generator: two paths to a custom model
&lt;/h1&gt;

&lt;p&gt;openWakeWord is the default answer when Home Assistant users want custom wake words, and for good reason: it's free, open source, and ships with a set of official pretrained models. I've used it, and parts of my own product exist because of its limitations.&lt;/p&gt;

&lt;p&gt;Because people ask me to compare it with &lt;a href="https://www.voicute.com" rel="noopener noreferrer"&gt;Voicute&lt;/a&gt; — the online generator I built — here is an honest breakdown: what openWakeWord's training path actually involves, where it struggles, and what a hosted generator changes. (microWakeWord, the ESP32-side cousin of openWakeWord, gets its own post.)&lt;/p&gt;

&lt;h2&gt;
  
  
  First, the right mental model
&lt;/h2&gt;

&lt;p&gt;These are not two versions of the same thing. openWakeWord is a &lt;strong&gt;pipeline you operate&lt;/strong&gt;: open-source training notebooks, open weights, open runtime, and you own every step. Voicute is a &lt;strong&gt;hosted workflow that operates the pipeline for you&lt;/strong&gt; — type a phrase, get a model. The training platform is closed source; the inference engine and the exported models are open.&lt;/p&gt;

&lt;p&gt;If your decision criterion is "must the training code be open?", this comparison is over — pick openWakeWord and be done. The comparison below is for everyone else.&lt;/p&gt;

&lt;h2&gt;
  
  
  What custom training on openWakeWord looks like
&lt;/h2&gt;

&lt;p&gt;For the official pretrained models, openWakeWord is excellent — download, load, done. The story changes when your phrase isn't one of them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Generate synthetic positive samples with the &lt;strong&gt;Piper sample generator&lt;/strong&gt; (free, open TTS)&lt;/li&gt;
&lt;li&gt;Assemble negative datasets: background audio, speech, music&lt;/li&gt;
&lt;li&gt;Run the training notebook (Colab or local Python)&lt;/li&gt;
&lt;li&gt;Export ONNX/tflite, test on the real device, and usually iterate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One structural fact explains most of the pain: the speech embedding backbone is &lt;strong&gt;frozen&lt;/strong&gt;. Custom models are small classifiers on top of a fixed feature space. When your phrase lives in a badly-covered region of that space, no amount of training steps pulls recall up — I've measured swings from roughly &lt;strong&gt;25% to 90% between two words trained with the identical recipe&lt;/strong&gt;. Lowering the threshold to recover recall buys you false wakes.&lt;/p&gt;

&lt;p&gt;Also note the language situation: the official pretrained models are English. The training notebook &lt;em&gt;can&lt;/em&gt; synthesize samples in other languages via Piper voices, but you own the entire validation burden — nobody has tuned that path for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the hosted generator does differently
&lt;/h2&gt;

&lt;p&gt;Same goal, different allocation of work:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;openWakeWord&lt;/th&gt;
&lt;th&gt;Voicute&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Code&lt;/td&gt;
&lt;td&gt;fully open (training + runtime)&lt;/td&gt;
&lt;td&gt;training closed; engine + models open (&lt;a href="https://github.com/voicute/onnx-wakeword" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sample TTS&lt;/td&gt;
&lt;td&gt;Piper (free)&lt;/td&gt;
&lt;td&gt;commercial neural TTS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Architecture&lt;/td&gt;
&lt;td&gt;frozen embedding + small classifier head&lt;/td&gt;
&lt;td&gt;from-scratch TCN per model&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Real recordings&lt;/td&gt;
&lt;td&gt;DIY — record, re-run notebook, repeat&lt;/td&gt;
&lt;td&gt;upload in browser, retrain is one click&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multi-keyword&lt;/td&gt;
&lt;td&gt;one model per word, stacked at runtime&lt;/td&gt;
&lt;td&gt;2–10 words in one model (~128 KB, &amp;lt;5 ms)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Languages&lt;/td&gt;
&lt;td&gt;English pretrained; others DIY&lt;/td&gt;
&lt;td&gt;Chinese, English, German, French, Japanese workflows&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Output&lt;/td&gt;
&lt;td&gt;ONNX / tflite&lt;/td&gt;
&lt;td&gt;ONNX + TFLite, standard formats&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Time to first model&lt;/td&gt;
&lt;td&gt;hours–days, notebook fluency required&lt;/td&gt;
&lt;td&gt;minutes to a testable model&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Three of these deserve a paragraph each.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No frozen embedding.&lt;/strong&gt; Because Voicute trains from scratch per model, the network can shape its feature space around your specific phrase instead of drawing a boundary inside a fixed one. That's the direct answer to the "word-picking" problem above — not magic, just not inheriting someone else's frozen features.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Commercial TTS + real recordings.&lt;/strong&gt; Piper is impressive for a fully open pipeline, but synthetic samples are the only positive evidence an openWakeWord model ever sees, and Piper's prosody/accent range is narrow. Voicute starts from commercial-grade neural TTS — closer to natural speech, fewer retrain cycles — and, more importantly, treats &lt;strong&gt;real recordings as a first-class step&lt;/strong&gt;: when recall disappoints on real hardware, you record a small varied set of the actual phrase, upload it, and retrain. A small varied set beats hundreds of duplicate takes. All of this is possible in openWakeWord's world too; it's just you, scripts, and an afternoon each time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Multi-keyword in one model.&lt;/strong&gt; openWakeWord trains one model per word, and your runtime stacks them. A wake word plus four commands means five models to tune and serve. Voicute trains 2–10 keywords into a single model with one inference pass — ~128 KB and under 5 ms on an ESP32-S3.&lt;/p&gt;

&lt;h2&gt;
  
  
  When openWakeWord is still the right call
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Your phrase is close to an official pretrained model — free, proven, done.&lt;/li&gt;
&lt;li&gt;You need the training pipeline itself open and auditable end to end.&lt;/li&gt;
&lt;li&gt;You're researching, not shipping, and the notebook loop is part of the fun.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  When the generator earns its keep
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The phrase is non-English, or English-but-picky (the 25%-recall kind).&lt;/li&gt;
&lt;li&gt;Recall must be stable without per-device threshold tuning.&lt;/li&gt;
&lt;li&gt;You need wake word + commands in one small model.&lt;/li&gt;
&lt;li&gt;The person doing this is a firmware engineer with a deadline, not an ML hobbyist.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's the whole trade: &lt;strong&gt;open pipeline you operate vs hosted workflow that operates it for you&lt;/strong&gt;, with different TTS, different model architecture, and a real-recording loop measured in minutes. If runtime openness matters to you, note that Voicute's engine and models are on GitHub — measure recall yourself rather than trusting any "90%+" claim, mine included.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Disclaimer: I'm the creator of Voicute.&lt;/strong&gt; openWakeWord is referenced fairly as far as I can — it's a genuinely good project; if I've mischaracterized anything, tell me and I'll correct it..&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>voice</category>
      <category>homeassistant</category>
    </item>
    <item>
      <title>What Is ONNX? Where Can a Custom Wake-Word Model Run?</title>
      <dc:creator>voicute</dc:creator>
      <pubDate>Wed, 28 Oct 2026 11:57:02 +0000</pubDate>
      <link>https://dev.to/buguatec/what-is-onnx-where-can-a-custom-wake-word-model-run-23h1</link>
      <guid>https://dev.to/buguatec/what-is-onnx-where-can-a-custom-wake-word-model-run-23h1</guid>
      <description>&lt;p&gt;ONNX is a portable model format. It helps move a trained wake-word model between compatible inference runtimes, but an ONNX file is not a complete voice assistant and it cannot be installed into every consumer device.&lt;/p&gt;

&lt;h2&gt;
  
  
  ONNX in simple terms
&lt;/h2&gt;

&lt;p&gt;ONNX, or Open Neural Network Exchange, describes a neural network graph, its weights, and its input/output definitions. An inference runtime loads the file and executes the model on a CPU, mobile device, desktop computer, browser, or edge system.&lt;/p&gt;

&lt;p&gt;For a custom wake word, the complete pipeline is usually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Microphone → audio preprocessing → Mel features → ONNX model
           → threshold and false-trigger filtering → application action
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The ONNX file only represents the model. Audio capture, feature extraction, thresholds, consecutive-frame confirmation, cooldowns, and device actions belong to the surrounding application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wake words are not the same as ASR
&lt;/h2&gt;

&lt;p&gt;Keyword spotting (KWS) answers a narrow question: did one of these fixed phrases occur? Automatic speech recognition (ASR) converts open-ended speech into text.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;KWS / wake word&lt;/th&gt;
&lt;th&gt;ASR&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Task&lt;/td&gt;
&lt;td&gt;Detect fixed phrases&lt;/td&gt;
&lt;td&gt;Transcribe speech&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Typical size&lt;/td&gt;
&lt;td&gt;KB to hundreds of KB&lt;/td&gt;
&lt;td&gt;Tens to hundreds of MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Runtime&lt;/td&gt;
&lt;td&gt;Always-on, low latency&lt;/td&gt;
&lt;td&gt;Usually starts after wake-up&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Use cases&lt;/td&gt;
&lt;td&gt;Wake words and fixed commands&lt;/td&gt;
&lt;td&gt;Open-ended dictation and conversation&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If a product only needs a wake word or a small set of commands, KWS can be much smaller, faster, and easier to keep offline than a full ASR system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where can an ONNX wake-word model run?
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;th&gt;Typical runtime&lt;/th&gt;
&lt;th&gt;Practical use&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Android&lt;/td&gt;
&lt;td&gt;ONNX Runtime or TFLite&lt;/td&gt;
&lt;td&gt;Local app listening and offline controls&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Linux / Raspberry Pi&lt;/td&gt;
&lt;td&gt;ONNX Runtime, Python, or C++&lt;/td&gt;
&lt;td&gt;Gateways, robots, desktop devices, and local automation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Windows / macOS&lt;/td&gt;
&lt;td&gt;ONNX Runtime&lt;/td&gt;
&lt;td&gt;Desktop tools and test applications&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Web&lt;/td&gt;
&lt;td&gt;ONNX Runtime Web with WASM/WebGL&lt;/td&gt;
&lt;td&gt;Browser demos and web applications with microphone permission&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;iPhone&lt;/td&gt;
&lt;td&gt;iOS runtime or Core ML integration&lt;/td&gt;
&lt;td&gt;Possible inside an app; it does not replace Siri&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Home Assistant&lt;/td&gt;
&lt;td&gt;Wyoming or an external local service&lt;/td&gt;
&lt;td&gt;A custom wake-word path for your own Home Assistant setup&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  What about ESP32?
&lt;/h3&gt;

&lt;p&gt;ESP32-S3 is an important exception. In practice, you normally do not copy a desktop ONNX file onto the microcontroller and run a full ONNX Runtime. Instead, convert and quantize the model to INT8 TFLite and use TensorFlow Lite Micro or another embedded runtime.&lt;/p&gt;

&lt;p&gt;The accurate statement is that one training result can target multiple deployment formats. Android, Linux, and Web may use ONNX, while ESP32-S3 generally uses an INT8 TFLite version.&lt;/p&gt;

&lt;h2&gt;
  
  
  Can Alexa, Google Home, or Siri use a custom wake word?
&lt;/h2&gt;

&lt;p&gt;Not by installing an ordinary ONNX file. Existing Amazon Echo, Google Home/Nest, and Siri products control their own microphone and wake-word pipeline. A user cannot arbitrarily replace the factory wake word with a custom model.&lt;/p&gt;

&lt;p&gt;The model can run in an Android app, a Raspberry Pi gateway, an ESP32-S3 device, or hardware that you control. That external system can then call Home Assistant, SwitchBot, Nature Remo, or another API.&lt;/p&gt;

&lt;p&gt;Portable inference and permission to modify a consumer product firmware are two different things.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use ONNX as a wake-word model
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Define the wake word or fixed commands and generate an ONNX or TFLite model.&lt;/li&gt;
&lt;li&gt;Choose the target device and audio-capture path.&lt;/li&gt;
&lt;li&gt;Connect the inference runtime and calculate the Mel features expected by the model.&lt;/li&gt;
&lt;li&gt;Add thresholds, consecutive-frame confirmation, cooldowns, and false-trigger protection.&lt;/li&gt;
&lt;li&gt;Start ASR after the wake word, or map the detected label directly to a fixed action.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The open-source &lt;a href="https://github.com/voicute/onnx-wakeword" rel="noopener noreferrer"&gt;onnx-wakeword&lt;/a&gt; project includes examples for Android, Web, Python, desktop, and embedded deployment. Always validate recall and false activations with the final microphone, distance, enclosure, and background noise.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting a custom model
&lt;/h2&gt;

&lt;p&gt;Teams with an ML workflow can prepare positive and negative data, train a KWS model, and export the target formats themselves. For faster product validation, &lt;a href="https://www.voicute.com" rel="noopener noreferrer"&gt;Voicute&lt;/a&gt; lets you enter a keyword, generate a custom model, and download it for local deployment.&lt;/p&gt;

&lt;p&gt;The important distinction is simple: ONNX makes model deployment more portable; it does not make every device installable or every factory wake word customizable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Generate and test a custom wake-word model at &lt;a href="https://www.voicute.com" rel="noopener noreferrer"&gt;Voicute&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>iot</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>Build a Multi-Keyword Offline Voice Controller with ONNX and TFLite</title>
      <dc:creator>voicute</dc:creator>
      <pubDate>Mon, 26 Oct 2026 09:40:12 +0000</pubDate>
      <link>https://dev.to/buguatec/build-a-multi-keyword-offline-voice-controller-with-onnx-and-tflite-5cmc</link>
      <guid>https://dev.to/buguatec/build-a-multi-keyword-offline-voice-controller-with-onnx-and-tflite-5cmc</guid>
      <description>&lt;p&gt;Many voice interfaces do not need to transcribe arbitrary speech. A lamp, robot, appliance, kiosk, or media controller may only need a small vocabulary such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;turn on the light
turn off the light
next
previous
stop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For this kind of product, a multi-keyword model can be a simpler fit than a full cloud ASR pipeline. The model answers a constrained question: which known command, if any, is present in the current audio window?&lt;/p&gt;

&lt;p&gt;This article shows the engineering shape of that system, including model metadata, local inference, command callbacks, and the tests that matter before connecting voice input to a real action.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. KWS is not general speech recognition
&lt;/h2&gt;

&lt;p&gt;Keyword spotting (KWS) detects a known phrase or a small set of known phrases. Automatic speech recognition (ASR) produces a transcript for open-ended speech.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Product requirement&lt;/th&gt;
&lt;th&gt;Suitable first tool&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Start an interaction with one phrase&lt;/td&gt;
&lt;td&gt;Single-keyword KWS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Recognize 2–10 fixed commands&lt;/td&gt;
&lt;td&gt;Multi-keyword KWS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Understand arbitrary sentences&lt;/td&gt;
&lt;td&gt;ASR plus intent parsing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Verify who is speaking&lt;/td&gt;
&lt;td&gt;Speaker verification&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A typical two-stage voice controller looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;always-on wake word
        ↓
short command window
        ↓
multi-keyword model
        ↓
command label
        ↓
safe application action
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The wake word and the command vocabulary are separate concerns. Keeping the command list fixed makes the application behavior easier to test and keeps the system local.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. One model, several command labels
&lt;/h2&gt;

&lt;p&gt;A multi-keyword model exposes a fixed output order. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"model_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"multi_keyword"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"keywords"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"turn on the light"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"turn off the light"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"next"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"stop"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"model_file"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"commands.onnx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mel_time"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;98&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"n_mels"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"cons_frames"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;keywords&lt;/code&gt; array is part of the interface. Its order must stay aligned with the model output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;output[0] → turn on the light
output[1] → turn off the light
output[2] → next
output[3] → stop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The application should map a recognized label to an action instead of embedding business logic inside the model.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. A minimal application callback
&lt;/h2&gt;

&lt;p&gt;The exact API differs between Python, Android, Web, and embedded runtimes, but the application boundary can remain simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;on_keyword&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;probability&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;turn on the light&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;lights&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_power&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;turn off the light&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;lights&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_power&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;next&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stop&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;player&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In a real product, add a cooldown and make repeated events safe. Voice detection should not directly bypass authorization or confirmation for destructive actions such as deleting data, unlocking a door, or purchasing something.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. The local inference pipeline
&lt;/h2&gt;

&lt;p&gt;The model file is only one part of a working detector:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;microphone
   ↓
mono PCM audio
   ↓
sample-rate conversion and framing
   ↓
log-Mel feature extraction
   ↓
ONNX or TFLite inference
   ↓
threshold and consecutive-frame logic
   ↓
command callback
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The runtime preprocessing must match the training and export configuration. A model can appear correct in one demo and lose recall if the target application changes the sample rate, frame shape, Mel settings, or input normalization.&lt;/p&gt;

&lt;p&gt;The open-source &lt;a href="https://github.com/voicute/onnx-wakeword" rel="noopener noreferrer"&gt;&lt;code&gt;onnx-wakeword&lt;/code&gt;&lt;/a&gt; repository contains the local inference examples. The same general model concept can be delivered as ONNX for desktop, Web, Android, and Python integrations, or as TFLite/TFLite Micro for constrained embedded targets.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. ONNX and TFLite are deployment choices
&lt;/h2&gt;

&lt;p&gt;Use the runtime that matches the target platform:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Target&lt;/th&gt;
&lt;th&gt;Typical format or runtime&lt;/th&gt;
&lt;th&gt;Important boundary&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Web&lt;/td&gt;
&lt;td&gt;ONNX Runtime Web&lt;/td&gt;
&lt;td&gt;Browser microphone permission and compatibility still matter&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Android&lt;/td&gt;
&lt;td&gt;ONNX Runtime in the open demo&lt;/td&gt;
&lt;td&gt;The current demo is not an Android TFLite SDK&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Python / desktop&lt;/td&gt;
&lt;td&gt;ONNX Runtime&lt;/td&gt;
&lt;td&gt;Audio device and operating-system setup must be tested&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ESP32-S3&lt;/td&gt;
&lt;td&gt;INT8 TFLite Micro&lt;/td&gt;
&lt;td&gt;The public hardware example is tied to its tested audio board&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;“The model is portable” does not mean that every audio device or board behaves identically. The final microphone, enclosure, operating system, and power budget need their own test.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Testing commands as a group
&lt;/h2&gt;

&lt;p&gt;Testing only one successful utterance per command is not enough. For each command, collect:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;positive examples from multiple speakers;&lt;/li&gt;
&lt;li&gt;different distances, speeds, and volumes;&lt;/li&gt;
&lt;li&gt;similar-sounding phrases;&lt;/li&gt;
&lt;li&gt;ordinary conversation and silence;&lt;/li&gt;
&lt;li&gt;television, music, fans, and device playback;&lt;/li&gt;
&lt;li&gt;the microphone and enclosure intended for the product.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Measure at least:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;recall = detected intended utterances / total intended utterances
false accepts per hour = unwanted activations / hours of negative audio
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also check confusion between commands. A model can have good recall for &lt;code&gt;next&lt;/code&gt; while incorrectly confusing &lt;code&gt;next&lt;/code&gt; with &lt;code&gt;stop&lt;/code&gt; in the same environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. When a second training round is useful
&lt;/h2&gt;

&lt;p&gt;If the baseline model triggers on a recurring sound, keep the false-trigger clips as hard negatives for a later training round:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;base model
   ↓
scan representative negative audio
   ↓
collect false-trigger clips
   ↓
retrain with hard negatives
   ↓
repeat held-out evaluation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do not reuse every clip as training data. Keep a separate held-out set so that the second evaluation still measures generalization.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Generate before you integrate
&lt;/h2&gt;

&lt;p&gt;The practical workflow for a fixed-command product is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Define the wake word and command vocabulary.&lt;/li&gt;
&lt;li&gt;Generate a Basic model for the target language.&lt;/li&gt;
&lt;li&gt;Test the phrases with real voices before downloading.&lt;/li&gt;
&lt;li&gt;Download the ONNX or TFLite artifact and its metadata.&lt;/li&gt;
&lt;li&gt;Integrate the matching local runtime.&lt;/li&gt;
&lt;li&gt;Measure recall, false accepts, latency, memory, and power on the target device.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Voicute supports custom keywords in Chinese, English, Spanish, Japanese, German, French, and Hindi. The online test is a screening step; it is not a production guarantee for every microphone or enclosure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;For a product with a small, known command vocabulary, one multi-keyword model can be cleaner than one detector per command or a full ASR service. The model recognizes the vocabulary; the application owns the action policy; the final device test decides whether the result is ready to ship.&lt;/p&gt;

&lt;p&gt;The open inference examples are available in &lt;a href="https://github.com/voicute/onnx-wakeword" rel="noopener noreferrer"&gt;&lt;code&gt;voicute/onnx-wakeword&lt;/code&gt;&lt;/a&gt;. You can generate and test your own fixed command vocabulary at &lt;a href="https://www.voicute.com/" rel="noopener noreferrer"&gt;Voicute&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Disclosure: I am the creator of Voicute. The model-generation service is commercial, while the local inference examples are open source. Results depend on the language, speakers, microphone, environment, and runtime configuration.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>iot</category>
      <category>machinelearning</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>How to Get a Wake-Word Model in 2026</title>
      <dc:creator>voicute</dc:creator>
      <pubDate>Fri, 23 Oct 2026 09:49:54 +0000</pubDate>
      <link>https://dev.to/buguatec/how-to-get-a-wake-word-model-in-2026-3amo</link>
      <guid>https://dev.to/buguatec/how-to-get-a-wake-word-model-in-2026-3amo</guid>
      <description>&lt;p&gt;Adding a wake word to a product sounds simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;microphone → wake-word model → application action
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The difficult part begins when the phrase is not one of the pre-trained examples, the language is not English, the microphone is inside a real product, or the model starts triggering on television and normal conversation.&lt;/p&gt;

&lt;p&gt;In 2026, there are two practical ways to obtain a custom wake-word model:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Train an open-source pipeline such as &lt;a href="https://github.com/dscripka/openWakeWord" rel="noopener noreferrer"&gt;openWakeWord&lt;/a&gt; yourself.&lt;/li&gt;
&lt;li&gt;Use an online or hosted training platform and download the resulting model.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Both approaches can work. The right choice depends on whether your priority is training control or getting to a deployable experiment quickly.&lt;/p&gt;

&lt;p&gt;This guide explains both paths and the validation steps that should happen before a model is used in a real device.&lt;/p&gt;

&lt;h2&gt;
  
  
  First: do you need a wake-word model?
&lt;/h2&gt;

&lt;p&gt;A wake-word model is a small keyword-spotting model. It answers a narrow question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Is the target phrase present in this short audio window?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It does not transcribe arbitrary speech and it does not understand open-ended requests.&lt;/p&gt;

&lt;p&gt;Use a wake-word or keyword-spotting model when the application needs phrases such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Hey device
Open the door
Turn on the light
Start recording
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use ASR and intent parsing when the user can say anything, for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Set the living-room light to 37 percent and turn it off after ten minutes.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A common product architecture is therefore:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Always-on wake word
          ↓
Short command window
          ↓
Fixed-command KWS or ASR
          ↓
Application action
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keeping these stages separate can reduce compute, latency, network dependency, and accidental microphone uploads.&lt;/p&gt;

&lt;h2&gt;
  
  
  One model can recognize multiple keywords
&lt;/h2&gt;

&lt;p&gt;The same workflow is useful when the product needs a fixed command set, not only one wake word. Instead of running one model for every command, you can train a multi-keyword model that returns a label for each phrase:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Turn on the light  → LIGHT_ON
Turn off the light → LIGHT_OFF
Pause              → PAUSE
Resume             → RESUME
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is still keyword spotting, not open-ended speech recognition. The vocabulary is defined before training, and the application maps the returned label to an action. A single multi-keyword model can simplify model packaging, feature extraction, threshold management, and updates.&lt;/p&gt;

&lt;p&gt;Each keyword still needs separate evaluation. Similar pronunciations may have different recall and false-trigger behavior, so one good result must not be used as a proxy for every class in the model.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does a custom wake-word model contain?
&lt;/h2&gt;

&lt;p&gt;The model file is only one part of the system. A working detector also needs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Microphone capture&lt;/li&gt;
&lt;li&gt;Sample-rate conversion&lt;/li&gt;
&lt;li&gt;Audio framing&lt;/li&gt;
&lt;li&gt;Feature extraction, often log-Mel features&lt;/li&gt;
&lt;li&gt;Model inference&lt;/li&gt;
&lt;li&gt;A detection threshold&lt;/li&gt;
&lt;li&gt;Cooldown and repeated-trigger logic&lt;/li&gt;
&lt;li&gt;Application callbacks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The same model can behave differently if the audio preprocessing changes. Before comparing training platforms, write down the target runtime requirements:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;th&gt;Example question&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Sample rate&lt;/td&gt;
&lt;td&gt;Does the runtime expect 16 kHz audio?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Input format&lt;/td&gt;
&lt;td&gt;Mono PCM, float32, or int16?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Model format&lt;/td&gt;
&lt;td&gt;ONNX, TFLite, or TFLite Micro?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Target device&lt;/td&gt;
&lt;td&gt;Browser, Android, Linux, ESP32-S3, or Raspberry Pi?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Trigger policy&lt;/td&gt;
&lt;td&gt;How many consecutive frames are required?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Evaluation&lt;/td&gt;
&lt;td&gt;Will you measure recall and false accepts per hour?&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This prevents a common mistake: training one model and then discovering that the deployment runtime expects a different feature pipeline.&lt;/p&gt;

&lt;h2&gt;
  
  
  Path 1: train openWakeWord yourself
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/dscripka/openWakeWord" rel="noopener noreferrer"&gt;openWakeWord&lt;/a&gt; is an open-source wake-word library with pre-trained models and tools for custom model training. Its documentation includes an automated training utility and a Google Colab workflow.&lt;/p&gt;

&lt;p&gt;The self-managed route gives you the most control. You can inspect the data, change the training process, run multiple experiments, and keep the pipeline inside your own infrastructure.&lt;/p&gt;

&lt;p&gt;It also means that you are responsible for the complete process.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: choose a phrase that can be detected
&lt;/h3&gt;

&lt;p&gt;Good wake words are distinctive and easy to pronounce. Avoid phrases that occur frequently in normal conversation or that are too close to common words.&lt;/p&gt;

&lt;p&gt;Test several candidate phrases before training a production model. A phrase that looks unique in text may be difficult to distinguish acoustically.&lt;/p&gt;

&lt;p&gt;For a multilingual product, test the phrase with native speakers. Pronunciation, tone, syllable boundaries, and speaking speed can change the difficulty significantly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: generate positive examples
&lt;/h3&gt;

&lt;p&gt;The positive examples contain the target phrase. A training pipeline may use synthetic speech, real recordings, or a mixture of both.&lt;/p&gt;

&lt;p&gt;Synthetic data is useful for quickly covering multiple voices and speaking styles. Real recordings are useful when the final users have a particular accent, microphone, speaking distance, or pronunciation pattern.&lt;/p&gt;

&lt;p&gt;At minimum, vary:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Speaker identity&lt;/li&gt;
&lt;li&gt;Speaking speed&lt;/li&gt;
&lt;li&gt;Volume&lt;/li&gt;
&lt;li&gt;Pronunciation&lt;/li&gt;
&lt;li&gt;Background noise&lt;/li&gt;
&lt;li&gt;Distance from the microphone&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Do not put every recording into one large training set without a separate test set. You need held-out examples to measure whether the model generalizes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: prepare negative audio
&lt;/h3&gt;

&lt;p&gt;Negative audio does not contain the target phrase. It should represent what the device will hear when it must remain silent:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Normal conversations&lt;/li&gt;
&lt;li&gt;Music&lt;/li&gt;
&lt;li&gt;Television&lt;/li&gt;
&lt;li&gt;Fans and appliances&lt;/li&gt;
&lt;li&gt;Similar-sounding words&lt;/li&gt;
&lt;li&gt;Silence and room noise&lt;/li&gt;
&lt;li&gt;Speech from different speakers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;False triggers are often caused by the negative data being too easy. A model that only sees clean speech and clean noise during training may fail in a living room, office, vehicle, or factory.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: run the official training workflow
&lt;/h3&gt;

&lt;p&gt;The openWakeWord repository provides training documentation and notebooks. Start with the automated workflow if you are learning the process, then move to a more controlled pipeline when you need production-level evaluation.&lt;/p&gt;

&lt;p&gt;Keep a record of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Repository commit or release version&lt;/li&gt;
&lt;li&gt;Training configuration&lt;/li&gt;
&lt;li&gt;Synthetic voice sources&lt;/li&gt;
&lt;li&gt;Positive and negative dataset versions&lt;/li&gt;
&lt;li&gt;Number of training steps&lt;/li&gt;
&lt;li&gt;Exported model format&lt;/li&gt;
&lt;li&gt;Threshold used during evaluation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without these details, it becomes difficult to reproduce a model or understand why a second training run behaves differently.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: evaluate the model before deployment
&lt;/h3&gt;

&lt;p&gt;Do not judge a model only by whether it triggers when you say the phrase once.&lt;/p&gt;

&lt;p&gt;Measure recall:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;recall = detected intended activations / total intended activations
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Measure false accepts per hour:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;false accepts per hour = unwanted activations / hours of negative audio
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run both tests with the final microphone if possible. A model can perform well on a laptop recording and poorly on a small embedded microphone.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why self-training can take longer than expected
&lt;/h2&gt;

&lt;p&gt;The first training run is usually not the end. Common problems include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The phrase is acoustically difficult.&lt;/li&gt;
&lt;li&gt;The synthetic voices do not match real speakers.&lt;/li&gt;
&lt;li&gt;The negative audio is too clean.&lt;/li&gt;
&lt;li&gt;The threshold is too low.&lt;/li&gt;
&lt;li&gt;The feature-extraction pipeline is different at runtime.&lt;/li&gt;
&lt;li&gt;The enclosure or microphone adds noise.&lt;/li&gt;
&lt;li&gt;The phrase is confused with a common word.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The usual improvement loop is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Train R0
   ↓
Test on real audio
   ↓
Collect false triggers and missed examples
   ↓
Add difficult examples
   ↓
Train R1
   ↓
Test again
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is why “I trained a model” and “I have a reliable product detector” are different milestones.&lt;/p&gt;

&lt;h2&gt;
  
  
  Path 2: use an online training platform
&lt;/h2&gt;

&lt;p&gt;The online route is useful when you want to validate a phrase without first building a machine-learning environment.&lt;/p&gt;

&lt;p&gt;The typical workflow is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Enter a wake word
      ↓
Choose a language or voice configuration
      ↓
Generate and train the model online
      ↓
Test it with a browser microphone
      ↓
Download the model
      ↓
Validate it on the target device
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This does not eliminate testing. It moves the training infrastructure out of your local machine.&lt;/p&gt;

&lt;h3&gt;
  
  
  What to check before choosing a platform
&lt;/h3&gt;

&lt;p&gt;Do not compare online platforms only by their landing pages. Check:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Supported languages and pronunciations.&lt;/li&gt;
&lt;li&gt;Whether the output is ONNX, TFLite, TFLite Micro, or proprietary.&lt;/li&gt;
&lt;li&gt;Whether the model can run without an API key or network connection.&lt;/li&gt;
&lt;li&gt;Whether commercial redistribution is allowed.&lt;/li&gt;
&lt;li&gt;Whether you can test with your own microphone before downloading.&lt;/li&gt;
&lt;li&gt;Whether real recordings or hard negatives can be used later.&lt;/li&gt;
&lt;li&gt;Whether the runtime includes the required preprocessing.&lt;/li&gt;
&lt;li&gt;Whether the model size fits the target hardware.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For ESP32 and ESPHome projects, &lt;a href="https://microwakeword.com/" rel="noopener noreferrer"&gt;microWakeWord&lt;/a&gt; is an example of a hosted workflow focused on small embedded models. Its API documentation describes INT8 TFLite model delivery and ESPHome integration.&lt;/p&gt;

&lt;p&gt;For a hosted openWakeWord-oriented workflow, &lt;a href="https://openwakeword.com/" rel="noopener noreferrer"&gt;openwakeword.com&lt;/a&gt; provides an online training experience built around the openWakeWord ecosystem. Verify its current model export and license terms before using a generated model commercially.&lt;/p&gt;

&lt;p&gt;For a multi-platform workflow, &lt;a href="https://www.voicute.com" rel="noopener noreferrer"&gt;Voicute&lt;/a&gt; provides online custom wake-word and keyword-spotting model generation, browser testing, and ONNX/TFLite-oriented deployment paths. The &lt;a href="https://github.com/voicute/onnx-wakeword" rel="noopener noreferrer"&gt;onnx-wakeword repository&lt;/a&gt; provides open inference examples.&lt;/p&gt;

&lt;p&gt;Voicute also supports multi-keyword models and multilingual training. The current language set is &lt;strong&gt;English, Chinese, Spanish, Japanese, German, French, and Hindi&lt;/strong&gt;. This matters for products that need the same fixed-command architecture across markets instead of building a separate training workflow for every language.&lt;/p&gt;

&lt;p&gt;When synthetic or baseline training is not enough for a specific accent, brand pronunciation, or microphone, the workflow can be extended with authorized real recordings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Base model → upload representative recordings → enhancement training → held-out evaluation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Recordings should cover the target speakers, distance, volume, pronunciation, and acoustic environment. They should not be copied into the evaluation set. Real-voice enhancement can improve the match to a product's users, but it does not remove the need to test the final microphone and background noise.&lt;/p&gt;

&lt;p&gt;These services have different goals. A platform optimized for ESP32-S3 is not automatically the best choice for Android or browser deployment. A platform with a simple web form is not automatically the best choice for a regulated or commercial product.&lt;/p&gt;

&lt;h2&gt;
  
  
  A simple decision guide
&lt;/h2&gt;

&lt;p&gt;Choose self-managed openWakeWord when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You have Python and machine-learning experience.&lt;/li&gt;
&lt;li&gt;You need to inspect or customize the training pipeline.&lt;/li&gt;
&lt;li&gt;You can manage datasets and evaluation.&lt;/li&gt;
&lt;li&gt;You want to control the infrastructure and model generation process.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Choose an online platform when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You need to test a phrase quickly.&lt;/li&gt;
&lt;li&gt;You do not want to install a GPU training environment.&lt;/li&gt;
&lt;li&gt;You need a guided train-and-download workflow.&lt;/li&gt;
&lt;li&gt;You are willing to validate the output independently.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Choose an ecosystem-specific platform when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your target is already fixed, such as ESP32-S3 and ESPHome.&lt;/li&gt;
&lt;li&gt;The platform's model format and license match your product.&lt;/li&gt;
&lt;li&gt;You prefer an integrated device workflow over general portability.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Deploy the model locally
&lt;/h2&gt;

&lt;p&gt;After obtaining a model, keep the runtime local during inference whenever possible:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Microphone
   ↓
Audio preprocessing
   ↓
Wake-word inference
   ↓
Threshold and cooldown logic
   ↓
Local application callback
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exported model can be integrated through standard ONNX/TFLite runtimes on &lt;strong&gt;ESP32, Raspberry Pi, Android, Web, Windows, macOS, Linux, and Home Assistant&lt;/strong&gt;. Constrained ESP32 devices commonly use INT8 TFLite/TFLite Micro, while desktop, browser, mobile, Linux, and Raspberry Pi applications can use an ONNX or TFLite runtime. Home Assistant can connect through a local Wyoming-oriented integration.&lt;/p&gt;

&lt;p&gt;Before shipping, verify:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The sample rate is correct.&lt;/li&gt;
&lt;li&gt;The audio channel layout is correct.&lt;/li&gt;
&lt;li&gt;The feature extractor matches the training pipeline.&lt;/li&gt;
&lt;li&gt;The output label is mapped correctly.&lt;/li&gt;
&lt;li&gt;The threshold is tested with positive and negative audio.&lt;/li&gt;
&lt;li&gt;Repeated detections are suppressed.&lt;/li&gt;
&lt;li&gt;The application does not perform unsafe actions on a single noisy frame.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;An ONNX model can be convenient for Python, desktop, Android, and browser runtimes with compatible ONNX Runtime support. TFLite or TFLite Micro is often more suitable for constrained embedded hardware. The model format should be chosen together with the target runtime, not after training is complete.&lt;/p&gt;

&lt;h2&gt;
  
  
  A reproducible test plan
&lt;/h2&gt;

&lt;p&gt;Use a small but repeatable test plan for every training route:&lt;/p&gt;

&lt;h3&gt;
  
  
  Positive test set
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;At least several speakers&lt;/li&gt;
&lt;li&gt;Multiple distances&lt;/li&gt;
&lt;li&gt;Quiet and noisy rooms&lt;/li&gt;
&lt;li&gt;Different speaking speeds&lt;/li&gt;
&lt;li&gt;The final microphone&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Negative test set
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Normal conversation&lt;/li&gt;
&lt;li&gt;Music and television&lt;/li&gt;
&lt;li&gt;Similar-sounding phrases&lt;/li&gt;
&lt;li&gt;Background appliances&lt;/li&gt;
&lt;li&gt;Long periods of room audio&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Report these numbers
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Recall percentage&lt;/li&gt;
&lt;li&gt;False accepts per hour&lt;/li&gt;
&lt;li&gt;Model size&lt;/li&gt;
&lt;li&gt;RAM and flash usage&lt;/li&gt;
&lt;li&gt;Average inference latency&lt;/li&gt;
&lt;li&gt;Runtime and operating system&lt;/li&gt;
&lt;li&gt;Threshold and cooldown settings&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the test conditions are not recorded, the results are difficult to compare. “It worked on my laptop” is a useful first observation, not a benchmark.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;There is no single correct way to obtain a wake-word model in 2026.&lt;/p&gt;

&lt;p&gt;Self-training openWakeWord gives you control and teaches you how the pipeline works. An online platform reduces setup time and is often the fastest way to validate a phrase. An ecosystem-specific service can be the most practical option when the hardware and runtime are already fixed.&lt;/p&gt;

&lt;p&gt;The safest workflow is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Choose the phrase
   → choose self-training or hosted training
   → generate the model
   → measure recall and false accepts
   → test the final microphone
   → deploy locally
   → repeat with hard negatives when necessary
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important result is not merely a downloaded model file. It is a model whose behavior is measured on the device and in the environment where it will actually be used.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Disclosure: I am the creator of Voicute. Voicute is mentioned as one online option in this guide. The comparison is not an independent third-party benchmark, and the performance of any wake-word model depends on the phrase, language, training data, threshold, microphone, and deployment environment.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>opensource</category>
    </item>
    <item>
      <title>I Turned a Product Name into an Offline Wake Word — What I Had to Test</title>
      <dc:creator>voicute</dc:creator>
      <pubDate>Wed, 21 Oct 2026 23:53:20 +0000</pubDate>
      <link>https://dev.to/buguatec/i-turned-a-product-name-into-an-offline-wake-word-what-i-had-to-test-46of</link>
      <guid>https://dev.to/buguatec/i-turned-a-product-name-into-an-offline-wake-word-what-i-had-to-test-46of</guid>
      <description>&lt;p&gt;Most smart products already have a name. The hard part is making the device hear that name reliably without sending every conversation to the cloud.&lt;/p&gt;

&lt;p&gt;This is the product question behind a custom wake word: can a device recognize one short phrase locally, then start the next interaction?&lt;/p&gt;

&lt;h2&gt;
  
  
  The product name and the wake word are different things
&lt;/h2&gt;

&lt;p&gt;A brand name is designed for people. A wake word is designed for a detector. The same phrase can be a good brand name and a poor wake word if it is too short, too common, or easily confused with normal conversation.&lt;/p&gt;

&lt;p&gt;For an example product, imagine a small robot called “Taro”. The desired flow is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;“Hey Taro”       → wake the robot
“Move forward”   → start a fixed action
“Stop”           → stop the motor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The wake phrase and the fixed commands are not the same product requirement.&lt;/p&gt;

&lt;h2&gt;
  
  
  KWS or ASR?
&lt;/h2&gt;

&lt;p&gt;If the product needs to understand arbitrary sentences, names, numbers, or parameters, it needs speech recognition and intent handling. But if it only needs one wake phrase or a small list of commands, keyword spotting is a more focused option.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Requirement&lt;/th&gt;
&lt;th&gt;First option&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Wake an assistant&lt;/td&gt;
&lt;td&gt;Single-keyword KWS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Detect 2–10 fixed commands&lt;/td&gt;
&lt;td&gt;Multi-keyword KWS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Understand open speech&lt;/td&gt;
&lt;td&gt;ASR plus intent parsing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Verify the speaker&lt;/td&gt;
&lt;td&gt;Speaker verification&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;KWS does not try to transcribe everything. It asks a narrower question: “did one of the target phrases occur?” That makes a small, local model possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I would test before choosing the name
&lt;/h2&gt;

&lt;p&gt;I would not approve a wake word from the spelling alone. I would test:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Several speakers saying the phrase naturally.&lt;/li&gt;
&lt;li&gt;Different speaking speeds and distances.&lt;/li&gt;
&lt;li&gt;The target microphone and enclosure.&lt;/li&gt;
&lt;li&gt;Background conversation, music, fans, and household noise.&lt;/li&gt;
&lt;li&gt;Similar-sounding phrases that should not trigger the product.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The browser is a useful first filter. It can tell us whether a phrase is worth taking to a device. It cannot prove that the same result will hold after the microphone, enclosure, distance, and noise environment change.&lt;/p&gt;

&lt;h2&gt;
  
  
  The delivery path
&lt;/h2&gt;

&lt;p&gt;The practical flow is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Product name
    ↓
Train a custom keyword model
    ↓
Test with real voices
    ↓
Export ONNX or TFLite
    ↓
Run locally on the target product
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a product team, the useful deliverable is not only a model file. The team also needs the audio input assumptions, feature extraction path, threshold behavior, cooldown logic, and a way to connect a detection callback to a safe product action.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where a small custom model fits
&lt;/h2&gt;

&lt;p&gt;For my experiments, I wanted a model that could run offline and fit several possible targets: Python, Web, Android, and embedded hardware. A standard ONNX or TFLite artifact makes that transition easier than a platform-locked runtime.&lt;/p&gt;

&lt;p&gt;Voicute is one way to start this process without building the training pipeline first: enter the product name, train a Basic model, test it with real voices, and decide whether the result is good enough to download. Real-voice enhancement can help when the target users have a specific accent or speaking style.&lt;/p&gt;

&lt;p&gt;The honest boundary is important: online testing is a screening step, not a production guarantee. The final product still needs measurements for recall, false triggers per hour, latency, memory and power.&lt;/p&gt;

&lt;h2&gt;
  
  
  A minimal local integration example
&lt;/h2&gt;

&lt;p&gt;The runtime should expose a simple event to the application layer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;on_keyword&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;probability&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hey_taro&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;robot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start_interaction&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stop&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;robot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The application should also implement cooldowns and safe failure behavior. A detector should not repeatedly start an action because the same phrase remains in the audio buffer.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I would ship with the project
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The ONNX or TFLite model;&lt;/li&gt;
&lt;li&gt;A reproducible inference example;&lt;/li&gt;
&lt;li&gt;The supported sample rate and audio format;&lt;/li&gt;
&lt;li&gt;Threshold and cooldown defaults;&lt;/li&gt;
&lt;li&gt;A test checklist for the final microphone and enclosure;&lt;/li&gt;
&lt;li&gt;Clear limitations instead of a universal accuracy claim.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The open-source runtime and examples are available in &lt;a href="https://github.com/voicute/onnx-wakeword" rel="noopener noreferrer"&gt;onnx-wakeword&lt;/a&gt;. If you want to test your own product name, use the &lt;a href="https://www.voicute.com/" rel="noopener noreferrer"&gt;Voicute online training page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Disclosure: Voicute is my project. I am sharing the engineering process and its limitations, not claiming that one wake-word model is best for every language or device.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>iot</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>How to Get a Wake-Word Model in 2026: Train openWakeWord Yourself or Use an Online Platform</title>
      <dc:creator>voicute</dc:creator>
      <pubDate>Wed, 21 Oct 2026 03:39:57 +0000</pubDate>
      <link>https://dev.to/buguatec/how-to-get-a-wake-word-model-in-2026-train-openwakeword-yourself-or-use-an-online-platform-11oi</link>
      <guid>https://dev.to/buguatec/how-to-get-a-wake-word-model-in-2026-train-openwakeword-yourself-or-use-an-online-platform-11oi</guid>
      <description>&lt;p&gt;Adding a wake word to a product sounds simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;microphone → wake-word model → application action
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The difficult part begins when the phrase is not one of the pre-trained examples, the language is not English, the microphone is inside a real product, or the model starts triggering on television and normal conversation.&lt;/p&gt;

&lt;p&gt;In 2026, there are two practical ways to obtain a custom wake-word model:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Train an open-source pipeline such as &lt;a href="https://github.com/dscripka/openWakeWord" rel="noopener noreferrer"&gt;openWakeWord&lt;/a&gt; yourself.&lt;/li&gt;
&lt;li&gt;Use an online or hosted training platform and download the resulting model.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Both approaches can work. The right choice depends on whether your priority is training control or getting to a deployable experiment quickly.&lt;/p&gt;

&lt;p&gt;This guide explains both paths and the validation steps that should happen before a model is used in a real device.&lt;/p&gt;

&lt;h2&gt;
  
  
  First: do you need a wake-word model?
&lt;/h2&gt;

&lt;p&gt;A wake-word model is a small keyword-spotting model. It answers a narrow question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Is the target phrase present in this short audio window?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It does not transcribe arbitrary speech and it does not understand open-ended requests.&lt;/p&gt;

&lt;p&gt;Use a wake-word or keyword-spotting model when the application needs phrases such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Hey device
Open the door
Turn on the light
Start recording
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use ASR and intent parsing when the user can say anything, for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Set the living-room light to 37 percent and turn it off after ten minutes.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A common product architecture is therefore:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Always-on wake word
          ↓
Short command window
          ↓
Fixed-command KWS or ASR
          ↓
Application action
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keeping these stages separate can reduce compute, latency, network dependency, and accidental microphone uploads.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does a custom wake-word model contain?
&lt;/h2&gt;

&lt;p&gt;The model file is only one part of the system. A working detector also needs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Microphone capture&lt;/li&gt;
&lt;li&gt;Sample-rate conversion&lt;/li&gt;
&lt;li&gt;Audio framing&lt;/li&gt;
&lt;li&gt;Feature extraction, often log-Mel features&lt;/li&gt;
&lt;li&gt;Model inference&lt;/li&gt;
&lt;li&gt;A detection threshold&lt;/li&gt;
&lt;li&gt;Cooldown and repeated-trigger logic&lt;/li&gt;
&lt;li&gt;Application callbacks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The same model can behave differently if the audio preprocessing changes. Before comparing training platforms, write down the target runtime requirements:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;th&gt;Example question&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Sample rate&lt;/td&gt;
&lt;td&gt;Does the runtime expect 16 kHz audio?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Input format&lt;/td&gt;
&lt;td&gt;Mono PCM, float32, or int16?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Model format&lt;/td&gt;
&lt;td&gt;ONNX, TFLite, or TFLite Micro?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Target device&lt;/td&gt;
&lt;td&gt;Browser, Android, Linux, ESP32-S3, or Raspberry Pi?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Trigger policy&lt;/td&gt;
&lt;td&gt;How many consecutive frames are required?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Evaluation&lt;/td&gt;
&lt;td&gt;Will you measure recall and false accepts per hour?&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This prevents a common mistake: training one model and then discovering that the deployment runtime expects a different feature pipeline.&lt;/p&gt;

&lt;h2&gt;
  
  
  Path 1: train openWakeWord yourself
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/dscripka/openWakeWord" rel="noopener noreferrer"&gt;openWakeWord&lt;/a&gt; is an open-source wake-word library with pre-trained models and tools for custom model training. Its documentation includes an automated training utility and a Google Colab workflow.&lt;/p&gt;

&lt;p&gt;The self-managed route gives you the most control. You can inspect the data, change the training process, run multiple experiments, and keep the pipeline inside your own infrastructure.&lt;/p&gt;

&lt;p&gt;It also means that you are responsible for the complete process.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: choose a phrase that can be detected
&lt;/h3&gt;

&lt;p&gt;Good wake words are distinctive and easy to pronounce. Avoid phrases that occur frequently in normal conversation or that are too close to common words.&lt;/p&gt;

&lt;p&gt;Test several candidate phrases before training a production model. A phrase that looks unique in text may be difficult to distinguish acoustically.&lt;/p&gt;

&lt;p&gt;For a multilingual product, test the phrase with native speakers. Pronunciation, tone, syllable boundaries, and speaking speed can change the difficulty significantly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: generate positive examples
&lt;/h3&gt;

&lt;p&gt;The positive examples contain the target phrase. A training pipeline may use synthetic speech, real recordings, or a mixture of both.&lt;/p&gt;

&lt;p&gt;Synthetic data is useful for quickly covering multiple voices and speaking styles. Real recordings are useful when the final users have a particular accent, microphone, speaking distance, or pronunciation pattern.&lt;/p&gt;

&lt;p&gt;At minimum, vary:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Speaker identity&lt;/li&gt;
&lt;li&gt;Speaking speed&lt;/li&gt;
&lt;li&gt;Volume&lt;/li&gt;
&lt;li&gt;Pronunciation&lt;/li&gt;
&lt;li&gt;Background noise&lt;/li&gt;
&lt;li&gt;Distance from the microphone&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Do not put every recording into one large training set without a separate test set. You need held-out examples to measure whether the model generalizes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: prepare negative audio
&lt;/h3&gt;

&lt;p&gt;Negative audio does not contain the target phrase. It should represent what the device will hear when it must remain silent:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Normal conversations&lt;/li&gt;
&lt;li&gt;Music&lt;/li&gt;
&lt;li&gt;Television&lt;/li&gt;
&lt;li&gt;Fans and appliances&lt;/li&gt;
&lt;li&gt;Similar-sounding words&lt;/li&gt;
&lt;li&gt;Silence and room noise&lt;/li&gt;
&lt;li&gt;Speech from different speakers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;False triggers are often caused by the negative data being too easy. A model that only sees clean speech and clean noise during training may fail in a living room, office, vehicle, or factory.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: run the official training workflow
&lt;/h3&gt;

&lt;p&gt;The openWakeWord repository provides training documentation and notebooks. Start with the automated workflow if you are learning the process, then move to a more controlled pipeline when you need production-level evaluation.&lt;/p&gt;

&lt;p&gt;Keep a record of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Repository commit or release version&lt;/li&gt;
&lt;li&gt;Training configuration&lt;/li&gt;
&lt;li&gt;Synthetic voice sources&lt;/li&gt;
&lt;li&gt;Positive and negative dataset versions&lt;/li&gt;
&lt;li&gt;Number of training steps&lt;/li&gt;
&lt;li&gt;Exported model format&lt;/li&gt;
&lt;li&gt;Threshold used during evaluation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without these details, it becomes difficult to reproduce a model or understand why a second training run behaves differently.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: evaluate the model before deployment
&lt;/h3&gt;

&lt;p&gt;Do not judge a model only by whether it triggers when you say the phrase once.&lt;/p&gt;

&lt;p&gt;Measure recall:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;recall = detected intended activations / total intended activations
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Measure false accepts per hour:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;false accepts per hour = unwanted activations / hours of negative audio
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run both tests with the final microphone if possible. A model can perform well on a laptop recording and poorly on a small embedded microphone.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why self-training can take longer than expected
&lt;/h2&gt;

&lt;p&gt;The first training run is usually not the end. Common problems include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The phrase is acoustically difficult.&lt;/li&gt;
&lt;li&gt;The synthetic voices do not match real speakers.&lt;/li&gt;
&lt;li&gt;The negative audio is too clean.&lt;/li&gt;
&lt;li&gt;The threshold is too low.&lt;/li&gt;
&lt;li&gt;The feature-extraction pipeline is different at runtime.&lt;/li&gt;
&lt;li&gt;The enclosure or microphone adds noise.&lt;/li&gt;
&lt;li&gt;The phrase is confused with a common word.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The usual improvement loop is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Train R0
   ↓
Test on real audio
   ↓
Collect false triggers and missed examples
   ↓
Add difficult examples
   ↓
Train R1
   ↓
Test again
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is why “I trained a model” and “I have a reliable product detector” are different milestones.&lt;/p&gt;

&lt;h2&gt;
  
  
  Path 2: use an online training platform
&lt;/h2&gt;

&lt;p&gt;The online route is useful when you want to validate a phrase without first building a machine-learning environment.&lt;/p&gt;

&lt;p&gt;The typical workflow is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Enter a wake word
      ↓
Choose a language or voice configuration
      ↓
Generate and train the model online
      ↓
Test it with a browser microphone
      ↓
Download the model
      ↓
Validate it on the target device
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This does not eliminate testing. It moves the training infrastructure out of your local machine.&lt;/p&gt;

&lt;h3&gt;
  
  
  What to check before choosing a platform
&lt;/h3&gt;

&lt;p&gt;Do not compare online platforms only by their landing pages. Check:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Supported languages and pronunciations.&lt;/li&gt;
&lt;li&gt;Whether the output is ONNX, TFLite, TFLite Micro, or proprietary.&lt;/li&gt;
&lt;li&gt;Whether the model can run without an API key or network connection.&lt;/li&gt;
&lt;li&gt;Whether commercial redistribution is allowed.&lt;/li&gt;
&lt;li&gt;Whether you can test with your own microphone before downloading.&lt;/li&gt;
&lt;li&gt;Whether real recordings or hard negatives can be used later.&lt;/li&gt;
&lt;li&gt;Whether the runtime includes the required preprocessing.&lt;/li&gt;
&lt;li&gt;Whether the model size fits the target hardware.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For ESP32 and ESPHome projects, &lt;a href="https://microwakeword.com/" rel="noopener noreferrer"&gt;microWakeWord&lt;/a&gt; is an example of a hosted workflow focused on small embedded models. Its API documentation describes INT8 TFLite model delivery and ESPHome integration.&lt;/p&gt;

&lt;p&gt;For a hosted openWakeWord-oriented workflow, &lt;a href="https://openwakeword.com/" rel="noopener noreferrer"&gt;openwakeword.com&lt;/a&gt; provides an online training experience built around the openWakeWord ecosystem. Verify its current model export and license terms before using a generated model commercially.&lt;/p&gt;

&lt;p&gt;For a multi-platform workflow, &lt;a href="https://www.voicute.com" rel="noopener noreferrer"&gt;Voicute&lt;/a&gt; provides online custom wake-word and keyword-spotting model generation, browser testing, and ONNX/TFLite-oriented deployment paths. The &lt;a href="https://github.com/voicute/onnx-wakeword" rel="noopener noreferrer"&gt;onnx-wakeword repository&lt;/a&gt; provides open inference examples.&lt;/p&gt;

&lt;p&gt;These services have different goals. A platform optimized for ESP32-S3 is not automatically the best choice for Android or browser deployment. A platform with a simple web form is not automatically the best choice for a regulated or commercial product.&lt;/p&gt;

&lt;h2&gt;
  
  
  A simple decision guide
&lt;/h2&gt;

&lt;p&gt;Choose self-managed openWakeWord when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You have Python and machine-learning experience.&lt;/li&gt;
&lt;li&gt;You need to inspect or customize the training pipeline.&lt;/li&gt;
&lt;li&gt;You can manage datasets and evaluation.&lt;/li&gt;
&lt;li&gt;You want to control the infrastructure and model generation process.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Choose an online platform when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You need to test a phrase quickly.&lt;/li&gt;
&lt;li&gt;You do not want to install a GPU training environment.&lt;/li&gt;
&lt;li&gt;You need a guided train-and-download workflow.&lt;/li&gt;
&lt;li&gt;You are willing to validate the output independently.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Choose an ecosystem-specific platform when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your target is already fixed, such as ESP32-S3 and ESPHome.&lt;/li&gt;
&lt;li&gt;The platform's model format and license match your product.&lt;/li&gt;
&lt;li&gt;You prefer an integrated device workflow over general portability.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Deploy the model locally
&lt;/h2&gt;

&lt;p&gt;After obtaining a model, keep the runtime local during inference whenever possible:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Microphone
   ↓
Audio preprocessing
   ↓
Wake-word inference
   ↓
Threshold and cooldown logic
   ↓
Local application callback
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before shipping, verify:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The sample rate is correct.&lt;/li&gt;
&lt;li&gt;The audio channel layout is correct.&lt;/li&gt;
&lt;li&gt;The feature extractor matches the training pipeline.&lt;/li&gt;
&lt;li&gt;The output label is mapped correctly.&lt;/li&gt;
&lt;li&gt;The threshold is tested with positive and negative audio.&lt;/li&gt;
&lt;li&gt;Repeated detections are suppressed.&lt;/li&gt;
&lt;li&gt;The application does not perform unsafe actions on a single noisy frame.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;An ONNX model can be convenient for Python, desktop, Android, and browser runtimes with compatible ONNX Runtime support. TFLite or TFLite Micro is often more suitable for constrained embedded hardware. The model format should be chosen together with the target runtime, not after training is complete.&lt;/p&gt;

&lt;h2&gt;
  
  
  A reproducible test plan
&lt;/h2&gt;

&lt;p&gt;Use a small but repeatable test plan for every training route:&lt;/p&gt;

&lt;h3&gt;
  
  
  Positive test set
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;At least several speakers&lt;/li&gt;
&lt;li&gt;Multiple distances&lt;/li&gt;
&lt;li&gt;Quiet and noisy rooms&lt;/li&gt;
&lt;li&gt;Different speaking speeds&lt;/li&gt;
&lt;li&gt;The final microphone&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Negative test set
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Normal conversation&lt;/li&gt;
&lt;li&gt;Music and television&lt;/li&gt;
&lt;li&gt;Similar-sounding phrases&lt;/li&gt;
&lt;li&gt;Background appliances&lt;/li&gt;
&lt;li&gt;Long periods of room audio&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Report these numbers
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Recall percentage&lt;/li&gt;
&lt;li&gt;False accepts per hour&lt;/li&gt;
&lt;li&gt;Model size&lt;/li&gt;
&lt;li&gt;RAM and flash usage&lt;/li&gt;
&lt;li&gt;Average inference latency&lt;/li&gt;
&lt;li&gt;Runtime and operating system&lt;/li&gt;
&lt;li&gt;Threshold and cooldown settings&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the test conditions are not recorded, the results are difficult to compare. “It worked on my laptop” is a useful first observation, not a benchmark.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;There is no single correct way to obtain a wake-word model in 2026.&lt;/p&gt;

&lt;p&gt;Self-training openWakeWord gives you control and teaches you how the pipeline works. An online platform reduces setup time and is often the fastest way to validate a phrase. An ecosystem-specific service can be the most practical option when the hardware and runtime are already fixed.&lt;/p&gt;

&lt;p&gt;The safest workflow is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Choose the phrase
   → choose self-training or hosted training
   → generate the model
   → measure recall and false accepts
   → test the final microphone
   → deploy locally
   → repeat with hard negatives when necessary
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important result is not merely a downloaded model file. It is a model whose behavior is measured on the device and in the environment where it will actually be used.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>opensource</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Best Online Wake Word Training Platforms in 2026: A Practical Comparison</title>
      <dc:creator>voicute</dc:creator>
      <pubDate>Wed, 21 Oct 2026 03:20:15 +0000</pubDate>
      <link>https://dev.to/buguatec/best-online-wake-word-training-platforms-in-2026-a-practical-comparison-54ge</link>
      <guid>https://dev.to/buguatec/best-online-wake-word-training-platforms-in-2026-a-practical-comparison-54ge</guid>
      <description>&lt;p&gt;If you need a custom wake word in 2026, the hard part is no longer running a neural network once. The hard part is choosing a training path that matches your language, target hardware, model format, testing process, and deployment constraints.&lt;/p&gt;

&lt;p&gt;There are now several ways to create a custom wake-word model:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Train an open-source model yourself.&lt;/li&gt;
&lt;li&gt;Use a hosted platform built around an open-source training pipeline.&lt;/li&gt;
&lt;li&gt;Use a platform focused on a specific ecosystem such as ESPHome or Home Assistant.&lt;/li&gt;
&lt;li&gt;Use a self-service platform that handles training, testing, and model delivery.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article compares those approaches from a developer's point of view. It does not claim that one platform is the best for every language or device.&lt;/p&gt;

&lt;h2&gt;
  
  
  What should an online wake-word platform provide?
&lt;/h2&gt;

&lt;p&gt;Before comparing products, it helps to define the actual job. A useful platform should answer these questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Can I create a model for my target phrase and language?&lt;/li&gt;
&lt;li&gt;Do I need to install Python, download datasets, or provide a GPU?&lt;/li&gt;
&lt;li&gt;What does the platform export: ONNX, TFLite, TFLite Micro, or a proprietary format?&lt;/li&gt;
&lt;li&gt;Can I test the model with my own microphone before downloading it?&lt;/li&gt;
&lt;li&gt;Can I measure both recall and false triggers?&lt;/li&gt;
&lt;li&gt;Can I deploy the result on my target device?&lt;/li&gt;
&lt;li&gt;What happens when the first model is not good enough?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The last question is especially important. A wake word is not production-ready just because training completed successfully. Real products need testing with different speakers, distances, microphones, background audio, television, music, and similar-sounding phrases.&lt;/p&gt;

&lt;h2&gt;
  
  
  The main options in 2026
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. openWakeWord: the self-managed open-source route
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/dscripka/openWakeWord" rel="noopener noreferrer"&gt;openWakeWord&lt;/a&gt; is an open-source wake-word library with pre-trained models and tools for training custom models. Its documentation includes an automated training utility and a Google Colab workflow.&lt;/p&gt;

&lt;p&gt;This is a strong choice when you want maximum control and are comfortable with Python, synthetic data generation, negative-data collection, training parameters, and evaluation scripts.&lt;/p&gt;

&lt;p&gt;The trade-off is that you own the entire pipeline. You still need to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Generate or collect positive examples.&lt;/li&gt;
&lt;li&gt;Prepare negative audio.&lt;/li&gt;
&lt;li&gt;Run training experiments.&lt;/li&gt;
&lt;li&gt;Tune thresholds.&lt;/li&gt;
&lt;li&gt;Measure false accepts and false rejects.&lt;/li&gt;
&lt;li&gt;Export and integrate the model with your runtime.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Colab workflow lowers the entry barrier, but it does not remove the need for deployment testing. The official project also notes that custom training can be quick while still producing a model that may not be sufficient for every deployment scenario.&lt;/p&gt;

&lt;p&gt;Use openWakeWord when you want to learn the training process or customize the pipeline yourself. Do not treat “the notebook finished” as a quality guarantee.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. openwakeword.com: a hosted openWakeWord route
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://openwakeword.com/" rel="noopener noreferrer"&gt;openwakeword.com&lt;/a&gt; provides a browser-oriented workflow for creating custom wake-word models and describes itself as powered by openWakeWord. It is closer to an online platform than the open-source repository alone because the training infrastructure and user workflow are hosted.&lt;/p&gt;

&lt;p&gt;This route can be useful if you want the openWakeWord ecosystem without setting up the complete training environment locally. It also makes the distinction between a library and a hosted training service clearer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;openWakeWord repository  -&amp;gt; self-managed training and runtime
openwakeword.com          -&amp;gt; hosted training workflow built around that ecosystem
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before using any hosted model in a product, verify the current export format, commercial license, supported languages, model size, and the exact runtime expected by the generated model.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. microWakeWord: optimized for ESP32 and ESPHome scenarios
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://microwakeword.com/" rel="noopener noreferrer"&gt;microWakeWord&lt;/a&gt; focuses on small wake-word models for constrained devices, especially ESP32-S3, ESPHome, and Home Assistant projects. Its current API documentation describes hosted training that returns a quantized INT8 TFLite model together with an ESPHome manifest.&lt;/p&gt;

&lt;p&gt;This is a good fit when the target is already known:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ESP32-S3 hardware&lt;/li&gt;
&lt;li&gt;ESPHome integration&lt;/li&gt;
&lt;li&gt;Home Assistant voice satellites&lt;/li&gt;
&lt;li&gt;Small TFLite Micro models&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The trade-off is portability. A platform optimized for one embedded ecosystem may not be the easiest choice for a browser, Android application, desktop application, or a product that needs a different model format.&lt;/p&gt;

&lt;p&gt;Choose microWakeWord when ESP32/ESPHome compatibility is the primary requirement. For a multi-platform product, check the runtime and export constraints before committing to the training workflow.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Voicute: a self-service model delivery workflow
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.voicute.com" rel="noopener noreferrer"&gt;Voicute&lt;/a&gt; takes a more product-oriented approach: enter a custom wake word or fixed command set, generate a model online, test it, and then use the exported model in a local application.&lt;/p&gt;

&lt;p&gt;The intended workflow is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Enter a phrase
      ↓
Generate a basic model
      ↓
Test with a real voice
      ↓
Add real-voice data or hard negatives when needed
      ↓
Download and validate on the target device
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The main difference is not simply “online training.” Other projects can also provide online or hosted training. The difference is the complete handoff from training to deployment:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Custom wake-word and fixed-command models&lt;/li&gt;
&lt;li&gt;Multilingual training options&lt;/li&gt;
&lt;li&gt;Multi-keyword models&lt;/li&gt;
&lt;li&gt;Optional real-voice enhancement&lt;/li&gt;
&lt;li&gt;Standard ONNX/TFLite delivery&lt;/li&gt;
&lt;li&gt;Browser, Android, Python, desktop, Home Assistant, and embedded runtime paths&lt;/li&gt;
&lt;li&gt;An open-source inference runtime in the &lt;a href="https://github.com/voicute/onnx-wakeword" rel="noopener noreferrer"&gt;onnx-wakeword repository&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The important limitation is the same as with every other platform: the downloaded model still needs to be tested with the final microphone, enclosure, device, and acoustic environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comparison table
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Approach&lt;/th&gt;
&lt;th&gt;Best for&lt;/th&gt;
&lt;th&gt;Main output or runtime direction&lt;/th&gt;
&lt;th&gt;Main trade-off&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;openWakeWord self-managed&lt;/td&gt;
&lt;td&gt;Developers who want full control&lt;/td&gt;
&lt;td&gt;Open-source runtime and custom training workflow&lt;/td&gt;
&lt;td&gt;You manage data, training, evaluation, and deployment&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;openwakeword.com&lt;/td&gt;
&lt;td&gt;Users who want hosted openWakeWord-style training&lt;/td&gt;
&lt;td&gt;Check the current hosted export and license&lt;/td&gt;
&lt;td&gt;Hosted workflow still needs independent product testing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;microWakeWord&lt;/td&gt;
&lt;td&gt;ESP32-S3, ESPHome, and Home Assistant&lt;/td&gt;
&lt;td&gt;Quantized TFLite / TFLite Micro path&lt;/td&gt;
&lt;td&gt;Less general for web, Android, or desktop deployments&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Voicute&lt;/td&gt;
&lt;td&gt;Small teams needing online generation and multi-platform delivery&lt;/td&gt;
&lt;td&gt;ONNX/TFLite plus open runtime examples&lt;/td&gt;
&lt;td&gt;Final hardware validation is still required&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;There is no single winner in this table. The right choice depends on what you value most:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Maximum control: openWakeWord self-managed.&lt;/li&gt;
&lt;li&gt;ESP32/ESPHome integration: microWakeWord.&lt;/li&gt;
&lt;li&gt;Hosted access to an openWakeWord-oriented workflow: openwakeword.com.&lt;/li&gt;
&lt;li&gt;A guided train → test → export workflow across multiple runtimes: Voicute.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What to benchmark before calling a platform “best”
&lt;/h2&gt;

&lt;p&gt;Marketing pages are not enough for wake-word selection. A useful comparison should use the same test protocol for every platform.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Use the same phrases
&lt;/h3&gt;

&lt;p&gt;Test at least one easy phrase, one short phrase, one phrase with similar-sounding words, and one phrase in the target language. Do not compare an English phrase on one platform with a difficult non-English phrase on another.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Measure recall separately from false triggers
&lt;/h3&gt;

&lt;p&gt;For intended activations, report recall:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;recall = detected intended activations / total intended activations
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For unwanted activations, report false accepts per hour:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;false accepts per hour = unwanted activations / hours of negative audio
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A high recall score with frequent false triggers is not a useful product result.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Test the final microphone
&lt;/h3&gt;

&lt;p&gt;The same model can behave differently with a laptop microphone, a phone microphone, an ESP32 audio board, and a microphone inside a plastic enclosure. Test the target hardware instead of relying only on a browser demo.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Check the license and model format
&lt;/h3&gt;

&lt;p&gt;Before shipping, verify:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Whether commercial use is allowed.&lt;/li&gt;
&lt;li&gt;Whether the generated model can be redistributed.&lt;/li&gt;
&lt;li&gt;Whether an API key or online activation is required at runtime.&lt;/li&gt;
&lt;li&gt;Whether the output is ONNX, TFLite, TFLite Micro, or a proprietary format.&lt;/li&gt;
&lt;li&gt;Whether the runtime includes the required preprocessing.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5. Repeat the test after hard-negative training
&lt;/h3&gt;

&lt;p&gt;When a model triggers on a specific television voice, phrase, or background sound, save that audio and use it in the next training round if the platform supports it. The second round should be evaluated against both the original test set and the new difficult negatives.&lt;/p&gt;

&lt;h2&gt;
  
  
  My practical recommendation
&lt;/h2&gt;

&lt;p&gt;Use openWakeWord if you are building a research or engineering pipeline and want to control every training decision.&lt;/p&gt;

&lt;p&gt;Use microWakeWord if your product is specifically an ESP32-S3 or ESPHome voice device.&lt;/p&gt;

&lt;p&gt;Use a hosted platform if your goal is to validate custom phrases quickly without assembling the training environment yourself. In that case, compare the actual export, licensing, testing workflow, and target-device results instead of comparing landing-page claims.&lt;/p&gt;

&lt;p&gt;For a product that needs multiple languages, custom commands, online pre-download testing, and ONNX/TFLite integration across more than one runtime, Voicute is one option worth evaluating. It should still be evaluated with the same benchmark as the other options.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The best online wake-word platform in 2026 is not necessarily the one with the most languages or the shortest training time. It is the one that lets you move from a phrase to a measurable, deployable model with the fewest hidden assumptions.&lt;/p&gt;

&lt;p&gt;The safest workflow is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Choose a phrase
   → train a model
   → test recall and false accepts
   → test the final microphone
   → export with a clear license
   → validate on the target device
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That process matters more than a “best platform” label.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Disclosure: I am the creator of Voicute. Voicute is included in this comparison because it is one of the platforms discussed, not because the comparison is an independent third-party benchmark. The performance of every option depends on the phrase, language, data, threshold, microphone, and deployment environment.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>ai</category>
      <category>iot</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>Building Offline Voice Control with a Custom Wake Word and ONNX</title>
      <dc:creator>voicute</dc:creator>
      <pubDate>Mon, 19 Oct 2026 21:38:28 +0000</pubDate>
      <link>https://dev.to/buguatec/building-offline-voice-control-with-a-custom-wake-word-and-onnx-57d2</link>
      <guid>https://dev.to/buguatec/building-offline-voice-control-with-a-custom-wake-word-and-onnx-57d2</guid>
      <description>&lt;p&gt;Cloud speech recognition is useful, but many voice-control products do not need to transcribe every sentence. If the interaction starts with a wake word and continues with a small list of fixed commands, local keyword spotting can be a simpler solution.&lt;/p&gt;

&lt;p&gt;This article shows a practical architecture for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Detecting a custom wake word locally&lt;/li&gt;
&lt;li&gt;Recognizing multiple fixed commands with one model&lt;/li&gt;
&lt;li&gt;Keeping microphone audio on the device&lt;/li&gt;
&lt;li&gt;Deploying the same workflow with ONNX or TFLite&lt;/li&gt;
&lt;li&gt;Improving false-trigger performance with a second training round&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The two-stage architecture
&lt;/h2&gt;

&lt;p&gt;A useful design is to separate wake-up from command recognition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Microphone
    ↓
Wake-word model
    ↓
Short command window
    ↓
Multi-keyword model
    ↓
Application action
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Wake word: Hey device
Command: Turn on the light
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The wake-word model can run continuously with a conservative threshold. After it detects the wake word, the application enables the command model for a short period.&lt;/p&gt;

&lt;p&gt;This avoids running a larger command recognizer continuously and makes the interaction state easier to control.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why not use speech recognition for the wake word?
&lt;/h2&gt;

&lt;p&gt;The Web Speech API is convenient for prototypes, but it is not a reliable always-on wake-word detector across mobile browsers. Browser support for &lt;code&gt;SpeechRecognition&lt;/code&gt; and its &lt;code&gt;continuous&lt;/code&gt; mode varies, and some implementations may disconnect or use a remote recognition service.&lt;/p&gt;

&lt;p&gt;For a local browser implementation, a better approach is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Request microphone access after a user gesture.&lt;/li&gt;
&lt;li&gt;Read the audio with &lt;code&gt;getUserMedia()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Convert the stream into the frame format expected by the model.&lt;/li&gt;
&lt;li&gt;Run local keyword-spotting inference.&lt;/li&gt;
&lt;li&gt;Start ASR or show the command interface only after the wake word is detected.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The browser still has permission and lifecycle limitations, but the keyword detector does not depend on &lt;code&gt;SpeechRecognition&lt;/code&gt; returning a transcript.&lt;/p&gt;

&lt;h2&gt;
  
  
  One model for multiple fixed commands
&lt;/h2&gt;

&lt;p&gt;Suppose a device needs these commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;next
previous
stop
open menu
close menu
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A multi-keyword model can return a score for each label. The application maps the selected label to an action:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;actions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;nextPage&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="na"&gt;previous&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;previousPage&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="na"&gt;stop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;stopPlayback&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;open menu&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;openMenu&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;close menu&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;closeMenu&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleKeyword&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="p"&gt;]?.();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This works well when the vocabulary is known in advance. It is not a replacement for open-ended speech recognition. A request such as “Set the living-room light to 37 percent” needs ASR and intent parsing because the words and parameters are not fixed.&lt;/p&gt;

&lt;h2&gt;
  
  
  False triggers: R0 and R1
&lt;/h2&gt;

&lt;p&gt;Getting the target phrase recognized is only the first part of the problem. A real device also has to reject:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Normal conversation&lt;/li&gt;
&lt;li&gt;Music and television audio&lt;/li&gt;
&lt;li&gt;Fans and mechanical noise&lt;/li&gt;
&lt;li&gt;Similar-sounding phrases&lt;/li&gt;
&lt;li&gt;Microphone or enclosure noise&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The first model can be treated as an R0 model. After testing it, collect the audio clips that incorrectly trigger it. These hard negatives become part of the next training round, often called R1.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;R0 model
   ↓
Scan difficult negative audio
   ↓
Collect false-trigger clips
   ↓
Retrain with hard negatives
   ↓
R1 model
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;R1 is a training process, not a second model that must run at runtime. The goal is to teach the model which confusing sounds should be rejected while preserving recall for the real phrase.&lt;/p&gt;

&lt;h2&gt;
  
  
  Local inference and privacy
&lt;/h2&gt;

&lt;p&gt;Local keyword spotting is useful when a product needs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Low latency&lt;/li&gt;
&lt;li&gt;Offline operation&lt;/li&gt;
&lt;li&gt;Predictable fixed-command behavior&lt;/li&gt;
&lt;li&gt;Lower cloud and network dependency&lt;/li&gt;
&lt;li&gt;Better control over microphone privacy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The model file is only one part of the system. The runtime also needs audio capture, framing, feature extraction, threshold handling, cooldown logic and application callbacks.&lt;/p&gt;

&lt;p&gt;For this reason, always validate the complete pipeline rather than testing only whether the model file can be loaded.&lt;/p&gt;

&lt;h2&gt;
  
  
  ONNX and TFLite deployment
&lt;/h2&gt;

&lt;p&gt;ONNX is convenient for desktop, Python, Android and browser runtimes that support ONNX Runtime. TFLite or TFLite Micro is commonly used on constrained embedded devices.&lt;/p&gt;

&lt;p&gt;Before moving a model to another runtime, verify:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sample rate&lt;/li&gt;
&lt;li&gt;PCM format&lt;/li&gt;
&lt;li&gt;Frame length and hop size&lt;/li&gt;
&lt;li&gt;Mel-feature configuration&lt;/li&gt;
&lt;li&gt;Input tensor shape&lt;/li&gt;
&lt;li&gt;Output label order&lt;/li&gt;
&lt;li&gt;Quantization settings&lt;/li&gt;
&lt;li&gt;Detection threshold&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If preprocessing changes, recall can drop even when the model file is unchanged.&lt;/p&gt;

&lt;h2&gt;
  
  
  A practical testing checklist
&lt;/h2&gt;

&lt;p&gt;Test the complete system with the final microphone and target environment:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Test the wake word with multiple speakers.&lt;/li&gt;
&lt;li&gt;Test different distances and speaking speeds.&lt;/li&gt;
&lt;li&gt;Play ordinary conversation and background audio.&lt;/li&gt;
&lt;li&gt;Measure false triggers per hour.&lt;/li&gt;
&lt;li&gt;Measure recall separately from false-trigger rate.&lt;/li&gt;
&lt;li&gt;Add difficult negative samples for the next training round.&lt;/li&gt;
&lt;li&gt;Test cooldown and repeated-trigger behavior.&lt;/li&gt;
&lt;li&gt;Verify that every recognized command maps to the intended safe action.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Do not optimize only for recall. A model that triggers too often is not practical for a product, even if it rarely misses the target phrase.&lt;/p&gt;

&lt;h2&gt;
  
  
  Open-source inference example
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://github.com/voicute/onnx-wakeword" rel="noopener noreferrer"&gt;onnx-wakeword&lt;/a&gt; project contains open-source inference code and examples for running ONNX wake-word and keyword-spotting models in local applications.&lt;/p&gt;

&lt;p&gt;It can be used to test the inference path before integrating a model into a larger product. The final result should still be tested with the actual microphone, operating system and hardware.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;For a product with one wake word and a limited command vocabulary, a two-stage local design is often easier to control than continuously running full ASR:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Wake word → command window → fixed keyword → local action
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The approach can provide low latency, offline operation and a small deployment footprint across ONNX- and TFLite-compatible platforms.&lt;/p&gt;

&lt;p&gt;You can read the longer architecture guide on &lt;a href="https://www.voicute.com/articles/offline-voice-control-multi-keyword-onnx.html" rel="noopener noreferrer"&gt;Voicute&lt;/a&gt;, or try the local inference code in the &lt;a href="https://github.com/voicute/onnx-wakeword" rel="noopener noreferrer"&gt;onnx-wakeword repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The accompanying German voice-control demonstration is available on &lt;a href="https://www.youtube.com/shorts/paNkv9Zdxx0" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>architecture</category>
      <category>iot</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>Multilingual Command Words on ESP32: A TFLite Alternative to MultiNet</title>
      <dc:creator>voicute</dc:creator>
      <pubDate>Sat, 17 Oct 2026 23:11:46 +0000</pubDate>
      <link>https://dev.to/buguatec/multilingual-command-words-on-esp32-a-tflite-alternative-to-multinet-13n0</link>
      <guid>https://dev.to/buguatec/multilingual-command-words-on-esp32-a-tflite-alternative-to-multinet-13n0</guid>
      <description>&lt;p&gt;ESP32 voice control is often discussed as if the hardware determines the language. In practice, the bigger limitation is usually the available acoustic model and its training pipeline.&lt;/p&gt;

&lt;p&gt;An embedded command-word system needs three separate pieces:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A wake-up or start-of-interaction detector.&lt;/li&gt;
&lt;li&gt;A small command-word model.&lt;/li&gt;
&lt;li&gt;Firmware logic that maps the model output to device actions.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A TFLite Micro workflow makes it possible to keep the runtime on the ESP32 while changing the language model.&lt;/p&gt;

&lt;h2&gt;
  
  
  The supported language set
&lt;/h2&gt;

&lt;p&gt;The current Voicute workflow supports custom keyword models in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Chinese&lt;/li&gt;
&lt;li&gt;English&lt;/li&gt;
&lt;li&gt;Japanese&lt;/li&gt;
&lt;li&gt;French&lt;/li&gt;
&lt;li&gt;German&lt;/li&gt;
&lt;li&gt;Spanish&lt;/li&gt;
&lt;li&gt;Hindi&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The important detail is that the language is in the trained model, not in the command list alone. Translating &lt;code&gt;turn on the light&lt;/code&gt; into another language does not create an acoustic model for that language.&lt;/p&gt;

&lt;h2&gt;
  
  
  One model, multiple keywords
&lt;/h2&gt;

&lt;p&gt;For a selected language, a Multi-Keyword model can recognize several fixed commands in one inference pass.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1 -&amp;gt; lights on
2 -&amp;gt; lights off
3 -&amp;gt; brighter
4 -&amp;gt; darker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The runtime returns a command ID. The ESP32 application decides what that ID means.&lt;/p&gt;

&lt;p&gt;This gives a MultiNet-like command recognition shape without requiring the product to use the same model family or language coverage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters on ESP32
&lt;/h2&gt;

&lt;p&gt;A full ASR system is often too large or power-hungry for a small always-on product. A fixed command model can stay compact and offline:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No network connection&lt;/li&gt;
&lt;li&gt;No cloud speech API&lt;/li&gt;
&lt;li&gt;Lower latency&lt;/li&gt;
&lt;li&gt;Predictable command vocabulary&lt;/li&gt;
&lt;li&gt;Easier privacy story&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The trade-off is that the device only recognizes the commands included in the model. This is a feature for appliances and embedded controls, not a limitation to hide.&lt;/p&gt;

&lt;h2&gt;
  
  
  The embedded audio contract
&lt;/h2&gt;

&lt;p&gt;The model and firmware must agree on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sample rate&lt;/li&gt;
&lt;li&gt;Channel count&lt;/li&gt;
&lt;li&gt;Frame size&lt;/li&gt;
&lt;li&gt;Feature extraction&lt;/li&gt;
&lt;li&gt;Quantization&lt;/li&gt;
&lt;li&gt;Output labels&lt;/li&gt;
&lt;li&gt;Threshold and smoothing behavior&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The common embedded input is 16 kHz, 16-bit, mono PCM. If the board supplies a different format, convert it before inference and test the conversion path itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  A practical architecture
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WakeNet or another wake detector
        |
        v
16 kHz mono audio
        |
        v
Multi-keyword INT8 TFLite model
        |
        v
command ID
        |
        v
ESP-IDF application action
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the language or command set changes, retrain/export the model. The firmware-side command-ID interface can remain stable.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to test
&lt;/h2&gt;

&lt;p&gt;For each language, test more than clean studio audio:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Different speakers and accents&lt;/li&gt;
&lt;li&gt;Quiet and noisy rooms&lt;/li&gt;
&lt;li&gt;Music and television&lt;/li&gt;
&lt;li&gt;Similar command phrases&lt;/li&gt;
&lt;li&gt;Short and long distances&lt;/li&gt;
&lt;li&gt;The final microphone and enclosure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Recall alone is not enough. Track false triggers per hour and confusion between commands.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final takeaway
&lt;/h2&gt;

&lt;p&gt;The useful comparison is not “which framework has the most preset words?” It is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can I train the language I need?&lt;/li&gt;
&lt;li&gt;Can one small model recognize my fixed command set?&lt;/li&gt;
&lt;li&gt;Can I export it to the runtime on my target board?&lt;/li&gt;
&lt;li&gt;Can I test it before shipping?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For an open offline implementation, see &lt;a href="https://github.com/voicute/onnx-wakeword" rel="noopener noreferrer"&gt;voicute/onnx-wakeword&lt;/a&gt;. For online custom model generation and testing, see &lt;a href="https://www.voicute.com" rel="noopener noreferrer"&gt;Voicute&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>hardware</category>
      <category>iot</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>One TFLite Model, Multiple Command Words on ESP32</title>
      <dc:creator>voicute</dc:creator>
      <pubDate>Sat, 17 Oct 2026 23:11:24 +0000</pubDate>
      <link>https://dev.to/buguatec/one-tflite-model-multiple-command-words-on-esp32-2mfh</link>
      <guid>https://dev.to/buguatec/one-tflite-model-multiple-command-words-on-esp32-2mfh</guid>
      <description>&lt;p&gt;Many embedded voice-control examples use one detector for one keyword:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;turn on the light&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;turn off the light&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;increase volume&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That works, but loading a separate model for every command is wasteful. A better pattern is a multi-keyword model: one model, shared feature extraction, one inference pass and multiple command IDs.&lt;/p&gt;

&lt;p&gt;This is functionally similar to the role of MultiNet in ESP-SR, while using a portable TFLite model delivery path.&lt;/p&gt;

&lt;h2&gt;
  
  
  The model interface
&lt;/h2&gt;

&lt;p&gt;The firmware does not need to treat every phrase as a separate application.&lt;/p&gt;

&lt;p&gt;A multi-keyword model can expose results like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0 -&amp;gt; no command
1 -&amp;gt; turn on the light
2 -&amp;gt; turn off the light
3 -&amp;gt; increase volume
4 -&amp;gt; decrease volume
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The application maps the result to an action:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;command_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;light_on&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;light_off&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;volume_up&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exact API depends on the runtime integration, but the important design is stable: the model recognizes the fixed command set, and the firmware owns the device behavior.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why one model is useful
&lt;/h2&gt;

&lt;p&gt;A shared multi-keyword model can provide:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One feature-extraction path&lt;/li&gt;
&lt;li&gt;One model invocation per audio window&lt;/li&gt;
&lt;li&gt;A consistent thresholding strategy&lt;/li&gt;
&lt;li&gt;A smaller integration surface&lt;/li&gt;
&lt;li&gt;Better joint testing of similar commands&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is not simply a folder containing several unrelated single-keyword models. The commands are evaluated together, which is important when phrases sound similar.&lt;/p&gt;

&lt;h2&gt;
  
  
  How many commands?
&lt;/h2&gt;

&lt;p&gt;For a small voice-controlled product, start with a small fixed vocabulary. Two to ten commands is a practical range for an embedded command interface:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;lights on&lt;/li&gt;
&lt;li&gt;lights off&lt;/li&gt;
&lt;li&gt;brighter&lt;/li&gt;
&lt;li&gt;darker&lt;/li&gt;
&lt;li&gt;next mode&lt;/li&gt;
&lt;li&gt;previous mode&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;More commands increase the confusion surface. Similar phrases should be tested as hard negatives, not added only after the model fails in production.&lt;/p&gt;

&lt;h2&gt;
  
  
  ESP32 deployment
&lt;/h2&gt;

&lt;p&gt;The open-source ESP32 example is here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/voicute/onnx-wakeword/tree/main/esp32" rel="noopener noreferrer"&gt;https://github.com/voicute/onnx-wakeword/tree/main/esp32&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The deployment shape is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;microphone
  -&amp;gt; 16 kHz mono PCM
  -&amp;gt; feature extraction
  -&amp;gt; INT8 TFLite model
  -&amp;gt; command ID
  -&amp;gt; ESP-IDF action
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A wake word detector can start the interaction, after which the multi-keyword model listens for the fixed command set. In some products the command model can also run directly as the always-on detector, depending on the UX and power budget.&lt;/p&gt;

&lt;h2&gt;
  
  
  Do not confuse command recognition with ASR
&lt;/h2&gt;

&lt;p&gt;This pattern is not general speech recognition.&lt;/p&gt;

&lt;p&gt;It is a small-vocabulary classifier for known phrases. That is why it can be much smaller and cheaper to run locally than an ASR system. It is a good fit for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lights&lt;/li&gt;
&lt;li&gt;Fans&lt;/li&gt;
&lt;li&gt;Modes&lt;/li&gt;
&lt;li&gt;Appliance controls&lt;/li&gt;
&lt;li&gt;Simple robot actions&lt;/li&gt;
&lt;li&gt;Fixed industrial commands&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is not a replacement for dictation or open-ended conversational speech.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test commands as a group
&lt;/h2&gt;

&lt;p&gt;For each command, measure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Positive recall&lt;/li&gt;
&lt;li&gt;Confusion with other commands&lt;/li&gt;
&lt;li&gt;False triggers from unrelated speech&lt;/li&gt;
&lt;li&gt;Detection delay&lt;/li&gt;
&lt;li&gt;Performance at different distances&lt;/li&gt;
&lt;li&gt;Performance with the device speaker playing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The most important test is often not “does command A work?” but “does command A remain distinct from commands B and C in the same room?”&lt;/p&gt;

&lt;h2&gt;
  
  
  Final takeaway
&lt;/h2&gt;

&lt;p&gt;If your ESP32 product needs a handful of fixed voice commands, one multi-keyword TFLite model is often a cleaner architecture than one model per phrase.&lt;/p&gt;

&lt;p&gt;The model handles recognition. The firmware handles command IDs and actions.&lt;/p&gt;

&lt;p&gt;You can find the example runtime at &lt;a href="https://github.com/voicute/onnx-wakeword" rel="noopener noreferrer"&gt;voicute/onnx-wakeword&lt;/a&gt;, and the multi-keyword training workflow at &lt;a href="https://www.voicute.com" rel="noopener noreferrer"&gt;Voicute&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>cpp</category>
      <category>iot</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>Custom Wake Word on ESP32-S3 with INT8 TFLite Micro</title>
      <dc:creator>voicute</dc:creator>
      <pubDate>Sat, 17 Oct 2026 23:10:53 +0000</pubDate>
      <link>https://dev.to/buguatec/custom-wake-word-on-esp32-s3-with-int8-tflite-micro-9p9</link>
      <guid>https://dev.to/buguatec/custom-wake-word-on-esp32-s3-with-int8-tflite-micro-9p9</guid>
      <description>&lt;h1&gt;
  
  
  How to Run a Custom Wake Word on ESP32-S3 with INT8 TFLite Micro
&lt;/h1&gt;

&lt;p&gt;A custom wake word is easy to demonstrate in a browser and much harder to ship on a real device.&lt;/p&gt;

&lt;p&gt;The microphone, enclosure, gain, background noise, memory budget and audio pipeline all affect the result. For an ESP32-S3 product, I prefer to treat the model and the embedded audio pipeline as one system.&lt;/p&gt;

&lt;p&gt;This post shows the practical path:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Train or generate a custom wake-word model.&lt;/li&gt;
&lt;li&gt;Export a compact INT8 TFLite model.&lt;/li&gt;
&lt;li&gt;Run it locally with TFLite Micro.&lt;/li&gt;
&lt;li&gt;Test it on the final microphone and enclosure.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Why ESP32-S3?
&lt;/h2&gt;

&lt;p&gt;The ESP32-S3 is a useful starting point for embedded keyword spotting because it has more compute and memory headroom than smaller ESP32 variants. Boards differ substantially, though. A model that works on an ESP32-S3 development kit is not automatically validated on an ESP32-C3 or a custom board.&lt;/p&gt;

&lt;p&gt;For a microcontroller target, the model format is only one part of the problem. The firmware also needs to reproduce:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;16 kHz mono PCM input&lt;/li&gt;
&lt;li&gt;The same window and frame configuration&lt;/li&gt;
&lt;li&gt;The same feature extraction&lt;/li&gt;
&lt;li&gt;The same quantization assumptions&lt;/li&gt;
&lt;li&gt;The same model output mapping&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Changing one of these can reduce recall even when the model file itself is unchanged.&lt;/p&gt;

&lt;h2&gt;
  
  
  The deployment path
&lt;/h2&gt;

&lt;p&gt;The public ESP32 example is available here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/voicute/onnx-wakeword/tree/main/esp32" rel="noopener noreferrer"&gt;https://github.com/voicute/onnx-wakeword/tree/main/esp32&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A basic ESP-IDF workflow looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/voicute/onnx-wakeword.git
&lt;span class="nb"&gt;cd &lt;/span&gt;onnx-wakeword/esp32/examples/esp32s3_hmi_devkit

idf.py set-target esp32s3
idf.py build
idf.py &lt;span class="nt"&gt;-p&lt;/span&gt; COM6 flash monitor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model and output head are a matched pair. Replace them together. Do not copy a model from one training/export configuration and keep the head from another configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Training a custom phrase
&lt;/h2&gt;

&lt;p&gt;There are two reasonable approaches:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use an online training workflow when the goal is fast product validation.&lt;/li&gt;
&lt;li&gt;Build a self-hosted training pipeline when you need complete control over data, augmentation and hard negatives.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a small product team, online training is usually the faster first step. The important part is not just whether the model detects the phrase in a quiet demo. It must be tested with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The final microphone&lt;/li&gt;
&lt;li&gt;Different speaking distances&lt;/li&gt;
&lt;li&gt;Different speakers&lt;/li&gt;
&lt;li&gt;TV, music and speech in the background&lt;/li&gt;
&lt;li&gt;Similar-sounding phrases&lt;/li&gt;
&lt;li&gt;Device vibration and enclosure noise&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Measuring the real result
&lt;/h2&gt;

&lt;p&gt;I would record at least:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Recall on positive utterances&lt;/li&gt;
&lt;li&gt;False triggers per hour&lt;/li&gt;
&lt;li&gt;Detection latency&lt;/li&gt;
&lt;li&gt;Flash and RAM usage&lt;/li&gt;
&lt;li&gt;Behavior after repeated commands&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A browser score is useful for iteration, but it is not an embedded benchmark.&lt;/p&gt;

&lt;h2&gt;
  
  
  When should you use ONNX instead?
&lt;/h2&gt;

&lt;p&gt;ONNX is a good fit for Linux, Android, Python or browser runtimes with a full ONNX Runtime implementation. For direct inference inside constrained ESP32 firmware, INT8 TFLite Micro is usually the more natural deployment target.&lt;/p&gt;

&lt;p&gt;The same trained keyword concept can therefore have different exports for different devices. Keep the evaluation set and acceptance criteria consistent across platforms.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final takeaway
&lt;/h2&gt;

&lt;p&gt;The shortest path to a custom ESP32 wake word is not “find a model file and flash it.” It is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;phrase
  -&amp;gt; training
  -&amp;gt; target-device audio test
  -&amp;gt; matched INT8 export
  -&amp;gt; ESP-IDF integration
  -&amp;gt; false-trigger evaluation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to try the open-source inference component and examples, start with &lt;a href="https://github.com/voicute/onnx-wakeword" rel="noopener noreferrer"&gt;onnx-wakeword&lt;/a&gt;. For online custom model training and testing, see &lt;a href="https://www.voicute.com" rel="noopener noreferrer"&gt;Voicute&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>hardware</category>
      <category>iot</category>
      <category>machinelearning</category>
    </item>
  </channel>
</rss>
