Разработка русскоговорящего «аналога» Siri за 7 дней

в 17:13, , рубрики: apple, ios development, siri, разработка под iOS, распознование речи, метки: , ,

После выхода iPhone 4S с Siri «на борту», владельцы остальных гаджетов Apple, чувствовали себя немного обделенными. Даже в свой новый iPad Apple не включила Siri. Разработчиками по всему миру были предприняты попытки портировать Siri на другие устройства или написать похожие аналоги. И только русскоязычный App Store хранил молчание. Наверно все разработчики очень заняты, подумал я, и решил исправить это досадное недоразумение…

DISCLAIMER:

1. Слово «аналога» не зря взято в кавычки. Мое приложение ни капельки не аналог Siri, а любительская поделка. Я прекрасно понимаю, что для создания действительно чего то похожего на Siri, нужны гигантские ресурсы и много средств.
2. Да я знаю что Apple объясняет, что не поддерживает другие iPhone, из за какого то специального чипа шумоподавления, встроенного в 4S. Но я не сильно в это верю, скорее всего их сервера не выдерживают нагрузки и от 4S. И если подключить к Siri все гаджеты Apple, сервера просто рухнут.
3. Приложение создавалось как Just for fun и не преследовало ни каких практических целей. И кроме этого работалась еще и основная работа.

Почему за 7 дней?

Я, изначально, решил не тратить на этот проект много времени по нескольким причинам. Во первых, я прочел много статей где было написано, что Apple не пропускает программы, похожие на Siri в App Store. Более того пытается удалить из App Store уже существующие, например Evi. По этому, есть большая вероятность, что и мою программу не пропустят. Как кстати и случилось, с написанным мной, клиентом для rutracker.org. Я 4 раза отправлял приложение на ревю, исправлял все что говорили мне цензоры, но в App Store прога так и не попала (я потом плюнул на это дело и выложил урезанную версию на 4PDA, не пропадать же труду). Во вторых ресурсами, для написания полноценной программы, я, естественно, не обладаю.

День 1-й. Проектирование

Вначале я продумал саму логику приложения. Естественно все преобразования text to speech и speech to text, должно выполняться на сервере. А само приложение быть всего лишь интерфейсом. В этом случае, решение будет работать даже на самых слабых устройствах, а также обладать кроссплатформенностью. Для переносимости на Android и Windows Phone, потребуется всего лишь написать интерфейс на эти платформы.

Таким образом логика приложения получилась такая:
А) записываем речь собеседника и передаем на сервер для распознания;
Б) получаем с сервера распознанную строку, и проводим легкую начальную обработку. Это ответы на самые частые вопросы, отсекаем маты и ругательства, перехватываем слова для поиска в Яндексе и поиска прогноза погоды. Другие команды типа отправь СМС или проверь почту, решил пока не встраивать из за опасения не пройти ревю;
В) отфильтрованную строку посылаем на свой сервер для распознавания. И получаем в ответ строку с ответом;
Г) посылаем ответ на сервер для преобразования в речь, получаем ссылку на поток mp3 и воспроизводим ответ;

Да получается медленно, но пока другого варианта, кроме как объединить все это на одном своем сервере я не вижу. Но это уже совсем другой порядок затрат: выделенный мощный сервер, скорее всего не один; покупка и лицензирование движка распознавания речи преобразования текста в речь и др. Так что остановимся, пока на такой логике.

День второй. Поиск движка

Ищу движки. Это оказалось не маленькой проблемой. Во первых, большинство из них платные и не мало от 50 долларов за 1000 слов, во вторых очень малое количество распознает русскую речь, в третьих качество тех что распознает русский просто ужасное.

Остановился я на движке ispeech.org. Во первых, он позволяет делать сразу два преобразования «речи в текст» и «текста в речь». Во вторых, он имеет SDK для iPhone и при использовании этого SDK выдается бесплатно ключ и распознавание бесплатно. Естественно, ради «шары» пришлось кое чем пожертвовать. Он отвратительно распознает русские города. По этому узнать прогноз погоды в каком то сложно произносимом городе не реально. В Москве без проблем.

Изучаю его API. Я остановился на формате JSON. Передаю на сервер ключ, язык который надо распознать, служебные поля типа формата звукового файла и саму речь, закодированный в base64encode, .wave файл. Получаю ответ, так же в формате JSON, error, если ошибка. И строку текста и точность распознавания, если успех.
Точно так же делается обратное преобразование. Посылаю на сервер строку для проговаривания, язык, и служебные поля и получаю в ответ mp3 поток, который и воспроизвожу.

День 3-й. Начинаю писать приложение. Дизайн

Стараюсь чтоб получилось что то похожее на Siri, но не повторяло в точности, а то цензоры зарубят.
Вот что получилось.
Разработка русскоговорящего «аналога» Siri за 7 дней
Ну совсем я не дизайнер. День потрачен зря.

День четвертый. Пишу логику приложения

Ничего сложного обычные http POST запросы. Встраиваю API. Первое тестирование. Ура!!! Работает, но не очень быстро. При WI FI нормально, хотя медленнее настоящей Siri. При 3G подтормаживает. При GPRS просто пытка, и ответа можно не дождаться. Причину понял быстро. На сервер передается файл wave, сжатый кодеком ULAW, дискретизация 44 КГц. Файл получается гигантский, надо пережать как для голоса на 8 КГц. Что то пережать не получается. Помечаю себе, что есть проблема, забиваю на это и двигаюсь дальше. Фильтрую маты и ругательства.
Разработка русскоговорящего «аналога» Siri за 7 дней

