Multi-Keyword Wake Word Detection: One Model, 10 Commands
Most wake word engines are built around a single assumption: one model detects one word. openWakeWord, the default in Home Assistant, works exactly this way. But a real voice interface rarely stops at one phrase. You wake the device with "Hey Lamp", then you want to say "brighter", "dimmer", "off" — and if each of those needs its own model, your integration gets complicated fast.
Why one-word-per-model is a problem
Say your product has one wake word and three commands. With the one-word-per-model approach you now run four models in parallel:
- Memory: four models × ~100 KB = ~400 KB, before you add anything else.
- CPU: four models each doing inference on every audio frame.
- Complexity: four callbacks, four threshold tunings, four places to debug false triggers.
Scale to ten commands and it's a mess. The clean alternative is a single model that detects multiple keywords at once.
How one model detects several words
The trick is a shared backbone. Instead of training four separate networks, you train one feature extractor that feeds a small set of per-word classifier heads. The expensive part — turning raw audio into acoustic features — runs once, and only the cheap classifier heads differ per word.
The result:
| Keywords in one model | Model size | Inference |
|---|---|---|
| 1 word | ~128 KB | < 5 ms |
| 3 words | ~135 KB | < 5 ms |
| 10 words | ~167 KB | < 5 ms |
Adding nine more keywords costs ~40 KB and roughly nothing in latency, because the backbone is shared. This is the difference between "a wake word" and "a small voice UI".
A concrete example
Train one model on four keywords — a wake word plus three commands — and the callback becomes a simple switch:
engine.start(lambda word, prob, info: handle(word))
def handle(word):
if word == "hey_lamp": return listen() # arm for commands
if word == "brighter": return set_brightness(+1)
if word == "dimmer": return set_brightness(-1)
if word == "off": return power_off()
The model is still standard ONNX, so it runs anywhere your single-keyword model did — Android, Linux, ESP32, Web — through the same open-source onnx-wakeword engine.
When multi-keyword beats "wake word + ASR"
The alternative to a multi-keyword model is pairing a wake word with a full speech-recognition (ASR) system to understand the commands. That's overkill for a fixed command set:
| Multi-keyword model | Wake word + ASR | |
|---|---|---|
| Model size | ~135–167 KB | 100–200 MB |
| Latency | < 5 ms | 100–500 ms |
| Runs offline on device | Yes, anywhere | Usually needs a bigger device or cloud |
| Accuracy on fixed phrases | High | High, but overkill |
If your commands are a known, fixed list — the common case for lights, fans, toys, and appliances — a multi-keyword model is dramatically lighter. ASR only earns its cost when the user can say anything.
The catch: most tools don't offer it
openWakeWord is one-word-per-model and English-only. Picovoice does multi-keyword but under a per-device license. DIY toolkits can do it, if you have the data and the time. If you need multiple keywords in one model, in a non-English language, without a licensing deal, that's exactly the gap a multi-keyword generator is for.
Train a multi-keyword model →