DIY Alexa on ESP32 with INMP441

Hi,

Just started with Home assistant and already amazed with how advanced things are. Was away from electronics hobby for a few years and was still in the arduino / PIC dark ages.
I was wondering how to setup a homemade alexa without having the cloud interaction. Rhasspy seems to be a winner. Thanks to all the good work made by @synesthesian.
In my case my home assistant is one virtual apliance install in one VM without access to hardware. Also i don’t find pratical having to speak near the server. So the ESP32 seems a good idea for having a satelite solution to pass the voice commands to Rhasspy from more that one place.

Then i stumble with this video from Atomic14 in youtube. Not sure i can post it here. (https://www.youtube.com/watch?v=re-dSV_a0tM )

This is half the work done, already has the wake up voice detection and passing the wav to a destination. Left a comment for Atomic14 to have a look into this forum. Hope this is helpfull for everyone following this topic.

I feel grateful for getting in touch with people that have the same hobbys as i have.

Hope i’m not building castles in the air and this is all doable.

I just received my ESP32 dev kit + INMP441and setting up the Visual code install.

Count me in for any testing/developing on this branch of the project. Not a pro programmer, but will do my best.

Thank you!

4 Likes

Welcome and good luck!

Hi beared,

I had the same Idea and found your post on the search for solutions. Thanks for the hint at the Atomic14-Repo. At the moment I’m setting up Rhasspy on a faster desktop with pi1s I had lying around as satellites/wakeword-clients with microphone as a replacement for my snips-system.

As I only have 3 pi1s lying around and around 6 Rooms to cover with voice-control I’m always looking around for some costworthy alternatives to the pi. With this setup a satellite would only cost around 20 Dollars, which would allow me to even equip our basement with voice-control ;-).

I think these are no castles in the air, but the job could be done about 90% by Atomic14.
Will also try to get the hardware components so I can also try to get it working with rhasspy and contriubte some code-snippets. (I’m a Java-Dev, so C++ is writable but not my speciality) Will post the code-Repo here as soon as I have the hardware and the time to make some progress.

1 Like

I also toyed with the idea a while ago:

For instance, I have this little piece of hardware lying on my desk:

Unfortunately I haven’t found the time yet to try to implement something. But I’d definitely like to have something cheaper and less power-hungry than a Raspberry Pi to work as a Rhasspy satellite.

@koan that is a nice device!
I wanted to have a small device as well and this seems exactly what I need.
My plans are to have a device like this each room, with some wakewords.
For instance, when my daughter enters her bedroom, she can say “lights on” and the light in her room switches on.
There would be this deviceL

  • lights on wakeword
  • lights off wakeword

Both of them taking action right away, so it is not a voice assistant but rather a very simple, very view command system.

Why? Because when you enter a small room, first activating the assistant and then ask it to switch a light takes too much time. It is much faster to flick a switch.

The Matrix Voice is not suited for such use cases, mine is not even in use at this moment since I have no nice case for it.

So you would train it then to recognize just a limited set of commands/wakewords? That’s actually a nice idea, a sort of ‘audio switch’ instead of a tactile switch.

Yes indeed, most of you want to turn on a couple of lights or activate a scene.
So, if you walk into your livingroom you can say “lights on” or something like that.
Rhasspy can be trained with Raven and you should be able to get something going with MQTT, Node-red to create actions directly responding to wakeword activation. In this case turn a set of light on or off.
Even better would be on device wakeword, but that is harder to do

1 Like

Hi Cephos,

Have you tried to compile the code from Atomic14 repo?
I’ve tried but got stuck on the fmax function not included in the C compiler i’m using.

Installed the Visual code and PlatformIO from scratch in Windows but i’m missing something cause there are many compile errors.

Bucket of cold water… as i was very interested in this.

