Skip to content

Instantly share code, notes, and snippets.

@alex-pat
Last active October 4, 2023 14:11
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alex-pat/f90a97f9ead839e299c11f00bcab512c to your computer and use it in GitHub Desktop.
Save alex-pat/f90a97f9ead839e299c11f00bcab512c to your computer and use it in GitHub Desktop.
Голосовой помощник

Делаем голосового помощника своими руками

С самого выхода Космической одиссеи Стенли Кубрика люди мечтали иметь компьютер, с которым можно было бы общаться так же, как с другим человеком. Прошло уже почти полвека с момента выхода сей культовой картины, а технологии лишь недавно позволили людям приблизиться к технологиям воображаемого будущего. И хотя космические корабли всё ещё слабо бороздят Большой театр просторы Вселенной, говорящие бездушные помощники уже более чем реальность. Такие компании как Google и Amazon уже торгуют своими Home и Echo, хотя далеко не каждый может себе позволить такую колонку. За Google Home компания просит $130, а Amazon за своё детище - все $180.

Не будем забывать, что существует огромный пласт активного населения, которые жить не могут, а им дай поиграть с конфигами заточить всё под себя, да добавлять новые фичи по мере потребности и оживления фантазии.

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

Как быть? Стало быть, нужен относительно дешёвый вариант, лекго конфигуриремый, с открытыми исходниками, и желательно не вылезающего в Интернет без необходимости. Из ближайшего, что подходит на эту роль - Raspberry PI. Благо, необходимости строить свой велосипед нет, так как уже нашлись умельцы, адаптировавшие всё это добро под Малину. А наша задача - разобраться с этим, настроить и дописать своё. Имя этому - легион Jasper

Железо

Нам понадобятся:

  1. Собственно Raspberry (3 в моём случае)
  2. Динамик
  3. Микрофон
  4. Внешняя звуковая карта

Дело в том, что Малина не имеет при себе ничего, что способно оцифровывать сигнал с микрофона, поэтому перед нами два варианта: USB-микрофон (дороговато), либо обычный микрофон с джеком + USBшная звуковая карта (дёшево, сердито).

Cофт

Если обратить внимание, то все обладатели RPI в сети имеют при себе лишнюю клавиатуру и монитор, чего студент не может себе позволить. Как минимум они считаются необходимыми для первоначальной настройки ОС, а именно, для поднятия wifi и ssh. Когда я изначально пытался настроить это без вышеписанных девайсов, т.е. только при помощи правки конфигов на карте - включения - проверки наличия в локальной сети нового устройства, я столкнулся с проблемой, что в случае отсутствия адекватного устройства вывода нереально сложно отлаживать скрипты конфигурации. В конце концов я добился своего, используя в качестве устройства ввода/вывода файловую систему, но потом оказалось, что...

...разработчики Jasper поставляют образы системы с уже настроенным ssh, так что необходимо было только прописать SSID и пароль в конфиге wpa_supplicant.

Мораль - не спеши, хотя иногда полученный в результате отрицательный опыт тоже бывает полезен

Итак, Официальная документация говорит нам скачать у них образ, записать его на microSD классическим dd, либо можно всё поставить руками, ибо есть даже пакет в AUR.

Подвох в том, что убийца - дворецкий на половине проделанной работы, в поисках ответа на очередную ошибку при установке пакета ты натыкаешься на подобный вопрос на форуме поддержки Jasper, а человеку отвечают загадочной фразой "Посмотрите, что написано на главной странице форума, выделено жёлтым". Следуем этой наводке и видим:

NOTICE TO NEW USERS:
Jasper Documentation/Image has not been updated on their site in a LONG TIME
Please DO NOT USE THE IMAGE ON THE SITE!
Please use the community image above.

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

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

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

Так как мы решили большую часть производить прямо на борту Малины, то и распознавание голоса должно по нашей задумке происходить там же. Нам предлагается несколько вариантов:

  • PocketSphinx - локально, на Сях, адаптировано под ARM, создано в университете Карнеги Меллон
  • Google STT - то же, что и в мобилках, но необходима сеть, так что отпадает в нашем случае
  • AT&T STT - онлайновый
  • Wit.ai STT - онлайновый
  • Julius - высокопроизводительный, локальный, но нужно тренировать свою аккустическую модель, что настолько сложно и опасно, что сами разработчики Jasper советуют использоать его только самым смелым.

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

Теперь для вывода - вариантов TTS предлагается достаточно, начиная от встроенного в Android 1.6 Donut, заканчивая Стивеном Хокингом поделкой от того же университета Карнеги Меллон. Здесь время уйдёт уже на выбор голоса по вкусу.

Как это работает

