GithubHelp home page GithubHelp logo

desklop / voice_chatbot Goto Github PK

View Code? Open in Web Editor NEW
59.0 5.0 17.0 370.62 MB

Chatbot in russian with speech recognition using PocketSphinx and speech synthesis using RHVoice. The AttentionSeq2Seq model is used. Imlemented using Python3+TensorFlow+Keras.

License: Other

Python 78.79% Shell 3.09% Perl 16.50% Dockerfile 1.61%
seq2seq pocketsphinx flask rhvoice gensim word2vec chatbot nlp speech-recognition speech-synthesis

voice_chatbot's Introduction

Voice ChatBot

Проект состоит из двух частей - голосовой бот и RESTful сервер для взаимодействия с ним.

Для запуска бота локально нужно выполнить python3 bot.py (или run_bot.sh) и в предложенном меню выбрать желаемый вариант работы (подробнее тут).

Для запуска RESTful сервера, предоставляющего интерфейс для взаимодействия с модулями голосового бота, нужно выполнить python3 rest_server.py (или run_rest_server.sh) (подробнее тут).

Для сборки docker-образа на основе RESTful сервера выполните sudo docker build -t voice_chatbot:0.1 . (подробнее тут).

ВНИМАНИЕ! Это был мой дипломный проект, по этому архитектура и код тут не очень хорошие, я это понимаю и как появится время - всё обновлю.

Зависимости

Полный список всех необходимых для работы зависимостей:

  1. Для Python3.5-3.6: decorator, Flask (>=1.0.2), Flask-HTTPAuth (>=3.2.4), gensim, gevent (>=1.3.7), h5py, Keras (>=2.2.4), matplotlib, numpy, pocketsphinx, pydub, simpleaudio, recurrentshop, requests, seq2seq, tensorflow[-gpu].
  2. Для Ubuntu: ffmpeg, x264, x265, make, git, scons, gcc, pkg-config, pulseaudio, libpulse-dev, portaudio19-dev, libglibmm-2.4-dev, libasound-dev, libao4, libao-dev, sonic, sox, swig, flite1-dev, net-tools, zip, unzip.
  3. Данные для обучения и готовые модели: необходимо вручную загрузить из Google Drive архив Voice_ChatBot_data.zip(3Gb) и распаковать в корень проекта (папки data и install_files).

Если вы используете Ubuntu 16.04 или выше, для установки всех пакетов можно воспользоваться install_packages.sh (проверено в Ubuntu 16.04 и 18.04). По умолчанию будет установлен TensorFlow для CPU. Если у вас есть видеокарта nvidia с утановленным официальным драйвером версии 410, вы можете установить TensorFlowGPU. Для этого необходимо при запуске install_packages.sh передать параметр gpu. Например:

./install_packages.sh gpu

В этом случае из моего Google Drive будет загружено 2 архива:

  1. Install_CUDA10.0_cuDNN_for410.zip(2.0Gb) с CUDA 10.0 и cuDNN 7.5.0 (если был передан параметр gpu). Установка будет выполнена автоматически, но если что-то пошло не так, есть инструкция Install.txt в загруженном архиве.
  2. Voice_ChatBot_data.zip(3Gb) с данными для обучения и готовыми моделями. Он будет автоматически распакован в папки data и install_files в корне проекта.

Если вы не можете или не хотите воспользоваться скриптом для установки всех необходимых пакетов, нужно вручную установить RHVoice и CMUclmtk_v0.7, используя инструкции в install_files/Install RHVoice.txt и install_files/Install CMUclmtk.txt. Так же необходимо скопировать файлы языковой, акустической модели и словаря для PocketSphinx из temp/ в /usr/local/lib/python3.6/dist-packages/pocketsphinx/model (у вас путь к python3.6 может отличаться). Файлы языковой модели prepared_questions_plays_ru.lm и словаря prepared_questions_plays_ru.dic необходимо переименовать в ru_bot_plays_ru.lm и ru_bot_plays_ru.dic (либо изменить их название в speech_to_text.py, если у вас есть своя языковая модель и словарь).

Бот

Основа бота - рекуррентная нейронная сеть, модель AttentionSeq2Seq. В текущей реализации она состоит из 2 двунаправленных LSTM ячеек в кодировщике, слоя внимания и 2 LSTM ячеек в декодировщике. Использование модели внимания позволяет установить "мягкое" соответствие между входными и выходными последовательностями, что повышает качество и производительность. Размерность входа в последней конфигурации равна 500 и длина последовательности 26 (т.е. максимальная длина предложений в обучающей выборке). Слова переводятся в вектора с помощью кодировщика word2vec (со словарём на 445.000 слов) из бибилотеки gensim. Модель seq2seq реализована с помощью Keras и RecurrentShop. Обученная модель seq2seq (веса которой находятся в data/plays_ru/model_weights_plays_ru.h5) с параметрами, которые указаны в исходных файлах, имеет точность 99.19% (т.е. бот ответит на 1577 из 1601 вопросов правильно).

На данный момент предусмотрено 3 набора данных для обучения бота: 1601 пара вопрос-ответ из различных пьес (data/plays_ru), 136.000 пар из различных произведений (data/conversations_ru, спасибо NLP Datasets) и 2.500.000 пар из субтитров к 347 сериалам (data/subtitles_ru, подробнее в Russian subtitles dataset). Модели word2vec обучены для всех наборов данных, но нейронная сеть обучена только на наборе данных из пьес.

Обучение модели word2vec и нейронной сети на наборе данных из пьес без изменения параметров длится примерно 7.5 часов на nvidia gtx1070 и intel core i7. Обучение на наборах данных из произведений и субтитров на данном железе будет длиться минимум нескольких суток.

Бот умеет работать в нескольких режимах:

  1. Обучение модели seq2seq.
  2. Работа с обученной моделью seq2seq в текстовом режиме.
  3. Работа с обученной моделью seq2seq с озвучиванием ответов с помощью RHVoice.
  4. Работа с обученной моделью seq2seq с распознаванием речи с помощью PocketSphinx.
  5. Работа с обученной моделью seq2seq с озвучиванием ответов и распознаванием речи.

1. Обучение модели seq2seq

Обучающая выборка состоит из 1600 пар вопрос %% ответ, взятых из различных русских пьес. Она хранится в файле data/plays_ru/plays_ru.txt. Каждая пара вопрос %% ответ пишется с новой строки, т.е. на одной строке только одна пара.

Все необходимые для обучения этапы выполняются методами prepare() или load_prepared() и train() класса TextToText из модуля text_to_text.py и метод build_language_model() класса LanguageModel из модуля preparing_speech_to_text.py. Или можно использовать функцию train() модуля bot.py.

Для запуска бота в режиме обучения нужно запустить bot.py с параметром train. Например, так:

python3 bot.py train

Или можно просто запустить bot.py (или выполнить run_bot.sh) и в предложенном меню выбрать режим 1 и 1.

Процесс обучения состоит из нескольких этапов:

1. Подготовка обучающей выборки.

Для подготовки обучающей выборки предназначен модуль source_to_prepared.py, состоящий из класса SourceToPrepared. Данный класс считывает обучающую выборку из файла, разделяет вопросы и ответы, удаляет неподдерживаемые символы и знаки препинания, преобразует полученные вопросы и ответы в последовательности фиксированного размера (с помощью слов-наполнителей <PAD>). Так же этот класс осуществляет подготовку вопросов к сети и обработку её ответов. Например:

Вход: "Зачем нужен этот класс? %% Для подготовки данных"

Выход: [['<PAD>', ..., '<PAD>', '?', 'класс', 'этот', 'нужен', 'Зачем', '<GO>'], ['Для', 'подготовки', 'данных', '<EOS>', '<PAD>', ..., '<PAD>']]

Обучающая выборка считывается из файла data/plays_ru/plays_ru.txt, преобразованные пары [вопрос,ответ] сохраняются в файл data/plays_ru/prepared_plays_ru.pkl. Так же при этом строится гистограмма размеров вопросов и ответов, которая сохраняется в data/plays_ru/histogram_of_sizes_sentences_plays_ru.png.

Для подготовки обучающей выборки из набора данных на основе пьес достаточно передать методу prepare_all() имя соответствующего файла. Что бы подготовить обучающую выборку из набора данных на основе произведений или субтитров, нужно вначале вызвать combine_conversations() или combine_subtitles(), а после вызывать preapre_all().

2. Перевод слов в вещественные вектора.

За этот этап отвечает модуль word_to_vec.py, состоящий из класса WordToVec. Данный класс кодирует последовательности фиксированного размера (т.е. наши вопросы и ответы) в вещественные вектора. Использутся кодировщик word2vec из библиотеки gensim. В классе реализованы методы для кодирования сразу всех пар [вопрос,ответ] из обучающей выборки в вектора, а так же для кодирования вопроса к сети и декодирования её ответа. Например:

Вход: [['<PAD>', ..., '<PAD>', '?', 'класс', 'этот', 'нужен', 'Зачем', '<GO>'], ['Для', 'кодирования', 'предложений', '<EOS>', '<PAD>', ..., '<PAD>']]

Выход: [[[0.43271607, 0.52814275, 0.6504923, ...], [0.43271607, 0.52814275, 0.6504923, ...], ...], [[0.5464854, 1.01612, 0.15063584, ...], [0.88263285, 0.62758327, 0.6659863, ...], ...]] (т.е. каждое слово кодируется вектором с длинной 500 (это значение можно изменить, аргумент size в методе build_word2vec()))

