Reality check: everything here was vibe-coded (even this post — I’m lazy). The trainer is a byproduct of another project I’m working on: it does what I need, so don’t expect regular updates — I’ll only jump in on the first functional-bug reports.
What it is
openwakeword-train is a self-contained, fully local pipeline to train custom openWakeWord models for your own wake phrase — the thing you say to wake up the assistant (e.g. “yo Ève” or “Pixi”) instead of relying on the prebuilt models.
It’s the training side only: it produces the model files that openWakeWord consumes, ready for Home Assistant, ESPHome or an ESP32. It has no dependency on a bigger assistant ecosystem and runs entirely on your machine.
Why you’d want it
The default openWakeWord models cover a fixed set of phrases. If you’d rather use your own wake word — a family name, a shorter word, anything — you have to train it yourself. The catch is usually collecting enough negative examples so the model doesn’t fire every time someone talks. This tool automates that:
- Positives — generates the target phrase with edge-tts (several voices × prosody variants), so you don’t record dozens of samples by hand.
- Negatives — everyday sentences in the target language + noise, and crucially real microphone recordings (read a paragraph + room ambience) that become real negatives and background context. That’s what gets rid of false positives in real use.
- Augmentation — audiomentations (noise, pitch, speed, distortion).
- Same feature pipeline and architecture openWakeWord uses (1536→32→32→1, LayerNorm+ReLU), trained in numpy then exported.
Output
Each training produces in openwakeword/:
| File | Use |
|---|---|
<name>.onnx |
the wake word model (openWakeWord / Python runtime) |
<name>.tflite |
int8 quantized — ESP32 / ESPHome (lightweight) |
<name>_float32.tflite |
float32 — Home Assistant (max fidelity) |
<name>.calib.npy |
training embeddings used as int8 calibration |
<name>.json |
metadata (phrase, threshold) |
If you already have a .onnx and want the .tflite variants without re-training, there’s a post-creation converter (onnx_to_tflite.py) that auto-uses the saved .calib.npy for a faithful int8 (no need to pass it by hand).
Multilingual
Negative sentences, TTS voices, the vosk read-aloud text, and the vosk model are all language-aware. Currently shipped: English, French, German, Spanish — adding a language is a few dictionary entries.
Testing note: so far only French has been validated end-to-end (a model was actually trained and tested in real use). English, German and Spanish are implemented but not yet fully validated in real conditions — expect to polish them (or report issues) before relying on them.
Installation
git clone https://github.com/kinder85/openwakeword-train.git
cd openwakeword-train
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements-train.txt
# optional, only if you want the .tflite export (heavy ~600 MB):
# python -m pip install "onnx2tf[tensorflow]" tf-keras
Usage
One-time per language (downloads vosk model + asks for the two mic recordings):
python first_run_train.py --lang en
GUI (generate → listen to each sample → train & export):
python trainer_gui.py
Headless:
python trainer.py "hey there" --lang en
Notes
- The exported model is auto-discovered by the openWakeWord runtime; this repo just produces the files.
- Network is needed for TTS generation and the first-time model downloads; training itself runs fully local.
Feedback, issues and PRs welcome. GitHub - kinder85/openwakeword-train · GitHub