Pocketsphinx. Распознавание речи и голосовое управление в Linux
— Всё в порядке, Лёня?
Динамики отрегулированы на максимум, я морщусь, отвечаю:
— Да. Тише звук.
— Звук — тише, — соглашается «Виндоус-Хоум», — тише, тише…
— Хватит, Вика
С.Лукьяненко, «Лабиринт отражений»
Введение
В данной статье я не буду касаться Julius, поскольку гайдов по его использованию (в том числе и в Рунете) хватает. Речь будет идти о CMU Sphinx.
Описание и установка
Не забудьте после установки выполнить:
Для работы с /dev/dsp установим согласно FAQ пакет oss-compat.
Базовое использование
/sphinx.
Синтаксис нашей команды таков:
-argflie: имя файла в текущей директории, содержащего все аргументы.
stderr для удобства перенаправим в файл.
Содержимое argfile:
-hmm: путь к каталогу, содержащему файлы акустической модели (шаблоны отдельных звуков).
-lm: путь к файлу триграммной языковой модели (можете почитать здесь).
-dict: путь к файлу словаря произношения.
-cepdir: путь к каталогу со звуковыми файлами. Будьте внимательны: если вы вносите -cepdir в файл аргументов, то сокращенный путь
/sphinx обрабатывается неправильно: приходится писать полный путь. Если вы будете прописывать аргумент после команды, то можете использовать сокращенный путь.
-ctl: файл с именами обрабатываемых файлов. Файл goforward.raw мы возьмем из комплекта исходников pocketsphinx (там есть еще пару файлов *.raw — можете распознать и их).
-cepext: расширение обрабатываемых файлов
-adcin: указатель принадлежности обрабатываемого файла к raw.
-hyp: имя файла, в который будет выведен распознанный текст.
Аргументы с путями к файлам моделей указывать обязательно. Помните, что многие параметры заданы по умолчанию (смотрите stderr). Поэтому для работы с файлом *.raw необходимо принудительно указать расширение, иначе будет использован параметр по умолчанию — расширение .mfc (а таких файлов у нас в базовом примере, естественно, нету — будут сыпаться ошибки).
В результате исполнения у нас в файле outname будет следующее содержимое:
Параллельно можете посмотреть, откомпилировать и запустить в каталоге с файлом goforward.raw программку аналогичного назначения на C (пример от разработчиков).
Для проверки на своих примерах я решил не мудрствовать и воспользовался sox (проверьте, установлен ли этот пакет у вас).
Писать звук будем следующим образом (можете почитать man sox ):
— для raw
Окончание записи по Ctrl+C .
У меня sox при этом ругался на невозможность использования частоты дискретизации: can’t set sample rate 16000; using 48000 . Учтите: нагло лжет — на самом деле все в порядке.
Я писал и распознавал raw и wav на различных примерах из подключенных словарей — все распознавалось вполне приемлимо.
Адаптация звуковой модели
Скачиваем по первой ссылке предлагаемые файлы в отдельную директорию, в которой и будем работать.
Теперь надиктуем предложения из файла arctic20.txt по образцу: у вас должно получиться двадцать файлов, названных по порядку согласно схеме arctic_0001.wav . arctic_0020.wav .
Чтобы упростить запись, воспользуемся предложенным скриптом:
Соответственно, чтобы прослушать полученное, выполним:
Скопируем акустическую модель (с которой мы и работали) из /usr/local/share/pocketsphinx/model/hmm/en_US/hub4wsj_sc_8k в нашу рабочую директорию.
Теперь создадим файлы акустических особенностей (напоминаю: работаем в директории с файлами *.wav).
В результате получаем файлы *.mfc.
Скачиваем экстра-пак (89,0 МБ); файл под названием mixture_weights из него, расположенный в pocketsphinx-extra/model/hmm/en_US/hub4_wsj_sc_3s_8k.cd_semi_5000 помещаем в каталог с акустической моделью.
Также необходимо конвертировать mdef-файл акустической модели в текстовый формат:
Теперь, согласно терминологии гайда по адаптации, соберем накопленные данные. Скопируем утилиту bw из /usr/local/libexec/sphinxtrain/bw в рабочий каталог (перед этим не забудьте установить sphinxtrain!).
Запускаем и видим:
SYSTEM_ERROR: «corpus.c», line 339: Unable to open arctic20.fileids for reading: No such file or directory
Очевидно, правая рука у разработчиков не ведает, что творит левая (про неактуальность части документации я уже не говорю).
Переименовываем в рабочем каталоге файл arctic20.listoffiles в arctic20.fileids
Теперь все работает.
Произведем MLLR-адаптацию (эффективна для ограниченного объема данных в модели):
Эта команда создаст файл адаптационных данных mllr_matrix .
Теперь при распознавании с адаптированной моделью можно добавлять параметр -mllr /path/to/mllr_matrix .
Параллельно произведем другой метод адаптации: MAP.
Сделаем копию модели:
И произведем MAP-адаптацию:
Теперь создадим sendump файл, отличающийся меньшим размером:
Тестирование адаптации
Проверяем (помните, что адаптация не приведет к стопроцентно верному результату: адаптированные модели будут точно так же ошибаться; плюс в том, что они будут делать это реже. Мои вполне наглядные записи были сделаны далеко не с первой попытки: было достаточно записей, где ошибались все модели):
1. Распознавание с помощью базовой модели:
2. Распознавание с помощью модели с MLLR-адаптацией: при указании параметром -mllr пути к моей матрице происходила ошибка сегментирования (копаться я не стал). При распознавании без этой опции результат полностью идентичен результату оригинальной модели.
Впрочем, в мануале заявлено, что MLLR-адаптация лучше всего подходит для непрерывной модели (т.е. для Sphinx4).
3. Распознавание с помощью модели с MAP-адаптацией:
Как можно убедиться, результат полностью идентичен записи. Адаптация реально работает!
Русский язык в Pocketsphinx
Скачаем отсюда русские модели, созданные на voxforge. На разнообразие моделей можно посмотреть здесь и просто в интернетах.
Реализовывать пример голосового управления компьютером мы будем на русском, а значит нам нужны собственная языковая модель и собственный словарь (вероятнее всего, части наших слов в распространенных примерах не будет).
Создание собственной статической языковой модели
Далее создаем словарный файл:
Создаем языковую модель в arpa-формате:
И создаем DMP-модель.
Создание собственного словаря
Тащим с гитхаба утилиты:
Переходим в каталог ./yourdir/text2dict и создаем там текстовый файл my_dictionary с вашим списком слов (каждое новое слово — с нового абзаца).
И вот ваш словарь создан.
Теперь пробуем распознавать слова, присутствующие в словаре (благо, в нашем примере их немного). Не забудьте указать в аргументах собственную языковую модель и словарь — все должно работать. При желании можно произвести адаптацию акустической модели (сразу предупреждаю: при использовании утилиты bw в процессе адаптации для большинства акустических моделей опция -svspec не нужна ).
Использование JavaScript Grammar File вместо статической языковой модели
«|» обозначает условие выбора. Т.е. мы можем сказать «тише» или «закрыть окно». Правда, по сравнению с использованием языковой модели есть один минус: говорить нужно гораздо членораздельнее.
Созданный jsgf-файл указываем с параметром -jsgf (параметр -lm в таком случае не нужен).
Реализация голосового управления
Моей целью не было реализовать крутой интерфейс управления: здесь все будет очень примитивно (если есть желание и возможность, можете посмотреть на заброшенный проект Gnome Voice Control).
Действовать будем следующим образом:
1. Пишем команду, распознаем её.
2. Передаем распознанный текст в файл, в соответствии с ним выполняем команду.
В качестве тестовых команд будем использовать уменьшение и увеличение громкости звука.
Внимательно почитав мануал к sox, я решил оканчивать запись по истечении секунды тишины с порогом тишины в 3.8% (порог явно является сугубо индивидуальным значением и зависит от вашего микрофона и окружающей обстановки).
К сожалению, я не нашел в pocketsphinx_batch параметр вывода только для распознанных слов, поэтому я воспользуюсь инструментом sed :
Эта конструкция удалит из строки вида «наша команда (audio -4023)» пробел перед открывающей скобкой, её саму и все последующее содержимое. В результате мы получим строку вида «наша команда», что нам и нужно.
Вот сам скрипт:
Скрипт в ответ на команды «тише» или «громче» выполняет соответствующие действия с сигнализацией через notify-send.
К сожалению, работать он будет только при запуске из терминала (иначе звук не пишется). Впрочем, представление о голосовом управлении он дает (возможно, вы предложите лучший метод).
Первый выпуск Dragonfire 1.0 — голосового помощника для Linux
После трёх лет разработки состоялся первый стабильный выпуск Dragonfire 1.0 — голосового ассистента для Linux, позволяющего организовать взаимодействие с рабочим столом при помощи голосовых команд. Изначально проект развивался для мотоциклетного шлема дополненной реальности Dargon Armor — полностью открытого проекта на основе плат Raspberry Pi 3, но впоследствии был расширен для применения на обычном Linux-десктопе. Код проекта написан на языке Python и распространяется по лицензии MIT. Доступны клиенты для десктопных дистрибутивов Linux, а также Android.
Для разбора голосовых команд применяется система распознавания речи Mozilla DeepSpeech, построенная на платформе машинного обучения TensorFlow. Для синтеза речи задействован пакет Festival. Интерфейс в форме вопрос/ответ базируется на библиотеке распознавания текста на естественном языке spaCy и данных из Wikipedia. Ответ формируется с применением нейронной сети seq2seq, натренированной по базе диалогов из фильмов. Для работы Dragonfire рекомендуется система с минимум 2 гигабайтами памяти и поддержкой CUDA. Кроме этого выпуск 1.0 может похвастаться следующими изменениями:
- Исправлены послеустановочные скрипты.
- Полностью реализован API.
- Значительно улучшен серверный режим, в котором Dragonfire можно использовать для создания чат-ботовю
- Базовый анализатор полностью задействует библиотеку spaCy.
- Обеспечена возможность сохранения данных обучения, исходящих от многих пользователей Android, в базе данных MySQL.
- В качестве альтернативы добавлена система распознавания речи Gspeech.
Для работы Dragonfire рекомендуется система с минимум 2 гигабайтами памяти и поддержкой CUDA.
Вах. Чтобы распознать 20 фиксированных запросов? Чтобы загуглить 100500 неправильных ответов? (см. README)?
И да, минус за название, пытающееся примазаться к проприетарщине.
и че,если я ему скажу, Вася, пропатч мне кеды, он смогёт?
Очевидно же — только под freebsd
To activate Dragonfire say DRAGONFIRE or HEY or WAKE UP.
To deactivate her say GO TO SLEEP.
To silence her say ENOUGH or SHUT UP.
To kill her say GOODBYE or BYE BYE or SEE YOU LATER or CATCH YOU LATER
Русскую речь понимает?
Изначально проект развивался для полностью открытого проекта на основе плат Raspberry Pi 3
Для работы Dragonfire рекомендуется система с минимум 2 гигабайтами памяти и поддержкой CUDA.
И где они в малине нашли все это? Или в чем отличие от малиновой версии?
Ну и по примерам не очень понятно зачем это все на десктопе, плюс хотелось бы увидеть пример обучения, когда я говорю «компьютер, давай смотреть поней», а он сам открывает браузер, ищет нужную серию и запускает просмотр.
Для работы Dragonfire рекомендуется система с минимум 2 гигабайтами памяти и поддержкой CUDA.