Hey Maya wake word, version 1 (microWakeWord, int8 streaming)
Browse files- README.md +87 -0
- hey_maya-v1.tflite +3 -0
- tflite_streaming_roc.txt +6 -0
- training_parameters.yaml +55 -0
README.md
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: apache-2.0
|
| 3 |
+
language:
|
| 4 |
+
- en
|
| 5 |
+
tags:
|
| 6 |
+
- wake-word
|
| 7 |
+
- keyword-spotting
|
| 8 |
+
- microwakeword
|
| 9 |
+
- tflite
|
| 10 |
+
---
|
| 11 |
+
|
| 12 |
+
# Hey Maya — wake word, version 1
|
| 13 |
+
|
| 14 |
+
"Hey Maya" is the phrase meant to start Maya, the Maya Foundation's assistant, on a person's phone, only
|
| 15 |
+
when that person has turned the "Hey Maya" setting on (it is off by default). This is the small model
|
| 16 |
+
that listens for the phrase. It runs on the phone; no audio needs to leave it.
|
| 17 |
+
|
| 18 |
+
## The files
|
| 19 |
+
|
| 20 |
+
| File | What it is |
|
| 21 |
+
| --- | --- |
|
| 22 |
+
| `hey_maya-v1.tflite` | The model: 62,304 bytes, SHA-256 `e95b7a1df30e0619dfa1f72134b0153d49f825cf4e63e656aa79ec0208da61bd`. A [microWakeWord](https://github.com/kahrendt/microWakeWord) streaming model that keeps its own state, quantised to int8 (microWakeWord's `stream_state_internal_quant` export). |
|
| 23 |
+
| `training_parameters.yaml` | The training settings, as used. |
|
| 24 |
+
| `tflite_streaming_roc.txt` | The test results below, as the training run wrote them. |
|
| 25 |
+
|
| 26 |
+
## Input and output
|
| 27 |
+
|
| 28 |
+
- **Features:** 16 kHz mono audio turned into 40-value frames by TensorFlow Lite Micro's audio front end
|
| 29 |
+
(the one microWakeWord trains with), one frame every 10 ms.
|
| 30 |
+
- **Input:** `[1, 3, 40]` int8 (scale 0.10196078568696976, zero point −128): three frames, 30 ms, per call.
|
| 31 |
+
- **Output:** `[1, 1]` uint8 (scale 1/256): how sure the model is that it just heard "Hey Maya".
|
| 32 |
+
- **State:** the model keeps its memory between calls in TensorFlow Lite resource variables
|
| 33 |
+
(`VAR_HANDLE`, `READ_VARIABLE`, `ASSIGN_VARIABLE`, `CALL_ONCE`), so the interpreter must support them
|
| 34 |
+
and must be called in order, once per 30 ms.
|
| 35 |
+
- **Deciding:** the test below averaged the last 5 outputs (150 ms, microWakeWord's default for this test)
|
| 36 |
+
and compared the average with the cutoff.
|
| 37 |
+
|
| 38 |
+
## How well it works — on test audio, not on real people yet
|
| 39 |
+
|
| 40 |
+
Measured by the training run on held-out audio. "Misses" is how often it did not wake on "Hey Maya" in
|
| 41 |
+
synthetic test speech; "wakes by mistake" counts wakes on speech and music with no "Hey Maya" in it.
|
| 42 |
+
|
| 43 |
+
| Cutoff | Misses "Hey Maya" | Wakes by mistake, per hour |
|
| 44 |
+
| --- | --- | --- |
|
| 45 |
+
| 0.99 (chosen for the app) | 15.7 % | 1.18 |
|
| 46 |
+
| 0.98 | 13.9 % | 1.45 |
|
| 47 |
+
| 0.97 | 13.1 % | 1.80 |
|
| 48 |
+
| 0.96 | 12.8 % | 2.00 |
|
| 49 |
+
|
| 50 |
+
AUC 0.795. **It has never heard a real voice:** every "Hey Maya" it learned from, and every one it was
|
| 51 |
+
tested on, was synthetic speech (a different speech engine for the test than for training). Accuracy on
|
| 52 |
+
real voices, in real rooms, is to be measured on phones before release and will differ from this table.
|
| 53 |
+
Version 2 is to be trained on real recordings that people choose to share.
|
| 54 |
+
|
| 55 |
+
## What it was trained on
|
| 56 |
+
|
| 57 |
+
Only data the app may ship with (checked 2026-10-21):
|
| 58 |
+
|
| 59 |
+
- **"Hey Maya" for training:** synthetic speech from the [Piper sample generator](https://github.com/rhasspy/piper-sample-generator) (MIT), using its 904-speaker LibriTTS-R voice model (LibriTTS-R, CC BY 4.0).
|
| 60 |
+
- **"Hey Maya" for testing:** Phonon-31m English and its 37 English voices (Apache 2.0), a different engine, so the test is not the training voices again.
|
| 61 |
+
- **Near misses** it must not wake on ("hey mia", "hey mayor", "maya" on its own, other assistants' names and more): the same Piper generator.
|
| 62 |
+
- **Ordinary speech:** LibriSpeech dev and test sets (CC BY 4.0), with every utterance whose transcript says Maya, Maia, Maja, Mayer or Mayas removed.
|
| 63 |
+
- **Noise and music:** MUSAN (CC BY 4.0), 80 % of the files for training and 20 % held out for the test.
|
| 64 |
+
- **Room echo:** OpenSLR 28 RIRS_NOISES (Apache 2.0).
|
| 65 |
+
|
| 66 |
+
Credits: LibriTTS-R (Koizumi et al., CC BY 4.0), LibriSpeech (Panayotov et al., CC BY 4.0), MUSAN (Snyder,
|
| 67 |
+
Chen and Povey, CC BY 4.0), RIRS_NOISES (Ko et al., Apache 2.0), Phonon-31m (Apache 2.0), Piper sample
|
| 68 |
+
generator (MIT), microWakeWord (Kevin Ahrendt, Apache 2.0).
|
| 69 |
+
|
| 70 |
+
## How it was made
|
| 71 |
+
|
| 72 |
+
microWakeWord (Apache 2.0) at commit `4665173cd35f1cff9a61e06fc427f124766c488e`, its "mixednet" model
|
| 73 |
+
(`--pointwise_filters 64,64,64,64 --repeat_in_block 1,1,1,1 --mixconv_kernel_sizes '[5], [7,11], [9,15], [23]'
|
| 74 |
+
--residual_connection 0,0,0,0 --first_conv_filters 32 --first_conv_kernel_size 5 --stride 3`), 20,000
|
| 75 |
+
training steps, trained on 2026-10-21 on one rented GPU, then quantised to the streaming TensorFlow Lite
|
| 76 |
+
model above.
|
| 77 |
+
|
| 78 |
+
## Use and limits
|
| 79 |
+
|
| 80 |
+
- For starting Maya when its owner has turned "Hey Maya" on. Not for telling who is speaking.
|
| 81 |
+
- English, and the phrase "hey maya" only. "Maia" and "Maja" sound the same and were left out of the near
|
| 82 |
+
misses on purpose; expect it to wake on them too.
|
| 83 |
+
- It sometimes wakes by mistake and sometimes misses; a tap on Maya's pill always works as well.
|
| 84 |
+
|
| 85 |
+
## Licence
|
| 86 |
+
|
| 87 |
+
The model: Apache 2.0. The training data keeps its own licences, credited above.
|
hey_maya-v1.tflite
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:e95b7a1df30e0619dfa1f72134b0153d49f825cf4e63e656aa79ec0208da61bd
|
| 3 |
+
size 62304
|
tflite_streaming_roc.txt
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
AUC 0.79460
|
| 2 |
+
Cutoff 1.00: frr=1.0000; faph=0.000
|
| 3 |
+
Cutoff 0.99: frr=0.1568; faph=1.177
|
| 4 |
+
Cutoff 0.98: frr=0.1392; faph=1.454
|
| 5 |
+
Cutoff 0.97: frr=0.1311; faph=1.801
|
| 6 |
+
Cutoff 0.96: frr=0.1284; faph=2.000
|
training_parameters.yaml
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
batch_size: 128
|
| 2 |
+
clip_duration_ms: 1500
|
| 3 |
+
eval_step_interval: 500
|
| 4 |
+
features:
|
| 5 |
+
- features_dir: /workspace/tm2/wake/features/wakeword
|
| 6 |
+
penalty_weight: 1.0
|
| 7 |
+
sampling_weight: 2.0
|
| 8 |
+
truncation_strategy: truncate_start
|
| 9 |
+
truth: true
|
| 10 |
+
type: mmap
|
| 11 |
+
- features_dir: /workspace/tm2/wake/features/near
|
| 12 |
+
penalty_weight: 1.0
|
| 13 |
+
sampling_weight: 6.0
|
| 14 |
+
truncation_strategy: truncate_start
|
| 15 |
+
truth: false
|
| 16 |
+
type: mmap
|
| 17 |
+
- features_dir: /workspace/tm2/wake/features/speech
|
| 18 |
+
penalty_weight: 1.0
|
| 19 |
+
sampling_weight: 10.0
|
| 20 |
+
truncation_strategy: random
|
| 21 |
+
truth: false
|
| 22 |
+
type: mmap
|
| 23 |
+
- features_dir: /workspace/tm2/wake/features/noise
|
| 24 |
+
penalty_weight: 1.0
|
| 25 |
+
sampling_weight: 5.0
|
| 26 |
+
truncation_strategy: random
|
| 27 |
+
truth: false
|
| 28 |
+
type: mmap
|
| 29 |
+
- features_dir: /workspace/tm2/wake/features/ambient
|
| 30 |
+
penalty_weight: 1.0
|
| 31 |
+
sampling_weight: 0.0
|
| 32 |
+
truncation_strategy: split
|
| 33 |
+
truth: false
|
| 34 |
+
type: mmap
|
| 35 |
+
freq_mask_count:
|
| 36 |
+
- 0
|
| 37 |
+
freq_mask_max_size:
|
| 38 |
+
- 0
|
| 39 |
+
learning_rates:
|
| 40 |
+
- 0.001
|
| 41 |
+
maximization_metric: average_viable_recall
|
| 42 |
+
minimization_metric: null
|
| 43 |
+
negative_class_weight:
|
| 44 |
+
- 20
|
| 45 |
+
positive_class_weight:
|
| 46 |
+
- 1
|
| 47 |
+
target_minimization: 0.9
|
| 48 |
+
time_mask_count:
|
| 49 |
+
- 0
|
| 50 |
+
time_mask_max_size:
|
| 51 |
+
- 0
|
| 52 |
+
train_dir: /workspace/tm2/wake/trained
|
| 53 |
+
training_steps:
|
| 54 |
+
- 20000
|
| 55 |
+
window_step_ms: 10
|