Le projet se compose de deux parties : un robot vocal et un serveur RESTful pour interagir avec lui.
Pour exécuter le bot localement, vous devez exécuter python3 bot.py
(ou run_bot.sh
) et sélectionner l'option d'opération souhaitée dans le menu proposé (plus de détails ici).
Pour démarrer un serveur RESTful qui fournit une interface pour interagir avec les modules de robot vocal, vous devez exécuter python3 rest_server.py
(ou run_rest_server.sh
) (plus de détails ici).
Pour créer une image Docker basée sur un serveur RESTful, exécutez sudo docker build -t voice_chatbot:0.1 .
(plus de détails ici).
ATTENTION! C'était mon projet de fin d'études, donc l'architecture et le code ici ne sont pas très bons, je comprends cela, et dès que j'aurai le temps, je mettrai tout à jour.
Une liste complète de toutes les dépendances nécessaires au fonctionnement :
Voice_ChatBot_data.zip
(3 Go) depuis Google Drive et la décompresser à la racine du projet (dossiers data
et install_files
). Si vous utilisez Ubuntu 16.04 ou supérieur, vous pouvez utiliser install_packages.sh
(testé sur Ubuntu 16.04 et 18.04) pour installer tous les packages. Par défaut, TensorFlow pour CPU sera installé. Si vous disposez d'une carte graphique nvidia avec la version officielle 410 du pilote installé, vous pouvez installer TensorFlowGPU. Pour ce faire, vous devez transmettre le paramètre gpu
lors de l'exécution install_packages.sh
. Par exemple:
./install_packages.sh gpu
Dans ce cas, 2 archives seront téléchargées depuis mon Google Drive :
Install_CUDA10.0_cuDNN_for410.zip
(2,0 Go) avec CUDA 10.0 et cuDNN 7.5.0 (si le paramètre gpu
a été passé). L'installation se terminera automatiquement, mais si quelque chose ne va pas, il y a une instruction Install.txt
dans l'archive téléchargée.Voice_ChatBot_data.zip
(3 Go) avec données de formation et modèles prêts à l'emploi. Il sera automatiquement décompressé dans data
et install_files
à la racine du projet. Si vous ne pouvez pas ou ne souhaitez pas utiliser le script pour installer tous les packages requis, vous devez installer manuellement RHVoice et CMUclmtk_v0.7 en suivant les instructions dans install_files/Install RHVoice.txt
et install_files/Install CMUclmtk.txt
. Vous devez également copier les fichiers de langage, de modèle acoustique et de dictionnaire pour PocketSphinx de temp/
vers /usr/local/lib/python3.6/dist-packages/pocketsphinx/model
(votre chemin vers python3.6
peut être différent). Les fichiers du modèle de langage prepared_questions_plays_ru.lm
et du dictionnaire prepared_questions_plays_ru.dic
doivent être renommés en ru_bot_plays_ru.lm
et ru_bot_plays_ru.dic
(ou changer leur nom en speech_to_text.py
si vous disposez de votre propre modèle de langage et dictionnaire).
Le bot est basé sur un réseau de neurones récurrent, le modèle AttentionSeq2Seq. Dans l'implémentation actuelle, il se compose de 2 cellules LSTM bidirectionnelles dans le codeur, d'une couche d'attention et de 2 cellules LSTM dans le décodeur. L'utilisation d'un modèle d'attention permet d'établir une correspondance « douce » entre les séquences d'entrée et de sortie, ce qui améliore la qualité et la productivité. La dimension d'entrée dans la dernière configuration est de 500 et la longueur de la séquence est de 26 (c'est-à-dire la longueur maximale des phrases dans l'ensemble d'apprentissage). Les mots sont convertis en vecteurs à l'aide de l'encodeur word2vec (avec un dictionnaire de 445 000 mots) de la bibliothèque gensim. Le modèle seq2seq est implémenté à l'aide de Keras et RecurrentShop. Le modèle seq2seq entraîné (dont les poids se trouvent dans data/plays_ru/model_weights_plays_ru.h5
) avec les paramètres spécifiés dans les fichiers sources a une précision de 99,19 % (c'est-à-dire que le bot répondra correctement à 1 577 questions sur 1 601).
À l'heure actuelle, il existe 3 ensembles de données pour entraîner le bot : 1601 paires de questions-réponses provenant de diverses pièces ( data/plays_ru
), 136 000 paires provenant de diverses œuvres ( data/conversations_ru
, grâce aux ensembles de données NLP) et 2 500 000 paires de sous-titres pour 347 séries télévisées ( data/subtitles_ru
, plus de détails dans l'ensemble de données des sous-titres russes). Les modèles word2vec sont entraînés sur tous les ensembles de données, mais le réseau neuronal n'est entraîné que sur l'ensemble de données des ensembles de jeux.
La formation du modèle word2vec et d'un réseau neuronal sur un ensemble de données de jeux sans modifier les paramètres prend environ 7,5 heures sur nvidia gtx1070 et Intel Core i7. La formation sur les jeux de données des œuvres et sous-titres sur ce matériel durera au minimum plusieurs jours.
Le bot peut fonctionner selon plusieurs modes :
L'ensemble de formation se compose de 1 600 questions %% paires de réponses tirées de diverses pièces de théâtre russes. Il est stocké dans le fichier data/plays_ru/plays_ru.txt
. Chaque paire de questions %% réponse est écrite sur une nouvelle ligne, c'est-à-dire Il n'y a qu'une seule paire sur une seule ligne.
Toutes les étapes nécessaires à la formation sont réalisées par les méthodes prepare()
ou load_prepared()
et train()
de la classe TextToText
du module text_to_text.py
et la méthode build_language_model()
de LanguageModel
du module preparing_speech_to_text.py
. Ou vous pouvez utiliser la fonction train()
du module bot.py
Pour exécuter le bot en mode entraînement, vous devez exécuter bot.py
avec le paramètre train
. Par exemple, comme ceci :
python3 bot.py train
Ou vous pouvez simplement exécuter bot.py
(ou run_bot.sh
) et sélectionner les modes 1 et 1 dans le menu proposé.
Le processus d'apprentissage comprend plusieurs étapes :
1. Préparation de l'échantillon de formation.
Pour préparer l'exemple de formation, le module source_to_prepared.py
, composé de la classe SourceToPrepared
, est utilisé. Cette classe lit un ensemble de formation à partir d'un fichier, sépare les questions et les réponses, supprime les caractères et la ponctuation non pris en charge et convertit les questions et réponses résultantes en séquences de taille fixe (en utilisant des mots de remplissage <PAD>
). Cette classe prépare également des questions pour le réseau et traite ses réponses. Par exemple:
Entrée : "Зачем нужен этот класс? %% Для подготовки данных"
Sortie : [['<PAD>', ..., '<PAD>', '?', 'класс', 'этот', 'нужен', 'Зачем', '<GO>'], ['Для', 'подготовки', 'данных', '<EOS>', '<PAD>', ..., '<PAD>']]
L'échantillon de formation est lu à partir du fichier data/plays_ru/plays_ru.txt
, les paires [question, réponse] converties sont enregistrées dans le fichier data/plays_ru/prepared_plays_ru.pkl
. En outre, un histogramme des tailles de questions et de réponses est construit, qui est enregistré dans data/plays_ru/histogram_of_sizes_sentences_plays_ru.png
.
Pour préparer un échantillon d'entraînement à partir d'un ensemble de données basé sur des jeux, transmettez simplement le nom du fichier correspondant à la méthode prepare_all()
. Pour préparer un échantillon de formation à partir d'un ensemble de données basé sur des œuvres ou des sous-titres, vous devez d'abord appeler combine_conversations()
ou combine_subtitles()
puis appeler preapre_all()
.
2. Traduction de mots en vecteurs réels.
Le module word_to_vec.py
, constitué de la classe WordToVec
, est responsable de cette étape. Cette classe code des séquences de taille fixe (c'est-à-dire nos questions et réponses) en vecteurs réels. L'encodeur word2vec de la bibliothèque gensim est utilisé. La classe implémente des méthodes pour coder simultanément toutes les paires [question, réponse] de l'ensemble d'apprentissage en vecteurs, ainsi que pour coder une question sur le réseau et décoder sa réponse. Par exemple:
Entrée : [['<PAD>', ..., '<PAD>', '?', 'класс', 'этот', 'нужен', 'Зачем', '<GO>'], ['Для', 'кодирования', 'предложений', '<EOS>', '<PAD>', ..., '<PAD>']]
Sortie : [[[0.43271607, 0.52814275, 0.6504923, ...], [0.43271607, 0.52814275, 0.6504923, ...], ...], [[0.5464854, 1.01612, 0.15063584, ...], [0.88263285, 0.62758327, 0.6659863, ...], ...]]
(c'est-à-dire que chaque mot est codé sous forme de vecteur d'une longueur de 500 (cette valeur peut être modifiée, l'argument size
dans la méthode build_word2vec()
))
Les paires [question, réponse] sont lues à partir du fichier data/plays_ru/prepared_plays_ru.pkl
(qui a été obtenu à l'étape précédente ; pour étendre et améliorer la qualité du modèle, il est recommandé de transmettre en plus un ensemble de données prétraitées à partir data/subtitles_ru/prepared_subtitles_ru.pkl
de sous-titres data/subtitles_ru/prepared_subtitles_ru.pkl
dans la méthode build_word2vec()
), les paires codées sont enregistrées dans le fichier data/plays_ru/encoded_plays_ru.npz
. De plus, au cours du processus de travail, une liste de tous les mots utilisés est construite, c'est-à-dire dictionnaire, qui est enregistré dans le fichier data/plays_ru/w2v_vocabulary_plays_ru.txt
. Le modèle word2vec formé est également enregistré dans data/plays_ru/w2v_model_plays_ru.bin
.
Pour traduire les mots de l'ensemble d'entraînement en vecteurs, transmettez simplement le nom du fichier correspondant à la méthode build_word2vec()
et définissez les paramètres souhaités.
3. Formation en réseau.
A ce stade, le modèle seq2seq est entraîné sur des données préalablement préparées. Le module text_to_text.py
, composé de la classe TextToText
, en est responsable. Cette classe entraîne le réseau, enregistre le modèle de réseau et les coefficients de pondération, et vous permet d'interagir facilement avec le modèle entraîné.
Pour la formation, vous avez besoin d'un fichier data/plays_ru/encoded_plays_ru.npz
contenant des paires [question, réponse] codées dans des vecteurs obtenus à l'étape précédente. Pendant le processus d'entraînement, toutes les 5 époques (cette valeur peut être modifiée), le résultat intermédiaire extrême de l'entraînement réseau est enregistré dans le fichier data/plays_ru/model_weights_plays_ru_[номер_итерации].h5
, et à la dernière itération dans le fichier data/plays_ru/model_weights_plays_ru.h5
(itération - un cycle de formation du réseau, un certain nombre d'époques, après quoi les poids sont enregistrés dans un fichier et vous pouvez, par exemple, évaluer la précision du réseau ou afficher d'autres paramètres. Par défaut, le nombre d'époques est de 5 et le nombre total d'itérations est de 200). Le modèle de réseau est enregistré dans le fichier data/plays_ru/model_plays_ru.json
.
Après la formation du réseau, la qualité de la formation est évaluée en soumettant toutes les questions à l'entrée du réseau formé et en comparant les réponses du réseau avec les réponses standard de l'ensemble de formation. Si la précision du modèle estimé est supérieure à 75 %, alors les réponses incorrectes du réseau sont enregistrées dans le fichier data/plays_ru/wrong_answers_plays_ru.txt
(afin qu'elles puissent être analysées ultérieurement).
Pour entraîner le réseau, transmettez simplement le nom du fichier correspondant à la méthode train()
et définissez les paramètres souhaités.
4. Création d'un modèle de langage et d'un dictionnaire pour PocketSphinx.
Cette étape est nécessaire si la reconnaissance vocale est utilisée. À ce stade, un modèle de langage statique et un dictionnaire phonétique pour PocketSphinx sont créés sur la base des questions de l'ensemble de formation (attention : plus il y a de questions dans l'ensemble de formation, plus il faudra de temps à PocketSphinx pour reconnaître la parole). Pour cela, utilisez build_language_model()
(qui accède text2wfreq, wfreq2vocab, text2idngram
et idngram2lm
depuis CMUclmtk_v0.7) de la classe LanguageModel
du module preparing_speech_to_text.py
. Cette méthode utilise les questions du fichier avec l'ensemble de formation d'origine (avant qu'elles ne soient préparées par le module source_to_prepared.py
), enregistre le modèle de langage dans le fichier temp/prepared_questions_plays_ru.lm
et le dictionnaire dans temp/prepared_questions_plays_ru.dic
( plays_ru
peut changer en fonction de l'ensemble d'entraînement utilisé). À la fin du travail, le modèle de langage et le dictionnaire seront copiés dans /usr/local/lib/python3.х/dist-packages/pocketsphinx/model
avec les noms ru_bot_plays_ru.lm
et ru_bot_plays_ru.dic
( plays_ru
peut changer dans le de la même manière qu'à l'étape précédente, vous devrez saisir le mot de passe de l'utilisateur root).
Pour interagir avec le modèle seq2seq entraîné, la fonction predict()
est destinée (qui est un wrapper sur la méthode predict()
de la classe TextToText
du module text_to_text.py
) du module bot.py
Cette fonction prend en charge plusieurs modes de fonctionnement. En mode texte, c'est à dire Lorsque l'utilisateur saisit une question au clavier et que le réseau répond avec du texte, seule la méthode predict()
de la classe TextToText
du module text_to_text.py
est utilisée. Cette méthode accepte une chaîne avec une question au réseau et renvoie une chaîne avec la réponse du réseau. Pour travailler, vous avez besoin de : le fichier data/plays_ru/w2v_model_plays_ru.bin
avec le modèle word2vec entraîné, le fichier data/plays_ru/model_plays_ru.json
avec les paramètres du modèle de réseau, et le fichier data/plays_ru/model_weights_plays_ru.h5
avec le poids du réseau formé.
Pour exécuter le bot dans ce mode, vous devez exécuter bot.py
avec le paramètre predict
. Par exemple, comme ceci :
python3 bot.py predict
Vous pouvez aussi simplement exécuter bot.py
(ou exécuter run_bot.sh
) et sélectionner les modes 2 et 1 dans le menu proposé.
Ce mode diffère du précédent dans le sens où le paramètre speech_synthesis = True
est passé à la fonction predict()
bot.py
Cela signifie que l’interaction avec le réseau se déroulera de la même manière qu’en mode 2, mais que la réponse du réseau sera en outre exprimée.
Exprimer des réponses, c'est-à-dire synthèse vocale, implémentée dans la méthode get()
de la classe TextToSpeech
du module text_to_speech.py
. Cette classe nécessite que le client RHVoice soit installé et, à l'aide d'arguments de ligne de commande, lui transmet les paramètres nécessaires à la synthèse vocale (vous pouvez voir comment installer RHVoice et des exemples d'accès au client RHVoice dans install_files/Install RHVoice.txt
). La méthode get()
prend en entrée la chaîne qui doit être convertie en parole et, si nécessaire, le nom du fichier .wav dans lequel la parole synthétisée sera enregistrée (avec une fréquence d'échantillonnage de 32 kHz et une profondeur de 16 bits, mono si non spécifié, la parole sera jouée immédiatement après la synthèse). Lors de la création d'un objet de la classe TextToSpeech
, vous pouvez préciser le nom de la voix à utiliser. 4 voix sont prises en charge : Aleksandr masculine et trois voix féminines - Anna, Elena et Irina (plus de détails dans RHVoice Wiki).
Pour exécuter le bot dans ce mode, vous devez exécuter bot.py
avec les paramètres predict -ss
. Par exemple, comme ceci :
python3 bot.py predict -ss
Vous pouvez aussi simplement exécuter bot.py
(ou exécuter run_bot.sh
) et sélectionner les modes 3 et 1 dans le menu proposé.
Pour travailler dans ce mode, vous devez passer le paramètre speech_recognition = True
à la fonction predict()
du module bot.py
Cela signifie que l'interaction avec le réseau, ou plutôt la saisie des questions, s'effectuera par la voix.
La reconnaissance vocale est implémentée dans la méthode get()
de la classe SpeechToText
du module speech_to_text.py
. Cette classe utilise PocketSphinx et un modèle de langage avec un dictionnaire ( ru_bot_plays_ru.lm
et ru_bot_plays_ru.dic
), qui ont été construits en mode formation réseau. La méthode get()
peut fonctionner selon deux modes : from_file
- reconnaissance vocale à partir d'un fichier .wav ou .opus avec une fréquence d'échantillonnage >=16 kHz, 16 bits, mono (le nom du fichier est passé en argument de fonction) et from_microphone
- parole reconnaissance à partir d'un microphone. Le mode de fonctionnement est défini lors de la création d'une instance de la classe SpeechRecognition
, car Le chargement du modèle de langage prend un certain temps (plus le modèle est grand, plus le chargement est long).
Pour exécuter le bot dans ce mode, vous devez exécuter bot.py
avec les paramètres predict -sr
. Par exemple, comme ceci :
python3 bot.py predict -sr
Vous pouvez aussi simplement exécuter bot.py
(ou exécuter run_bot.sh
) et sélectionner les modes 4 et 1 dans le menu proposé.
Il s'agit d'une combinaison des modes 3 et 4.
Pour travailler dans ce mode, vous devez passer les paramètres speech_recognition = True
et speech_synthesis = True
à la fonction predict()
du module bot.py
Cela signifie que les questions seront saisies vocalement et que les réponses du réseau seront prononcées. Une description des modules utilisés se trouve dans la description des modes 3 et 4.
Pour exécuter le bot dans ce mode, vous devez exécuter bot.py
avec les paramètres predict -ss -sr
. Par exemple, comme ceci :
python3 bot.py predict -sr -ss
ou
python3 bot.py predict -ss -sr
Vous pouvez aussi simplement exécuter bot.py
(ou exécuter run_bot.sh
) et sélectionner les modes 5 et 1 dans le menu proposé.
Ce serveur fournit une API REST pour interagir avec le bot. Lorsque le serveur démarre, un réseau neuronal formé sur un ensemble de données issues des jeux est chargé. Les ensembles de données des œuvres et des sous-titres ne sont pas encore pris en charge.
Le serveur est implémenté à l'aide de Flask et en mode multithread (version de production) à l'aide de gevent.pywsgi.WSGIServer. Le serveur a également une limite sur la taille des données reçues dans le corps de la requête égale à 16 Mo. L'implémentation se trouve dans le module rest_server.py
.
Vous pouvez démarrer le serveur WSGI en exécutant run_rest_server.sh
(en démarrant le serveur WSGI à 0.0.0.0:5000
).
Le serveur prend en charge les arguments de ligne de commande, ce qui facilite son démarrage. Les arguments ont la structure suivante : [ключ(-и)] [адрес:порт]
.
Clés possibles :
-d
- lancer un serveur Flask de test (si la clé n'est pas spécifiée, le serveur WSGI sera lancé)-s
- démarre le serveur avec le support https (utilise un certificat auto-signé, obtenu à l'aide d'openssl) адрес:порт
:
host:port
- lancement sur l' host
et port
spécifiéslocaladdr:port
- lancement avec détection automatique de l'adresse de la machine sur le réseau local et du port
spécifiéhost:0
ou localaddr:0
- si port = 0
, alors tout port disponible sera sélectionné automatiquementListe des combinaisons possibles d'arguments de ligne de commande et leur description :
5000
. Par exemple : python3 rest_server.py
host:port
- lance le serveur WSGI sur l' host
et port
spécifiés. Par exemple : python3 rest_server.py 192.168.2.102:5000
-d
- lancer un serveur Flask de test sur 127.0.0.1:5000
. Par exemple : python3 rest_server.py -d
-d host:port
- lance un serveur Flask de test sur l' host
et port
spécifiés. Par exemple : python3 rest_server.py -d 192.168.2.102:5000
-d localaddr:port
- lance un serveur Flask de test avec détection automatique de l'adresse de la machine sur le réseau local et du port port
. Par exemple : python3 rest_server.py -d localaddr:5000
-s
- lance un serveur WSGI avec support https, détection automatique de l'adresse de la machine sur le réseau local et du port 5000
. Par exemple : python3 rest_server.py -s
-s host:port
- lance un serveur WSGI avec prise en charge https sur l' host
et port
spécifiés. Par exemple : python3 rest_server.py -s 192.168.2.102:5000
-s -d
- lance un serveur Flask de test avec prise en charge https sur 127.0.0.1:5000
. Par exemple : python3 rest_server.py -s -d
-s -d host:port
- lance un serveur Flask de test avec prise en charge https sur l' host
et port
spécifiés. Par exemple : python3 rest_server.py -s -d 192.168.2.102:5000
-s -d localaddr:port
- lance un serveur Flask de test avec prise en charge https, détection automatique de l'adresse de la machine sur le réseau local et du port port
. Par exemple : python3 rest_server.py -s -d localaddr:5000
Le serveur peut choisir lui-même le port disponible ; pour ce faire, vous devez spécifier le port 0
dans host:port
ou localaddr:port
(par exemple : python3 rest_server.py -d localaddr:0
).
Au total, 5 requêtes sont prises en charge :
/chatbot/about
renverra des informations sur le projet/chatbot/questions
renverra une liste de toutes les questions prises en charge/chatbot/speech-to-text
, accepte un fichier .wav/.opus et renvoie la chaîne reconnue/chatbot/text-to-speech
, prend une chaîne et renvoie un fichier .wav avec la parole synthétisée/chatbot/text-to-text
, accepte une chaîne et renvoie la réponse du bot sous forme de chaîne 1. Le serveur dispose d’une autorisation http de base. Ceux. Pour accéder au serveur, vous devez ajouter un en-tête à chaque requête contenant login:mot de passe, codé en base64
(login: bot
, mot de passe: test_bot
). Exemple en python :
import requests
import base64
auth = base64.b64encode('testbot:test'.encode())
headers = {'Authorization' : "Basic " + auth.decode()}
Cela ressemblera à ceci :
Authorization: Basic dGVzdGJvdDp0ZXN0
2. Dans la requête de reconnaissance vocale (qui porte le numéro 3), le serveur attend un fichier .wav ou .opus (>=16 kHz 16 bits mono) avec la parole enregistrée, qui est également transmise à json en utilisant l'encodage base64
(c'est-à-dire ouvre .wav / Fichier .opus, lu dans un tableau d'octets, puis codé base64
, le tableau résultant est décodé sous forme d'octets en une chaîne utf-8
et placé en json), en python cela ressemble à ceci :
# Формирование запроса
auth = base64.b64encode('testbot:test'.encode())
headers = {'Authorization' : "Basic " + auth.decode()}
with open('test.wav', 'rb') as audio:
data = audio.read()
data = base64.b64encode(data)
data = {'wav' : data.decode()}
# Отправка запроса серверу
r = requests.post('http://' + addr + '/chatbot/speech-to-text', headers=headers, json=data)
# Разбор ответа
data = r.json()
data = data.get('text')
print(data)
3. Dans la demande de synthèse vocale (qui porte le numéro 4), le serveur enverra une réponse json avec un fichier .wav (16 bits 32 kHz mono) avec la parole synthétisée, qui a été codée comme décrit ci-dessus (pour le décoder, vous devez obtenez-le de json la chaîne souhaitée dans un tableau d'octets, puis décodez-la en base64
et écrivez-la dans un fichier ou un flux pour une lecture ultérieure), exemple en python :
# Формирование запроса
auth = base64.b64encode('testbot:test'.encode())
headers = {'Authorization' : "Basic " + auth.decode()}
data = {'text':'который час'}
# Отправка запроса серверу
r = requests.post('http://' + addr + '/chatbot/text-to-speech', headers=headers, json=data)
# Разбор ответа
data = r.json()
data = base64.b64decode(data.get('wav'))
with open('/home/vladislav/Проекты/Voice chat bot/temp/answer.wav', 'wb') as audio:
audio.write(data)
Toutes les données transmises sont enveloppées dans JSON (y compris les réponses contenant des erreurs).
{
"text" : "Информация о проекте."
}
{
"text" : ["Вопрос 1",
"Вопрос 2",
"Вопрос 3"]
}
{
"wav" : "UklGRuTkAABXQVZFZm10IBAAAAABAAEAAH..."
}
ou
{
"opus" : "ZFZm10IBUklQVZFZm10IBARLASBAAEOpH..."
}
Le serveur lui enverra :
{
"text" : "который час"
}
{
"text" : "который час"
}
Le serveur lui enverra :
{
"wav" : "UklGRuTkAABXQVZFZm10IBAAAAABAAEAAH..."
}
{
"text" : "прощай"
}
Le serveur lui enverra :
{
"text" : "это снова я"
}
1. Demande GET à /chatbot/about
Un exemple de requête générée par python-requests
:
GET /chatbot/about HTTP/1.1
Host: 192.168.2.83:5000
Connection: keep-alive
Accept-Encoding: gzip, deflate
Authorization: Basic dGVzdGJvdDp0ZXN0
User-Agent: python-requests/2.9.1
Un exemple de requête générée par curl ( curl -v -u testbot:test -i http://192.168.2.83:5000/chatbot/about
) :
GET /chatbot/about HTTP/1.1
Host: 192.168.2.83:5000
Authorization: Basic dGVzdGJvdDp0ZXN0
User-Agent: curl/7.47.0
Dans les deux cas, le serveur a répondu :
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 305
Date: Fri, 02 Nov 2018 15:13:21 GMT
{
"text" : "Информация о проекте."
}
2. Requête GET à /chatbot/questions
Un exemple de requête générée par python-requests
:
GET /chatbot/questions HTTP/1.1
Host: 192.168.2.83:5000
Authorization: Basic dGVzdGJvdDp0ZXN0
User-Agent: python-requests/2.9.1
Connection: keep-alive
Accept-Encoding: gzip, deflate
Un exemple de requête générée par curl ( curl -v -u testbot:test -i http://192.168.2.83:5000/chatbot/questions
) :
GET /chatbot/questions HTTP/1.1
Host: 192.168.2.83:5000
Authorization: Basic dGVzdGJvdDp0ZXN0
User-Agent: curl/7.47.0
Dans les deux cas, le serveur a répondu :
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 1086
Date: Fri, 02 Nov 2018 15:43:06 GMT
{
"text" : ["Что случилось?",
"Срочно нужна твоя помощь.",
"Ты уезжаешь?",
...]
}
3. Requête POST sur /chatbot/speech-to-text
Un exemple de requête générée par python-requests
:
POST /chatbot/speech-to-text HTTP/1.1
Host: 192.168.2.83:5000
User-Agent: python-requests/2.9.1
Accept: */*
Content-Length: 10739
Connection: keep-alive
Content-Type: application/json
Authorization: Basic dGVzdGJvdDp0ZXN0
Accept-Encoding: gzip, deflate
{
"wav" : "UklGRuTkAABXQVZFZm10IBAAAAABAAEAAH..."
}
Un exemple de requête générée par curl ( curl -v -u testbot:test -i -H "Content-Type: application/json" -X POST -d '{"wav":"UklGRuTkAABXQVZFZm10IBAAAAABAAEAAH..."}' http://192.168.2.83:5000/chatbot/speech-to-text
) :
POST /chatbot/speech-to-text HTTP/1.1
Host: 192.168.2.83:5000
Authorization: Basic dGVzdGJvdDp0ZXN0
User-Agent: curl/7.47.0
Accept: */*
Content-Type: application/json
Content-Length: 10739
{
"wav" : "UklGRuTkAABXQVZFZm10IBAAAAABAAEAAH..."
}
Le serveur a répondu :
HTTP/1.1 200 OK
Content-Length: 81
Date: Fri, 02 Nov 2018 15:57:13 GMT
Content-Type: application/json
{
"text" : "Распознные слова из аудиозаписи"
}
4. Requête POST sur /chatbot/text-to-speech
Un exemple de requête générée par python-requests
:
POST /chatbot/text-to-speech HTTP/1.1
Host: 192.168.2.83:5000
Connection: keep-alive
Accept: */*
User-Agent: python-requests/2.9.1
Accept-Encoding: gzip, deflate
Content-Type: application/json
Content-Length: 73
Authorization: Basic dGVzdGJvdDp0ZXN0
{
"text" : "который час"
}
Un exemple de requête générée par curl ( curl -v -u testbot:test -i -H "Content-Type: application/json" -X POST -d '{"text":"который час"}' http://192.168.2.83:5000/chatbot/text-to-speech
) :
POST /chatbot/text-to-speech HTTP/1.1
Host: 192.168.2.83:5000
Authorization: Basic dGVzdGJvdDp0ZXN0
User-Agent: curl/7.47.0
Accept: */*
Content-Type: application/json
Content-Length: 32
{
"text" : "который час"
}
Le serveur a répondu :
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 78151
Date: Fri, 02 Nov 2018 16:36:02 GMT
{
"wav" : "UklGRuTkAABXQVZFZm10IBAAAAABAAEAAH..."
}
5. Requête POST sur /chatbot/text-to-text
Un exemple de requête générée par python-requests
:
POST /chatbot/text-to-text HTTP/1.1
Host: 192.168.2.83:5000
Accept-Encoding: gzip, deflate
Content-Type: application/json
User-Agent: python-requests/2.9.1
Connection: keep-alive
Content-Length: 48
Accept: */*
Authorization: Basic dGVzdGJvdDp0ZXN0
{
"text" : "прощай"
}
Un exemple de requête générée par curl ( curl -v -u testbot:test -i -H "Content-Type: application/json" -X POST -d '{"text":"прощай"}' http://192.168.2.83:5000/chatbot/text-to-text
) :
POST /chatbot/text-to-text HTTP/1.1
Host: 192.168.2.83:5000
Authorization: Basic dGVzdGJvdDp0ZXN0
User-Agent: curl/7.47.0
Accept: */*
Content-Type: application/json
Content-Length: 23
{
"text" : "прощай"
}
Le serveur a répondu :
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 68
Date: Fri, 02 Nov 2018 16:41:22 GMT
{
"text" : "это снова я"
}
Le projet contient un Dockerfile, qui vous permet de créer une image Docker basée sur ce projet. Si vous avez utilisé install_packages.sh
pour installer toutes les dépendances et que vous n'avez jamais installé Docker auparavant, vous devrez l'installer manuellement. Par exemple, comme ceci (testé sur Ubuntu 16.04-18.04) :
sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D
sudo apt-add-repository 'deb https://apt.dockerproject.org/repo ubuntu-xenial main' -y
sudo apt-get -y update
sudo apt-get install -y docker-engine
Après l'installation, exécutez sudo systemctl status docker
pour vous assurer que tout est installé et fonctionne (dans la sortie de cette commande, vous trouverez une ligne avec du texte vert active (running)
).
Pour créer l'image, vous devez accéder au dossier contenant le projet dans le terminal et exécuter ( -t
- lancer le terminal, .
- le répertoire à partir duquel docker build est appelé (point - cela signifie que tous les fichiers de l'image sont dans le répertoire courant), voice_chatbot:0.1
- label de l'image et sa version) :
sudo docker build -t voice_chatbot:0.1 .
Après avoir réussi cette opération, vous pouvez lister les images disponibles en exécutant :
sudo docker images
Dans la liste résultante, vous verrez notre image - voice_chatbot:0.1
.
Vous pouvez maintenant exécuter cette image ( -t
- démarrer le terminal, -i
- mode interactif, --rm
- supprimer le conteneur une fois terminé, -p 5000:5000
- transférer toutes les connexions sur le port 5000 vers la machine hôte vers le conteneur sur le port 5000 (vous pouvez aussi spécifier explicitement une autre adresse à laquelle vous devrez vous connecter en externe, par exemple : -p 127.0.0.1:5000:5000
)) :
sudo docker run -ti --rm -p 5000:5000 voice_chatbot:0.1
De ce fait, le serveur RESTful démarrera à 0.0.0.0:5000
et vous pourrez y accéder à l'adresse indiquée dans le terminal (si vous n'en avez pas précisé une autre lors du démarrage de l'image).
Remarque : l'image docker assemblée pèse 5,2 Go. Les fichiers sources du projet incluent également un fichier .dockerignore
, qui contient les noms des fichiers qui n'ont pas besoin d'être ajoutés à l'image. Afin de minimiser la taille de l'image finale, tous les fichiers liés à l'ensemble de données provenant des histoires et des sous-titres, les fichiers avec des résultats intermédiaires du traitement des données et de la formation du réseau neuronal en ont été exclus. Cela signifie que l'image contient uniquement les fichiers réseau entraînés et les ensembles de données sources brutes.
Juste au cas où, dans les fichiers sources du projet, il existe un fichier command_for_docker.txt
contenant l'ensemble minimum de commandes requis pour travailler avec Docker.
Si vous avez des questions ou souhaitez collaborer, vous pouvez m'écrire à [email protected] ou sur LinkedIn.