Locale Alexa

Il s’agit d’implanter un agent conversationnel complètement autonome sur une Raspberry Pi 3 B+. Le but est de ne pas être dépendant du réseau.
L’article actuellement traite de la reconnaissance de la parole spontanée. Une première partie concerne l’installation de Python et des packages de deep learning. Dans une seconde partie, on teste la reconnaissance de parole, basé sur un système performant « Wav2Vec2 ».

Le but de cet article :

  • installer un environnement virtuel pour python
  • ajouter du swap (point technique)
  • installer les packages pytorch et transformers (Hugging Face/Meta)
  • utiliser la librairie transormers, pour :
  1. utiliser wav2vec2 pour la reconnaissance de la parole
  2. comparer les temps de calcul avec un PC sous linux

Mise en place de Python et des packages

Ci-dessous, de quoi faire une mise à jour du Rpi + installation du gestionnaire de version git (et d’autres trucs qui traînent là… à vous de creuser un peu, c’est p-e parfaitement inutile ou déjà installé)

sudo apt update
sudo apt upgrade
sudo apt install libffi-dev libbz2-dev liblzma-dev libsqlite3-dev libncurses5-dev libgdbm-dev zlib1g-dev libreadline-dev libssl-dev tk-dev build-essential libncursesw5-dev libc6-dev openssl git

En novembre 2022, plus besoin d’installer python 3.7 parce qu’il est présent d’office dans les versions récentes de l’OS, cependant il est plus prudent d’utiliser un environnement virtuel qui permet d’éviter de « tout casser ».

On va utiliser virtualenv, il y a bcp d’autres possibilités, j’ai l’habitude sous PC d’utiliser anaconda, mais là ça me paraît bcp plus light. L’installation est expliquée dans ce lien : https://raspberrypi-guide.github.io/programming/create-python-virtual-environment

Ci-dessous, la création d’un env virtuel « main » avec virtualenv (une fois virtualenv installé)

$ mkvirtualenv main
$ workon main
$ which python3
/home/pi/.virtualenvs/main/bin/python3
$ python3 --version
Python 3.7.3
$ pip install --upgrade pip

C’est tout bon! l’environnement virtuel (c-a-d séparé du reste du système, en partie) et python 3.7
(on sort de l’env avec la commande « deactivate »)

Avant de passer aux modèles de réseaux de neurones avec pytorch, on va devoir ajouter de la mémoire pour le swap

LE SWAP parce que le Rpi 3 n’a qu’1 Go de RAM (le Rpi 4 à 2 Go ça ne serait pas nécessaire. Bizarrement, on disant autrefois que si on a X Go de RAM il faut un swap deux fois plus grand, aujourd’hui sur Ubuntu et Debian (c’est les cas que je connais), ce n’est plus le cas par défaut on a quelques centaines de Méga. Parce que les ordinateurs modernes ont suffisamment de RAM j’imagine et parce qu’un swap de 16 ou 32 Go ça fait bizarre. Bref vous m’avez compris on a 1 Go de RAM et 100 Mo de swap, let’s add 512 Mo de swap: DEUX SUPERS ARTICLES EN FRANÇAIS : https://standartux.fr/astuces-ajout-de-swap-a-la-mano/ ET https://www.it-connect.fr/comment-ajouter-de-lespace-de-swap-sur-gnu-linux-debian-10/

créer le fichier de swap:
$ sudo dd if=/dev/zero of=/swap.file bs=1024 count=512000

$ sudo chmod 600 /swap.file
editer /etc/fstab comme indiqué dans le tutoriel,
$ sudo mkswap /swap.file
pour activer
sudo swapon /swap.file,

pour vérifierla mémoire utiliser la commande free -h :

total used free shared buff/cache
Mem 874Mi 123Mi ???? ???? ????
Swap 599Mi 10Mi 589Mi ???? ????

au moins si on dépasse les 800 Mo d’utilisation de la mémoire RAM, ça ne va pas complètement geler le Raspberry pi

On va installer pytorch, le paquet de d’apprentissage machine (profond ou pas) et de réseaux de neurones (profonds ou pas)

On récupère le build (wheel) sur un dépôt sur github : https://github.com/radimspetlik/pytorch_rpi_builds (au 10/2022)

Pytorch Raspberry Pi builds / Installing downloaded wheels

$ git clone https://github.com/radimspetlik/pytorch_rpi_builds.git
$ cd pytorch_rpi_builds,
$ cd torch
$ pip3 install torch-1.5.0a0+4ff3872-cp37-cp37m-linux_armv7l.whl
Idéalement il faudrait installer python 3.8 si on veut installer torchvision

Reconnaissance de la parole avec Wav2Vec2

On va faire de la reco de la parole offline (enregistrée) avec le package transformers fourni par meta/hugging face (https://huggingface.co/), https://huggingface.co/docs/transformers/model_doc/wav2vec2,
Wav2Vec2 est vraiment un bijou de technologie, il transforme un audio brut, pas des caractéristiques issues de l’audio, comme le spectrogramme mel, basé sur transformée de Fourier à court terme.

Wav2Vec2 réalise cette performance de prendre en entrée le signal brut, la forme d’onde, et de prédire non pas les phonèmes, mais les lettres! C’est un peu comme s’il avait appris à écrire (attention avec l’anthropomorphisme en IA, il faut vraiment s’en méfier).
La base du système est le module Wav2Vec, qui est appris sur une quantité astronomique de parole non transcrite, de manière dite non supervisée (pas de tâche précise), grâce à un critère appelé « contrastive predictive coding« . Après s’ajoute à cela une quantification vectorielle et l’utilisation de transformers, voir le papier fondateur « Attention is all you need ».

Codons un peu tout ça:

Pur l’intstallation de transformers sur CPU uniquement : pip install transformers[pytorch]

J’ai repris un code du site hugging face en le modifiant un peu. Sur le dépôt et le hub de hugging face, on trouve du code et des modèles etc. Hugging Face se met en position de leader dans le domaine des transformers et de la NLP (Natural Language Processing)
On utilise le modèle facebook/wav2vec2-base-960h, « base » signifiant qu’il est de taille raisonnable.
Mon code Python se trouve sur le dépôt https://github.com/laurentbenaroya/rpi_speech :
$ git clone https://github.com/laurentbenaroya/rpi_speech.git
$ cd rpi_speech
Le script est speech2text_wav2vec2.py

workon main
python3 -m pip install -r requirements.txt
python3 speech2text_wav2vec2.py ./audio/p232_228.wav

le téléchargement du modèle et du « processor » se fait lors du premier appel à la fonction, après il est stocké en cache.

Output de la commande ci-dessus :

facebook/wav2vec2-base-960h

tokenize
Elapsed time 0.32 sec

retrieve logits
Elapsed time 11.65 sec

take argmax and decode
Elapsed time 0.02 sec

transcription : LY EVIDENT THAT THE TIME FOR AN INQUIRY WILL COME

Ce n’est qu’un exemple mais la reconnaissance de la parole semble fonctionner. Il faudrait naturellement faire un benchmark. Le point important est que l’extrait ne dure que 2.63 secondes et est traité en 12 secondes. C’est très long dans la perspective d’un agent conversationnel. Par contre, niveau reconnaissance de la parole, c’est top.
Alors c’est tentant, on va faire la même chose sur mon PC (Intel® Core™ i5-6500 CPU @ 3.20GHz × 4 cœurs; 8 Go RAM; 64 bits; pas de GPU),
le temps total de calcul (tokenisation + inférence modèle + décodage) = 0.28 secondes, ce qui est parfaitement acceptable comme latence (je n’aime pas le terme « temps réel »), la véritable différence se situe sur l’appel au modèle (11.65 secondes sur Raspberry Pi 3 B+ contre 0.28 secondes sur PC en utilisant le CPU uniquement). Boum! Évidemment on comprends mieux pourquoi les agents conversationnels utilisent sur le cloud.

Affaire à suivre …