Русский
Русский
English
Статистика
Реклама

Chat bot

Из песочницы Голосовой бот телефония на полном OpenSource. Часть 1 создание и обучение текстового бота RU

20.07.2020 14:14:41 | Автор: admin

В наше время голосовые роботы набирают огромную популярность, от банального заказа такси, до продаж клиентам. Создание голосового бота сводится к трем базовым этапам.

  1. Распознавание голоса ASR.
  2. Выяснение смысла сказанного и поиск необходимых сущностей в тексте(к примеру адрес, сумма, ФИО итд )
  3. Генерация ответа, преобразование текста в речь TTS. Мы пройдем от пути создания простого текстового бота до интеграции с системой телефонии freeswitch с распознаванием голоса и озвучиванием подготовленных ответов. Данная статья описывает используемые инструменты и путь по их интеграции вместе для создания голосового робота.

В первой части поговорим о создании простого текстового бота, которого можно встроить в чат.

Пример разговора Б-бот Ч-человек

Б:привет я могу посоветовать тебе фильм или сериалЧ:приветБ:здорово дружищеЧ:какой фильм про космос посмотреть?Б:аполлон тринадцатьЧ:ты любишь алису?Б:алиса? я лучше алисы это точноЧ:тыБ:не понял вас

Немного теории

Бот работает на принципе понятия намерения пользователя. На каждое намерение есть список заготовленных ответов. Чтобы бот мог понять намерение пользователя, необходимо обучить модель на датасете с намерениями и фразами, которые могут активировать это намерение

К примеру

Намерение: Поздороваться
Возможные фразы: привет, добрый день, дратути
Ответ: Привет

Намерение: Попрощаться
Возможные фразы: Пока, До свидания, Прощай
Ответ: Пока

Шаг 1: Предобработка датасета


За основу взят датасет из открытого обучения skillbox по написанию чат бота в телеграмм, который может пообщаться с вами на тему кино. Выложить не могу по понятным причинам.
Предобработка является очень важным этапом.

Первым делом уберем все символы и цифры из текста и приведем все к нижнему регистру.

Далее необходимо исправить опечатки и ошибки в словах.

Сервара - сервера

Эта задача не самая простая, есть хороший инструмент от Yandex под названием Speller, но он ограничен по числу запросов в день, поэтому будем искать бесплатные альтернативы
Для python есть замечательная библиотека jamspell, которая неплохо исправляет опечатки. Для нее есть хорошая предобученная модель для русского языка. Прогоним все входные данные через эту библиотеку. Для голосового бота этот шаг не так актуален, так как система распознавания речи не должна выдавать слова с ошибками, она может выдать не то слово. Для чат бота этот процесс необходим. Так же для минимизации влияния опечаток можно обучать сеть не на словах, а на n-граммах.

N-граммы, это части слов, состоящие из n букв. к примеру 3-граммы для слова привет будут
при, рив, иве, вет. Это поможет быть менее зависимым от опечаток и повысит точность распознавания.

Далее необходимо привести слова к нормальной форме, так называемый процесс лемматицизии слов.

Доброе утро - добрый утро

Для данной задачи хорошо подходит библиотека rulemma .

Так же можно из фраз убрать стоп слова, которые несут мало смысловой нагрузки, но увеличивают размер нейронной сети (я брал из библиотеки nltk stopwords.words(russian)), но в нашем случае лучше их не убирать, так как пользователь может ответить роботу только одним словом, а оно может быть из списка стоп слов.

Шаг 2: Преобразование датасета в понятный для NN вид


Для начала необходимо сформировать словарь из всех слов датасета.

Для обучения модели понадобится перевести все слова в oneHotVector
Это массив, которые равен длине словаря слов, в котором все значения равны 0 и только одно равно 1 в позиции слова в словаре.

Далее все входные фразы преобразовываются в 3-х мерный массив, который содержит все фразы, фраза содержит список слов в формате oneHotVector это и будет наш входной датасет X_train.

Каждой входной фразе нужно сопоставить подходящее к ней намерение так же в формате oneHotVector это наш выход y_train.

Шаг 3: Создание модели


Для небольшого бота достаточно маленькой модели с двумя слоями lstm и двумя полносвязными слоями:

model = Sequential()model.add(LSTM(64,return_sequences=True,input_shape=(description_length, num_encoder_tokens)))model.add(LSTM(32))model.add(Dropout(0.25))model.add(Dense(1024, activation='relu'))model.add(Dropout(0.25))model.add(Dense(len(set(y)), activation='softmax'))