Пары [вопрос,ответ] считываются из файла data/plays_ru/prepared_plays_ru.pkl (который был получен на предыдущем этапе, для расширения и повышения качества модели рекомендуется дополнительно передать методу build_word2vec() предобработанный набор данных из субтитров data/subtitles_ru/prepared_subtitles_ru.pkl), закодированные пары сохраняются в файл data/plays_ru/encoded_plays_ru.npz. Так же в процессе работы строится список всех используемых слов, т.е. словарь, который сохраняется в файле data/plays_ru/w2v_vocabulary_plays_ru.txt. Также сохраняется обученная модель word2vec в data/plays_ru/w2v_model_plays_ru.bin.

Для перевода слов из обучающей выборки в вектора достаточно передать методу build_word2vec() имя соответствующего файла и задать желаемые параметры.

3. Обучение сети.

На этом этапе выполняется обучение модели seq2seq на уже подготовленных ранее данных. За это отвечает модуль text_to_text.py, состоящий из класса TextToText. Данный класс осуществляет обучение сети, сохранение модели сети и весовых коэффициентов, и позволяет удобно взаимодействовать с обученной моделью.

Для обучение необходим файл data/plays_ru/encoded_plays_ru.npz, содержащий пары [вопрос,ответ], закодированные в вектора, которые были получены на предыдущем этапе. В процессе обучения после каждой 5-ой эпохи (это значение можно изменить) сохраняется крайний промежуточный результат обучения сети в файл data/plays_ru/model_weights_plays_ru_[номер_итерации].h5, а на последней итерации в файл data/plays_ru/model_weights_plays_ru.h5 (итерация - один цикл обучения сети, некоторое число эпох, после которых происходит сохранение весов в файл и можно например оценить точность работы сети или вывести другие её параметры. По умолчанию число эпох равно 5, а общее число итераций 200). Модель сети сохраняется в файле data/plays_ru/model_plays_ru.json.

После обучения сети выполняется оценка качества обучения путём подачи на вход обученной сети всех вопросов и сравнения ответов сети с эталонными ответами из обучающей выборки. Если точность оцениваемой модели получается выше 75%, то неправильные ответы сети сохраняются в файл data/plays_ru/wrong_answers_plays_ru.txt (что бы их можно было потом проанализировать).

Для обучения сети достаточно передать методу train() имя соответствующего файла и задать желаемые параметры.

4. Построение языковой модели и словаря для PocketSphinx.

Этот этап нужен в случае, если будет использоваться распознавание речи. На этом этапе осуществляется создание статической языковой модели и фонетического словаря для PocketSphinx на основе вопросов из обучающей выборки (осторожно: чем больше вопросов в обучающей выборке, тем дольше PocketSphinx будет распознавать речь). Для этого используется метод build_language_model() (которая обращается к text2wfreq, wfreq2vocab, text2idngram и idngram2lm из CMUclmtk_v0.7) класса LanguageModel из модуля preparing_speech_to_text.py. Данный метод использует вопросы из файла с исходной обучающей выборкой (до их подготовки модулем source_to_prepared.py), сохраняет языковую модель в файл temp/prepared_questions_plays_ru.lm, а словарь в temp/prepared_questions_plays_ru.dic (plays_ru может меняться, в зависимости от того, какая обучающая выборка была использована). В конце работы языковая модель и словарь будут скопированы в /usr/local/lib/python3.х/dist-packages/pocketsphinx/model с именами ru_bot_plays_ru.lm и ru_bot_plays_ru.dic (plays_ru может меняться так же, как и на предыдущем этапе, потребуется ввод пароля root-пользователя).


2. Работа с обученной моделью seq2seq в текстовом режиме

Для взаимодействия с обученной моделью seq2seq предназначена функция predict() (которая является обёрткой над методом predict() класса TextToText из модуля text_to_text.py) модуля bot.py. Данная функция поддерживает несколько режимов работы. В текстовом режиме, т.е. когда пользователь вводит вопрос с клавиатуры и сеть отвечает текстом, используется только метод predict() класса TextToText из модуля text_to_text.py. Данный метод принимает строку с вопросом к сети и возвращает строку с ответом сети. Для работы необходимы: файл data/plays_ru/w2v_model_plays_ru.bin с обученной моделью word2vec, файл data/plays_ru/model_plays_ru.json с параметрами модели сети и файл data/plays_ru/model_weights_plays_ru.h5 с весами обученной сети.

Для запуска бота в данном режиме нужно запустить bot.py с параметром predict. Например, так:

python3 bot.py predict

Так же можно просто запустить bot.py (или выполнить run_bot.sh) и в предложенном меню выбрать режим 2 и 1.


3. Работа с обученной моделью seq2seq с озвучиванием ответов с помощью RHVoice

Данный режим отличается от предыдущего тем, что функции predict() модуля bot.py передаётся параметр speech_synthesis = True. Это означает, что взаимодействие с сетью будет проходить так же, как и в режиме 2, но ответ сети дополнительно будет озвучиваться.

Озвучивание ответов, т.е. синтез речи, реализован в методе get() класса TextToSpeech из модуля text_to_speech.py. Данный класс требует установленного RHVoice-client и с помощью аргументов командной строки передаёт ему необходимые параметры для синтеза речи (об установке RHVoice и примеры обращения к RHVoice-client можно посмотреть в install_files/Install RHVoice.txt). Метод get() принимает на вход строку, которую нужно преобразовать в речь, и, если требуется, имя .wav файла, в который будет сохранена синтезированная речь (с частотой дискретизации 32 кГц и глубиной 16 бит, моно; если его не указывать - речь будет воспроизводиться сразу после синтеза). При создании объекта класса TextToSpeech можно указать имя используемого голоса. Поддерживается 4 голоса: мужской Aleksandr и три женских - Anna, Elena и Irina (подробнее в RHVoice Wiki).

Для запуска бота в данном режиме нужно запустить bot.py с параметрами predict -ss. Например, так:

python3 bot.py predict -ss

Так же можно просто запустить bot.py (или выполнить run_bot.sh) и в предложенном меню выбрать режим 3 и 1.


4. Работа с обученной моделью seq2seq с распознаванием речи с помощью PocketSphinx

Для работы в этом режиме необходимо функции predict() модуля bot.py передать параметр speech_recognition = True. Это означает, что взаимодействие с сетью, а точнее ввод вопросов, будет осуществляться с помощью голоса.

Распознавание речи реализовано в методе get() класса SpeechToText модуля speech_to_text.py. Данный класс использует PocketSphinx и языковую модель со словарём (ru_bot_plays_ru.lm и ru_bot_plays_ru.dic), которые были построены в режиме обучения сети. Метод get() может работать в двух режимах: from_file - распознавание речи из .wav или .opus файла с частотой дискретизации >=16кГц, 16bit, моно (имя файла передаётся в качестве аргумента функции) и from_microphone - распознавание речи с микрофона. Режим работы задаётся при создании экземпляра класса SpeechRecognition, т.к. загрузка языковой модели занимает некоторое время (чем больше модель, тем дольше она загружается).

Для запуска бота в данном режиме нужно запустить bot.py с параметрами predict -sr. Например, так:

python3 bot.py predict -sr

Так же можно просто запустить bot.py (или выполнить run_bot.sh) и в предложенном меню выбрать режим 4 и 1.


5. Работа с обученной моделью seq2seq с озвучиванием ответов и распознаванием речи

Это комбинация режимов 3 и 4.

Для работы в этом режиме необходимо функции predict() модуля bot.py передать параметры speech_recognition = True и speech_synthesis = True. Это означает, что ввод вопросов будет осуществляться с помощью голоса, а ответы сети будут озвучиваться. Описание используемых модулей можно найти в описании режимов 3 и 4.

Для запуска бота в данном режиме нужно запустить bot.py с параметрами predict -ss -sr. Например, так:

python3 bot.py predict -sr -ss

или

python3 bot.py predict -ss -sr

Так же можно просто запустить bot.py (или выполнить run_bot.sh) и в предложенном меню выбрать режим 5 и 1.

RESTful сервер

Данный сервер предоставляет REST-api для взаимодействия с ботом. При старте сервера загружается нейронная сеть, обученная на наборе данных из пьес. Наборы данных из произведений и субтитров пока не поддерживаются.

Сервер реализован с помощью Flask, а многопоточный режим (production-версия) с помощью gevent.pywsgi.WSGIServer. Также сервер имеет ограничение на размер принимаемых данных в теле запроса равное 16 Мб. Реализация находится в модуле rest_server.py.

Запустить WSGI сервер можно выполнив run_rest_server.sh (запуск WSGI сервера на 0.0.0.0:5000).

Сервер поддерживает аргументы командной строки, которые немного упрощают его запуск. Аргументы имеют следующую структуру: [ключ(-и)] [адрес:порт].

Возможные ключи:

  1. -d - запуск тестового Flask сервера (если ключ не указывать - будет запущен WSGI сервер)
  2. -s - запуск сервера с поддержкой https (используется самоподписанный сертификат, получен с помощью openssl)

