Jasper-tutorial: Bouw je eigen spraakassistent

Google en Amazon proberen hun spraak-gestuurde apparaten Home en Echo als een centraal punt voor slimme apparaten aan te bieden. Maar deze bedrijven hebben het niet zo op privacy. Gelukkig is er een opensource-alternatief. Lees in deze Jasper-tutorial hoe je je eigen spraakassistent bouwt!

Aan het einde van dit artikel heb je dus je eigen Google Home of Amazon Echo, maar dan een die je privacy respecteert en waar je zelf volledige controle over hebt. Daarvoor zetten we een Raspberry Pi 3 in. Dat minicomputertje heeft ingebouwde wifi, zodat we een kabel minder nodig hebben. Het besturingssysteem plaatsen we op een micro-sd-kaartje. Het enige wat we dan naast de voeding nog dienen aan te sluiten, zijn een microfoon en luidsprekers. De luidsprekers sluiten we aan op de analoge uitgang van de Pi. De geluidskwaliteit daarvan is niet geweldig, maar voor zo’n computerstem is het voldoende.

Een analoge ingang heeft de Pi niet, maar we sluiten eenvoudig een usb-microfoon aan. Het resultaat van ons knutselwerk is uiteraard niet zo mooi als een Google Home of Amazon Echo, maar als je wat handig bent, bouw je het geheel eenvoudig in een houten behuizing die niet misstaat in je woonkamer. Die afwerking laten we als oefening voor jou!

Jasper downloaden

Voor de software gebruiken we Jasper, een opensource-spraakassistent. De oorspronkelijke ontwikkelaars hebben het project al een tijdje geen update meer gegeven, maar Matt Curry heeft de ontwikkeling op zich genomen en al enkele nieuwe releases uitgebracht. We werken in deze masterclass met versie 1.5 van Matt Curry.

Let dus op dat je niet een officieel image van het Jasper-project downloadt, want dat is niet meer up-to-date. Download een image van de website van Matt Curry (http://bit.ly/2nwRBV9). Vink het bestand op de Amazon Drive van Matt Curry aan en klik onderaan op Download. Het is 1,4 GB groot en het duurt wel even voor je het binnen hebt.

Pak het tar.gz-bestand uit, bijvoorbeeld met het programma 7-Zip dat allerlei compressieformaten ondersteunt. Open het bestand daarvoor met 7-Zip en klik op Extract om het img-bestand erin uit te pakken.

Schrijf dan het uitgepakte bestand naar het micro-sd-kaartje. Dat kan met het programma Win32DiskImager. Steek je micro-sd-kaartje in de kaartlezer van je computer en kies in Win32DiskImager de schijfletter van je kaartje. Selecteer het img-bestand van Jasper en klik op Write om het naar je kaartje te schrijven.

Let op: het programma overschrijft de volledige inhoud van het kaartje! Gebruik dus alleen een kaartje waar geen data meer op staan die je nodig hebt, en controleer dubbel of je de juiste schijfletter kiest voordat je op Write klikt. Nadat het image naar het kaartje is geschreven, haal je het uit je kaartlezer en steek je het in je Pi.

Raspbian op Raspberry Pi

Sluit tijdelijk een toetsenbord en scherm op je Pi aan voor de configuratie, sluit je luidsprekers en usb-microfoon aan en tot slot de voedingskabel. Als alles goed gaat, start je Pi nu en krijg je een inlogprompt van Raspbian te zien. Log in met gebruikersnaam pi en wachtwoord raspberry. Voer het configuratieprogramma van Raspbian uit met

sudo raspi-config

Kies eerst Expand Filesystem zodat het bestandssysteem je volledige micro-sd-kaart inneemt. Kies daarna Change User Password om het standaardwachtwoord te wijzigen.

Zorg dat Wait for Network at Boot ingeschakeld is. Bij Internationalisation Options kies je je taal, tijdzone, toetsenbordindeling en je land. Ga dan naar Advanced Options en zet onder Memory Split de hoeveelheid geheugen voor de gpu op 16 megabytes, zodat je zoveel mogelijk geheugen voor de cpu overhoudt. Schakel ook de ssh-server in onder SSH, zodat je het toetsenbord en beeldscherm niet aangesloten hoeft te houden, maar met Putty via het netwerk kunt inloggen. Ga tot slot met de Tab-toets naar Finish en antwoord No bij de vraag om nu te herstarten.

Nu hoeven we alleen nog wifi te configureren. Scan naar de aanwezige wifi-netwerken met

sudo iwlist wlan0 scan

Achter ESSID staat de naam van het netwerk. Open daarna het configuratiebestand met

sudo nano /etc/wpa_supplicant/wpa_supplicant.conf

en voeg de configuratie voor je netwerk toe met regels

network={, ssid="JouwESSID", psk="JouwWifiWachtwoord"

En

}

Herstart daarna je Pi met

sudo reboot
Media has no description

© PXimport

Audio instellen

We gaan ervan uit dat je speakers hebt aangesloten op de 3,5mm-uitgang van de Pi en een usb-luidspreker op een usb-poort. We zorgen dat Raspbian de usb-audiodrivers eerst laadt. Open daarvoor het juiste bestand met

sudo nano /etc/modprobe.d/alsa-base.conf

en zorg dat bij snd_usb_audio als index 0 staat en bij snd_bcm2835 als index 1. Zorg ook dat op de laatste regel van dit bestand bij slots eerst snd-usb-audio komt en daarna pas snd-bcm2835. Sla het bestand op met Ctrl+O en sluit nano af met Ctrl+X. Voer daarna

sudo nano /usr/share/alsa/alsa.conf

uit en zoek met Ctrl+W naar defaults.ctl.card. Controleer of hier en bij defaults.pcm.card als waarde 0 staat en verander dit indien nodig. Controleer nu of je met de luidspreker iets kunt opnemen. Voer daarvoor de opdracht

arecord temp.wav

uit en spreek iets in. Sluit de opname af met Ctrl+C. Speel de opname daarna af met

aplay -D hw:1,0 temp.wav

Hoor je wat je zojuist hebt ingesproken, dan is je audio correct geconfigureerd.

Lees verder op de volgende pagina.

Nu is ons besturingssysteem klaar om Jasper te installeren.

Jasper installeren en configureren

Ga naar de juiste directory met

cd Jasper-RPI-Tools/installers

en voer het installatieprogramma uit met

./jasper-repo-installer.sh

Druk op Enter om te bevestigen dat je Jasper wilt downloaden, bevestig dat gebruiker pi het programma draait, dat je het programma in de directory /home/pi wilt installeren en kies de versie main. Herstart daarna je Pi.

Met de standaardinstellingen werkt Jasper al bijna, maar je hebt nog één ding nodig: een server-token voor Wit.ai. Log op die website in met een GitHub- of Facebook-account. Klik zodra je ingelogd bent bovenaan rechts op Settings en kopieer het Server Access Token. Voer dan op je Pi de opdracht

nano ~/.jasper/profile.yml

uit en vul wat gegevens in, zoals je naam, Gmail-adres, Gmail-wachtwoord, telefoonnummer, locatie, tijdzone enzovoort. Informatie die je niet wilt invullen, laat je gewoon open.

Vul bij stt_engine de engine witai in. Voeg ook de regels

witai-stt:

En

access_token: ERJKGE86SOMERANDOMTOKEN23471AB

toe, waarbij je uiteraard je eigen token van Wit.ai invult. Sla het bestand op met Ctrl+O en sluit het af met Ctrl+X. Herstart Jasper met

sudo systemctl restart jasper-daemon.service
Media has no description

© PXimport

Debuggen

Als Jasper niet doet wat hij moet doen, is het moeilijk om te zien wat er juist misloopt. Is het omdat Jasper je accent niet verstaat, of omdat je een fout in het configuratiebestand hebt staan? Sluit daarom alle draaiende Jasper-instanties af met

pkill python2

en start Jasper manueel op met

jasper-client/jasper.py --debug

Het programma toont nu zijn uitvoer en met de optie --debug krijg je nog meer informatie te zien. Als er iets mis is met het configuratiebestand, krijg je hier een waarschuwing of foutmelding te zien. En als je een opdracht inspreekt, krijg je de tekst te zien die Jasper uit je spraak herkent. Zo weet je onmiddellijk wanneer je wat duidelijker moet articuleren. Is je probleem opgelost, sluit Jasper dan af met Ctrl+C en start het programma terug op de achtergrond op met

sudo systemctl start jasper-daemon.service

Praten met Jasper

Wanneer Jasper start, zegt hij “How can I be of service?” gevolgd door je naam. Vanaf dan luistert je assistent naar jou. Als je “Jasper” zegt, laat Jasper een hoog biepje horen. Dan spreek je je opdracht in, bijvoorbeeld “What’s the time?”, waarna Jasper een laag biepje genereert. Daarna spreekt Jasper zijn antwoord uit. Let wel op dat je onmiddellijk na het eerste biepje je opdracht inspreekt, want Jasper wacht niet lang.

Elke opdracht die Jasper verstaat, zit in een afzonderlijke module. Standaard komt Jasper al met enkele modules, zoals de tijd, “How’s the weather”, “What’s in the news”, “What’s the meaning of life”, “Tell me a joke”, enzovoort.

Voor de integratie met Gmail vul je de variabelen gmail_address en gmail_password in het configuratiebestand ~/.jasper/profile.yml in met nano. Let op: iedereen die het micro-sd-kaartje van je Pi steelt of via het netwerk op je Pi inbreekt omdat je het standaardwachtwoord niet hebt veranderd, is zo in staat om je Gmail-wachtwoord te lezen.

Gebruik daarom authenticatie in twee stappen voor Gmail en stel een app-wachtwoord in voor Jasper, dat je in zijn configuratiebestand invult. Dit wachtwoord kun je op elk moment intrekken op https://myaccount.google.com/security. Als je Gmail-gegevens geconfigureerd zijn, vraag je aan Jasper “Do I have any email?” en antwoordt hij met het aantal ongelezen e-mails.

Ook integratie met Facebook is mogelijk: dan kun je je Facebook-notificaties opvragen of Jasper vragen wie er vandaag jarig is. En heb je Spotify Premium, dan laat je eenvoudig je afspeellijsten van Spotify door je Pi afspelen met stembesturing. Beide modules vereisen wel wat meer configuratie, we verwijzen daarvoor naar de documentatie van Jasper.

Pocketsphinx, een andere speech-to-text-engine

We hebben nu met de standaard speech-to-text-engine (STT) Wit.ai gewerkt, omdat die eenvoudig te activeren is. Een nadeel is dat die al je spraak over internet stuurt naar de servers van Wit.ai, wat vanuit privacystandpunt niet aan te raden is. Bovendien levert het sturen van je spraak over internet ook een vertraging op. We tonen hier daarom hoe je naar een offline stt-engine overschakelt, Pocketsphinx. Let wel op: die herkent iets minder goed spraak dan Wit.ai.

Ververs eerst de pakketbronnen van Raspbian met

sudo apt-get update

Installeer daarna Pocketsphinx en de Python-module voor Pocketsphinx met

sudo apt-get install pocketsphinx python-pocketsphinx

Daarna dienen we enkele afhankelijkheden zelf te compileren. Dat is nogal een omslachtig proces. We verwijzen daarvoor naar de documentatie van Jasper, maar niet alles klopt meer. Volg eerst de uitleg onder het kopje ‘Installing CMUCLMTK’.

Download nu OpenFST 1.3.4 met de opdracht

wget -O openfst_1.3.4-1_armhf.deb https://docs.google.com/uc?id=0ByR-0pXyV40pNlZZY0p6MUVpWW8&export=download

En installeer het met

sudo dpkg -i openfst_1.3.4-1_armhf.deb

Download dan m2m-aligner 1.2 met

wget https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/m2m-aligner/m2m-aligner-1.2.tar.gz

Pak het uit met

tar xvzf m2m-alifner-1.2.tar.gz

Open de directory en compileer het met

cd m2m-aligner-1.2 en sudo make

Ga terug naar de home-directory met

cd

en download mitlm 0.4.1 met

wget https://github.com/mitlm/mitlm/releases/download/v0.4.1/mitlm_0.4.1.tar.gz

Pak het uit met

tar xvzf mitlm_0.4.1.tar.gz

Ga in de directory met

cd mitlm-0.4.1/

configureer het pakket met

./configure

en installeer het met

sudo make install
Media has no description

© PXimport

Ga terug naar de home-directory met

cd

en download Phonetisaurus 0.8.1 met

wget https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/phonetisaurus/is2013-conversion.tgz

Pak het bestand uit met

tar xvzf is2013-conversion.tgz

Ga naar de juiste directory met

cd is2013-conversion/phonetisaurus/src

en compileer Phonetisaurus met

sudo make

Maak ondertussen maar een wandeling met de hond, want het compileren duurt een tijdje. Ga dan terug naar de home-directory (met cd) en kopieer enkele gecompileerde bestanden met

sudo cp ~/m2m-aligner-1.2/m2m-aligner is2013-conversion/bin/phonetisaurus-g2p /usr/local/bin

Download dan het Phonetisaurus FST-model met

wget https://www.dropbox.com/s/kfht75czdwucni1/g014b2b.tgz

en pak het uit met

tar xvzf g014b2b.tgz

Ga daarna naar de uitgepakte directory met

cd g014b2b/

en bouw het FST-model met

./compile-fst.sh

Ga daarna terug naar de home-directory en geef de uitgepakte directory een andere naam met

mv ~/g014b2b ~/phonetisaurus

Je bent nu eindelijk klaar met de installatie van Pocketsphinx! Pas daarna in ~/.jasper/profile.yml de stt-engine aan door de regel

stt_engine: sphinx

Voeg ook de regel

pocketsphinx:

En daaronder

hmm_dir: '/usr/share/pocketsphinx/model/hmm/en_US/hub4wsj_sc_8k'

toe. Sla op met Ctrl+O en sluit nano af met Ctrl+X. Start Jasper nu opnieuw, waarna je spraakassistent werkt zonder je spraak het internet op te sturen. Het heeft dus wat moeite gekost, maar daar krijg je wel wat voor terug!

Jasper ondersteunt dus meerdere speech-to-text engines. Drie daarvan sturen wat je tegen Jasper zegt door over internet om de spraak daar te analyseren en de herkende tekst terug te sturen. De engine van Wit.ai werkt met het Wit.ai-platform dat spraakherkenningsalgoritmes door crowdsourcing traint. De engine van Google is dezelfde als die je op Android gebruikt als je “OK, Google” zegt. En de engine van AT&T bouwt voort op de diensten van het gelijknamige telecommunicatiebedrijf.

Als je niet wilt dat anderen in principe kunnen meeluisteren in je woonkamer naar wat je tegen Jasper zegt, laat je deze engines links liggen. Maar toevallig zijn het wel de engines die het beste werken. Wil je een offline stt-engine, dan is Pocketsphinx de eerste keuze. Deze opensource-engine werkt snel en is geoptimaliseerd voor systemen met weinig processorkracht zoals de Raspberry Pi.

De spraakherkenning is wel duidelijk minder goed dan die van de online engines. Een andere offline engine is Julius. Die dien je echter met je eigen akoestisch model te trainen, wat nogal een complexe taak is.

Een andere stem voor Jasper

De stem van Jasper klinkt standaard nogal robotachtig. Dat is de verantwoordelijkheid van de standaard text-to-speech engine die Jasper gebruikt, espeak. Gelukkig is het kiezen van een andere text-to-speech-engine niet zo’n lijdensweg als de installatie van Pocketsphinx. De SVOX Pico tts-engine installeer je eenvoudig met

sudo apt-get install libttspico-utils

Ook de configuratie is eenvoudig. Open het bestand ~/.jasper/profile.yml met nano en voeg de regel

tts_engine: pico-tts

toe. Sla het bestand op met Ctrl+O en sluit nano af met Ctrl+X. Als je nu Jasper opnieuw start, krijg je een veel menselijker klinkende stem te horen. Bovendien hebben we nog altijd het voordeel Jasper zijn uitgesproken woorden niet over internet stuurt, zodat je spraakassistent je privacy garandeert.

Een schoonheidsfoutje is dat de stem van de Pico-tts-engine vrouwelijk is en onze spraakassistent nog altijd naar de mannelijke naam Jasper luistert. In Jasper 1.6 zal de naam eenvoudig te veranderen zijn.

Jasper ondersteunt maar liefst acht text-to-speech engines. Is je privacy je lief, dan vallen verschillende al af omdat ze online werken en de tekst die Jasper naar spraak wil omzetten naar een server sturen. Het zijn wel de tts-engines die de beste spraakherkenning hebben.

Google TTS gebruikt dezelfde text-to-speech-api als die van nieuwere Android-apparaten. De spraaksynthese gebeurt op servers van Google. Ivona TTS werkt met de Ivona Speech Cloud van Amazon, die we ook van in de Kindle Fire kennen. Ook hier gebeurt de spraaksynthese online. MaryTTS werkt ook met een server, maar het voordeel is dat de server opensource is en dat je ze op je eigen machine kunt installeren. Voor de Raspberry Pi is het programma echter nogal zwaar.

Maak je gebruik van een publieke MaryTTS-server, dan is je privacy uiteraard niet gegarandeerd. Tot de offline engines behoren eSpeak, Festival en Flite, die nogal robotachtig klinken. SVOX Pico TTS is de engine die in Android 1.6 gebruikt werd en heeft een vrij goede kwaliteit. Draai je Jasper op een Mac, dan kun je ook Mac OS X TTS inzetten, die de say-opdracht van macOS aanroept.

Deel dit artikel
Voeg toe aan favorieten