El proyecto consta de dos partes: un robot de voz y un servidor RESTful para interactuar con él.
Para ejecutar el bot localmente, debe ejecutar python3 bot.py
(o run_bot.sh
) y seleccionar la opción de operación deseada en el menú propuesto (más detalles aquí).
Para iniciar un servidor RESTful que proporciona una interfaz para interactuar con módulos de bot de voz, debe ejecutar python3 rest_server.py
(o run_rest_server.sh
) (más detalles aquí).
Para crear una imagen de Docker basada en un servidor RESTful, ejecute sudo docker build -t voice_chatbot:0.1 .
(más detalles aquí).
¡ATENCIÓN! Este fue mi proyecto de graduación, por lo que la arquitectura y el código aquí no son muy buenos. Lo entiendo y, cuando llegue el momento, actualizaré todo.
Una lista completa de todas las dependencias necesarias para la operación:
Voice_ChatBot_data.zip
(3Gb) de Google Drive y descomprimirlo en la raíz del proyecto (carpetas data
e install_files
). Si está utilizando Ubuntu 16.04 o superior, puede usar install_packages.sh
(probado en Ubuntu 16.04 y 18.04) para instalar todos los paquetes. De forma predeterminada, se instalará TensorFlow para CPU. Si tiene una tarjeta gráfica nvidia con la versión 410 del controlador oficial instalada, puede instalar TensorFlowGPU. Para hacer esto, debe pasar el parámetro gpu
cuando ejecute install_packages.sh
. Por ejemplo:
./install_packages.sh gpu
En este caso, se descargarán 2 archivos desde mi Google Drive:
Install_CUDA10.0_cuDNN_for410.zip
(2.0Gb) con CUDA 10.0 y cuDNN 7.5.0 (si se pasó el parámetro gpu
). La instalación se completará automáticamente, pero si algo sale mal, hay una instrucción Install.txt
en el archivo descargado.Voice_ChatBot_data.zip
(3Gb) con datos de entrenamiento y modelos listos para usar. Se descomprimirá automáticamente en data
y install_files
en la raíz del proyecto. Si no puede o no desea utilizar el script para instalar todos los paquetes necesarios, debe instalar manualmente RHVoice y CMUclmtk_v0.7 siguiendo las instrucciones en install_files/Install RHVoice.txt
e install_files/Install CMUclmtk.txt
. También necesita copiar los archivos de idioma, modelo acústico y diccionario para PocketSphinx desde temp/
a /usr/local/lib/python3.6/dist-packages/pocketsphinx/model
(su ruta a python3.6
puede ser diferente). Los archivos del modelo de idioma prepared_questions_plays_ru.lm
y el diccionario prepared_questions_plays_ru.dic
deben cambiarse de nombre a ru_bot_plays_ru.lm
y ru_bot_plays_ru.dic
(o cambiar su nombre a speech_to_text.py
si tiene su propio modelo de idioma y diccionario).
El bot se basa en una red neuronal recurrente, el modelo AttentionSeq2Seq. En la implementación actual, consta de 2 celdas LSTM bidireccionales en el codificador, una capa de atención y 2 celdas LSTM en el decodificador. El uso de un modelo de atención le permite establecer una correspondencia "suave" entre las secuencias de entrada y salida, lo que mejora la calidad y la productividad. La dimensión de entrada en la última configuración es 500 y la longitud de la secuencia es 26 (es decir, la longitud máxima de oraciones en el conjunto de entrenamiento). Las palabras se convierten en vectores utilizando el codificador word2vec (con un diccionario de 445.000 palabras) de la biblioteca gensim. El modelo seq2seq se implementa utilizando Keras y RecurrentShop. El modelo seq2seq entrenado (cuyos pesos se encuentran en data/plays_ru/model_weights_plays_ru.h5
) con los parámetros especificados en los archivos fuente tiene una precisión del 99,19% (es decir, el bot responderá correctamente 1577 de 1601 preguntas).
Por el momento, existen 3 conjuntos de datos para entrenar el robot: 1.601 pares de preguntas y respuestas de varias obras ( data/plays_ru
), 136.000 pares de varias obras ( data/conversations_ru
, gracias a NLP Datasets) y 2.500.000 pares de subtítulos para 347 series de televisión ( data/subtitles_ru
, más detalles en el conjunto de datos de subtítulos en ruso). Los modelos de word2vec se entrenan en todos los conjuntos de datos, pero la red neuronal solo se entrena en el conjunto de datos de los juegos.
Entrenar el modelo word2vec y una red neuronal en un conjunto de datos de reproducciones sin cambiar los parámetros toma aproximadamente 7,5 horas en nvidia gtx1070 e intel core i7. La formación sobre conjuntos de datos de obras y subtítulos en este hardware durará al menos varios días.
El bot puede funcionar en varios modos:
El conjunto de entrenamiento consta de 1600 pares de %% de preguntas y respuestas tomadas de varias obras de teatro rusas. Se almacena en el archivo data/plays_ru/plays_ru.txt
. Cada par de preguntas %% respuesta se escribe en una nueva línea, es decir Sólo hay un par en una línea.
Todas las etapas necesarias para el entrenamiento se realizan mediante los métodos prepare()
o load_prepared()
y train()
de la clase TextToText
del módulo text_to_text.py
y el método build_language_model()
de LanguageModel
del módulo preparing_speech_to_text.py
. O puede utilizar la función train()
del módulo bot.py
Para ejecutar el bot en modo de entrenamiento, debe ejecutar bot.py
con el parámetro train
. Por ejemplo, así:
python3 bot.py train
O simplemente puede ejecutar bot.py
(o run_bot.sh
) y seleccionar el modo 1 y 1 del menú propuesto.
El proceso de aprendizaje consta de varias etapas:
1. Elaboración de la muestra formativa.
Para preparar la muestra de entrenamiento, se utiliza el módulo source_to_prepared.py
, que consta de la clase SourceToPrepared
. Esta clase lee un conjunto de capacitación de un archivo, separa preguntas y respuestas, elimina caracteres y puntuación no admitidos y convierte las preguntas y respuestas resultantes en secuencias de tamaño fijo (usando palabras de relleno <PAD>
). Esta clase también prepara preguntas para la red y procesa sus respuestas. Por ejemplo:
Entrada: "Зачем нужен этот класс? %% Для подготовки данных"
Salida: [['<PAD>', ..., '<PAD>', '?', 'класс', 'этот', 'нужен', 'Зачем', '<GO>'], ['Для', 'подготовки', 'данных', '<EOS>', '<PAD>', ..., '<PAD>']]
La muestra de entrenamiento se lee del archivo data/plays_ru/plays_ru.txt
, los pares [pregunta, respuesta] convertidos se guardan en el archivo data/plays_ru/prepared_plays_ru.pkl
. Además, se crea un histograma de los tamaños de preguntas y respuestas, que se guarda en data/plays_ru/histogram_of_sizes_sentences_plays_ru.png
.
Para preparar una muestra de entrenamiento a partir de un conjunto de datos basado en jugadas, simplemente pase el nombre del archivo correspondiente al método prepare_all()
. Para preparar una muestra de entrenamiento a partir de un conjunto de datos basado en obras o subtítulos, primero debe llamar combine_conversations()
o combine_subtitles()
y luego llamar preapre_all()
.
2. Traducción de palabras a vectores reales.
El módulo word_to_vec.py
, que consta de la clase WordToVec
, es responsable de esta etapa. Esta clase codifica secuencias de tamaño fijo (es decir, nuestras preguntas y respuestas) en vectores reales. Se utiliza el codificador word2vec de la biblioteca gensim. La clase implementa métodos para codificar todos los pares [pregunta, respuesta] del conjunto de entrenamiento en vectores a la vez, así como para codificar una pregunta en la red y decodificar su respuesta. Por ejemplo:
Entrada: [['<PAD>', ..., '<PAD>', '?', 'класс', 'этот', 'нужен', 'Зачем', '<GO>'], ['Для', 'кодирования', 'предложений', '<EOS>', '<PAD>', ..., '<PAD>']]
Salida: [[[0.43271607, 0.52814275, 0.6504923, ...], [0.43271607, 0.52814275, 0.6504923, ...], ...], [[0.5464854, 1.01612, 0.15063584, ...], [0.88263285, 0.62758327, 0.6659863, ...], ...]]
(es decir, cada palabra está codificada como un vector con una longitud de 500 (este valor se puede cambiar, el argumento size
en el método build_word2vec()
))
Los pares [pregunta, respuesta] se leen del archivo data/plays_ru/prepared_plays_ru.pkl
(que se obtuvo en la etapa anterior; para ampliar y mejorar la calidad del modelo, se recomienda pasar adicionalmente un conjunto de datos preprocesados a partir de data/subtitles_ru/prepared_subtitles_ru.pkl
de subtítulos data/subtitles_ru/prepared_subtitles_ru.pkl
al método build_word2vec()
), los pares codificados se guardan en el archivo data/plays_ru/encoded_plays_ru.npz
. Además, durante el proceso de trabajo, se crea una lista de todas las palabras utilizadas, es decir, un diccionario que se guarda en el archivo data/plays_ru/w2v_vocabulary_plays_ru.txt
. El modelo word2vec entrenado también se guarda en data/plays_ru/w2v_model_plays_ru.bin
.
Para traducir palabras del conjunto de entrenamiento a vectores, simplemente pase el nombre del archivo correspondiente al método build_word2vec()
y establezca los parámetros deseados.
3. Formación en red.
En esta etapa, el modelo seq2seq se entrena con datos previamente preparados. El módulo text_to_text.py
, que consta de la clase TextToText
, es responsable de esto. Esta clase entrena la red, guarda el modelo de red y los coeficientes de ponderación y le permite interactuar cómodamente con el modelo entrenado.
Para el entrenamiento, necesita un archivo data/plays_ru/encoded_plays_ru.npz
que contenga pares [pregunta, respuesta] codificados en vectores que se obtuvieron en la etapa anterior. Durante el proceso de entrenamiento, después de cada quinta época (este valor se puede cambiar), el resultado intermedio extremo del entrenamiento de la red se guarda en el archivo data/plays_ru/model_weights_plays_ru_[номер_итерации].h5
, y en la última iteración en el archivo data/plays_ru/model_weights_plays_ru.h5
(iteración: un ciclo de entrenamiento de la red, una cierta cantidad de épocas, después de las cuales los pesos se guardan en un archivo y puede, por ejemplo, evaluar la precisión de la red o mostrar otros De forma predeterminada, el número de épocas es 5 y el número total de iteraciones es 200). El modelo de red se guarda en el archivo data/plays_ru/model_plays_ru.json
.
Después de capacitar a la red, la calidad de la capacitación se evalúa enviando todas las preguntas a la entrada de la red entrenada y comparando las respuestas de la red con las respuestas estándar del conjunto de capacitación. Si la precisión del modelo estimado es superior al 75%, las respuestas incorrectas de la red se guardan en el archivo data/plays_ru/wrong_answers_plays_ru.txt
(para poder analizarlas más adelante).
Para entrenar la red, simplemente pase el nombre del archivo correspondiente al método train()
y establezca los parámetros deseados.
4. Construir un modelo de lenguaje y un diccionario para PocketSphinx.
Esta etapa es necesaria si se utilizará el reconocimiento de voz. En esta etapa, se crea un modelo de lenguaje estático y un diccionario fonético para PocketSphinx basado en las preguntas del conjunto de capacitación (precaución: cuantas más preguntas haya en el conjunto de capacitación, más tiempo le tomará a PocketSphinx reconocer el habla). Para hacer esto, use build_language_model()
(que accede text2wfreq, wfreq2vocab, text2idngram
e idngram2lm
desde CMUclmtk_v0.7) de la clase LanguageModel
del módulo preparing_speech_to_text.py
. Este método utiliza preguntas del archivo con la muestra de entrenamiento original (antes de que sean preparadas por el módulo source_to_prepared.py
), guarda el modelo de lenguaje en el archivo temp/prepared_questions_plays_ru.lm
y el diccionario en temp/prepared_questions_plays_ru.dic
( plays_ru
puede cambiar dependiendo del conjunto de entrenamiento utilizado). Al final del trabajo, el modelo de lenguaje y el diccionario se copiarán en /usr/local/lib/python3.х/dist-packages/pocketsphinx/model
con los nombres ru_bot_plays_ru.lm
y ru_bot_plays_ru.dic
( plays_ru
puede cambiar en el De la misma manera que en la etapa anterior, deberá ingresar la contraseña del usuario root).
Para interactuar con el modelo seq2seq entrenado, se utiliza la función predict()
(que es un contenedor sobre el método predict()
de la clase TextToText
del módulo text_to_text.py
) del módulo bot.py
Esta función admite varios modos de funcionamiento. En modo texto, es decir. Cuando el usuario ingresa una pregunta desde el teclado y la red responde con texto, solo se usa el método predict()
de la clase TextToText
del módulo text_to_text.py
. Este método acepta una cadena con una pregunta para la red y devuelve una cadena con la respuesta de la red. Para trabajar, necesita: el archivo data/plays_ru/w2v_model_plays_ru.bin
con el modelo word2vec entrenado, el archivo data/plays_ru/model_plays_ru.json
con los parámetros del modelo de red y el archivo data/plays_ru/model_weights_plays_ru.h5
con el Pesos de la red entrenada.
Para ejecutar el bot en este modo, debe ejecutar bot.py
con el parámetro predict
. Por ejemplo, así:
python3 bot.py predict
También puede simplemente ejecutar bot.py
(o run_bot.sh
) y seleccionar los modos 2 y 1 en el menú propuesto.
Este modo se diferencia del anterior en que el parámetro speech_synthesis = True
se pasa a la función predict()
del módulo bot.py
Esto significa que la interacción con la red se realizará de la misma manera que en el modo 2, pero además se expresará la respuesta de la red.
Respuestas expresadas, es decir. síntesis de voz, implementada en el método get()
de la clase TextToSpeech
del módulo text_to_speech.py
. Esta clase requiere que RHVoice-client esté instalado y, usando argumentos de línea de comando, le pasa los parámetros necesarios para la síntesis de voz (puede ver cómo instalar RHVoice y ejemplos de cómo acceder a RHVoice-client en install_files/Install RHVoice.txt
). El método get()
toma como entrada la cadena que necesita convertirse a voz y, si es necesario, el nombre del archivo .wav en el que se guardará la voz sintetizada (con una frecuencia de muestreo de 32 kHz y una profundidad de 16 bits, mono; si no se especifica, la voz se reproducirá inmediatamente después de la síntesis). Al crear un objeto de la clase TextToSpeech
, puede especificar el nombre de la voz a utilizar. Se admiten 4 voces: Aleksandr masculino y tres femeninas: Anna, Elena e Irina (más detalles en RHVoice Wiki).
Para ejecutar el bot en este modo, debe ejecutar bot.py
con los parámetros predict -ss
. Por ejemplo, así:
python3 bot.py predict -ss
También puede simplemente ejecutar bot.py
(o run_bot.sh
) y seleccionar los modos 3 y 1 en el menú propuesto.
Para trabajar en este modo, debe pasar el parámetro speech_recognition = True
a la función predict()
del módulo bot.py
Esto significa que la interacción con la red, o más bien la introducción de preguntas, se realizará mediante voz.
El reconocimiento de voz se implementa en el método get()
de la clase SpeechToText
del módulo speech_to_text.py
. Esta clase utiliza PocketSphinx y un modelo de lenguaje con un diccionario ( ru_bot_plays_ru.lm
y ru_bot_plays_ru.dic
), que se crearon en modo de entrenamiento en red. El método get()
puede funcionar en dos modos: from_file
- reconocimiento de voz desde un archivo .wav o .opus con una frecuencia de muestreo >=16 kHz, 16 bits, mono (el nombre del archivo se pasa como argumento a la función) y from_microphone
- reconocimiento de voz desde un micrófono. El modo de funcionamiento se establece al crear una instancia de la clase SpeechRecognition
, porque Cargar el modelo de lenguaje lleva algo de tiempo (cuanto más grande sea el modelo, más tardará en cargarse).
Para ejecutar el bot en este modo, debe ejecutar bot.py
con los parámetros predict -sr
. Por ejemplo, así:
python3 bot.py predict -sr
También puede simplemente ejecutar bot.py
(o ejecutar run_bot.sh
) y seleccionar los modos 4 y 1 en el menú propuesto.
Esta es una combinación de los modos 3 y 4.
Para trabajar en este modo, debe pasar los parámetros speech_recognition = True
y speech_synthesis = True
a la función predict()
del módulo bot.py
Esto significa que las preguntas se ingresarán mediante voz y las respuestas de la red se hablarán. Una descripción de los módulos utilizados se puede encontrar en la descripción de los modos 3 y 4.
Para ejecutar el bot en este modo, debe ejecutar bot.py
con los parámetros predict -ss -sr
. Por ejemplo, así:
python3 bot.py predict -sr -ss
o
python3 bot.py predict -ss -sr
También puede simplemente ejecutar bot.py
(o ejecutar run_bot.sh
) y seleccionar los modos 5 y 1 en el menú propuesto.
Este servidor proporciona una API REST para interactuar con el bot. Cuando se inicia el servidor, se carga una red neuronal entrenada con un conjunto de datos de jugadas. Aún no se admiten conjuntos de datos de obras y subtítulos.
El servidor se implementa mediante Flask y el modo multiproceso (versión de producción) mediante gevent.pywsgi.WSGIServer. El servidor también tiene un límite en el tamaño de los datos recibidos en el cuerpo de la solicitud igual a 16 MB. La implementación está en el módulo rest_server.py
.
Puede iniciar el servidor WSGI ejecutando run_rest_server.sh
(iniciando el servidor WSGI en 0.0.0.0:5000
).
El servidor admite argumentos de línea de comando, lo que facilita un poco su inicio. Los argumentos tienen la siguiente estructura: [ключ(-и)] [адрес:порт]
.
Posibles claves:
-d
: inicia un servidor Flask de prueba (si no se especifica la clave, se iniciará el servidor WSGI)-s
: inicia el servidor con soporte https (utiliza un certificado autofirmado, obtenido mediante openssl) Opciones válidas адрес:порт
:
host:port
: se inicia en el host
y port
especificadoslocaladdr:port
: inicio con detección automática de la dirección de la máquina en la red local y el port
especificadohost:0
o localaddr:0
: si port = 0
, cualquier puerto disponible se seleccionará automáticamenteLista de posibles combinaciones de argumentos de línea de comando y su descripción:
5000
. Por ejemplo: python3 rest_server.py
host:port
: inicia el servidor WSGI en el host
y port
especificados. Por ejemplo: python3 rest_server.py 192.168.2.102:5000
-d
: inicia un servidor Flask de prueba en 127.0.0.1:5000
. Por ejemplo: python3 rest_server.py -d
-d host:port
: inicia un servidor Flask de prueba en el host
y port
especificados. Por ejemplo: python3 rest_server.py -d 192.168.2.102:5000
-d localaddr:port
: inicia un servidor Flask de prueba con detección automática de la dirección de la máquina en la red local y port
. Por ejemplo: python3 rest_server.py -d localaddr:5000
-s
: inicia un servidor WSGI con soporte https, detección automática de la dirección de la máquina en la red local y puerto 5000
. Por ejemplo: python3 rest_server.py -s
-s host:port
: inicia un servidor WSGI con soporte https en el host
y port
especificados. Por ejemplo: python3 rest_server.py -s 192.168.2.102:5000
-s -d
: inicia un servidor Flask de prueba con soporte https en 127.0.0.1:5000
. Por ejemplo: python3 rest_server.py -s -d
-s -d host:port
: inicia un servidor Flask de prueba con soporte https en el host
y port
especificados. Por ejemplo: python3 rest_server.py -s -d 192.168.2.102:5000
-s -d localaddr:port
: inicia un servidor Flask de prueba con soporte https, detección automática de la dirección de la máquina en la red local y el port
. Por ejemplo: python3 rest_server.py -s -d localaddr:5000
El servidor puede elegir el puerto disponible por sí mismo; para hacer esto, debe especificar el puerto 0
en host:port
o localaddr:port
(por ejemplo: python3 rest_server.py -d localaddr:0
).
Se admiten un total de 5 consultas:
/chatbot/about
devolverá información sobre el proyecto/chatbot/questions
devolverá una lista de todas las preguntas admitidas/chatbot/speech-to-text
, acepta un archivo .wav/.opus y devuelve la cadena reconocida/chatbot/text-to-speech
, toma una cadena y devuelve un archivo .wav con voz sintetizada/chatbot/text-to-text
, acepta una cadena y devuelve la respuesta del bot como una cadena 1. El servidor tiene autorización http básica. Aquellos. Para obtener acceso al servidor, debe agregar un encabezado a cada solicitud que contenga inicio de sesión: contraseña, codificado con base64
(inicio de sesión: bot
, contraseña: test_bot
). Ejemplo en Python:
import requests
import base64
auth = base64.b64encode('testbot:test'.encode())
headers = {'Authorization' : "Basic " + auth.decode()}
Se verá así:
Authorization: Basic dGVzdGJvdDp0ZXN0
2. En la solicitud de reconocimiento de voz (que es la número 3), el servidor espera un archivo .wav o .opus (>=16kHz 16bit mono) con voz grabada, que también se transmite a json usando codificación base64
(es decir, abre .wav / .opus, leído en una matriz de bytes, luego codificado en base64
, la matriz resultante se decodifica desde el formato de bytes a una cadena utf-8
y colocado en json), en python se ve así:
# Формирование запроса
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. En la solicitud de síntesis de voz (que es la número 4), el servidor enviará una respuesta json con un archivo .wav (mono de 16 bits y 32 kHz) con voz sintetizada, que fue codificada como se describe arriba (para decodificarla nuevamente debe obtenga de json la cadena deseada en una matriz de bytes, luego decodifíquela usando base64
y escríbala en un archivo o secuencia para reproducirla más tarde), ejemplo 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)
Todos los datos transmitidos están empaquetados en json (incluidas las respuestas con errores).
{
"text" : "Информация о проекте."
}
{
"text" : ["Вопрос 1",
"Вопрос 2",
"Вопрос 3"]
}
{
"wav" : "UklGRuTkAABXQVZFZm10IBAAAAABAAEAAH..."
}
o
{
"opus" : "ZFZm10IBUklQVZFZm10IBARLASBAAEOpH..."
}
El servidor le enviará:
{
"text" : "который час"
}
{
"text" : "который час"
}
El servidor le enviará:
{
"wav" : "UklGRuTkAABXQVZFZm10IBAAAAABAAEAAH..."
}
{
"text" : "прощай"
}
El servidor le enviará:
{
"text" : "это снова я"
}
1. OBTENER solicitud a /chatbot/about
Un ejemplo de una solicitud que genera 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 ejemplo de una solicitud que genera 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
En ambos casos el servidor respondió:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 305
Date: Fri, 02 Nov 2018 15:13:21 GMT
{
"text" : "Информация о проекте."
}
2. OBTENER solicitud a /chatbot/questions
Un ejemplo de una solicitud que genera 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 ejemplo de una solicitud que genera 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
En ambos casos el servidor respondió:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 1086
Date: Fri, 02 Nov 2018 15:43:06 GMT
{
"text" : ["Что случилось?",
"Срочно нужна твоя помощь.",
"Ты уезжаешь?",
...]
}
3. PUBLICAR solicitud en /chatbot/speech-to-text
Un ejemplo de una solicitud que genera 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 ejemplo de una solicitud que genera 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..."
}
El servidor respondió:
HTTP/1.1 200 OK
Content-Length: 81
Date: Fri, 02 Nov 2018 15:57:13 GMT
Content-Type: application/json
{
"text" : "Распознные слова из аудиозаписи"
}
4. PUBLICAR solicitud en /chatbot/text-to-speech
Un ejemplo de una solicitud que genera 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 ejemplo de una solicitud que genera 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" : "который час"
}
El servidor respondió:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 78151
Date: Fri, 02 Nov 2018 16:36:02 GMT
{
"wav" : "UklGRuTkAABXQVZFZm10IBAAAAABAAEAAH..."
}
5. PUBLICAR solicitud en /chatbot/text-to-text
Un ejemplo de una solicitud que genera 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 ejemplo de una solicitud que genera 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" : "прощай"
}
El servidor respondió:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 68
Date: Fri, 02 Nov 2018 16:41:22 GMT
{
"text" : "это снова я"
}
El proyecto contiene un Dockerfile, que le permite crear una imagen de Docker basada en este proyecto. Si usó install_packages.sh
para instalar todas las dependencias y no ha instalado Docker antes, deberá instalarlo manualmente. Por ejemplo, así (probado en 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
Después de la instalación, ejecute sudo systemctl status docker
para asegurarse de que todo esté instalado y funcionando (en el resultado de este comando encontrará una línea con el texto verde active (running)
).
Para crear la imagen, debe ir a la carpeta con el proyecto en la terminal y ejecutar ( -t
- iniciar la terminal, .
- el directorio desde donde se llama a Docker Build (punto: esto significa que todos los archivos de la imagen están en el directorio actual), voice_chatbot:0.1
- etiqueta de imagen y su versión):
sudo docker build -t voice_chatbot:0.1 .
Después de completar con éxito esta operación, puede enumerar las imágenes disponibles ejecutando:
sudo docker images
En la lista resultante verá nuestra imagen: voice_chatbot:0.1
.
Ahora puede ejecutar esta imagen ( -t
- iniciar la terminal, -i
- modo interactivo, --rm
- eliminar el contenedor una vez finalizado, -p 5000:5000
- reenviar todas las conexiones en el puerto 5000 a la máquina host al contenedor en el puerto 5000 (también puede especificar explícitamente otra dirección a la que deberá conectarse externamente, por ejemplo: -p 127.0.0.1:5000:5000
)):
sudo docker run -ti --rm -p 5000:5000 voice_chatbot:0.1
Como resultado, el servidor RESTful se iniciará en 0.0.0.0:5000
y podrá acceder a él en la dirección especificada en la terminal (si no especificó una diferente al iniciar la imagen).
Nota : la imagen acoplable ensamblada pesa 5,2 GB. Los archivos fuente del proyecto también incluyen un archivo .dockerignore
, que contiene los nombres de los archivos que no es necesario agregar a la imagen. Para minimizar el tamaño de la imagen final, se excluyeron de ella todos los archivos relacionados con el conjunto de datos de historias y subtítulos, archivos con resultados intermedios del procesamiento de datos y entrenamiento de redes neuronales. Esto significa que la imagen contiene solo los archivos de red entrenados y los conjuntos de datos de origen sin procesar.
Por si acaso, en los archivos fuente del proyecto hay un archivo command_for_docker.txt
que contiene el conjunto mínimo requerido de comandos para trabajar con Docker.
Si tienes alguna duda o quieres colaborar, puedes escribirme a [email protected] o en LinkedIn.