Компилируем модель и подбираем оптимизитор, я выбрал adam, так как он давал лучший результат.

Шаг 4: Обучение модели


После подготовки датасета и компиляции модели можно запустить ее обучение. Так как датасет небольшой, пришлось обучать модель на 250-500 эпохах, после чего происходило переобучение.

Шаг 5: Пытаемся поговорить с нашим ботом


Чтобы поговорить с нашим ботом, надо на вход обученной модели подать правильно подготовленные данные. Пользовательский ввод необходимо обработать так же как и датасет из первого шага. Дальше преобразовать его в вид, понятный NN как во втором шаге используя тот же словарь слов и их индексы, чтобы входные слова соответствовали словам, на которых проводилось обучение.

Обработанный ввод подаем в модель и получаем массив значений, в котором присутствуют вероятности попадания нашей фразы в то или иное намерение, нам же необходимо выбрать то намерение, у которого самая высокая вероятность, это можно сделать через библиотеку numpy

np.argmax(results)

Необходимо оценить уверенность сети в этом ответе и подобрать порог, при котором выдавать пользователю failure phrases, типа я вас не понял. Для своих целей я установил порог в 50% уверенности, ниже которого бот скажет, что не понял вас.

Далее из списка наших намерений выбираем подходящий ответ и выдаем его пользователю

P.S.: Модель можно обучить не только на основе слов но и разделяя фразы на буквы или n-граммы, в таком случае понадобится модель посерьезнее.

model = Sequential()model.add(LSTM(512,return_sequences=True,input_shape=(description_length, num_encoder_tokens)))model.add(LSTM(256))model.add(Dropout(0.25))model.add(Dense(len(set(y)), activation='softmax'))
Подробнее..

Голосовой бот телефония на полном OpenSource. Часть 2 учим бота слушать и говорить

12.10.2020 04:15:08 | Автор: admin

В первой части статьи я описал как создать простого чат бота, в этой статье мы научим нашего бота говорить и слушать русскую речь и переводить ее в текст.

Чтобы наш чат-бот заговорил и начал слушать, нужно пройти несколько подготовительных этапов:

  1. Озвучить все ответные фразы
  2. Установить систему телефонии
  3. Установить систему распознавания голоса
  4. Написать простые скрипты для связи телефонии и нашей нейронной сети с чат-ботом

Шаг 1: Озвучка ответных фраз


Так как наш бот довольно примитивный и может произносить только заранее подготовленные фразы, то первым делом озвучим все наши ответные фразы с использованием к примеру yandex speechkit. Положим их в корневую директорию с аудиозаписями freeswitch /usr/share/freeswitch/sounds/en/us/callie/ivr предварительно обрежем длину имени до 50 символов.

Шаг 2: Установка системы телефонии


Для того, чтобы наш робот приносил пользу, его надо научить работать с системой телефонии. Была выбрана перспективная система телефонии Freeswitch.

Чтобы научить freeswitch понимать русскую речь, ему необходимо настроить интеграцию с системой распознавания речи, в нашем случае это будет бесплатный сервер vosk.

Для сборки freeswitch с поддержкой mod_vosk рекомендуется использовать репозиторий, предлагаемый разработчиком vosk. Скомпилировать его можно по инструкциина сайте freeswitch. Важный момент, для корректной работы mod_vosk необходимо перекомпилировать libks из репозитория.

PS. для удобства конфигурирования Freeswitch можно установить вэб-интерфейс FusionPBX

Шаг 3: Установка системы распознавания голоса


Для распознавания голоса был выбран бесплатный сервер vosk. Базовая установка очень проста, достаточно просто скачать докер образ и запустить на вашей машине.

docker run -d -p 2700:2700 alphacep/kaldi-ru:latest

Далее необходимо сконфигурировать mod_vosk для freeswitch, для этого в директории /etc/freeswitch/autoload_configs необходимо создать файл vosk.conf.xml, если его нет. В данном файле необходимо указать только адрес вашего vosk сервера:

<configuration name="vosk.conf" description="Vosk ASR Configuration">  <settings>    <param name="server-url" value="ws://localhost:2700"/>    <param name="return-json" value="0"/>  </settings></configuration>

После настройки можно запустить сам freeswitch

systemctl start freeswitch

И запустить модуль

fs_cli -x "load mod_vosk