Допустимые варианты адрес:порт:

  1. host:port - запуск на указанном host и port
  2. localaddr:port - запуск с автоопределением адреса машины в локальной сети и указанным port
  3. host:0 или localaddr:0 - если port = 0, то будет выбран любой доступный порт автоматически

Список возможных комбинаций аргументов командной строки и их описание:

  1. без аргументов - запуск WSGI сервера с автоопределением адреса машины в локальной сети и портом 5000. Например: python3 rest_server.py
  2. host:port - запуск WSGI сервера на указанном host и port. Например: python3 rest_server.py 192.168.2.102:5000
  3. -d - запуск тестового Flask сервера на 127.0.0.1:5000. Например: python3 rest_server.py -d
  4. -d host:port - запуск тестового Flask сервера на указанном host и port. Например: python3 rest_server.py -d 192.168.2.102:5000
  5. -d localaddr:port - запуск тестового Flask сервера с автоопределением адреса машины в локальной сети и портом port. Например: python3 rest_server.py -d localaddr:5000
  6. -s - запуск WSGI сервера с поддержкой https, автоопределением адреса машины в локальной сети и портом 5000. Например: python3 rest_server.py -s
  7. -s host:port - запуск WSGI сервера с поддержкой https на указанном host и port. Например: python3 rest_server.py -s 192.168.2.102:5000
  8. -s -d - запуск тестового Flask сервера с поддержкой https на 127.0.0.1:5000. Например: python3 rest_server.py -s -d
  9. -s -d host:port - запуск тестового Flask сервера с поддержкой https на указанном host и port. Например: python3 rest_server.py -s -d 192.168.2.102:5000
  10. -s -d localaddr:port - запуск тестового Flask сервера с поддержкой https, автоопределением адреса машины в локальной сети и портом port. Например: python3 rest_server.py -s -d localaddr:5000

Сервер может сам выбрать доступный порт, для этого нужно указать в host:port или localaddr:port порт 0 (например: python3 rest_server.py -d localaddr:0).

Всего поддерживается 5 запросов:

  1. GET-запрос на /chatbot/about, вернёт информацию о проекте
  2. GET-запрос на /chatbot/questions, вернёт список всех поддерживаемых вопросов
  3. POST-запрос на /chatbot/speech-to-text, принимает .wav/.opus-файл и возвращает распознанную строку
  4. POST-запрос на /chatbot/text-to-speech, принимает строку и возвращает .wav-файл с синтезированной речью
  5. POST-запрос на /chatbot/text-to-text, принимает строку и возвращает ответ бота в виде строки

Описание сервера

1. Сервер имеет базовую http-авторизацию. Т.е. для получения доступа к серверу надо в каждом запросе добавить заголовок, содержащий логин:пароль, закодированный с помощью base64 (логин: bot, пароль: test_bot). Пример на python:

import requests
import base64

auth = base64.b64encode('testbot:test'.encode())
headers = {'Authorization' : "Basic " + auth.decode()}

Выглядеть это будет так:

Authorization: Basic dGVzdGJvdDp0ZXN0

2. В запросе на распознавание речи (который под номером 3) сервер ожидает .wav или .opus файл (>=16кГц 16бит моно) с записанной речью, который так же передаётся в json с помощью кодировки base64 (т.е. открывается .wav/.opus-файл, читается в массив байт, потом кодирутеся base64, полученный массив декодируется из байтовой формы в строку utf-8 и помещается в json), в python это выглядит так:

# Формирование запроса
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. В запросе на синтез речи (который под номером 4) сервер пришлёт в ответе json с .wav-файлом (16бит 32кГц моно) с синтезированной речью, который был закодирован так, как описано выше (что бы обратно его декодировать нужно из json получить нужную строку в массив байт, потом декодировать его с помощью base64 и записать в файл или поток, что бы потом воспроизвести), пример на 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)

Передаваемые данные в каждом запросе

Все передаваемые данные обёрнуты в json (в том числе и ответы с ошибками).

  1. Сервер передаёт клиенту:
{
"text" : "Информация о проекте."
}
  1. Сервер передаёт клиенту:
{
"text" : ["Вопрос 1",
          "Вопрос 2",
          "Вопрос 3"]
}
  1. Клиент в теле запроса должен отправить:
{
"wav" : "UklGRuTkAABXQVZFZm10IBAAAAABAAEAAH..."
}

или

{
"opus" : "ZFZm10IBUklQVZFZm10IBARLASBAAEOpH..."
}

Сервер ему передаст:

{
"text" : "который час"
}
  1. Клиент в теле запроса должен отправить:
{
"text" : "который час"
}

Сервер ему передаст:

{
"wav" : "UklGRuTkAABXQVZFZm10IBAAAAABAAEAAH..."
}
  1. Клиент в теле запроса должен отправить:
{
"text" : "прощай"
}

Сервер ему передаст:

{
"text" : "это снова я"
}

Примеры запросов

1. GET-запрос на /chatbot/about

Пример запроса, который формирует 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

Пример запроса, который формирует 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

В обоих случаях сервер ответил:

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 305
Date: Fri, 02 Nov 2018 15:13:21 GMT

{
"text" : "Информация о проекте."
}

2. GET-запрос на /chatbot/questions

Пример запроса, который формирует 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

Пример запроса, который формирует 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

В обоих случаях сервер ответил:

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 1086
Date: Fri, 02 Nov 2018 15:43:06 GMT

{
"text" : ["Что случилось?",
          "Срочно нужна твоя помощь.",
          "Ты уезжаешь?",
          ...]
}

3. POST-запрос на /chatbot/speech-to-text

Пример запроса, который формирует 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..."
}

Пример запроса, который формирует 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..."
}

Сервер ответил:

HTTP/1.1 200 OK
Content-Length: 81
Date: Fri, 02 Nov 2018 15:57:13 GMT
Content-Type: application/json

{
"text" : "Распознные слова из аудиозаписи"
}

4. POST-запрос на /chatbot/text-to-speech

Пример запроса, который формирует 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" : "который час"
}

Пример запроса, который формирует 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" : "который час"
}

Сервер ответил:

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 78151
Date: Fri, 02 Nov 2018 16:36:02 GMT

{
"wav" : "UklGRuTkAABXQVZFZm10IBAAAAABAAEAAH..."
}

5. POST-запрос на /chatbot/text-to-text

Пример запроса, который формирует 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" : "прощай"
}

Пример запроса, который формирует 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" : "прощай"
}

Сервер ответил:

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 68
Date: Fri, 02 Nov 2018 16:41:22 GMT

{
"text" : "это снова я"
}

Предполагаемый алгоритм работы с сервером

  1. Запросить список вопросов у сервера (запрос 2) и отобразить его
  2. В зависимости от выбранного режима:
  • Записать речь с микрофона клиента
  • Отправить на сервер (запрос 3) и получить ответ с распознанным текстом
  • Отобразить текст в поле ввода
  • Отправить текст на сервер (запрос 5) и получить ответ бота
  • Отправить ответ бота на сервер (запрос 4) и получить аудиофайл с синтезированной речью
  • Воспроизвести аудиофайл
  1. Если клиент хочет узнать информацию о данном проекте, послать запрос 1 на сервер и отобразить полученные данные

Docker-образ с RESTful сервером