День 5-й. Интегрирование поиска в Яндексе и погоды. Отправка в App Store

Выделяю ключевые поля типа «поиск», «искать», «найти», «погода» и т.д. Приходится для надежности переспросить что конкретно ищем и в каком городе нужен прогноз погоды. Вроде получается. Тут выясняется, что города понимаются плохо. Столько труда пропадает, но решил не выбрасывать эту фичу, вдруг движок со временем научится лучше понимать города. Тестирую еще раз и еще раз и еще раз. Результатом доволен. Выкладываю приложение в App Store, пусть ждет ревю, пока я пишу свой сервер.
Разработка русскоговорящего «аналога» Siri за 7 дней Разработка русскоговорящего «аналога» Siri за 7 дней

День 6-й. Лингвистика и анализ речи. Написание сервера

Штудирую литературу по искусственному интеллекту и анализу речи. Тихо офигеваю. Осваиваю азы. Решаю пока не заморачиваться на искусственном интеллекте, а просто разобрать приложение на фразы, сделать простейший анализ, выделить ключевые слова и уже по ним производить поиск в базе.
Набрасываю краткую идею, в каком направлении двигаться. Значит составляю базу знаний, поиском сравниваю выделенные из предложения ключевые слова с базой и выдаю ту запись которая наиболее соответствует вопросу.
Нахожу в открытых источниках словари для программ- собеседников, конечно качество их недостаточно и надо будет дорабатывать. Но для старта подойдет.

Пишу не сложную программу на PHP для поиска ответов на своем сервере. Чтоб к серверу не обращались посторонние и не уронили его, предусмотрел передачу телефоном токена, который жестко зашит в приложении. Пока на авторизации решил сильно не заморачиваться.
Так же решил пока не передавать на сервер GPS координаты телефона, хотя сама идея мне нравится. Зная координаты телефона можно использовать API какого либо погодного сервера, для выдачи прогноза погоды. Еще можно использовать координаты телефона для нахождения ближайших баров, кафе, магазинов. Но опять же нужен ресурс с нормальным API, на который послал запрос и координаты и получил внятный ответ. Записал эту идею и отложил на потом, если буду писать новую версию приложения.

Все, заданные вопросы, и ответы на них заносятся в базу данных, кстати UDID [IMEI] телефончика тоже. Да да «Большой Брат» следит за вами (шутка). На самом деле это нужно для развития программы. Зная вопросы, которые задают, я смогу оперативно пополнять базу знаний и отлавливать глюки программы. UDID нужен для развития в дальнейшем. Я планирую чтоб программа помнила предыдущие вопросы, вот я и использую UDID для идентификации телефона. Зная предыдущие вопросы можно сделать поведение приложения еще более интеллектуальным. Интересно а Siri учитывает предыдущие вопросы при построении диалога?
При поиске ответов по базе знаний, используется полнотекстовый поиск MATCH-AGAINST. Обычные SQL запросы, ничего особенного.

День седьмой. Сегодня

Протестировал как работает поиск по базе знаний. Остался доволен. Я сел писать статью на Хабр, а мой 12-ти летний сын изъявил желание по обучать базу знаний.
Он нашел в интернет информацию, какие вопросы чаще всего задают Siri, и я долго смеялся. В данный момент я пишу эту статью, а он вкладывает «в голову» машине свое понимание этого мира. Что «ВКонтакте» лучше чем «Одноклассники» и другое. Я, конечно, потом все проверю, что он там занес в базу.
Разработка русскоговорящего «аналога» Siri за 7 дней Разработка русскоговорящего «аналога» Siri за 7 дней

Итог

Что получилось.
За семь дней вполне реально написать простейшего виртуального собеседника, который сможет поддержать беседу и отвечать на некоторые вопросы. Конечно до Siri ему как для луны, но как небольшое развлечение вполне годится. Именно в категорию «Развлечения», если цензоры пропустят приложение, оно и попадет.
Легко можно портировать под Android и Widows Phone.

Недостатки программы.
1. Долгая отсылка речи на сервер из-за формата wave.
Планирую уменьшить дискретизацию до 8 КГц, но пока не знаю как.

2. Не очень хорошее распознавание речи, особенно русских городов, движком распознавания.
Может воспользуюсь гугловским движком, он говорят лучше. Но для него нужно перекодировать речь в формат FLAC, что тоже пока не знаю как сделать. Надо искать соответствующую библиотеку. И, конечно, остается вопрос лицензионной чистоты такого пути.

3. Работает медленнее чем Siri.
Это решается только покупкой движка распознавания речи и установкой его на свой выделенный сервер. Не уверен, что пойду по такому пути, уж очень он затратный.

4. Не может многое из того что может Siri.
Ну эта проблема решается выпуском апдейтов и развитием базы знаний. Это всего лишь вопрос времени и выделенных на это средств.

Если какие то моменты упустил, готов ответить в комментариях.

Автор: a1ndrey


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js