-
Notifications
You must be signed in to change notification settings - Fork 53
Reconnaissance vocale (expert)
Pour déclencher un nouveau service comme la qualité de l’air par la voix, il est nécessaire :
- d’adapter le modèle de reconnaissance vocale (ASR) afin de lui permettre de reconnaître les nouvelles phrases ;
- de définir les phrases possibles pour le modèle de NLU (Natural Language Understanding) ;
- de modifier le code du service (ici
nabairqualityd.py
) pour répondre aux commandes vocales.
L’adaptation du modèle de reconnaissance vocale est relativement rapide et pourrait éventuellement se faire directement sur le Pi Zero (?). Dans ce tutoriel, nous allons utiliser Docker sur desktop pour cette partie, le reste se faisant directement sur le lapin.
Sur desktop, récupérer le code source de pynab avec git (git clone https://github.com/nabaztag2018/pynab
), puis tout se passe dans le répertoire asr
.
git clone https://github.com/nabaztag2018/pynab
cd asr
Il s’agit de modifier le fichier nabaztag-grammar-fr.jsgf
pour adapter la grammaire aux nouvelles commandes, et éventuellement de compléter le fichier dict-fr-nabaztag.ipa
pour ajouter les nouveaux mots.
Ici, on modifie le début de nabaztag-grammar-fr.jsgf
pour ajouter <airquality>
dans la règle <control>
:
public <control> =
<noise> +
| [ <euh> ] ( <weather> | <airquality> | <8ball> | <surprise> | <taichi> | <carot> | <clock> ) [ <euh> ];
Et on ajoute la règle suivante :
<airquality> =
air
| [ <giveme> la ] qualité de l'air [ <date> ]
| [ <giveme> le ] taux de CO2 [ <date> ]
| quelle est la qualité de l'air [<date>] [ dehors | à l'extérieur ]
| quel est le taux de CO2 [<date>] [ dehors | à l'extérieur ]
| est-ce que je peux aller [ dehors | à l'extérieur ] ou c'est trop pollué
| c'est pas un peu pollué [<date>]
;
Il faut également ajouter les nouveaux mots dans le lexique dict-fr-nabaztag.ipa
. On peut récupérer les prononciations dans un dictionnaire beaucoup plus complet à cette adresse :
https://github.com/pguyot/zamia-speech/tree/master/data/src/dicts
Par exemple il nous faut les nouveaux mots suivants :
ou;u
pas;pa
peu;pø
pollué;pɔlɥe
trop;tʁo
Ensuite, on lance le script adapt-model.sh
avec le paramètre fr
qui fait tout le boulot, en s’appuyant sur zamia-speech. S’il manque des mots dans le lexique, le script échouera et il est possible de les rajouter et de le relancer.
bash adapt-model.sh fr
Au final, ce script génère le modèle sous une forme compressée (en .tar.xz). Il s’agit ensuite de le copier sur le lapin, de le décompresser dans /opt/kaldi/model
puis de modifier la configuration dans nabd/asr.py
pour utiliser ce nouveau modèle.
Le modèle de reconnaissance vocale en anglais est spécialisé de la même manière.
Il s’agit de créer des fichiers intent_*.yaml
pour chaque langue dans nabairqualityd/nlu/
.
Ces fichiers sont compilés par le script d’installation.
Le fichier pour le français est le suivant (il reprend grossièrement la grammaire du modèle Kaldi) :
---
type: intent
name: airquality_forecast
utterances:
- air
- donne-moi la qualité de l'air
- qualité de l'air
- quelle est la qualité de l'air [date:snips/datetime](aujourd'hui)
- est-ce que je peux aller dehors ou c'est trop pollué
- c'est pas un peu pollué [date:snips/datetime](aujourd'hui)
Tous les fichiers intent sont combinés en un modèle unique, chargé par nabd. Pour mettre à jour ce modèle :
cd /home/pi/pynab
venv/bin/python -m snips_nlu generate-dataset en */nlu/intent_en.yaml > nabd/nlu/nlu_dataset_en.json
rm -rf nabd/nlu/engine_fr
venv/bin/snips-nlu train nabd/nlu/nlu_dataset_fr.json nabd/nlu/engine_fr
venv/bin/python -m snips_nlu generate-dataset fr */nlu/intent_fr.yaml > nabd/nlu/nlu_dataset_fr.json
rm -rf nabd/nlu/engine_en
venv/bin/snips-nlu train nabd/nlu/nlu_dataset_en.json nabd/nlu/engine_en
Il faut ensuite redémarrer nabd pour qu’il charge les nouveaux modèles (ASR & NLU).
sudo service nabd restart
Il suffit d’ajouter une fonction process_nabd_packet
qui traite les paquets de type "asr_event"
avec la bonne valeur dans ["nlu"]["intent"]
.
async def process_nabd_packet(self, packet):
if packet["type"] == "asr_event" and packet["nlu"]["intent"] == "airquality_forecast":
now = datetime.datetime.now(datetime.timezone.utc)
expiration = now + datetime.timedelta(minutes=1)
self.perform(expiration, "today")