В проекте содержится Dockerfile, который позволяет собрать docker образ на основе данного проекта. Если для установки всех зависимостей вы использовали install_packages.sh и ранее Docker вы не устанавливали, вам необходимо установить его вручную. Например, так (проверено в 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

После установки выполните sudo systemctl status docker что бы убедиться, что всё установилось и работает (в выводе данной команды вы найдёте строку с зелёным текстом active (running)).

Для сборки образа необходимо перейти в терминале в папку с проектом и выполнить (-t — запуск терминала, . — директория, из которой вызывается docker build (точка — значит в текущей директории находятся все файлы для образа), voice_chatbot:0.1 — метка образа и его версия):

sudo docker build -t voice_chatbot:0.1 .

После успешного выполнения данной операции вы можете вывести список имеющихся образов, выполнив:

sudo docker images

В полученном списке вы увидите наш образ — voice_chatbot:0.1.

Теперь вы можете запустить этот образ (-t — запуск терминала, -i — интерактивный режим, --rm — удалить контейнер после завершения его работы, -p 5000:5000 — пробросить все подключения на порт 5000 к машине-хосту в контейнер на порт 5000 (вы так же можете явно указать другой адрес, к которому нужно будет подключиться извне, например: -p 127.0.0.1:5000:5000)):

sudo docker run -ti --rm -p 5000:5000 voice_chatbot:0.1

В результате запустится RESTful сервер на 0.0.0.0:5000 и можно к нему обращаться по указанному в терминале адресу (если вы не указали другой при запуске образа).

Примечание: собранный docker-образ весит 5.2Гб. Исходные файлы проекта так же включают файл .dockerignore, в котором находятся имена файлов, которые не нужно добавлять в образ. Для минимизации размера итогового образа, из него были исключены все файлы, относящиеся к наборку данных из рассказов и из субтитров, файлы с промежуточными результатами обработки данных и обучения нейронной сети. Это значит, что образ содержит только файлы обученной сети и сырые исходные наборы данных.

На всякий случай, в исходных файлах проекта есть файл command_for_docker.txt, содержащий минимально необходимый набор команд для работы с docker.


Если у вас возникнут вопросы или вы хотите сотрудничать, можете написать мне на почту: [email protected] или в LinkedIn.

voice_chatbot's People

Contributors

desklop avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

voice_chatbot's Issues

Pocketshinx

При попытке использования вылазит ошибка, в чем косяк всё стоит верно!

python3 speech_to_text.py
[i] Загрузка языковой модели... Traceback (most recent call last):
File "speech_to_text.py", line 101, in
main()
File "speech_to_text.py", line 94, in main
sr = SpeechRecognitionclass('from_microphone')
File "speech_to_text.py", line 45, in init
dic=os.path.join(model_path, 'ru_bot.dic')
File "/usr/local/lib/python3.6/dist-packages/pocketsphinx/init.py", line 208, in init
super(LiveSpeech, self).init(**kwargs)
File "/usr/local/lib/python3.6/dist-packages/pocketsphinx/init.py", line 90, in init
super(Pocketsphinx, self).init(config)
File "/usr/local/lib/python3.6/dist-packages/pocketsphinx/pocketsphinx.py", line 275, in init
this = _pocketsphinx.new_Decoder(*args)
RuntimeError: new_Decoder returned -1

Ошибка обучения

root@Dell:/home/lavrenkov/Voice_ChatBOt# python3 preprocessing.py
Ты бот?

root@Dell:/home/lavrenkov/Voice_ChatBOt#

Python 3.6

Нужно положить акустическую модель в /usr/local/lib/python3.5/dist-packages/pocketsphinx/model. Подробнее про это можно найти в статье на хабре https://habr.com/post/351376/

P.S. Это ошибка не RHVoice, а PocketSphinx.

Просто положить файлы в такую же деректорию для python 3.6 не канает

Не запускается в докере

  1. После запуска docker build -t voice_chatbot:0.1 . выводит
Step 19/41 : RUN unzip install_files/RHVoice.zip
 ---> Running in 673881a195c1
  End-of-central-directory signature not found.  Either this file is not
  a zipfile, or it constitutes one disk of a multi-part archive.  In the
  latter case the central directory and zipfile comment will be found on
  the last disk(s) of this archive.
note:  install_files/RHVoice.zip may be a plain executable, not an archive
unzip:  cannot find zipfile directory in one of install_files/RHVoice.zip or
        install_files/RHVoice.zip.zip, and cannot find install_files/RHVoice.zip.ZIP, period.
  1. Если закомментировать Установка RHVoice, билдится успешно, но при запуске контейнера пишет
➜  Voice_ChatBot git:(master) ✗ docker run -ti --rm -p 5000:5000 voice_chatbot:0.1
Traceback (most recent call last):
  File "rest_server.py", line 30, in <module>
    from tensorflow import get_default_graph
ImportError: cannot import name 'get_default_graph'

При запуске bot.py predict ошибка с векторами

Возинкает ошибка при выборе опции 1:
ValueError: invalid literal for int() with base 10: 'version
что-то с векторами модели.

`python3 bot.py predict

/home/joo/anaconda3/lib/python3.6/site-packages/h5py/init.py:36: FutureWarning: Conversion of the second argument of issubdtype from float to np.floating is deprecated. In future, it will be treated as np.float64 == np.dtype(float).type.
from ._conv import register_converters as _register_converters
Using TensorFlow backend.
/home/joo/anaconda3/lib/python3.6/site-packages/smart_open/ssh.py:34: UserWarning: paramiko missing, opening SSH/SCP/SFTP paths will be disabled. pip install paramiko to suppress
warnings.warn('paramiko missing, opening SSH/SCP/SFTP paths will be disabled. pip install paramiko to suppress')
[i] Выберите набор данных:
1. plays_ru - набор диалогов из пьес
2. conversations_ru - набор диалогов из различных произведений
3. subtitles_ru - набор диалогов из субтитров к 347 сериалам
[W] conversations_ru и subtitles_ru ещё в разработке!
Ваш выбор: 1
[i] Используется набор данных plays_ru
[i] Загрузка параметров модели из data/plays_ru/model_plays_ru.json и data/plays_ru/model_weights_plays_ru.h5
2019-05-12 15:20:13.148420: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
2019-05-12 15:20:13.228519: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:964] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2019-05-12 15:20:13.228865: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1432] Found device 0 with properties:
name: GeForce GTX 1080 major: 6 minor: 1 memoryClockRate(GHz): 1.7715
pciBusID: 0000:01:00.0
totalMemory: 7.93GiB freeMemory: 6.86GiB
2019-05-12 15:20:13.228881: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1511] Adding visible gpu devices: 0
2019-05-12 15:20:13.426428: I tensorflow/core/common_runtime/gpu/gpu_device.cc:982] Device interconnect StreamExecutor with strength 1 edge matrix:
2019-05-12 15:20:13.426457: I tensorflow/core/common_runtime/gpu/gpu_device.cc:988] 0
2019-05-12 15:20:13.426463: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1001] 0: N
2019-05-12 15:20:13.426600: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1115] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 6609 MB memory) -> physical GPU (device: 0, name: GeForce GTX 1080, pci bus id: 0000:01:00.0, compute capability: 6.1)
[i] Установлена максимальная длина предложения 26 слов(-а)
[i] Загрузка модели word2vec из data/plays_ru/w2v_model_plays_ru.bin...
Traceback (most recent call last):
File "bot.py", line 259, in
main()
File "bot.py", line 202, in main
predict()
File "bot.py", line 143, in predict
ttt = TextToText(f_name_w2v_model=f_name_w2v_model, f_name_model=f_name_model, f_name_model_weights=f_name_model_weights)
File "/home/joo/Документы/LocalRepository/Voice_ChatBot-master/text_to_text.py", line 74, in init
self.w2v = WordToVec(f_name_w2v_model)
File "/home/joo/Документы/LocalRepository/Voice_ChatBot-master/word_to_vec.py", line 33, in init
self.model = word2vec.Word2VecKeyedVectors.load_word2vec_format(f_name_w2v_model, binary=True)
File "/home/joo/anaconda3/lib/python3.6/site-packages/gensim/models/keyedvectors.py", line 1476, in load_word2vec_format
limit=limit, datatype=datatype)
File "/home/joo/anaconda3/lib/python3.6/site-packages/gensim/models/utils_any2vec.py", line 344, in _load_word2vec_format
vocab_size, vector_size = (int(x) for x in header.split()) # throws for invalid file format
File "/home/joo/anaconda3/lib/python3.6/site-packages/gensim/models/utils_any2vec.py", line 344, in
vocab_size, vector_size = (int(x) for x in header.split()) # throws for invalid file format
ValueError: invalid literal for int() with base 10: 'version'`

При выборе опции 3 будет другая ошибка:

File "/home/joo/Документы/LocalRepository/Voice_ChatBot-master/text_to_text.py", line 230, in __load_model with open(f_name_model, 'r') as f_model: FileNotFoundError: [Errno 2] No such file or directory: 'data/subtitles_ru/model_subtitles_ru.json'

RHVoice eror

[i] Выберите вариант работы бота:
1. train - обучение модели seq2seq
2. predict - работа с обученной моделью seq2seq
3. predict -ss - включено озвучивание ответов с помощью RHVoice
4. predict -sr - включено распознавание речи с помощью PocketSphinx
5. predict -ss -sr - включено озвучивание ответов и распознавание речи
Введите цифру: 4
[i] Загрузка параметров сети из data/net_model.txt и data/net_final_weights.h5
2018-11-21 19:01:24.488971: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
[i] Инициализация языковой модели...
Traceback (most recent call last):
File "bot.py", line 239, in
main()
File "bot.py", line 218, in main
predict(True, False)
File "bot.py", line 136, in predict
sr = SpeechRecognition('from_microphone')
File "/home/lavrenkov/Voice_ChatBot/speech_to_text.py", line 45, in init
dic=os.path.join(model_path, 'ru_bot.dic')
File "/usr/local/lib/python3.6/dist-packages/pocketsphinx/init.py", line 208, in init
super(LiveSpeech, self).init(**kwargs)
File "/usr/local/lib/python3.6/dist-packages/pocketsphinx/init.py", line 90, in init
super(Pocketsphinx, self).init(config)
File "/usr/local/lib/python3.6/dist-packages/pocketsphinx/pocketsphinx.py", line 273, in init
this = _pocketsphinx.new_Decoder(*args)
RuntimeError: new_Decoder returned -1

Eror imort tkiner

root@Dell:/home/lavrenkov/Voice_ChatBOt# python3 bot.py train
Traceback (most recent call last):
File "bot.py", line 8, in
from preprocessing import Preparation
File "/home/lavrenkov/Voice_ChatBOt/preprocessing.py", line 11, in
import matplotlib.pyplot as plt
File "/usr/local/lib/python3.6/dist-packages/matplotlib/pyplot.py", line 2374, in
switch_backend(rcParams["backend"])
File "/usr/local/lib/python3.6/dist-packages/matplotlib/pyplot.py", line 207, in switch_backend
backend_mod = importlib.import_module(backend_name)
File "/usr/lib/python3.6/importlib/init.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "/usr/local/lib/python3.6/dist-packages/matplotlib/backends/backend_tkagg.py", line 1, in
from . import _backend_tk
File "/usr/local/lib/python3.6/dist-packages/matplotlib/backends/_backend_tk.py", line 5, in
import tkinter as Tk
ModuleNotFoundError: No module named 'tkinter'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.