Serveur Web pour Deepspeech

Objectif

Déployer un serveur web pour utiliser deepspeech

Matériels nécessaires

  • Un client (Raspberry PI)
  • Un serveur (Celui utilisé dans ce tutoriel : Deepspeech serveur)

Technologies utilisées

  • NodeJS
  • Python

Comment ça fonctionne

  1. J'enregistre un échantillon vocale que je veux traduire en texte.
  2. J'envoi le fichier enregistrer sur le serveur
  3. le serveur le reçoit.
  4. Le serveur enregistre le fichier dans un répertoire
  5. Le serveur traite le fichier reçu grâce au model qui a été créé préalablement.
  6. une réponse est retourné en JSON.

Configuration du serveur

Mon serveur ne supporte pas AVX alors je dois tout recompiler pour supporter mon système.

La base de ce tutoriel ce trouve ici : Installation et configuration de Deepspeech serveur

L'architecture des dossiers ressemble à ceci:

├── DeepSpeech
└── tensorflow

Première étape

Installer toutes les dépendances

curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -
sudo apt-get install -y nodejs

Copier les fichiers nécessaires et qui ont été compilés dans le dossier tensorflow.

mkdir DeepSpeech/native_client/javascript/lib/binding/v0.1.0/linux-x64/

cp tensorflow/bazel-bin/tensorflow/libtensorflow_cc.so DeepSpeech/native_client/javascript/lib/binding/v0.1.0/linux-x64/
cp tensorflow/bazel-bin/tensorflow/libtensorflow_framework.so DeepSpeech/native_client/javascript/lib/binding/v0.1.0/linux-x64/
cp tensorflow/bazel-bin/native_client/libdeepspeech_utils.so DeepSpeech/native_client/javascript/lib/binding/v0.1.0/linux-x64/
cp tensorflow/bazel-bin/native_client/libdeepspeech.so DeepSpeech/native_client/javascript/lib/binding/v0.1.0/linux-x64/

Deuxième étape

Installer Deepspeech depuis NPM,

Normalement, c'est la seule étape, cependant mon système ne supporte pas AVX.

npm install deepspeech


├── DeepSpeech
├── node_modules
└── tensorflow

Maintenant, on doit copier le fichier deepspeech.node

cp  node_module/deepspeech/lib/binding/v0.1.0/linux-x64/node-v46/linux-x64/node-v46/deepspeech.node DeepSpeech/native_client/javascript/lib/binding/v0.1.0/linux-x64/node-v46/

Dans le cas où vous n'avez pas la même architecture, vous pouvez vérifier à partir de ce répertoire : DeepSpeech/native_client/javascript/lib/binding/v0.1.0/ les autres versions disponibles.

Troisième étape

On peut à présent créer un serveur web pour recevoir les enregistrements.

cd DeepSpeech/native_client/javascript
ls -al
npm install
npm install --save node-wav multer express body-parser fs
nano server.js
### Ajouter ce qui suit : 

const express = require('express')
const app = express()
const port = 3000
const bodyParser = require('body-parser')
const Deepspeech = require('./client')
const fs = require('fs')
const multer = require('multer');
const wav = require('node-wav');

app.use(bodyParser.json({ limit: '50mb' }));
app.use(bodyParser.raw({ type: 'audio/wav', limit: '50mb' }));

app.get('/', (request, response) => {
  response.send('Hello You ! Please use the route : /recognize')
})

const path = '/home/tgingras/vocal/tfv1/DeepSpeech/native_client/javascript/'

const storage = multer.diskStorage({
  destination: function(req, file, cb){
    cb(null, './')
  },
  filename: function(req, file, cb){
    cb(null, file.fieldname + '-' + Date.now() + '.wav')
  }
});
const upload = multer({ 
  storage: storage
});

