Instal·lació de sphinxbase i pocketsphinx a la RPi (proves)
Introducció
Estic aquí perquè vull fer un Magic Mirror amb reconeixement de veu (i en català). Estava instal·lant Jasper i m'he encallat amb la instal·lació de pocketsphinx a la RPi. Aquest és un tema prou important com per fer un tema apart.
Contingut
Instal·lació a la Raspberry Pi
How to install PocketSphinx on a Raspberry Pi
- https://howchoo.com/g/ztbhyzfknze/how-to-install-pocketsphinx-on-a-raspberry-pi
- https://manpages.debian.org/testing/pocketsphinx/pocketsphinx_continuous.1.en.html
1.
wget https://sourceforge.net/projects/cmusphinx/files/sphinxbase/5prealpha/sphinxbase-5prealpha.tar.gz/download -O sphinxbase.tar.gz wget https://sourceforge.net/projects/cmusphinx/files/pocketsphinx/5prealpha/pocketsphinx-5prealpha.tar.gz/download -O pocketsphinx.tar.gz
2.
tar -xzvf sphinxbase.tar.gz tar -xzvf pocketsphinx.tar.gz
Es creen les carpetes sphinxbase-5prealpha i pocketsphinx-5prealpha, que són els projectes correctes.
3. Install bison, ALSA, and swig
sudo apt-get install bison libasound2-dev swig sudo apt-cache search swig swig - Generate scripting interfaces to C/C++ code swig-doc - HTML documentation for SWIG swig-examples - Examples for applications of SWIG swig-sphinxbase - Speech recognition tool - swig helpers swig3.0 - Generate scripting interfaces to C/C++ code swig3.0-doc - HTML documentation for SWIG swig3.0-examples - Examples for applications of SWIG
4. Compile sphinxbase
cd sphinxbase-5prealpha ./configure --enable-fixed make sudo make install
5. Compile pocketsphinx
cd ../pocketsphinx-5prealpha ./configure make sudo make install
Els dos projectes s'han instal·la correctament i sense problemes (venia de fer la instal·lació de Jasper, i allí he tingut molts problemes).
6. Test out the installation
Aquí ve la part interessant.
Test out the installation
La RPi no té un microfon incorporat. Faig servir una targeta audio USB amb dos jacks (auriculars i mic).
$ cat /proc/asound/cards 0 [PCH ]: HDA-Intel - HDA Intel PCH HDA Intel PCH at 0xc2600000 irq 29 1 [Device ]: USB-Audio - USB PnP Sound Device USB PnP Sound Device at usb-0000:00:1d.0-1.1, full speed $ arecord -l **** List of CAPTURE Hardware Devices **** card 1: Device [USB PnP Sound Device], device 0: USB Audio [USB Audio] Subdevices: 1/1 Subdevice #0: subdevice #0
He de comprovar que funciona i que té una qualitat acceptable amb arecord i aplay. Per exemple:
$ speaker-test -c2 -D plughw:1 -twav $ arecord -f cd -t wav -D plughw:1 foobar.wav $ aplay -v -D plughw:1 foobar.wav
Com que encara no conec tota la teoria del modelat del llenguatge i les tècniques de reconeixament de la parla, hauré de fer una mica d'assaig/error.
$ man pocketsphinx_continuous $ src/programs/pocketsphinx_continuous -> es visualitza el help $ src/programs/pocketsphinx_continuous -samprate 48000 -adcdev 1 -inmic yes -adcdev Name of audio device to use for input -inmic yes
ERROR: "fe_interface.c", line 105: FFT: Number of points must be greater or equal to frame size (1230 samples) -nfft 2048 ERROR: "acmod.c", line 76: Acoustic model definition is not specified either with -mdef option or with -hmm pocketsphinx_continuous -hmm hmmdir -dict dictfile [ options ]... -dict pronunciation dictionary (lexicon) input file -hmm Directory containing acoustic model files -mdef Model definition input file
Aquests tres últims paràmetres són molt importants.
Aquí tenim el model amb anglès (lm , language model) i el diccionari que suposo que s'ha fet servir (és el llistat de les paraules que es vol reconèixer). El fet de servir un diccionari fa que es faciliti molt la feina. Per exemple, en el Magic Mirror, si tinc un diccionari petit de comandes que vull reconèixer, es facilita molt la feina i les probabilitats d'encert augmenten molt.
$ ls model/en-us/ cmudict-en-us.dict en-us en-us.lm.bin en-us-phone.lm.bin
-adcdev plughw:1,0 $ src/programs/pocketsphinx_continuous -samprate 48000 -adcdev plughw:1,0 -inmic yes -nfft 2048 -dict model/en-us/cmudict-en-us.dict -hmm model/en-us/en-us/ ERROR: "pocketsphinx.c", line 945: No search module is selected, did you forget to specify a language model or grammar? Building an application with PocketSphinx https://cmusphinx.github.io/wiki/tutorialpocketsphinx/
Falta encara el paràmetre -lm:
$ src/programs/pocketsphinx_continuous -samprate 48000 -adcdev plughw:1,0 -inmic yes -nfft 2048 -dict model/en-us/cmudict-en-us.dict -hmm model/en-us/en-us/ -lm model/en-us/en-us.lm.bin
No me n'en surto, i en comptes d'utilitzar el micròfon puc utilitzar wav files com a font d'entrada. Val a dir que en aquest punt no en tenia ni idea de què feia, i el wav file que tenia (que vaig trobar a Internet) no tenia res a veure amb el diccionari, i per això obtenia uns resultats estranys.
En qualsevol cas, el fitxer wav és important que sigui: it must be 16khz, 16bit mono WAV file:
16KHz sample rate -samprate 16000
El programa dóna molta informació a la consola, i si vull veure per la consola la informació que m'interessa farem (el que m'interessa surt per la consola, i queda guardat a words.log):
$ src/programs/pocketsphinx_continuous -samprate 16000 -adcdev plughw:1,0 -inmic yes -nfft 2048 -dict model/en-us/cmudict-en-us.dict -hmm model/en-us/en-us/ -lm model/en-us/en-us.lm.bin 2>./unwanted-stuff.log | tee ./words.log </pr> '''sox''' és una bona eina per convertir formats de dades. Per tal de què sox pugui convertir un mp3 a wav <pre> $ sudo apt-get install libsox-fmt-mp3
$ sox sss1.wav -r 16000 -b 16 -c 1 sss1_16000_16bit_mono.wav
$ src/programs/pocketsphinx_continuous -samprate 16000 -adcdev plughw:1,0 -inmic yes -nfft 2048 -dict model/en-us/cmudict-en-us.dict -hmm model/en-us/en-us/ -lm model/en-us/en-us.lm.bin 2>./unwanted-stuff.log | tee ./words.log telèfon (8KHz): $ src/programs/pocketsphinx_continuous -samprate 16000 -adcdev plughw:1,0 -inmic yes -nfft 2048 -dict model/en-us/cmudict-en-us.dict -hmm model/en-us/en-us/ -lm model/en-us/en-us-phone.lm.bin 2>./unwanted-stuff.log | tee ./words.log
Clarification: I understand that a large grammar will take a long time to initialize, but I don't think it should take a long time for recognition to run using it.
Estic fent proves i no és gens fiable, a part de què és lent.
aquí podria estar la solució. Necessito un diccionari que me'l puc fer jo mateix.
També està explicat aquí:
i per tant aquest servei web només és vàlid per a english.
What it does: Builds a consistent set of lexical and language modeling files for Sphinx (and compatible) decoders.
prova.txt:
united states of america france spain england germany colombia canada italy
Es generen aquests fitxers:
[TXT] 4836.dic 255 Pronunciation Dictionary [ ] 4836.lm 1.6K Language Model [ ] 4836.log_pronounce 165 Log File [ ] 4836.sent 148 Corpus (processed) [ ] 4836.vocab 76 Word List [ ] TAR4836.tgz 1.1K COMPRESSED TARBALL
I amb això tinc un diccionari petit i que funciona:
$ src/programs/pocketsphinx_continuous -samprate 16000 -adcdev plughw:1,0 -inmic yes -nfft 2048 -dict /home/pi/4836.dic -hmm model/en-us/en-us/ -lm /home/pi/4836.lm 2>./unwanted-stuff.log | tee ./words.log
i ara ja funciona (anglès) encara que va una mica lent. Estic reconeixent els països.
el hmm és el model definition (acoustic model files), que és el fitxer mdef que es troba dins de model/en-us/en-us/. Aquest fitxer consta d'una sèrie de paràmetes que es poden tunejar.
Com fer que vagi més ràpid? speed is traded of for accuracy. És a dir, si vull rapidesa, no tindré tanta fiabilitat.
llegir: (basicament el que he de llegir és un bon tutorial de speech recognition)
- https://cmusphinx.github.io/wiki/models/
- https://cmusphinx.github.io/wiki/tutorialadapt/#other-acoustic-models
Em preocupa el tema de la rapidesa. Em descarrego aquest model (que conté un fitxer mdef) a veure si hi ha canvis.
cmusphinx-en-us-ptm-8khz-5.2 $ cat feat.params -lowerf 130 -upperf 3700 -nfilt 20 -transform dct -lifter 22 -feat 1s_c_d_dd -svspec 0-12/13-25/26-38 -agc none -cmn current -varnorm no -cmninit 40,3,-1 -model ptm
$ src/programs/pocketsphinx_continuous -samprate 16000 -adcdev plughw:1,0 -inmic yes -nfft 2048 -dict /home/pi/4836.dic -hmm /home/pi/cmusphinx-en-us-ptm-8khz-5.2 -lm /home/pi/4836.lm 2>./unwanted-stuff.log | tee ./words.log També va bé, però és igual de lent. Puc millorar la rapidesa canviat el ''samprate'': <pre> -samprate 16000: 4 segons -samprate 8000: 3 segons -samprate 7400: 3 segons No puc baixar de 7400 Upper frequency 3700.0 is higher than samprate/2 (2000.0) el mínim que puc posar és 7400 -upperf 6855.4976 3.700000e+03
De moment no he pogut baixar dels 3 segons. Potser és normal perquè és un dels cons que es comenten de pocketsphins (la principal avantatge és que és offline, i per tant es garanteix la privacitat.
Model català
Català: anem a reconèixer la veu catalana
ca-es-models-v0.4.0.zip scp ca-es-models-v0.4.0.zip pi@192.168.1.60:/home/pi
fitxer paisos.txt compilo a:
i obtenim: TAR2874.tgz
NOTA: però això no funciona tal qual pel català. Aquesta pàgina web només funciona per l'anglès. FAQ: If you need non-English models you may still be able to use the tool, either by downloading quicklm or by using the handdict option (see below). Otherwise we recommend that you use one of the standard tools described above.
$ ls ca-es acoustic-model LICENSE README.md language-model.lm.bin pronounciation-dictionary.dict $ cd pocketsphinx-5prealpha/ $ src/programs/pocketsphinx_continuous -samprate 16000 -adcdev plughw:1,0 -inmic yes -nfft 2048 -dict /home/pi/ca-es/pronounciation-dictionary.dict -hmm /home/pi/ca-es/acoustic-model/ -lm /home/pi/ca-es/language-model.lm.bin 2>./unwanted-stuff.log | tee ./words.log
No funciona el reconeixement de les paraules del diccionari...
Model castellà
Igual que en català, no obtinc bons resultats.
- cmusphinx-es-5.2.tar.gz
~/cmusphinx-es-5.2/model_parameters/voxforge_es_sphinx.cd_ptm_4000 $ ls feat.params means noisedict transition_matrices mdef mixture_weights sendump variances ~/cmusphinx-es-5.2/etc $ ls allprompts voxforge_es_sphinx.fileids.train.all es-20k.lm.gz voxforge_es_sphinx.filler feat.params voxforge_es_sphinx.phone lower.py voxforge_es_sphinx.transcription sphinx_train.cfg voxforge_es_sphinx.transcription.test voxforge_es_sphinx.dic voxforge_es_sphinx.transcription.train voxforge_es_sphinx.fileids.test voxforge_es_sphinx.transcription.train.all voxforge_es_sphinx.fileids.train $ ls allprompts voxforge_es_sphinx.fileids.train.all es-20k.lm.gz voxforge_es_sphinx.filler feat.params voxforge_es_sphinx.phone lower.py voxforge_es_sphinx.transcription sphinx_train.cfg voxforge_es_sphinx.transcription.test el model està en el fitxer: es-20k.lm.gz gunzip es-20k.lm.gz es-20k.lm
$ cd pocketsphinx-5prealpha/ $ src/programs/pocketsphinx_continuous -samprate 16000 -adcdev plughw:1,0 -inmic yes -nfft 2048 -dict /home/pi/cmusphinx-es-5.2/etc/voxforge_es_sphinx.dic -hmm /home/pi/cmusphinx-es-5.2/model_parameters/voxforge_es_sphinx.cd_ptm_4000 -lm /home/pi/cmusphinx-es-5.2/etc/es-20k.lm 2>./unwanted-stuff.log | tee ./words.log
Sí que funciona. Ara bé, va lent i a vegades no és fiable.
Ara faig un diccionari petit que vull contrastar amb aquest model, i no funciona, perquè no deu ser aquest el procediment: dict_prueba_es.dic:
] a _a a _b b e _c z e _d d e _e e _f e f e _g j e _h a ch e _i i _j j o t a _k k a _l e le _m e m e _n e n e _o o _p p e _q c u _r e r e _s e s e _t t e _u u _v b e _w d o b l e u b e _x e k i s _y i g r i e g a _z z e t a hola h o l a pepito p e p i t o cómo c o m o me m e llamo ll a m o juan j u a n te t e canto k a n t o una u n a canción k a n z i o n
Pocketsphinx amb interfície python
pip install --upgrade pip setuptools wheel pip install --upgrade pocketsphinx ...Installing collected packages: pocketsphinx Successfully installed pocketsphinx-0.1.15 ... <pre> Per saber en quin directori estan els models: <pre> $ python3 -c "from pocketsphinx import get_model_path; print(get_model_path())" /usr/local/lib/python3.7/dist-packages/pocketsphinx/model
en aquesta carpeta ja tenim un model i diccionari amb anglès, i ara he de portar aquí la mateixa estructura del model castellà: 2 fitxers (el diccionari i el lm), i una carpeta (del model castellà)
script test_es-es.py:
import os from pocketsphinx import LiveSpeech, get_model_path model_path = get_model_path() print(model_path) speech = LiveSpeech( verbose=False, sampling_rate=16000, buffer_size=2048, no_search=False, full_utt=False, hmm= os.path.join(model_path, 'es-es'), lm= os.path.join(model_path, 'es-20k.lm'), dict= os.path.join(model_path, 'es.dict') ) for phrase in speech: print(phrase)
$ python3 test_es-es.py me llamo juan ...
i funciona igual que en el vídeo de l'enllaç.
creat per Joan Quintana Compte, maig 2020