O projeto consiste em duas partes - um bot de voz e um servidor RESTful para interagir com ele.
Para executar o bot localmente, você precisa executar python3 bot.py
(ou run_bot.sh
) e selecionar a opção de operação desejada no menu proposto (mais detalhes aqui).
Para iniciar um servidor RESTful que fornece uma interface para interagir com módulos de bot de voz, você precisa executar python3 rest_server.py
(ou run_rest_server.sh
) (mais detalhes aqui).
Para construir uma imagem docker baseada em um servidor RESTful, execute sudo docker build -t voice_chatbot:0.1 .
(mais detalhes aqui).
ATENÇÃO! Esse foi meu projeto de graduação, então a arquitetura e o código aqui não são muito bons, eu entendo isso, e quando chegar a hora irei atualizar tudo.
Uma lista completa de todas as dependências necessárias para operação:
Voice_ChatBot_data.zip
(3Gb) do Google Drive e descompactá-lo na raiz do projeto (pastas data
e install_files
). Se estiver usando Ubuntu 16.04 ou superior, você pode usar install_packages.sh
(testado no Ubuntu 16.04 e 18.04) para instalar todos os pacotes. Por padrão, o TensorFlow para CPU será instalado. Se você tiver uma placa gráfica nvidia com o driver oficial versão 410 instalado, poderá instalar o TensorFlowGPU. Para fazer isso, você precisa passar o parâmetro gpu
ao executar install_packages.sh
. Por exemplo:
./install_packages.sh gpu
Neste caso, 2 arquivos serão baixados do meu Google Drive:
Install_CUDA10.0_cuDNN_for410.zip
(2,0 Gb) com CUDA 10.0 e cuDNN 7.5.0 (se o parâmetro gpu
foi passado). A instalação será concluída automaticamente, mas se algo der errado, há uma instrução Install.txt
no arquivo baixado.Voice_ChatBot_data.zip
(3Gb) com dados de treinamento e modelos prontos. Ele será descompactado automaticamente data
e install_files
na raiz do projeto. Se você não puder ou não quiser usar o script para instalar todos os pacotes necessários, deverá instalar manualmente o RHVoice e o CMUclmtk_v0.7 usando as instruções em install_files/Install RHVoice.txt
e install_files/Install CMUclmtk.txt
. Você também precisa copiar o idioma, o modelo acústico e os arquivos de dicionário do PocketSphinx de temp/
para /usr/local/lib/python3.6/dist-packages/pocketsphinx/model
(seu caminho para python3.6
pode ser diferente). Os arquivos do modelo de idioma prepared_questions_plays_ru.lm
e o dicionário prepared_questions_plays_ru.dic
devem ser renomeados para ru_bot_plays_ru.lm
e ru_bot_plays_ru.dic
(ou altere seu nome para speech_to_text.py
se você tiver seu próprio modelo de idioma e dicionário).
O bot é baseado em uma rede neural recorrente, o modelo AttentionSeq2Seq. Na implementação atual, consiste em 2 células LSTM bidirecionais no codificador, uma camada de atenção e 2 células LSTM no decodificador. Usar um modelo de atenção permite estabelecer uma correspondência “suave” entre as sequências de entrada e saída, o que melhora a qualidade e a produtividade. A dimensão de entrada na última configuração é 500 e o comprimento da sequência é 26 (ou seja, o comprimento máximo das sentenças no conjunto de treinamento). As palavras são convertidas em vetores usando o codificador word2vec (com dicionário de 445.000 palavras) da biblioteca gensim. O modelo seq2seq é implementado usando Keras e RecurrentShop. O modelo seq2seq treinado (cujos pesos estão localizados em data/plays_ru/model_weights_plays_ru.h5
) com os parâmetros especificados nos arquivos de origem tem uma precisão de 99,19% (ou seja, o bot responderá corretamente 1.577 de 1.601 perguntas).
No momento, existem 3 conjuntos de dados para treinar o bot: 1.601 pares de perguntas e respostas de várias peças ( data/plays_ru
), 136.000 pares de vários trabalhos ( data/conversations_ru
, graças aos conjuntos de dados de PNL) e 2.500.000 pares de legendas para 347 séries de TV ( data/subtitles_ru
, mais detalhes no conjunto de dados de legendas em russo). Os modelos word2vec são treinados em todos os conjuntos de dados, mas a rede neural é treinada apenas no conjunto de dados de conjuntos de jogos.
Treinar o modelo word2vec e uma rede neural em um conjunto de dados de reproduções sem alterar os parâmetros leva aproximadamente 7,5 horas na nvidia gtx1070 e no intel core i7. O treinamento em conjuntos de dados de obras e legendas neste hardware durará pelo menos vários dias.
O bot pode funcionar em vários modos:
O conjunto de treinamento consiste em 1.600 pares de perguntas %% de respostas retiradas de várias peças russas. Ele é armazenado no arquivo data/plays_ru/plays_ru.txt
. Cada par de perguntas %% respondidas é escrito em uma nova linha, ou seja, Existe apenas um par em uma linha.
Todas as etapas necessárias para o treinamento são realizadas pelos métodos prepare()
ou load_prepared()
e train()
da classe TextToText
do módulo text_to_text.py
e pelo método build_language_model()
da classe LanguageModel
do módulo preparing_speech_to_text.py
. Ou você pode usar a função train()
do módulo bot.py
Para executar o bot no modo de treinamento, você precisa executar bot.py
com o parâmetro train
. Por exemplo, assim:
python3 bot.py train
Ou você pode simplesmente executar bot.py
(ou run_bot.sh
) e selecionar os modos 1 e 1 no menu proposto.
O processo de aprendizagem consiste em várias etapas:
1. Preparação da amostra de treinamento.
Para preparar a amostra de treinamento, é usado o módulo source_to_prepared.py
, que consiste na classe SourceToPrepared
. Esta classe lê um conjunto de treinamento de um arquivo, separa perguntas e respostas, remove caracteres e pontuação não suportados e converte as perguntas e respostas resultantes em sequências de tamanho fixo (usando palavras de preenchimento <PAD>
). Esta aula também prepara perguntas para a rede e processa suas respostas. Por exemplo:
Entrada: "Зачем нужен этот класс? %% Для подготовки данных"
Saída: [['<PAD>', ..., '<PAD>', '?', 'класс', 'этот', 'нужен', 'Зачем', '<GO>'], ['Для', 'подготовки', 'данных', '<EOS>', '<PAD>', ..., '<PAD>']]
A amostra de treinamento é lida no arquivo data/plays_ru/plays_ru.txt
, os pares convertidos [pergunta, resposta] são salvos no arquivo data/plays_ru/prepared_plays_ru.pkl
. Além disso, é construído um histograma dos tamanhos das perguntas e respostas, que é salvo em data/plays_ru/histogram_of_sizes_sentences_plays_ru.png
.
Para preparar uma amostra de treinamento a partir de um conjunto de dados baseado em reproduções, basta passar o nome do arquivo correspondente para o método prepare_all()
. Para preparar uma amostra de treinamento a partir de um conjunto de dados baseado em obras ou legendas, você deve primeiro chamar combine_conversations()
ou combine_subtitles()
e depois chamar preapre_all()
.
2. Tradução de palavras em vetores reais.
O módulo word_to_vec.py
, composto pela classe WordToVec
, é responsável por esta etapa. Esta classe codifica sequências de tamanho fixo (ou seja, nossas perguntas e respostas) em vetores reais. O codificador word2vec da biblioteca gensim é usado. A classe implementa métodos para codificar todos os pares [pergunta, resposta] do conjunto de treinamento em vetores de uma só vez, bem como para codificar uma pergunta para a rede e decodificar sua resposta. Por exemplo:
Entrada: [['<PAD>', ..., '<PAD>', '?', 'класс', 'этот', 'нужен', 'Зачем', '<GO>'], ['Для', 'кодирования', 'предложений', '<EOS>', '<PAD>', ..., '<PAD>']]
Saída: [[[0.43271607, 0.52814275, 0.6504923, ...], [0.43271607, 0.52814275, 0.6504923, ...], ...], [[0.5464854, 1.01612, 0.15063584, ...], [0.88263285, 0.62758327, 0.6659863, ...], ...]]
(ou seja, cada palavra é codificada como um vetor com comprimento de 500 (este valor pode ser alterado, o argumento size
no método build_word2vec()
))
Os pares [pergunta, resposta] são lidos no arquivo data/plays_ru/prepared_plays_ru.pkl
(que foi obtido na etapa anterior; para expandir e melhorar a qualidade do modelo, recomenda-se passar adicionalmente um conjunto de dados pré-processados a partir de data/subtitles_ru/prepared_subtitles_ru.pkl
de legendas data/subtitles_ru/prepared_subtitles_ru.pkl
para o método build_word2vec()
) , os pares codificados são salvos no arquivo data/plays_ru/encoded_plays_ru.npz
. Além disso, durante o processo de trabalho, é construída uma lista de todas as palavras utilizadas, ou seja, um dicionário que é salvo no arquivo data/plays_ru/w2v_vocabulary_plays_ru.txt
. O modelo word2vec treinado também é salvo em data/plays_ru/w2v_model_plays_ru.bin
.
Para traduzir palavras do conjunto de treinamento em vetores, basta passar o nome do arquivo correspondente para o método build_word2vec()
e definir os parâmetros desejados.
3. Treinamento em rede.
Nesta fase, o modelo seq2seq é treinado em dados previamente preparados. O módulo text_to_text.py
, composto pela classe TextToText
, é responsável por isso. Esta classe treina a rede, salva o modelo da rede e os coeficientes de ponderação e permite interagir convenientemente com o modelo treinado.
Para o treinamento, você precisa de um arquivo data/plays_ru/encoded_plays_ru.npz
contendo pares [pergunta, resposta] codificados em vetores que foram obtidos no estágio anterior. Durante o processo de treinamento, a cada 5 épocas (este valor pode ser alterado), o resultado intermediário extremo do treinamento da rede é salvo no arquivo data/plays_ru/model_weights_plays_ru_[номер_итерации].h5
, e na última iteração no arquivo data/plays_ru/model_weights_plays_ru.h5
(iteração - um ciclo de treinamento de rede, um certo número de épocas, após o qual os pesos são salvos em um arquivo e você pode, por exemplo, avaliar a precisão da rede ou exibir outros parâmetros Por padrão, o número de épocas é 5 e o número total de iterações é 200). O modelo de rede é salvo no arquivo data/plays_ru/model_plays_ru.json
.
Após o treinamento da rede, a qualidade do treinamento é avaliada submetendo todas as questões à entrada da rede treinada e comparando as respostas da rede com as respostas padrão do conjunto de treinamento. Se a precisão do modelo estimado for superior a 75%, as respostas incorretas da rede são salvas no arquivo data/plays_ru/wrong_answers_plays_ru.txt
(para que possam ser analisadas posteriormente).
Para treinar a rede, basta passar o nome do arquivo correspondente ao método train()
e definir os parâmetros desejados.
4. Construindo um modelo de linguagem e dicionário para PocketSphinx.
Este estágio é necessário se o reconhecimento de fala for usado. Nesta fase, um modelo de linguagem estática e um dicionário fonético para o PocketSphinx são criados com base nas perguntas do conjunto de treinamento (atenção: quanto mais perguntas no conjunto de treinamento, mais tempo o PocketSphinx levará para reconhecer a fala). Para fazer isso, use build_language_model()
(que acessa text2wfreq, wfreq2vocab, text2idngram
e idngram2lm
de CMUclmtk_v0.7) da classe LanguageModel
do módulo preparing_speech_to_text.py
. Este método usa perguntas do arquivo com a amostra de treinamento original (antes de serem preparadas pelo módulo source_to_prepared.py
), salva o modelo de linguagem no arquivo temp/prepared_questions_plays_ru.lm
e o dicionário em temp/prepared_questions_plays_ru.dic
( plays_ru
may mudar dependendo de qual conjunto de treinamento foi usado). Ao final do trabalho, o modelo de linguagem e o dicionário serão copiados para /usr/local/lib/python3.х/dist-packages/pocketsphinx/model
com os nomes ru_bot_plays_ru.lm
e ru_bot_plays_ru.dic
( plays_ru
pode mudar no da mesma forma que na etapa anterior, você precisará inserir a senha do usuário root).
Para interagir com o modelo seq2seq treinado, a função predict()
é pretendida (que é um wrapper sobre o método predict()
da classe TextToText
do módulo text_to_text.py
) do módulo bot.py
Esta função suporta vários modos de operação. No modo de texto, ou seja, Quando o usuário digita uma pergunta no teclado e a rede responde com texto, apenas o método predict()
da classe TextToText
do módulo text_to_text.py
é usado. Este método aceita uma string com uma pergunta para a rede e retorna uma string com a resposta da rede. Para funcionar, você precisa de: o arquivo data/plays_ru/w2v_model_plays_ru.bin
com o modelo word2vec treinado, o arquivo data/plays_ru/model_plays_ru.json
com os parâmetros do modelo de rede e o arquivo data/plays_ru/model_weights_plays_ru.h5
com o pesos da rede treinada.
Para executar o bot neste modo, você precisa executar bot.py
com o parâmetro predict
. Por exemplo, assim:
python3 bot.py predict
Você também pode simplesmente executar bot.py
(ou run_bot.sh
) e selecionar os modos 2 e 1 no menu proposto.
Este modo difere do anterior porque o parâmetro speech_synthesis = True
é passado para a função predict()
bot.py
Isto significa que a interação com a rede ocorrerá da mesma forma que no modo 2, mas a resposta da rede será adicionalmente expressa.
Expressando respostas, ou seja, síntese de fala, implementada no método get()
da classe TextToSpeech
do módulo text_to_speech.py
. Esta classe requer que o RHVoice-client seja instalado e, usando argumentos de linha de comando, passe os parâmetros necessários para a síntese de fala (você pode ver sobre a instalação do RHVoice e exemplos de acesso ao RHVoice-client em install_files/Install RHVoice.txt
). O método get()
toma como entrada a string que precisa ser convertida em fala e, se necessário, o nome do arquivo .wav no qual a fala sintetizada será salva (com taxa de amostragem de 32 kHz e profundidade de 16 bits, mono; se não for especificado, a fala será reproduzida imediatamente após a síntese). Ao criar um objeto da classe TextToSpeech
, você pode especificar o nome da voz a ser usada. São suportadas 4 vozes: Aleksandr masculino e três femininas - Anna, Elena e Irina (mais detalhes em RHVoice Wiki).
Para executar o bot neste modo, você precisa executar bot.py
com os parâmetros predict -ss
. Por exemplo, assim:
python3 bot.py predict -ss
Você também pode simplesmente executar bot.py
(ou run_bot.sh
) e selecionar os modos 3 e 1 no menu proposto.
Para trabalhar neste modo, você precisa passar o parâmetro speech_recognition = True
para a função predict()
do módulo bot.py
Isso significa que a interação com a rede, ou melhor, a inserção de dúvidas, será feita por voz.
O reconhecimento de fala é implementado no método get()
da classe SpeechToText
speech_to_text.py
. Esta classe usa PocketSphinx e um modelo de linguagem com dicionário ( ru_bot_plays_ru.lm
e ru_bot_plays_ru.dic
), que foram construídos no modo de treinamento de rede. O método get()
pode funcionar em dois modos: from_file
- reconhecimento de fala de um arquivo .wav ou .opus com frequência de amostragem >=16 kHz, 16 bits, mono (o nome do arquivo é passado como argumento para a função) e from_microphone
- reconhecimento de fala de um microfone. O modo de operação é definido ao criar uma instância da classe SpeechRecognition
, pois O carregamento do modelo de linguagem leva algum tempo (quanto maior o modelo, mais tempo leva para carregar).
Para executar o bot neste modo, você precisa executar bot.py
com os parâmetros predict -sr
. Por exemplo, assim:
python3 bot.py predict -sr
Você também pode simplesmente executar bot.py
(ou executar run_bot.sh
) e selecionar os modos 4 e 1 no menu proposto.
Esta é uma combinação dos modos 3 e 4.
Para trabalhar neste modo, você precisa passar os parâmetros speech_recognition = True
e speech_synthesis = True
para a função predict()
do módulo bot.py
Isso significa que as perguntas serão inseridas por voz e as respostas da rede serão faladas. Uma descrição dos módulos utilizados pode ser encontrada na descrição dos modos 3 e 4.
Para executar o bot neste modo, você precisa executar bot.py
com os parâmetros predict -ss -sr
. Por exemplo, assim:
python3 bot.py predict -sr -ss
ou
python3 bot.py predict -ss -sr
Você também pode simplesmente executar bot.py
(ou executar run_bot.sh
) e selecionar os modos 5 e 1 no menu proposto.
Este servidor fornece uma API REST para interagir com o bot. Quando o servidor é iniciado, uma rede neural treinada em um conjunto de dados de reproduções é carregada. Conjuntos de dados de obras e legendas ainda não são suportados.
O servidor é implementado usando Flask e modo multithread (versão de produção) usando gevent.pywsgi.WSGIServer. O servidor também possui um limite de tamanho dos dados recebidos no corpo da solicitação igual a 16 MB. A implementação está no módulo rest_server.py
.
Você pode iniciar o servidor WSGI executando run_rest_server.sh
(iniciando o servidor WSGI em 0.0.0.0:5000
).
O servidor suporta argumentos de linha de comando, o que torna o início um pouco mais fácil. Os argumentos têm a seguinte estrutura: [ключ(-и)] [адрес:порт]
.
Chaves possíveis:
-d
- inicia um servidor Flask de teste (se a chave não for especificada, o servidor WSGI será iniciado)-s
- inicia o servidor com suporte https (usa um certificado autoassinado, obtido usando openssl) Opções válidas адрес:порт
:
host:port
– inicia no host
e port
especificadoslocaladdr:port
- inicia com detecção automática do endereço da máquina na rede local e na port
especificadahost:0
ou localaddr:0
- se port = 0
, então qualquer porta disponível será selecionada automaticamenteLista de combinações possíveis de argumentos de linha de comando e sua descrição:
5000
. Por exemplo: python3 rest_server.py
host:port
– inicia o servidor WSGI no host
e na port
especificados. Por exemplo: python3 rest_server.py 192.168.2.102:5000
-d
- inicia um servidor Flask de teste em 127.0.0.1:5000
. Por exemplo: python3 rest_server.py -d
-d host:port
– inicia um servidor Flask de teste no host
e na port
especificados. Por exemplo: python3 rest_server.py -d 192.168.2.102:5000
-d localaddr:port
- inicia um servidor Flask de teste com detecção automática do endereço da máquina na rede local e porta port
. Por exemplo: python3 rest_server.py -d localaddr:5000
-s
- inicia um servidor WSGI com suporte https, detecção automática do endereço da máquina na rede local e porta 5000
. Por exemplo: python3 rest_server.py -s
-s host:port
– inicia um servidor WSGI com suporte https no host
e port
especificados. Por exemplo: python3 rest_server.py -s 192.168.2.102:5000
-s -d
- inicia um servidor Flask de teste com suporte https em 127.0.0.1:5000
. Por exemplo: python3 rest_server.py -s -d
-s -d host:port
- inicia um servidor Flask de teste com suporte https no host
e na port
especificados. Por exemplo: python3 rest_server.py -s -d 192.168.2.102:5000
-s -d localaddr:port
- inicia um servidor Flask de teste com suporte https, detecção automática do endereço da máquina na rede local e porta port
. Por exemplo: python3 rest_server.py -s -d localaddr:5000
O próprio servidor pode escolher a porta disponível; para fazer isso, você precisa especificar a porta 0
em host:port
ou localaddr:port
(por exemplo: python3 rest_server.py -d localaddr:0
).
Um total de 5 consultas são suportadas:
/chatbot/about
retornará informações sobre o projeto/chatbot/questions
retornará uma lista de todas as perguntas suportadas/chatbot/speech-to-text
, aceita um arquivo .wav/.opus e retorna a string reconhecida/chatbot/text-to-speech
, pega uma string e retorna um arquivo .wav com fala sintetizada/chatbot/text-to-text
, aceita uma string e retorna a resposta do bot como uma string 1. O servidor possui autorização http básica. Aqueles. Para obter acesso ao servidor, você precisa adicionar um cabeçalho a cada solicitação contendo login:password, codificado em base64
(login: bot
, senha: test_bot
). Exemplo em python:
import requests
import base64
auth = base64.b64encode('testbot:test'.encode())
headers = {'Authorization' : "Basic " + auth.decode()}
Será assim:
Authorization: Basic dGVzdGJvdDp0ZXN0
2. Na solicitação de reconhecimento de fala (que é o número 3), o servidor espera um arquivo .wav ou .opus (>=16kHz 16bit mono) com fala gravada, que também é transmitida para json usando codificação base64
(ou seja, abre .wav / Arquivo .opus, lido em uma matriz de bytes e, em seguida, codificado em base64
, a matriz resultante é decodificada do formato de bytes em uma string utf-8
e colocado em json), em python fica assim:
# Формирование запроса
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. Na solicitação de síntese de fala (que é o número 4), o servidor enviará uma resposta json com um arquivo .wav (16 bits 32kHz mono) com fala sintetizada, que foi codificada conforme descrito acima (para decodificá-la de volta você precisa obtenha do json a string desejada em uma matriz de bytes, decodifique-a usando base64
e grave-a em um arquivo ou fluxo para reprodução posterior), exemplo em 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 os dados transmitidos são agrupados em JSON (incluindo respostas com erros).
{
"text" : "Информация о проекте."
}
{
"text" : ["Вопрос 1",
"Вопрос 2",
"Вопрос 3"]
}
{
"wav" : "UklGRuTkAABXQVZFZm10IBAAAAABAAEAAH..."
}
ou
{
"opus" : "ZFZm10IBUklQVZFZm10IBARLASBAAEOpH..."
}
O servidor irá enviar a ele:
{
"text" : "который час"
}
{
"text" : "который час"
}
O servidor irá enviar a ele:
{
"wav" : "UklGRuTkAABXQVZFZm10IBAAAAABAAEAAH..."
}
{
"text" : "прощай"
}
O servidor irá enviar a ele:
{
"text" : "это снова я"
}
1. Solicitação GET para /chatbot/about
Um exemplo de solicitação gerada por 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
Um exemplo de solicitação gerada por 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
Em ambos os casos o servidor respondeu:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 305
Date: Fri, 02 Nov 2018 15:13:21 GMT
{
"text" : "Информация о проекте."
}
2. Solicitação GET para /chatbot/questions
Um exemplo de solicitação gerada por 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
Um exemplo de solicitação gerada por 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
Em ambos os casos o servidor respondeu:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 1086
Date: Fri, 02 Nov 2018 15:43:06 GMT
{
"text" : ["Что случилось?",
"Срочно нужна твоя помощь.",
"Ты уезжаешь?",
...]
}
3. Solicitação POST para /chatbot/speech-to-text
Um exemplo de solicitação gerada por 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..."
}
Um exemplo de solicitação gerada por 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..."
}
O servidor respondeu:
HTTP/1.1 200 OK
Content-Length: 81
Date: Fri, 02 Nov 2018 15:57:13 GMT
Content-Type: application/json
{
"text" : "Распознные слова из аудиозаписи"
}
4. Solicitação POST para /chatbot/text-to-speech
Um exemplo de solicitação gerada por 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" : "который час"
}
Um exemplo de solicitação gerada por 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" : "который час"
}
O servidor respondeu:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 78151
Date: Fri, 02 Nov 2018 16:36:02 GMT
{
"wav" : "UklGRuTkAABXQVZFZm10IBAAAAABAAEAAH..."
}
5. Solicitação POST para /chatbot/text-to-text
Um exemplo de solicitação gerada por 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" : "прощай"
}
Um exemplo de solicitação gerada por 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" : "прощай"
}
O servidor respondeu:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 68
Date: Fri, 02 Nov 2018 16:41:22 GMT
{
"text" : "это снова я"
}
O projeto contém um Dockerfile, que permite construir uma imagem docker com base neste projeto. Se você usou install_packages.sh
para instalar todas as dependências e não instalou o Docker antes, será necessário instalá-lo manualmente. Por exemplo, assim (testado no 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
Após a instalação, execute sudo systemctl status docker
para ter certeza de que tudo está instalado e funcionando (na saída deste comando você encontrará uma linha com texto verde active (running)
).
Para construir a imagem, você precisa ir até a pasta com o projeto no terminal e executar ( -t
- iniciar o terminal, .
- o diretório a partir do qual o docker build é chamado (ponto - isso significa que todos os arquivos da imagem estão em o diretório atual), voice_chatbot:0.1
- rótulo da imagem e sua versão):
sudo docker build -t voice_chatbot:0.1 .
Depois de concluir esta operação com sucesso, você pode listar as imagens disponíveis executando:
sudo docker images
Na lista resultante você verá nossa imagem - voice_chatbot:0.1
.
Agora você pode executar esta imagem ( -t
- iniciar o terminal, -i
- modo interativo, --rm
- excluir o contêiner após sua conclusão, -p 5000:5000
- encaminhar todas as conexões na porta 5000 para a máquina host para o contêiner na porta 5000 (você também pode especificar explicitamente outro endereço ao qual precisará se conectar externamente, por exemplo: -p 127.0.0.1:5000:5000
)):
sudo docker run -ti --rm -p 5000:5000 voice_chatbot:0.1
Como resultado, o servidor RESTful iniciará em 0.0.0.0:5000
e você poderá acessá-lo no endereço especificado no terminal (se você não especificou um diferente ao iniciar a imagem).
Nota : a imagem docker montada pesa 5,2 GB. Os arquivos de origem do projeto também incluem um arquivo .dockerignore
, que contém os nomes dos arquivos que não precisam ser adicionados à imagem. Para minimizar o tamanho da imagem final, foram excluídos dela todos os arquivos relacionados ao conjunto de dados de histórias e legendas, arquivos com resultados intermediários de processamento de dados e treinamento de redes neurais. Isso significa que a imagem contém apenas os arquivos de rede treinados e os conjuntos de dados de origem brutos.
Por precaução, nos arquivos de origem do projeto há um arquivo command_for_docker.txt
contendo o conjunto mínimo de comandos necessários para trabalhar com o docker.
Se você tiver alguma dúvida ou quiser colaborar, pode escrever para mim em [email protected] ou no LinkedIn.