Hello!
It`s really good idea to use small hidden device instead Raspberry.
Unfortunately I am not a programmer and cannot help. But there is a link to espressif voice project.

And similar DIY project.

1 Like

Haven’t really looked at I2S on the ESP32 but at $5 a pop with built in flash they make great little devices.

I will have a look at that vid later one time.

I did notice it mention the Google Command set which is just a collection of audio files and for some reason no-ones mentions this but its full of bad word recordings that really have an affect on accuracy.
I spent ages cleaning it up and removed almost 10% of samples from the ver 2.0 collection and got a huge accuracy increase.

1 Like

Hopefully this won’t derail the thread - but couldn’t an ESP32 device simply function as a duplex audio streaming device and let the base process the stream for wake words/intents? That’s what the base already does, and it removes programming/wake word detection complexities from the ESP32, basically turning the device into a mic/speaker stream that can be consumed by the base station.

I can’t imagine the audio streaming network usage to be large (I’d guesstimate less than 15KB/s).

If this is trivial enough to do, I guess it would be up to Rhasspy to support multiple simultaneous in/out audio streams that could be aliased like a satellite id (so different intents could trigger from the ids of different streams, so “turn the lights on” on stream1 is for one room, stream2 is for another, etc.)

Hmm, interesting. Your post prompted me to search a bit about the INMP441 (I hadn’t heard of it before). There’s a Youtube video about using it with ESP32 which you may already have seen ( https://www.youtube.com/watch?v=m8LwPNXqK9o )
I think I’ll order an INMP441 to play with!

Any I2s mic will do but the INMP441 are very cheap on ali express https://www.aliexpress.com/item/4000045517597.html

I got some pre brexit but seems a lot are now not supplying the UK

ESP32 could well function as a duplex device the ram considerations for ring-buffers and generally resources are pretty low but quite a lot is possible.

Also there are a few different types of ESP32 but the Wrover version often is just a tad more expensive but has more RAM and probably more likely.
There are some dev boards loaded with mics and codecs but really they are just a Wrover mounted with ancillaries @ approx pi zero price or above and prob a bit pointless as an I2S mic & Amp are really dirt cheap now.

I really like what Atomic did in the above vid and have been banging for a while about either a tensorflow, keras or pytorch KWS as for some reason the Precise implementation seems to be very heavy.

Be wary of the Google command set and the old adage of “Garbage in / Garbage out” as this seems very true of models.
I was using the Linto HMG with the “Visualise” key word from the Google Command set ver 2.0.
The GUI is just a handy tool as it shows false positives/negatives with an easy button to play and this led me to realise how bad many of the samples are in the Google Command set.
Just really simple stuff of badly cut words, very bad recordings or pronunciation which I had presumed would of already been trimmed from the dataset.
Not so approx 10% is bad and if you take the time running and deleting bad your overall accuracy will sky rocket.
Add a few of your own recording, pitch shift slightly, trim and normalise with a touch of variation and add background noise will create a qty that will also greatly increase accuracy.

Using a distinct 3 phoneme word ‘visualise’ helps much but doesn’t have a snappy name like Marvin.

The ESP-32 does have a AMR-WB encoder or WAV but quite a choice of decoders.
I really like what Atomic has done as if you could include the keyword hit score in the audio stream you could broadcast from keyword hit to silence and use the hit score metadata to pick the best mic signal from an array of mics that is far better than just an RMS target.

The $5 ESP32 are exceptionally cheap don’t need an SD card to program and also do models with a U.FL antenna connector that can greatly help with signal level of on board types.
There is no far field if you can cheaply place a distributed array which is an extremely beneficial option whilst we still have lack of Linux opensource beamforming.
Picking the nearest mic on the strongest keyword hit doesn’t need any fancy algs.

The raspberry Pi is the same and for audio in you can just wire up 2x I2s mics very simply to gpio but the esp32 wrover is actually much cheaper than a Pi0

I did notice this design by the invensense engineers https://invensense.tdk.com/wp-content/uploads/2015/02/Low-Noise-Directional-Studio-Microphone-Reference-Design1.pdf
Ignore the array and think of as 2 mics part of an I2S pair and I presule we could do as they did it. Digitally would be just subtracting the value of 1 mic from the value in the other mics delay buffer but still have to try.
https://invensense.tdk.com/wp-content/uploads/2015/02/Microphone-Array-Beamforming.pdf

1 Like

Just one update.
I did have it compiled in windows visual code+platformio installation with the latest code atomic14 made available.
One blocking point was also the mic interference i was getting cause i ran the wires bellow the board. It was picking up the wifi radio interference. After i changed that the wake word detection rate increased a lot.
Also wired the output board (MAX98357) to the speaker. It works great.

Hi there,

Yes time is not always available. I managed to get the HW setup up and running. Now just need to make the coding going.

Hi Alexey,

Thank you for sharing that. Added to my library.
I’ll also will take a look at that. But for now i want to follow this path till the end.

Hi there,

Not derailing the thread. I did think of that option, but after watching the video i shared, i loved the way it was laid off and explained and just for that it made my day!
I’ll stick down this path till the end. The solution you pointed can be another project or branch as there are many branches in the rhasspy project.
Although i see that having ie 5 satellites streaming all the time to the rhasspy could have a impact on functionality and make it not work.
The wake word detection on the ESP32 is the way i want to go.(Done!)
Passing the audio stream to rhasspy is the next step.
Keeping traffic low and under control makes a tidy network :slight_smile:
(I see what the reader is thinking, yes we can implement VLANS…)

You don’t need to stream all the time as you can use VAD to stream from KW hit till silence.
This also gives the option of maybe MQTT or another port to send KW hit level to accompany the stream.

That way you can have distributed mics that do not broadcast all the time and you can encode to amr-wb to reduce bandwidth.

I wouldn’t want constant streaming mics but have no problem with a sentence from kw hit till vad silence or timeout.

I have a hunch you might see another instalment from atomic for a KWS on ESP32

Maybe have a look at my streamer for ideas:

Check also the rewrite branch, much cleaner already but stripped of some features (w.i.p.)

PS if anyone is interested in setting up a github and discussing some ideas.

I think Atomic since he kicked started the should be given the chance to opt-in, maybe lead.

Personally I think there is are some good reasons to focus on the AI Thinker A1S as its a Wrover with a AC101 coded built in.

The all-in-one dev kit is available for £14 but the actual A1S modules is less than $5.
The dev board does work with the ESP32 ADF and it can be found here.

You just have to download the toolchain set the adf path to this directory and the idf path to the one contained.

If you combine with a single good quality uni-directional mic you can provide extremely cheap high quality distributed mics.

The ADF contains AMR-WB encode and have been playing with the ALC but doesn’t see to work but many heads make short work.

I am just using the dev board for now but the idea of a simple cheap custom board for the A1S module is enticing.

Hi, I made a simple INMP441 device on " [ESP32-Rhasspy-Satellite] " https://github.com/Romkabouter/ESP32-Rhasspy-Satellite/issues/52 for my esp32cam. I hear correctly the voice (alexa) that I have collected with a script querying mqtt, but wakeword is not recognised by Porcupine on Rhasspy (2.5.9). Any ideas?

Did you properly declare the satellite id in your rhasspy instance?
Maybe post your rhasspy config for review.

I confirm I declared satellite siteIds.
This my config:

{
"dialogue": {
    "satellite_site_ids": "satellite",
    "system": "rhasspy"
},
"handle": {
    "satellite_site_ids": "satellite",
    "system": "hass"
},
"home_assistant": {
    "access_token": "xxx",
    "handle_type": "event",
    "url": "http://192.168.1.108:8123"
},
"intent": {
    "satellite_site_ids": "satellite",
    "system": "fsticuffs"
},
"microphone": {
    "command": {
        "record_arguments": "udpsrc port=12333 ! rawaudioparse use-sink-caps=false format=pcm pcm-format=s16le sample-rate=16000 num-channels=1 ! queue ! audioconvert ! audioresample ! filesink location=/dev/stdout",
        "record_program": "gst-launch-1.0"
    },
    "system": "hermes"
},
"mqtt": {
    "enabled": "true",
    "host": "192.168.1.108",
    "port": "1883"
},
"speech_to_text": {
    "satellite_site_ids": "satellite",
    "system": "kaldi"
},
"wake": {
    "debug": "true",
    "porcupine": {
        "keyword_path": "alexa_linux.ppn",
        "sensitivity": "0.5"
    },
    "raven": {
        "keywords": {
            "alexa": {
                "enabled": true
            }
        }
    },
    "satellite_site_ids": "satelitte",
    "system": "porcupine"
}

}

This is my settings.ini of ESP32-Rhasspy-Satellite:

[General]
hostname=192.168.1.108
deployhost=192.168.1.108
siteId=satellite
;supported: M5ATOMECHO=0, MATRIXVOICE=1, AUDIOKIT=2, INMP441=3
device_type=INMP441

[Wifi]
ssid=xxx
password=xxx

;uncomment next 4 lines and fill with your own values if you want to use a static ip address
ip=192.168.1.23
gateway=192.168.1.1
subnet=255.255.255.0
dns1=192.168.1.1
;optional: second dns server
;dns2=192.168.xxx.xxx

[OTA]
;supported: upload, ota, matrix
;-upload: device should be attached to computer via usb
;-ota: will use espota
;-matrix: matrix voice should be attached to a raspberry pi with matrix software.
;         deployhost should be set to ip of the pi
method=upload
password=OTApassword
port=3232

[MQTT]
hostname=192.168.1.108
port=1883
username=
password=

I have this error:

[DEBUG:2021-04-03 22:59:21,748] rhasspywake_porcupine_hermes: Enabled                                                                                                                                                                                                                   
[ERROR:2021-04-03 22:59:21,729] rhasspyserver_hermes:                                                                                                                                                                                                                                   
Traceback (most recent call last):                                                                                                                                                                                                                                                      
  File "/usr/lib/rhasspy/.venv/lib/python3.7/site-packages/quart/app.py", line 1821, in full_dispatch_request                                                                                                                                                                           
    result = await self.dispatch_request(request_context)                                                                                                                                                                                                                               
  File "/usr/lib/rhasspy/.venv/lib/python3.7/site-packages/quart/app.py", line 1869, in dispatch_request                                                                                                                                                                                
    return await handler(**request_.view_args)                                                                                                                                                                                                                                          
  File "/usr/lib/rhasspy/rhasspy-server-hermes/rhasspyserver_hermes/__main__.py", line 923, in api_listen_for_command                                                                                                                                                                   
    async for response in core.publish_wait(handle_intent(), [], message_types):                                                                                                                                                                                                        
  File "/usr/lib/rhasspy/rhasspy-server-hermes/rhasspyserver_hermes/__init__.py", line 985, in publish_wait                                                                                                                                                                             
    result_awaitable, timeout=timeout_seconds                                                                                                                                                                                                                                           
  File "/usr/lib/python3.7/asyncio/tasks.py", line 423, in wait_for                                                                                                                                                                                                                     
    raise futures.TimeoutError()                                                                                                                                                                                                                                                        
concurrent.futures._base.TimeoutError                                                                                                                                                                                                                                                   
[DEBUG:2021-04-03 22:59:21,752] rhasspyasr_kaldi_hermes: <- AsrStopListening(site_id='default', session_id='default-default-aa04462f-f0cf-40b0-97e7-8a199ee4884c')                                                                                                                      
[DEBUG:2021-04-03 22:59:21,755] rhasspyasr_kaldi_hermes: -> AsrRecordingFinished(site_id='default', session_id='default-default-aa04462f-f0cf-40b0-97e7-8a199ee4884c')

I believe the microphone on the rhasspy instance should be disabled (not set to hermes). The way it is right now it expects to get mic data for the site name of the rhasspy instance and not reading from “satellite”. Once you disable the mic in the rhasspy instance it would read from the satellite siteid. Also note that I observed that a rhasspy instance can only do wake word detection for only one audio source.

This should be 3, not INMP441. But apparently that works too :smiley:

The mic should be set the hermes, but your server should be something other than “satellite”, is it?
If you have 1 device, you can set the server is to satellite, and remove all satellite-id from the inputboxes.

The yavilevich method is the way, thank you!

The default/satelitte configuration is not working.

I have last version of Rhasspy (2.5.10) of docker in a Qnap NAS.

1 Like

Glad you got it sorted. Hopefully you will share/publish your INMP441 work.

That is not accurate. The default satellite configuration is meant for a main and a satellite where both are raspberry pis, each running its own wake detection engine locally. I believe it works fine that way.

When the satellite is an ESP32 which doesn’t do its own wake detection you will need a rhasspy raspi instance to do detection for the ESP32. Each rhasspy instance can only do one wake detection process at a time so you can’t have a main do both its own audio processing and one for the satellite. This is why you need to disable the processing of audio on the main and set it to process for the satellite by adding the satellite name. Perhaps having both use the same site id will also work, I have not tried that.

The reason why one rhasspy instance can only do one wake detection at a time seems to be historical. It is not a bug. I believe synesthesiam mentioned that he would want to refactor that someday. It probably needs an architectural change.

Thank you yavilevich !

There is a possibility that esp32 can do local wake detection?

It should be possible but not sure about the quality of detection that can be achieved.

Atomic14 (the topic of this original post) got close. check his solution.

I am not familiar with other implementations.

that seems a very interresting project
is there a lot of latency ?
could you make a small video like Atomic14’s ?

You can on ESP32 but the models you can run are limited but from what I have seen much is due to poor choice of training.
Many seem to use the Google command set which really is a benchmark dataset and deliberately contains wide universal variation with approx 10% bad.
It needs to be that way as all state-of-art KWS would be registering 100% and its use as accuracy benchmark would be little use.

I have learnt some tricks from the Google-KWS repo https://github.com/google-research/google-research/tree/master/kws_streaming which adds a 3rd classification to KW & !KW which they call ‘silence’ which is just background noise and that really helps accuracy as many low volume signals that could be a lottery between KW & !KW have another classification entropy and that simple addition increases accuracy.
I thought it was some sort of VAD/SAD implementation but it is a sort of catch-all for anything not KW or !KW.

If you are making a custom model then use the voices that will use it and record on the device of use where KW is obviously the KW and then some choice sentences split into words of ‘voice of use’ become !KW.
When you choose a KW it needs to be as unique as possible with hopefully a 3 phone/syllable word.
Also they use the background_noise folder to produce the ‘silence’ category but also mix into KW, !KW.

Atomic did a great implementation of code and that broadcast on KW till silence (remote vad) should be very possible, his dataset choice and training methods where not so good from choice of KW to dataset.
Which is great as you could use his code but work on a better dataset and choice of KW that is ‘your voice’ on ‘your device’ in ‘your room’.
The further you digress from actual use obviously the less accuracy you get, but from playing with the GoogleKWS I can get 100% validation with models that are extremely tolerant of high levels of noise that vastly surpass any KW system of Rhasspy and much is purely training.

TensorflowML is under heavy development but MFCC front end and models is part of the Google Streaming KWS I do have a couple of ESP32 just never got round to trying but on a Pi3A+ they are extremely lite running less than 20% on a single core.

Prob though the new ESP32-S3 which has SIMD vector acceleration specifically for NN models is likely to be a killer platform for satelite VoiceAI.

English phonetic pangrams

Pangrams which use all the phonemes, or phones, of English (rather than alphabetic characters):

  • “With tenure, Suzie’d have all the more leisure for yachting, but her publications are no good.” (for certain US accents and phonological analyses)
  • “Shaw, those twelve beige hooks are joined if I patch a young, gooey mouth.” (perfect for certain accents with the cot-caught merger)
  • “Are those shy Eurasian footwear, cowboy chaps, or jolly earthmoving headgear?” (perfect for certain Received Pronunciation accents)
  • “The beige hue on the waters of the loch impressed all, including the French queen, before she heard that symphony again, just as young Arthur wanted.” (a phonetic, not merely phonemic, pangram. It contains both nasals [m] and [ɱ] (as in ‘symphony’), the fricatives [x] (as in ‘loch’) and [ç] (as in ‘hue’), and the ‘dark L’ [ɫ] (as in ‘all’) – in other words, it contains different allophones.)

I have been trying to twist Atomics arm to give it another go but failing :slight_smile:

Thanks rolyan_trauts ! What you write is fascinating, and I realize that I know nothing about it.
I understand that you have experience in the implementation of these models. Do you think you are able to implement a compatible model for ESP32 to be integrated into the ESP32-Rhasspy-Satellite program so as to realize the local wake word?

Nope as its just my opinion but the manner of satellites/hermes audio is just a really poor implementation and was done backwards with server first and protocol with satelites being this addon.

Also I wouldn’t really want to hack anything but its already there in what Atomic did it just needs to broadcast from KW and controlled to stop via remote vad and not just a long timeout.

What atomic did was great but even that CNN if used with a better dataset maybe use the models from G-s-kws it would be far more accurate.

As far as I can gather to use remote vad you need to communicate with hermes audio which is just such a brainfart to send audio chunks over mqtt encrypted and that alone takes much resources.
I think the http chunk method doesn’t exist but I don’t use because of my dislike of a whole lot of pointless that the only rationale is some sort of branding I just don’t get.
If you can do remote vad over http with MQTT just being a message control protocol it should be then the answer is yes but would like a ESP32 wizz rather than me hacking Atomics code.

I have MS and my memory with coding is extremely frustrating so tend to not, but yeah with better datsets and what I have been playing with out of curiosity is that KWS can be far more accurate and tolerant with better recipes of dataset.
I haven’t tried the TFL4M but see references for the microcontroller version quite often as Google seem quite active there. We have all seen Atomics code work and I know with a better dataset it would be more accurate.

Tensorflow lite for Arm mobile can delegate layers out to any delegate from full TF to another ‘engine’ but with the microcontroller it likely your not going to have larger libs installed and use only layers in TFL4M.
Google have variation of a CNN that I think is streaming on ESP32 and only a couple of % behind state-of-art NN in accuracy, but so is any with a better dataset.

A KWS should be outside of rhaspy and be like any form of HMI where it connects to a server that converts to protocols needed as there is no need to embed system protocols in any HMI even a KWS and said this a couple of times.

So the answer is no not because a ESP32 KWS would not work or well but purely because the Rhasspy infrastructure is whack.

I recently found out about the Knowles Smart Mics. (IA611). (thanks to Atomic14).
They are small digital MEMS microphones for a few dollars (not much more than the INMP441) but they integrate logic and a dsp to do the keyword recognition themselfs (only needing about 2 mA in listen mode).

I thought about buying a eval kit (to have board and not just a small SMD mems mic) but: They do not provide the API and firmware open on their website. You need to apply for it. And you can only apply as company. I tried it with company “None” but well it’s been a week and now anser. Not very DIY/maker friendly :frowning:

Atomic apparently is trying to get the Dev for a review

I have a PR open for this.

I need to implement it for the other wakeword systems as well.
Also, I am hoping that porcupine creates a lib for esp32 so I can implement a local hotword detection for the esp32-satellite.

4 Likes

@romkabouter
For local hotword detection, an alternative could be implement TensorflowLite model as Atomic14 did in Alexa Project. What do you think?

Yes, I was thinking about that but I think it will require a lot of effort for users to be able to use it.
This with regards to training and such, but I will have a better look. Maybe it is easier then I think :slight_smile:

I’m agree with you. Anyway it could be possible to provide more solutions to realize hotword detection, that a user can select configuring setting.ini file.

The only thing Atomic got wrong was the dataset as it confuses all as the ‘Goggle command dataset’ is a benchmark dataset to test accuracy and hence contains a high proportion of bad samples and extremely varied accent content.
If you are making a custom dataset you should use the input voices only as why add native accents from around the world without the possibility they are coming to visit.

Also he used Marvin which is 2 syllable and fairly short whilst 3 syllable and filling the frame as ‘heymarvin’ would also of been much better, contains more phones and is more unique.

A couple of choice sentences can return 40 or more words and the only hassle is repeating your KW the same amount of times.
Record on the device of use and mic of use and then tools such as Sox can quickly augment to result in 1-2k KW & !KW.

Atomic also followed the basic audio Tensorflow example which is more of an introduction than a supposed working KWS where google have published a framework of current state-of-art KWS.

I have published a repo just to make it easier to get started and install tensorflow & tensorflow addons (not needed for esp32 as delegation is not supported)

I also created a sample repo of how to create datasets as a last thing that was missing from Atomics KWS was a silence classification which acts as a catch all between spoken KW and spoken !kw and greatly increases accuracy.

https://www.tensorflow.org/lite/microcontrollers supports ESP32 and the CNN examples in the G-KWS are perfect to export to microcontroller and use the front-end ops for microcontrollers.

When you create your dataset the quantities of samples greatly effect the classification weights and with the 3 classifications of Silence, !KW & KW the quantities they contain can be tweaked to attain the results required.
Training is in for stages with prob 2k steps each being a minimum and 8k starting to get to a point of no real return.

You can get an extremely noise resilient KWS that far surpasses ASR which is not tolerant of noise.

All very nice, but the DIY Alexa project uses marvin as keyword.
I might try and add it, but the keyword should be a custom keyword.
This involves training the model and for some of us training it will do fine, but for most of use (users instead of tinkerers) a better tool is needed to train custom models.
If there was a tool users can easily use to train their custom keyword, it would be great. I could not find such a tool.

I will investigate that project and I might be able to incorporate the marvin keyword.

As said Marvin because of a low phonetic count is a bad choice and Atomic got poor results on that even A-Lex-A is 3, Hey-Goo-Gle are better, use Marvin if you wish but the shorter and less phones the less accurate your KWS will be.

There is no such thing as a better tool to train custom models as it runs from a single command line and is by Google Research for state-of-art KWS for liteweight platforms.
Nothing needs to be done to train a model as that is all done with tensorflow or other frameworks, the work that is needed and is critical to results is the dataset builder.
You need to build a dataset where training/testing/validation sets are made for the right percentages for 3 classifications ‘silence’ ‘!kw’ & ‘kw’.
You need to mix in background noise and not make the classic error of drowning the foreground and its that simple.
Its a button press to train from then and just wait for step completion and resultant .pb and .tflite

I just knocked up the dataset builder for @synesthesiam so he could take a look at the rough requirements and maybe at one stage provide an interface through the web console.
Its extremely easy to augment samples so that relatively small 20-40 word samples can be varied that quickly become 1-2k in each classification.

An on screen prompter should provide some phonetic language sentences that for a language contain as many phones & allophones and don’t have to make sense and prob could be contributed by the community.
For English examples are http://clagnut.com/blog/2380/#English_phonetic_pangrams

*“With tenure, Suzie’d have all the more leisure for yachting, but her publications are no good.” *
“Shaw, those twelve beige hooks are joined if I patch a young, gooey mouth.”
*“Are those shy Eurasian footwear, cowboy chaps, or jolly earthmoving headgear?” *
“The beige hue on the waters of the loch impressed all, including the French queen, before she heard that symphony again, just as young Arthur wanted.”

4 simple sentences can provide enough for an initial model and then its choose your KW and repeat approx x40 and starter model is good to go with the addition of a background_noise folder.

The G_KWS & Dataset_builder where just proof of concepts to test resultant accuracy and the results are extremely high.

The Google KWS framework plus a dataset builder should reside on Rhasspy as then the collection of use of KW and !KW command sentences can be used to create highly accurate KWS far in excess of what ASR is capable of as the resultant .tflite model files can be shipped out OTA to any satelite and a system will get better through use.
It just needs web front end putting on it but it would seem apart from Synesthesiam who already provides a mass of code there is a lack of ability than to merely copy projects and rebadge but the actual code is there and process is fairly simple as even a non coder like me can create something in python that works and proves its concept.

1 Like

I’ve finally made some progress this week on KWS. The Google system @rolyan_trauts mentioned works pretty well, but it’s always bugged me that you need to start from scratch each time you train a new keyword.

Then I came across this paper: Few-Shot Keyword Spotting in Any Language. Their approach mixes aspects of an earlier proposal from @rolyan_trauts:

  1. Gather 1 million+ samples of hundreds of keywords from open speech data like Common Voice
  2. Augment the samples with time shifting, background noise, and SpecAugment
  3. Train a KWS model to classify each of the keywords (as well as a “background” category)

So far, this is a vanilla keyword spotter, but here’s what I think is the cool part:

  1. Freeze the model weights and put them on top of a second model that will only classify KW, not-KW, and silence/background
  2. Train on ~5 positive samples (augmented as before), as well as some negative/background – about 256 total

By choosing the initial keyword set carefully (multiple languages / broad phoneme coverage), you can pre-train a very robust system. The final customization can then be done on device with very few examples.

I trained a model like the paper’s using augmentation techniques from @rolyan_trauts’s dataset builder, but with a lot of other corners cut (no attempt to balance categories, etc.). The results were surprisingly good, but the CPU usage was not (20% on my desktop). So I’m going to try this trick with the Google KWS CRNN model – pre-train on many keywords, freeze weights, add layer, train on one keyword.

3 Likes

Yes, but Marvin is used in that project

What I need is existing keyword models or a clear and simple tutorial on how to create them
You say:

But it is the “from then” part which is totally unclear to me. Building a dataset? Mixing background noise? Probably simple when you have build enough knowledge on the whole topic, but I do not have that.
I will have a look on the dataset builder repo, but it still requires efforts for users to build their own keywords.

What I want for my project is a set of keywords already existing and from which a user can choose and enter in settings. For tensorflow, the only example I got is Marvin

I would be extremely useful if it would work like raven does in Rhasspy.
Record a couple of samples and then download a model

The difference between a universal prebuilt model and a custom tailored model can be a noisy WER (Word Error Rate) difference of almost 30%.

Marvin is used in that project purely because Atomic choose to use the 1 second ‘Marvin’ samples for a KW, but as said the ‘Google command set’ is a benchmark dataset that contains up to 10% bad and has an extremely high proportion of non native speakers.
Its a dataset to test the metal of the best state-of-art KWS models to give a datum that no KWS will manage 100% as we would not be able to differentiate accuracy.

You do not build keywords as keywords are just a collection of 1 second samples of the keyword being spoken and you record keywords.
If you want existing keywords then that has to encompass all regional variation, gender and age profiles and all noise profiles and microphone response and the difference in end WER to a custom model using the conditions of use is absolutely massive.

That is what I am saying as you can do what raven does but create highly noise resilient. extremely accurate lite-weight KWS that scale voice actors without extra load.
You record approx 20 - 40 KWs in a web boutique that merely asks you to emphasise a pause between words and silence strip a spoken recording into 1 second samples.
They are then augmented with pitch, tempo, volume and padding to create small variations to create a larger number of samples because the 10% validation and testing parts of the dataset expect a minimum of 100 so we need a minimum 1000 which is automated from the initial 20-40 extracted words of a recorded sentence (the different samples of noise mixed greatly varies sample and creates noise resilience).

Its also better to record twice @near & @far usually (0.3m & 3m from your mic but whatever the far sensitivity allows) the natural room reverberation and proximity effects will be recorded to create more accuracy but you can just do near as the accuracy increase is only fractional compared to the huge increases of a model based on the voices of actual use.

For tensorflow Tensorflow give examples in fact they have created a MFCC front end for microcontrollers specifically for KWS whilst Atomic just uses the casual introduction tutorial to audio spectrograms.

Its documented here and I have posted this now a plethora of times to even have it deleted.

TensorFlow Lite for Microcontrollers step by step it shows the simple procedure for taking a tflite model Get started with microcontrollers

The info and procedures have been there for 2 years but the recent introduction of the Audio “frontend” TensorFlow operations for feature generation was obviously a stumbling block so they now provide the microcontroller code.

From code to tutorials to training framework its all provided 100% by Google and its state-of-the-art and all it needs is a Web GUI to record and review KW, !KW & Silence.

Its so simple that a brain damaged MS sufferer with no Python experience can hack together extremely accurate working models that surely any Rhasspy dev can automate as example proof of concept have been forwarded by a community member above.

If you can not work it out for your self I can help and tell you how as maybe my confusion why this hasn’t been implemented and why code is just being copied rebranded whilst the likes of Google have opensource already provided.

You just have to read what they have provided like I have done and keep posting here to no avail.

The more custom a model goes from all voice to native speaking, to regional accent, to own voice are massive steps in accuracy as a model becomes more defined as the reality is they are little more than highly evolved tensor classification filters and the less cross entropy in the dataset means more clear cut classification and higher accuracy and its that simple.

sox -m noise.mp3 voice.wav mixed.flac what is so confusing about that in terms of a dev providing a solution?
All I am stressing is that the noise samples need to be volume matched to dataset samples otherwise the noise may become the foreground audio turning the dataset sample into a garbage entry.
Check volumes and adjust before mixing and this is just simple code that has been missing for some time (always mix in noise at a lower volume than the sample or the sample will be overwritten) as the Precise training methodology is broken and introduces large proportions of garbage and cross entropy.

It shouldn’t end there because we are on a local private VoiceAI we should be able to easily capture KW and command sentences to create datasets of use and a KWS that ships out models OTA that increase in accuracy by use by using the recorded samples of use automatically in a 2 stage firmware like delivery.

I just got a like on this topic and saw your reply.
@synesthesiam The new federated learning additions are really important as a new keyword always needs to trained from scratch as you are pattern matching on a keyword which is far more accurate or should be than phonetic dictionary based ASR.

So it doesn’t solve that but if you want to add to the dataset you always had to have the full dataset and retrain where now with federated learning you can train a main model and then have a smaller local model specific to user and device hardware that alters the weights of the main model.
So you can increase accuracy for a user and device for accent and device usage tonal results.

I haven’t worked it out yet but know from the new Pixel phones it is what they use to such effect there models are now offline.
The new Tensor TPU and cutting edge phone obviously has some grunt but currently Googles mobile models seem to be providing leading edge ASR & KWS and a few other great AI enhanced methods as well as what has become normal in HDR photography.