app.post('/recognize', upload.single('document'), (req, res) => {
  console.log(req.body)

  if(req.body){
    const result = wav.decode(req.body);
    const file = 'Sample' + '-' + Date.now() + '.wav'
    const audio = new Buffer(req.body, 'base64').toString('binary')

    const _audioBuffer = new Buffer(audio, 'binary')
    
    fs.writeFile(file, _audioBuffer, {encoding: null}, function(err){
      console.error(err)
      if(!err)
        Deepspeech.transcribe(path+"output_graph.pb", path+file, path+"alphabet.txt", path+"lm.binary", path+"trie", function(result, time, audioTime){
          console.log(result)
          console.log(time)
          console.log(audioTime)
          return res.status(200).json({
              'message':'Success',
              'response':result,
              'totalTime':time,
              'audioFileTime':audioTime
          })
        });
    });
  } else if(req.file && req.file.filename) {
    Deepspeech.transcribe(path+"output_graph.pb", path+req.file.filename, path+"alphabet.txt", path+"lm.binary", path+"trie", function(result, time, audioTime){
      console.log(result)
      console.log(time)
      console.log(audioTime)
      return res.status(200).json({
        'message':'Success',
        'response':result,
        'totalTime':time,
        'audioFileTime':audioTime
      })
    });
  }else{
    res.status(500).json({message: 'An error occur'})
    
  }
    
})

app.listen(port, (err) => {
  if (err) {
    return console.log('something bad happened', err)
  }

  console.log('server is listening on port : ' + port)
})
 
### Modifier la variable path pour réfléter votre chemin

Ne pas oublier de modifier la variable path pour entrer votre chemin absolu.

Le script accepte deux type de transmission.

Celui avec le form-data et celle par buffer. Je recommande d'utiliser la première (req.body) et l'example client utilise celle-là.

Quatrième étape

Démarrer le serveur web

node server.js

Si tout va bien il va écouter patiemment de recevoir un fichier audio.

Il écoute sur le port 3000 et la route doit être de type POST par exemple : POST X.X.X.X:3000/recognize

Configuration du client

Ceci est un example que j'ai fait avec jasper (Jasper Project)

J'utilise cet outil pour me faciliter la vie avec les fonctions futures qui seront adaptés à ce projet.

La partie transcribe est celle qui peut vous intéresser le plus.

import json
import logging
import urllib
import urlparse
import wave
import requests
from jasper import plugin
#from requests_toolbelt import MultipartEncoder
from requests_toolbelt.multipart import encoder


class DeepspeechSTTPlugin(plugin.STTPlugin):
    """
    Speech-To-Text implementation which relies on the Tensorflow DeepSpeech API.

    Customized by Tommy Gingras.

    """

    def __init__(self, *args, **kwargs):
        plugin.STTPlugin.__init__(self, *args, **kwargs)

        self._logger = logging.getLogger(__name__)
        self._request_url = None
        self._http = requests.Session()


    @property
    def request_url(self):
        return self._request_url

    @classmethod
    def get_config(cls):
        # No need
        config = {}

        return config


    def transcribe(self, fp):
        """
        Performs STT via the DeepSpeech API, transcribing an audio file and
        returning a string.

        Arguments:
        audio_file_path -- the path to the .wav file to be transcribed
        """
        dataWav = fp.read()
        r = requests.post("http://mysuper.server.local:3000/recognize",
                          data=dataWav,
                          headers={'Content-Type': 'audio/wav'})
        try:
            r.raise_for_status()
        except requests.exceptions.HTTPError:
            self._logger.critical('Request failed with http status %d',
                                  r.status_code)
            if r.status_code == requests.codes['forbidden']:
                self._logger.warning('Status 403 is probably caused by an ' +
                                     'invalid request.')
            return []
        r.encoding = 'utf-8'
        try:
            recognition = r.json()
            print(recognition)
            print(recognition['response'])
            if recognition == {}:
                # Response result is empty
                raise ValueError('Nothing has been transcribed.')
        except ValueError as e:
            self._logger.warning('Empty response: %s', e.args[0])
            results = []
        else:
            # Convert all results to uppercase
            results = recognition['response'].upper()
            self._logger.info('Transcribed: %r', results)
        return results

    @classmethod
    def is_available(cls):
        return diagnose.check_network_connection()

Comment obtenir jasper (J'utilise la version dev Jasper-dev):

git clone https://github.com/jasperproject/jasper-client.git jasper
cd jasper
git checkout jasper-dev

 

Laisser un commentaire