Шаг 4: Скрипты для запуска распознавания голоса


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

Шаг 4.1: REST API интерфейс для нейронной сети


Самым быстрым и удобным способом научить нейросеть отвечать на http запросы является библиотека Fastapi для python. Для начала объявим класс Prediction, который содержит формат входных данных для запроса.

class Prediction(BaseModel):text: str

Загрузим нашу модель

model = Sequential()model.add(LSTM(64,return_sequences=True,input_shape=(description_length, num_encoder_tokens)))model.add(LSTM(32))model.add(Dropout(0.25))model.add(Dense(1024, activation='relu'))model.add(Dropout(0.25))model.add(Dense(158, activation='softmax'))opt=keras.optimizers.adam(lr=0.01,amsgrad=True)model.compile(loss='categorical_crossentropy',  optimizer=opt,  metrics=['accuracy'])#model.summary()model.load_weights("h_10072020.h5")

напишем небольшую функцию по предсказанию ответа

def get_answer(text):t = preprocess_ru_text(text) # функция по препроцессингу текста, такая же как и при обучении моделиinput_data = np.zeros((1,description_length,num_encoder_tokens),dtype='float32')j=0for word in t:wordidxs = np.zeros((num_encoder_tokens),dtype='float32')if word in input_token_index:wordidxs[input_token_index[word]]=1input_data[0,j]=wordidxsj+=1print(word)results = model.predict(input_data)print (results[0][np.argmax(results)],          list(y_dict)[np.argmax(results)])if results[0][np.argmax(results)]>0.5:return random.choice(result_config['intents'][list(y_dict)[np.argmax(results)]]['responses'])else: #если уверенность нейронной сети меньше 50%, возвращаем фразу, что не расслышали вопрос.return random.choice(result_config['failure_phrases'])

и в конце сделаем интерфейс для получения ответа по запросу:

@app.post('/prediction/',response_model=Prediction)async def prediction_route(text: Prediction):question = text.textanswer = get_answer(question)return HTMLResponse(content=clear_text(answer)[:50], status_code=200) # обрезаем длину ответа до 50, чтобы совпадало с именем озвученных файлов

Можно запускать наш сервис:

uvicorn main:app --reload --host 0.0.0.0

Теперь при запросе на localhost:8000/prediction:

{"text":"привет"}

мы получаем ответ:

Хай

Шаг 4.2: LUA скрипт для запуска приложения на freeswitch


Задачами lua скрипта будут во первых получение распознанного текста из звонка, во вторых получение ответа от нейронной сети и воспроизведение подготовленного файла с озвученной фразой.

Для возможности осуществления http запросов из lua необходимо установить библиотеку luasocket.

Чтобы без проблем импортировать эту библиотеку, добавьте в свой скрипт строчку:

package.path = package.path .. ";" .. [[/usr/share/lua/5.2/?.lua]];

Далее напишем небольшую функцию получения ответа от нашей нейронной сети:

function sendRequest(speech_res)  local path = "http://localhost:8000/prediction/";  local payload = string.format("{\"text\":\"%s\"}",speech_res);  log.notice(payload);  local response_body = { };  log.notice(path);  local res, code, response_headers, status = http.request  {    url = path,    method = "POST",    headers =    {      ["Authorization"] = "",      ["Content-Type"] = "application/json",      ["Content-Length"] = payload:len()    },    source = ltn12.source.string(payload),    sink = ltn12.sink.table(response_body)  }  return trim1(table.concat(response_body))end

И запускаем в бесконечном цикле распознавание и воспроизведение ответных фраз:

session:execute("play_and_detect_speech", "ivr/привет я могу посоветовать тебе фильм или сериал.wav detect:vosk default");while session:ready() do    local res = session:getVariable('detect_speech_result');if res ~= nil thenlocal speech_res = session:getVariable("detect_speech_result");local response_body = sendRequest(speech_res);log.notice(response_body);session:execute("play_and_detect_speech", "ivr/"..response_body..".wav detect:vosk default");endend

Чтобы повесить этот скрипт на определенный номер, достаточно создать конфигурацию такого вида:

<extension name="7000" continue="false"><condition field="destination_number" expression="7000"><action application="lua" data="test_vosk.lua"/></condition></extension>

И перечитать конфиги:

fs_cli -x "reloadxml"

Заключение


После запуска нейронной сети и freeswitch можно позвонить на номер с привязанным lua скриптом и поговорить с роботом.
Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru