Команды для колонки маруси

Команды колонки Маруси подаются как голосом, так и с помощью прикосновений к панели и отдельным кнопкам (в зависимости от модели устройства). Кроме того, Вы можете управлять гаджетом с телефона при помощи специального мобильного приложения. При этом Вам не обязательно заучивать все команды для колонки Маруся, система распознает действия даже если Вы не произнесете определенный порядок слов.

Привет, Хабр! Меня зовут Коля Кремер, уже 4 года я работаю в команде мобильного приложения Маруси, где мы постоянно стараемся сделать так, чтобы с нашим помощником было удобно и интересно общаться.

Я несколько раз начинал писать и откладывал этот ретроспективный пост, но потом к нему подключились ребята из нашей команды и помог довести его до публикации. Хочу поблагодарить Влада Голоднюка, старшего программиста, и Пашу Муханова, руководителя мобильной разработки, и рассказать сообществу Хабра о том, как мы отучили Марусю в приложении триггериться на себя и научили правильно слышать и понимать ваши запросы.

Сначала про Android

При инициализации записи объекту передается источник записи с помощью MediaRecorder::setAudioSource(int).

Для микрофона имеется стандартный параметр MediaRecorder.AudioSource.MIC, который будет возвращать в колбек аудиодорожку, записанную микрофоном, после постобработки средствами устройства.

Также имеются дополнительные константы:

  • MediaRecorder.AudioSource.VOICE_COMMUNICATION
  • MediaRecorder.AudioSource.VOICE_RECOGNITION

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

Читайте также  Новости

На самом деле этот класс задействует те же системные инструменты, что и MediaRecorder при передаче описанных выше констант VOICE_COMMUNICATION и VOICE_RECOGNITION, но кастомные прошивки могут вообще этого не делать, поэтому если вы решитесь использовать эти инструменты, следует отдельно пытаться подключить эхоподавление для большей надежности.

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

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

Что такое самотриггерение?

Когда четыре года назад мы запустили Марусю, она уже была сообразительной и помогала решать самые разные задачи:

  • поиск интересных фильмов в кинотеатрах
  • треки в VK Музыке
  • рассказ сказок для детей
  • прогнозы погоды.

Кроме того, она могла (и может) поддерживать беседу и давать осмысленные ответы. Однако ряд пользователей сталкивался с ситуацией, когда помощник останавливался в середине ответа, как будто обдумывая следующее слово. Это сбивало с толку, хотя причина была в том, что Маруся внимательна к вам во время разговора, чтобы собеседник мог прервать её если необходимо.

Следовательно, когда в её ответе или ваших словах встречаются KWS (key word spotter — слово, на которое голосовой помощник триггерится), то, слыша слово Маруся (которое и есть KWS), она думает, что вы обратились к ней, останавливая выполнение всех текущих команд.

Это сбивало с толку, хотя причина была в том, что Маруся внимательна к вам во время разговора, чтобы собеседник мог прервать её если необходимо.

Очевидно, что это не самая приятная ситуация и для нас и для пользователя. Именно это называется проблемой самотриггерения — ситуации, при которой голосовой помощник активируется (триггерится) сам на себя.

Как работает решение?

Для большой части запросов у Маруси, как и у всех retrieval-based ассистентов, есть набор стандартных ответов и шаблонов, из которых она выбирает наиболее подходящий. Как правило, их конечное число, поэтому мы храним их на сервере не в текстовом виде, а как текст и аудио (tts — text to speech — аудиодорожка с озвучкой текста Маруси).

Вместе с этим для каждой такой аудиодорожки можно создать и хранить timestamp (временные метки), в которых есть триггерное слово Маруся. Это необходимо для того, чтобы для каждого такого timestamp сервер слал команду skip_kws на клиент (мобильное приложение) для блокировки микрофона.

Как мы обнаружили проблему самотриггерения?

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

Как мы решаем проблему?

Пользователь что-то спрашивает у Маруси, а она ищет наиболее подходящий ответ. Если он есть в списке готовых с аудиодорожками и командами skip_kws, то все работает верно. В этом случае сервер присылает в качестве ответа текст, аудиодорожку и команду skip_kws с параметрами на каких секундах приложение нужно блокировать микрофон.

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

Если для ответа нет готового TTS, то Маруся реагирует сама на себя из-за отсутствия команды skip_kws.

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

На одном из UX-исследований с фокус группами мы обнаружили, что пользователи жаловались на самотриггерение, говоря о том, что Маруся тормозит и сбивается. То есть пользователи воспринимали это не как проблему самотриггерения, они просто считали, что Маруся не может ответить на вопрос. Стало понятно, что проблема немного больше, чем мы предполагали.

Для исследования мы собрали с добровольных тестеров выборку в 2000 случайных аудиодорожек, в которых проверили нулевой чанк — начало аудиодорожки, т. е. момент активации Маруси. Результаты не были плачевными, но и не обрадовали нас: 6% из 2000 активаций были самотриггерением. Небольшое отступление, важно понимать, что если бы починка бага занимала мало времени и ресурсов, то мы бы запланировали её в ближайший релиз в рамках ZBP (Zero Bug Policy), но готового простого решения не нашлось, поэтому пришлось начинать с его поиска.

Сторонние библиотеки

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

Как зарегистрировать скилл?

Чтобы зарегистрировать скилл, откройте раздел для разработчиков ВКонтакте.

Сервисный ключ доступа

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

Теперь ваш бот сможет отсылать изображения, предусмотренные в сценарии.

Как мы выбирали из всех возможных вариантов решения

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

  1. Конкурент 1:

    • Во время озвучки TTS полностью выключает микрофон.
    • Сценарий нам не подошел, т.к. пользователю нужно дождаться, пока ассистент закончит вещать или перебить его тапом по кнопке.
    • После этого можно опять активировать ассистента тапом или по KWS и задать новый вопрос.
  2. Конкурент 2:

    • Перед использованием требует дообучения модели на голосе пользователя.
    • На онбординге ассистент просит пользователя зачитать текст, и записанный голос пользователя использует для дообучения локальной модели, которая распознает KWS.
    • Требует долгой работы ML-команды.
    • Забрали в бэклог.
  3. Конкурент 3:

    • Помощник отключает микрофон девайса в момент озвучивания ключевого слова.
    • Решение неплохое, но не работает на эхо, создаваемое другими приложениями.
    • Кладем в бэклог со звездочкой.
  4. Конкурент 4:

    • Как и мы, ассистент страдает проблемой самотриггерения.

Затем мы попытались найти простое решение, например, с помощью активных инструментов.

Как управлять?

Есть несколько вариантов, как управлять капсулой Маруся:

  • Голосом
  • Кнопками
  • Жестами

Во всех вариантах есть свои плюсы и минусы. Но главное — это достигнуть определенного результата.

Управление умной колонкой Маруся

Самый простой вариант управления — подавать команды для умной колонки Маруся голосом. Для этого Вам нужно сначала назвать имя голосового помощника, а затем дать конкретное указание. Например, скажите Маруся, включи сказку Волк и семеро козлят. И через динамики Вы услышите текст сказки.

Благодаря своему устройству гаджет способен распознать речь даже на расстоянии и в шумном помещении. Так что можете попробовать поэкспериментировать.

Соответственно тут же возникает следующий логичный вопрос: Какие вопросы можно задать колонке Марусе. Полный список, какие навыки капсулы Маруси доступны, можно найти на официальном сайте устройства marusia vk com, в разделе Функции. На начало июня 2023 года тут насчитывается больше 600 функций, доступных колонке.

Кроме того, Вы можете спросить саму колонку: Что ты умеешь, и голосовой помощник с радостью расскажет о доступном функционале.

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

Прикосновения

Следующий вариант отправить команды для ВК капсулы Маруся Мини (да и любой другой модели), — это управление с помощью кнопок и прикосновений. Разберем на конкретных примерах.

VK капсула

Внимательно осмотрите гаджет. Вся верхняя часть представляет собой сенсорную панель. Чтобы управлять аксессуаром, нужно правильно нажимать и прикасаться к ней. Главное — не нажимать вне круга с микрофонами. Основные навыки колонки Маруся:

Мини и Нео

Следующие на очереди на разбор — команды колонки Маруся Мини и Нео. Они очень похожи. В этих сериях для управления (кроме голосовых команд) используются кнопки, которые вынесены на панель.

Prestigio SmartVoice

В этой модели также можно управлять функционалом с помощью клавиш. Основные команды:

Mi Smart Speaker

На верхнюю панель вынесены кнопки.

Есть ли команды, как с колонки Маруся управлять компьютером? К сожалению, нет. Вы можете производить аудиозаписи с компа через динамики, но давать указания ПК через микрофоны капсулы не получится.

Мобильное приложение

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

Главное условие, чтобы устройство уже было подключено к мобильному приложению в настройках. Для проверки можно нажать на 3 черточки в правом верхнем углу. Затем пролистайте до раздела «Мои устройства». Если есть подключенный гаджет, там будет указано его название.

Как работает Маруся?​

Маруся выполняет различные задачи с помощью скиллов (навыков), дополнительных функций голосового помощника. Например, скилл «Заказать пиццу» или «Включить музыку».

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

Aimylogic позволяет вам создавать свои собственные скиллы для Маруси, которые станут доступны для всех, кто будет использовать помощника.

Как делали

Самым оптимальным решением является блокировка микрофона, но не во время всего проигрывания TTS, а только ключевого слова. Механизм выглядит простым, а значит надежным — компромисс между затрачиваемыми ресурсами и результатом.

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

В нашем приложении на Android для проигрывания звуков мы используем ExoPlayer2

В iOS грузим данные через

. В методе init можно передать ​​URLSessionDelegate, который и необходимо реализовать в качестве колбека для данных.

Для вычисления ключевого слова из потока микрофона мы используем несколько вероятностных моделей, которые объединены в библиотеку на C++, которую мы используем через Java Native Interface и Swift bridging.

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

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

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

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

Допустим, мы получили, что в конкретном месте массива байтов модель нашла ключевое слово, но все же как мы поймем, когда надо отключать микрофон?

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

Примерная схема работы алгоритма.

Маруся — голосовой помощник от компании Mail.ru.

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

Теперь про iOS

Реализуется максимально просто с помощью стандартных инструментов: класс AudioUnit.

desc.componentSubType = kAudioUnitSubType_VoiceProcessingIO

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

Обобщая результат по двум платформам, можно резюмировать, что системное эхоподавление работает с большим количеством ошибок и может искажать исходящий звук, что не подходит для голосового ассистента, который использует звук как средство коммуникации — benefits < drawbacks. Не берём в бэклог.

И всё?

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

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

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

Здесь мы будем рассматривать модель, которой передаются пороги вероятностей в качестве коэффициентов, как булеву функцию от байтового массива f1(a, x), где a — искомые коэффициенты, а x — массив байтов.

Как упоминалось ранее, параметры модели для микрофона уже заданы, следовательно она является функцией с заданными коэффициентами f2(x), при этом исходный массив байтов искажается по пути до f2, следовательно существует некоторая случайная функция искажения b(x), которая возвращает новый массив байтов. Ранее упоминал, что эта функция в том числе зависит от громкости звука динамиков, поэтому точнее будет ввести параметр v, который принимает целочисленные значения 1–10 (10–100%): b(v, x)

Таким образом, нам необходимо подобрать такое значение a, при котором функции f1(a, x) и f2(b(v, x)) как можно чаще выдают одинаковый ответ. т. е. Такие значения, что f1(a, x) ≈ f2(b(v, x))

Так как для нас пороги вероятностей являются целочисленными значениями от 0 до 100, то найти оптимальное значение можно простым перебором. Так как все это происходит на реальных девайсах, подбирать мы будем там же через написанный скрипт. Необходимо собрать большой массив аудиодорожек в качестве тестового набора данных, где в том числе будут различные искаженные или похожие варианты ключевого слова, после чего необходимо проиграть эти аудиодорожки при разных значениях громкости динамика, поймать микрофоном и проанализировать. Ответы для разных значений громкости всегда можно усреднить. Далее анализируем исходные дорожки с разными порогами вероятностей в цикле и находим те, при которых количество ошибок минимальное, при этом стоит учитывать, что ложное срабатывание при анализе исходной дорожки является менее серьезной проблемой, чем пропуск ключевого слова, поэтому следует добавить разные веса этим ошибкам.

Как опубликовать скилл?​

Маруся появится в списке каналов, к которым подключен ваш бот.

Под названием созданного канала нажмите Получить вебхук. URL хука будет скопирован в буфер обмена. Он понадобится вам далее при регистрации скилла.

Как создать скилл?​

Скилл — это чат-бот, для которого вы выбираете голосового помощника в качестве канала публикации.

Перейдите в Aimylogic, разработайте сценарий, а затем опубликуйте бота в канал.

Особенности канала​

Если не использовать разметку TTS, вернется следующая ошибка:

WARN — Reply type audio is not supported for Marusia channel.

Как это делают умные колонки?

Умная колонка — полностью кастомный продукт со своей прошивкой. Поэтому она может получать в реальном времени поток с микрофона и звук из динамиков, вычищая шумы и получая чистый звук. Такая реализация — эталон по отношению к тому, что должно быть реализовано в системном движке эхоподавления смартфонов, и должно быть реализовано средствами производителя, но, как было написано ранее, реализовывается на малом количестве флагманских смартфонов. Поэтому для мобильного приложения это решение не подходит.

Что в итоге?

После разработки решения для начала мы раскатали его на небольшую аудиторию, проверили эффективность: доля самотриггерений голосового помощника в потоке упала с 6% до 0,1%, пользователи остались довольны. Сейчас мы обновляем SDK для VK и Почты, чтобы Маруся больше нигде на мобильных устройствах не триггерилась.

Понравилась статья? Поделиться с друзьями:
ТВОЙ ВК
Добавить комментарий