Tofu Wake Word
Custom INT8 TFLite Micro wake-word detector for ESP32-S3. Fires on:
hey tofuhi tofuhello tofuokay tofu
Metrics
| Metric | Value |
|---|---|
| FRR (positives) | 0.00% |
| FAR (bulk negatives, /hour) | 0.00 |
| Detection threshold | 0.850 |
| Model size | 60.7 kB |
| Mel features | 40 bins, 25 ms hop, 194 frames |
Per-bucket FAR:
| Bucket | FAR |
|---|---|
| (no buckets) | — |
Use with ESPHome
micro_wake_word:
microphone: tofu_mic
vad:
models:
- model: tofu
probability_cutoff: 0.850
sliding_window_size: 5
url: https://huggingface.co/nagisanzeninz/tofu-wakeword-v0/resolve/main/tofu-wakeword-v0.tflite
Full ESPHome example in esphome.yaml.
Training recipe
Trained with the customWakeWord pipeline:
- ~10000 synthetic positives across 4 trigger phrases (Piper + Kokoro + MeloTTS + Parler-TTS, 200+ distinct voices).
- ~~2500 hand- and LLM-curated hard-negatives covering 5 collision categories.
- ~300 hours of bulk negative audio sampled from MUSAN, DEMAND, Common Voice, AudioSet.
- audiomentations chain: RIR convolution + additive noise + codec degradation + pitch/speed jitter.
- microWakeWord streaming-Inception architecture, INT8 post-training quantized for tflite-micro on ESP32-S3.
See the repo README for replicability.
License
Apache 2.0. Built from open-source, permissively-licensed components only — safe to redistribute commercially.
Citation
@misc{tofu-wakeword-v0,
title = { tofu Wake Word v0: custom keyword spotter for ESP32-S3 },
year = { 2026 },
url = { https://huggingface.co/nagisanzeninz/tofu-wakeword-v0 },
note = { Apache 2.0. Built with the customWakeWord toolkit. }
}