jasper.py организует вcю работу Джаспера. Он создает экземпляры микрофона, профиля и разговора. Затем экземпляр разговора получает микрофон и профиль в качестве входных данных, из которых он создает уведомитель и мозг. На самом деле, объект Mic отвечает здесь не только за микрофон, а за звук в принципе - через его метод say() можно дать указание машине зачитать текст.

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

Каждый модуль - файл в директории client/modules/ - должен реализовывать функции isValid() и handle(), а также определять список ключевых слов WORDS = [...]. isValid() проверяет запрос на соответствие шаблону, handle - выполняет обработку запроса.

Например, модуль, отвечающий на вопрос о смысле жизни может быть таким:

import random
import re

WORDS = ["MEANING", "OF", "LIFE"]


def handle(text, mic, profile):
    messages = ["It's 42, you idiot.",
                "It's 42. How many times do I have to tell you?"]

    message = random.choice(messages)

    mic.say(message)


def isValid(text):
    return bool(re.search(r'\bmeaning of life\b', text, re.IGNORECASE))

Объект profile - настройки из файла ~/.jasper/profile.yml. Там могут быть как служебные данные (пути к файлам голосовых моделей, например), так и любая полезная информация (местоположение для модуля погоды).

Модули

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

Некоторые полезные мои и переписанные чужие модули можно найти здесь.

/etc

Стоит отметить, что расширению легко поддаются не только собственно модули, но и внутрянняя кухня Джаспера. Однажды я понял, что мне не хватает тех двух способов запуска: голосового и текстового, а мне нужнен ещё один: ввод с клавиатуры, ответ в виде текста и звука. И сделать это оказалось очень легко, ведь во время парсинга агрументов командной строки просто импоритруеются "микрофоны" из разных файлов, но с разной реализацией методов.

if args.local:
    from client.local_mic import Mic
else:
    from client.mic import Mic

такой вот своеобразный способ реализации паттернов, но вполне себе рабочий.

Локальное распознавание голоса. Оно, честно говоря, слабовато, то ли из-за самой используемой техники, то ли из-за дешёвого микрофона.

Итоги

Две с половиной недели назад Google совместно с Raspberry создали то же самое, только с Google Assistant на борту, и практически за те же деньги. Интересное ощущение, когда сначала ты начинаешь делать курсовую, а потом её делает Google.

@CodePixelPioner
Copy link

Привет, очень понравилась твоя статья) хотела бы узнать более подробно про твою реализацию и посмотреть документацию, просто думаю диплом делать на данную тему, очень интересно 😅

@alex-pat
Copy link
Author

Привет @CodePixelPioner, вот уж не ожидал, что этот текст снова кому-то станет интересен. Так как с написания статьи прошло 6.5 лет, воспоминания улетучились из головы чуть более чем полностью. Однако, из того, что может помочь, кроме непосредственно текста и кода в репозитории, кто-то писал мне по поводу статьи спустя год после написания, тогда я ещё хоть что-то помнил, так что выложу свой ответ для будущих поколений.

On Sun, Jun 10, 2018 at 06:20:10PM +0200, kykryniks spb wrote:  
> 1 Есть ли у вас более подробная инструкция установки Jasper и всего доп.  
> софта на разбари пи?  
  
Подробной инструкции у меня нет, но если память мне не изменяет, то  
образы с форума поддержки (не с официального сайта, как вы поняли из  
статьи) имели почти всё в себе, мне оставалось только в конфиге  
wpa_supplicant прописать данные своего вайфая.  
  
> В данный момент пробую все это установит на виртуальную машины, что бы  
> понять как это будет выглядит в компактном варианте.  
  
На самом деле, совсем нестрашно лить образ сразу на малину (только  
сделайте бэкап старой системы на всякий случай -- dd вполне годится).  
  
> 2 Есть ли у вас опыт работы с другими программами? Спрашиваю так как  
> возможно вы уже попробовали что то более современное и удобное.  
  
Ничего больше не пробовал. Реальность в том, что мне всё это  
понадобилось только в качестве курсового проекта.  
  
> 3 Какие сайты, форумы, или сообщества по этой теме (меня волнует  
> практическая сторона) вы можете посоветовать?  
  
Форуп поддержки:  
https://groups.google.com/forum/#!forum/jasper-support-forum
По поводу официального сайта сложно сказать, я давно там не был, во  
времена написания статьи там было некоторое количество как полезной  
информации, так и устаревшей.

@CodePixelPioner
Copy link

А остались ли материалы по курсовой работе? Интересно будет почитать Ваши рассуждения, помимо других источников)

@CodePixelPioner
Copy link

например, сам курсач или чертежи?) это немного упростило бы мне работу) если найдется что-то Вы бы очень помогли))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment