Page MenuHomePhabricator

Set up non-puppet TTS server on wmflabs
Closed, ResolvedPublic12 Estimated Story Points

Description

Create an instance on wmflabs in the wikispeech project and install the TTS server manually. This will allow us to figure out the interaction between the TTS sever and the extension, without having to create a puppet role. It will also enable running the demo (T151786) entirely on wmflabs.

  • Create instance
  • Install TTS server
  • Enable communication between TTS server and demo wiki, but disallow external access to the server
  • Document

It turns out that it was not possible to limit access to the wiki, since the requests are sent from the client through javascript.


IMPORTANT: This has been updated and copied to https://www.mediawiki.org/wiki/Extension:Wikispeech.

Documentation

Creating an instance

Follow instructions on https://wikitech.wikimedia.org/wiki/Help:Instances#Creating_an_instance:

  1. Log in to https://horizon.wikimedia.org and go to the wikispeech project (in top bar).
  2. ComputeOverview and check that there are instances available.
  3. Create a Security Group:
    • ComputeAccess & SecurityCreate Security Group, Name: TTS-provider
      • Manage RulesAdd Rule, Port: 10000, Remote: CIDR, CIDR: 0.0.0.0/0
  4. Open Launch Instance dialogue (ComputeInstancesLaunch Instance):
    1. Details: only set Instance Name: wikispeech-tts
    2. Source: Select boot source: Image, under Available add ubuntu-14.04-trusty
    3. Flavor: Under Available add m1.medium (marytts uses ~ 1.1 GB on local machine)
    4. Security Groups: Under Available add default, TTS-provider, web-server
  5. Make services accessible through proxy, DNSWeb proxiesCreate proxy
    1. Hostname: wikispeech-tts, Backend instance: wikispeech-tts, Backend port: 10000
    2. Hostname: wikispeech-tts-audio, Backend Instance: wikispeech-tts, Backend port: 80

To ssh to the new instance, see: https://wikitech.wikimedia.org/wiki/Help:Getting_Started#Project_Instances

Install TTS server

The TTS server consists of three components: MaryTTS (TTS platform), pronlex (a pronunciation lexicon database) and wikispeech_mockup (wikispeech API).

Install MaryTTS

  1. Log into wikispeech-tts
  2. Install java: $ sudo apt install openjdk-7-jdk
  3. Create a user to run the server: $ sudo useradd -m tts-agent -p <password>.
  4. Become this user: $ sudo su - tts-agent
  5. Clone marytts-installer repo: $ git clone https://github.com/marytts/marytts-installer.git
  6. Follow instructions to install English voices
  7. Download needed STTS-voices from https://github.com/HaraldBerthelsen/marytts/tree/master/stts_voices into /installed/ (e.g. voice-stts_sv_nst-hsmm-5.2-SNAPSHOT.jar)
  8. Install marrytts-lang-sv:
    1. Clone the forked maryTTS repo into stts_marytts: $ git clone https://github.com/HaraldBerthelsen/marytts.git stts_marytts
    2. Build: cd stts_marytts; ./gradlew build
    3. Copy Swedish language into marytts-installer: $ cp build/install/marytts/lib/marytts-lang-sv-6.0-SNAPSHOT.jar ../marytts-installer/installed/
    4. Delete stts_marytts: $ cd ..; rm -R stts_marytts

Install pronlex

Prerequisites
These first steps need to be done with super user access, i.e. not as tts-agent:

  • Install gcc: $ sudo apt-get install gcc
  • Install build-essential: $ sudo apt-get install build-essential
  • Install Sqlite3: $ sudo apt install sqlite3
  • Install go:
    1. Get the compatible version (1.7.4)
    2. Install: $ tar -C /usr/local -xzf go1.7.4.linux-amd64.tar.gz

As tts-agent, follow the instruction at https://github.com/stts-se/lexdata/wiki/Create-lexicon-database:

  1. Add export PATH=$PATH:/usr/local/go/bin to .bashrc
  2. "Import lexicon files": Follow the instruction linked in II. Import lexicon files (command line)

Install wikispeech_mockup

Following instruction at https://github.com/stts-se/wikispeech_mockup:
As user with super user access:

  1. Install the Prerequisites but skip the remaining steps
  2. Install opusenc: $ sudo apt install opus-tools.

As tts-agent:

  1. In home directory, clone https://github.com/stts-se/wikispeech_mockup.git: $ git clone https://github.com/stts-se/wikispeech_mockup.git
  2. Create tmp directory in wikispeech_mockup: $ mkdir wikispeech_mockup/tmp
  3. Add host=0.0.0.0 to app.run() in wikispeech.py (see: http://stackoverflow.com/questions/30554702/cant-connect-to-flask-web-service-connection-refused).

Make audio files accessible

  1. Install apache: $ sudo apt install apache2
  2. Link the audio file directory in /var/www/html: $ cd /var/www/html; sudo ln -s ~/wikispeech_mockup/tmp/ audio

Audio files generated by the TTS should now be accessible through: http://wikispeech-tts-audio.wmflabs.org/audio/.

  • Disallow access to non-opus files by adding a .htaccess-file in ~/wikispeech_mockup/tmp/ with the following content
<FilesMatch "\.*$">
  Deny from all
</FilesMatch>
<FilesMatch "\.opus$">
  Order deny,allow
  Allow from all
</FilesMatch>
  • Remove directory listing by adding a index.html file in ~/wikispeech_mockup/tmp/ with something like the following content:

This is a service to serve Wikispeech audio files. There is really never any reason to see this page.

  • To also display this page in the root directory (instead of apache default): $ cd /var/www/html/; sudo rm index.html; sudo ln -s audio/index.html

Update the server with the new path

  1. In ~/wikispeech_mockup/wikispeech.py, change:
    • In synthesise()
-    audio_url = "%s/wikispeech_mockup/%s" % (hostname,opus_audio)
+    audio_url = "//wikispeech-tts-audio.wmflabs.org/audio/%s" % (opus_audio)
  • In saveAndConvertAudio()
-    opus_url_suffix = re.sub("^.*/%s/" % tmpdir, "%s/" % tmpdir, tmpopus)
+    opus_url_suffix = re.sub("^.*/%s/" % tmpdir, "", tmpopus)

Start processes in screen

As user tts-agent:

  1. $ script /dev/null, needed to get screen running (http://serverfault.com/a/116830)
  2. Start MaryTTS
    1. $ cd ~/marytts-installer/
    2. $ ./marytts
  3. Create new window: +a, w
  4. Start pronlex
    1. $ cd ~/go/src/github.com/stts-se/pronlex/lexserver/
    2. $ go run *.go
  5. Create new window
  6. Start wikispeech.py
    1. $ cd ~/wikispeech_mockup/
    2. $ python3 wikispeech.py

You can now detach the screen +a, d and resume with $ screen -r. Note that $ script /dev/null is required to run screen each time you become tts-agent.

Event Timeline

Creating an instance

Follow instructions on https://wikitech.wikimedia.org/wiki/Help:Instances#Creating_an_instance

  1. Go to horizon.wikimedia.org and go to the wikispeech project.
  2. ComputeOverview and check that there are instances available.
  3. Create security groups:
    • ComputeAccess & securityCreate security group, name TTS-consumer
    • ComputeAccess & securityCreate security group, name TTS-provider
      • Add rule: port = 10000, Remote = Security group, Security Group = TTS-consumer
  4. In launch instance dialogue:
    1. Details: only set name (wikispeech-tts)
    2. Source: Select boot source = image
    3. Under available choose image (ubuntu)
    4. Flavor: Choose flavor (m1.medium, marytts uses ~ 1.1 GB on local machine)
    5. Security groups: choose security group (default, tts-provider)
  5. ComputeInstancesDropdown for wikispeech-wikiEdit Security Groups: add tts-consumer

For ssh'ing: https://wikitech.wikimedia.org/wiki/Help:Getting_Started#Project_Instances

Install TTS server

Install MaryTTS

  1. Log into wikispeech-tts
  2. Install java: sudo apt install openjdk-7-jdk
  3. Create a user to run the server: sudo useradd -m tts-agent -p <password>.
  4. Become this user using sudo su - tts-agent
  5. Clone marytts-installer repo from Home
  6. Follow instructions to install English voices
  7. Download needed STTS-voices from https://github.com/HaraldBerthelsen/marytts/tree/master/stts_voices into /installed/ (e.g. voice-stts_sv_nst-hsmm-5.2-SNAPSHOT.jar)
  8. Install marrytts-lang-sv:
    1. Clone the forked maryTTS repo into stts_marytts
    2. Run ./gradlew build
    3. Copy Swedish language into marytts (cp build/install/marytts/lib/marytts-lang-sv-6.0-SNAPSHOT.jar ../marytts-installer/installed/
    4. Delete stts_marytts
  9. To start marytts run: ./marytts

Install pronlex

Following instruction at https://github.com/stts-se/lexdata/wiki/Create-lexicon-database

  1. Install go:
    1. Get teh compatible version (1.7.4)
    2. Install using tar -C /usr/local -xzf go1.7.4.linux-amd64.tar.gz
    3. Add export PATH=$PATH:/usr/local/go/bin to .bashrc
  2. Install Sqlite3: per instructions
  3. "Clone the source code": Follow instructions but use https://github.com/stts-se/pronlex.git
  4. "Clone the lexdata repository": Follow instructions but use https://github.com/stts-se/lexdata.git
  5. "Prepare symbol set files": Standing in Pronlex repo (not gitrepos). Follow instructions
  6. "Create an empty database":
    1. Install gcc: sudo apt-get install gcc
    2. Install build-essential: `sudo apt-get install build-essential
    3. Install go-sqlite3: go get github.com/mattn/go-sqlite3
    4. Install regexp2: go get github.com/dlclark/regexp2
    5. Follow instructions.
  7. Start server: per instructions
  8. "Import lexicon files": Instruction require GUI so instead
    1. ~/go/src/github.com/stts-se/pronlex$ go run lexio/import/import.go lexserver/pronlex.db sv-se.nst ~/gitrepos/lexdata/sv-se/nst/swe030224NST.pron-ws.utf8.gz sv-se_ws-sampa

Install wikispeech-mockup

Following instruction at https://github.com/stts-se/wikispeech_mockup

  1. Install the Prerequisites but skip the remaining steps
  2. Install opusenc: sudo apt install opus-tools.
  3. Clone https://github.com/stts-se/wikispeech_mockup.git from Home
  4. Create tmp directory in wikispeech_mockup: mkdir tmp
  5. Add host=0.0.0.0 to app.run() in wikispeech.py (see: http://stackoverflow.com/questions/30554702/cant-connect-to-flask-web-service-connection-refused).
  6. Start wikispeech server: python3 wikispeech.py

wikispeech_mockup also requires opusenc: sudo apt install opus-tools.

wikispeech_mockup also requires opusenc: sudo apt install opus-tools.

Added above

Creating an instance

  • ComputeAccess & scurityCreate security group, name TTS-provider
    • Add rule: port = 10000, Remote = Security group, Security Group = TTS-consumer

While this is the way we would probably want to do it it does not work since the request is client side. So instead it needs to be opened up for everyone:

  • Add rule: port = 10000, Remote = CIDR, CIDR = 0.0.0.0/0
  • DNSWeb proxiesCreate proxy
    • Hostname: wikispeech-tts, Backend instance wikispeech-tts, Backend port: 10000

To make audio files accessible:

  1. Install apache: sudo apt install apache2
  2. Link the audio file directory in /var/www/html: sudo ln -s ~/wikispeech_mockup/tmp/ audio
  3. Add proxy: Hostname: wikispeech-tts-audio, Backend instance wikispeech-tts, Backend port: 80

Audio files generated by the TTS should now be accessible through: http://wikispeech-tts-audio.wmflabs.org/audio/.

  • Disallow access to non-opus files by adding a .htaccess file to /audio/ with the following content
<FilesMatch "\.*$">
  Deny from all
</FilesMatch>
<FilesMatch "\.opus$">
  Order deny,allow
  Allow from all
</FilesMatch>
  • Remove directory listing by adding a index.html file to /audio/ with something like the following content:

This is a service to serve Wikispeech audio files. There is really never any reason to see this page.

  • To also display this page in the root directory: sudo rm index.html;sudo ln -s audio/index.html

Note that adding Options -Indexes to the top of .htaccess did not prevent the directory listing.

Update the server with the new path:

  1. In wikispeech_mockup/wikispeech.py, change:
    • In synthesise()
-    audio_url = "%s/wikispeech_mockup/%s" % (hostname,opus_audio)
+    audio_url = "//wikispeech-tts-audio.wmflabs.org/audio/%s" % (opus_audio)
  • In saveAndConvertAudio()
-    opus_url_suffix = re.sub("^.*/%s/" % tmpdir, "%s/" % tmpdir, tmpopus)
+    opus_url_suffix = re.sub("^.*/%s/" % tmpdir, "", tmpopus)

@Sebastian_Berlin-WMSE Add the following to "To make audio files accessible:"

  • Disallow access to non-opus files by adding a .htaccess file to /audio/ with the following content
<FilesMatch "\.*$">
  Deny from all
</FilesMatch>
<FilesMatch "\.opus$">
  Order deny,allow
  Allow from all
</FilesMatch>
  • Remove directory listing by adding a index.html file to /audio/ with something like the following content:

This is a service to serve Wikispeech audio files. There is really never any reason to see this page.

  • To also display this page in the root directory: sudo rm index.html;sudo ln -s audio/index.html

Note that adding Options -Indexes to the top of .htaccess did not prevent the directory listing.

Start processes in screen

As user tts-agent:

  1. script /dev/null, needed to get screen running (http://serverfault.com/a/116830)
  2. Start MaryTTS
    1. $ cd ~/marytts-installer/
    2. $ ./marytts
  3. Create new window: +a, w
  4. Start pronlex
    1. $ cd ~/go/src/github.com/stts-se/pronlex/lexserver/
    2. $ go run *.go
  5. Create new window
  6. Start wikispeech.py
    1. $ cd ~/wikispeech_mockup/
    2. $ python3 wikispeech.py

You can now detach the screen +a, d and resume with $ screen -r.

@Lokal_Profil: I've compiled the documentation from the comments in the description. Please have a read through and fix anything that's unclear or if we ended up doing things some other way.

Lokal_Profil updated the task description. (Show Details)
Lokal_Profil moved this task from 📆 This week to ☑️ Done on the User-LokalProfil board.

Note for the future. While the audio needs to be publicly accessible it could be possible to make the main tts server only speak to the wiki by having client requests go to the action api (of the MediaWiki extension) which in turn forwards these to he TTS service and handles the reply. If so the Security group settings are those in T161094#3125200.

The question which such an approach is the trade-of between any performance losses (due to the api go-between) and potential security gains. This is worth revisiting after T153841 which will likely introduce/require some of the action api functionality anyway.

For "Install pronlex", I have updated the instructions on https://github.com/stts-se/lexdata/wiki/Create-lexicon-database, so all the special exceptions/instructions should be deleted I think. Please have a look, and see if you agree with me.

Your more detailed instructions for installing go and sqlite3 should probably not be deleted though.

Please note that we support go 1.8. I will update the wiki.

As for the pronlex prerequisites (gcc and build-essentials), we didn't notice these dependencies, probably since we already had these packages installed.
Should we add this also to the instructions on our Wiki?

Thanks for the update. Everything seems to be working.

I think it's best to mention that gcc and build-essentials are required. Even if these may often be installed, it's good to have for when they're not.

Thanks for the update. Everything seems to be working.

I think it's best to mention that gcc and build-essentials are required. Even if these may often be installed, it's good to have for when they're not.

So maybe add these to our instructions? Better than to have it in separate places?
But apt install is not a universal solution either though.... This is more what works on your server I guess.

For Arabic, a few extra tricks are needed at the moment:

  1. Make sure Java 8 is installed
    1. For Ubuntu 14.04, follow http://askubuntu.com/a/464894 (under "Original Message")

Install Arabic resources for MaryTTS

  1. cd marytts-installer
  2. cd installed
  3. wget https://github.com/HaraldBerthelsen/marytts-lang-ar/releases/download/v0.1-alpha/marytts-lang-ar-6.0-SNAPSHOT.jar
  4. wget https://github.com/HaraldBerthelsen/voice-ar-nah-hsmm/releases/download/v5.2/voice-ar-nah-hsmm-5.2.jar
  5. cd ..
  6. ./marytts

Install Msihkal

git clone https://github.com/linuxscout/mishkal.git
cd mishkal
EDIT mishkal/tashkeel/tashkeel.py
CHANGE line 385
from
vocalized_text = u" ".join([vocalized_text, self.display(word, format_display)])
to
vocalized_text = u" ".join([vocalized_text, self.display(voc_word, format_display)])

(The variable "word" is wrong, should be "voc_word")

Run webserver with:
python interfaces/web/mishkal-webserver.py

AND:

In marytts-installer-5.2 (or wherever your marytts-installer is):

cd installed
wget http://repo1.maven.org/maven2/org/glassfish/javax.json/1.0.4/javax.json-1.0.4.jar
cd ..
./marytts