
Салют, Хабр!
Я Иван, в SberDevices я руковожу направлением голосового управления умным домом. Сегодня выпустили большое обновление — теперь взаимодействие пользователя с Умным домом Sber через умные колонки стало проще и удобнее. Колонке можно одной репликой дать сразу несколько команд; можно управлять освещением и климатом нативными командами — сказать: «Салют, мне темно», чтобы включился свет. Ещё появилась возможность создавать сценарии с помощью GigaChat: если сказать умной колонке: «Салют, я проснулся», она предложит варианты действий с устройствами умного дома: включить свет? Открыть шторы? Когда вы подтвердили выбор, колонка сама создаст в приложении сценарий.
Благодаря обновлению пользователю стало проще и органичнее управлять умным домом. В этой статье расскажу, как мы реализовали многозадачность в умных колонках.
Как умные колонки определяют, что в одной фразе несколько команд
В апреле базовые возможности умных колонок — общение, музыка, погода и другие — перешли под управление GigaChat. Запрос обрабатывается так: пользователь даёт команду — звуковая дорожка стримится в Automatic Speech Recognition (ASR) — текст запроса поступает в NLP-платформу Intent Recognizer. Тот либо решает, какая бэкенд-система необходима для ответа пользователю, и вызывает соответствующий навык, либо передаёт реплику в GigaChat. Упрощённо Intent Recognizer выглядел как на схеме ниже.

Благодаря переходу на GigaChat умные колонки получили многозадачность в отношении базовых навыков… но не команд умного дома. Дело в том, что для них нужна чуть более сложная архитектура обработки команды. Модель должна уметь трактовать запрос пользователя в зависимости от текущего состояния умного дома — какие устройства, сценарии и комнаты есть у пользователя; какие из них сейчас активны. И делать это как можно быстрее. Поэтому, решая задачу выполнения сразу нескольких команд, мы ориентировались на:
— минимально возможную latency. Никто не хочет ждать в темноте, пока включится свет.
— максимальный recall. Все команды должны выполняться.
Мы предположили, что с точки зрения архитектуры минимальную latency для команд умного дома нам обеспечит дополнительная модель в пайплайне Intent Recognizer. И создали мультикол-классификатор — бинарный классификатор, обученный методом supervised fine-tuning.
Часть данных для обучающего датасета была уже размечена, так как мы взяли их из нашего SFT. Небольшой процент данных составили аугментации. В общей сложности в датасет вошло более 70 тысяч реплик пользователей. У каждой два варианта метки: 1 или 0, в фразе несколько команд или нет. Например:
get_weather — одна команда
smart_home, smart_home — несколько команд умного дома
turn_on_music, timer — несколько команд.
Соотношение «многозадачных» реплик к другим в датасете составило примерно 1:7. В общем, по нашим наблюдениям, подобные команды составляют примерно 7-8% от всех. Чтобы компенсировать имбалансность классов, в дообучении использовался weight loss для бинарной классификации фраз с несколькими командами и тех, что ими не являются. Во время обучения мы четыре раза доливали данные в трейн (и помечали в датесете, в какой версии появились данные, на случай появления возможных ошибок). Не создавая лоссы под разные категории запросов, мы всё же учитывали их в разных итерациях обучения, когда определяли с дата-аналитиками, какие категории стоит подлить в датасет. Скоринг под разные категории с опорой на positive и false positive срабатывания фактически позволил учесть даже небольшие сегменты.
Команда GigaNLP ML для классификатора дообучила классификационную голову на основе эмбеддера основной модели Roberta large, которая входит в Intent Recognizer. Поскольку модель уже дообучена на диалогах с ассистентом, этот подход позволил дополнительно снизить latency.
На вход классификатор получает данные, пропущенные через детектор, который заменяет текстовые имена устройств, комнат, сценариев на их ID. Он скорит каждый запрос, и, если скор больше определённого порога, выдаёт ярлык — 0 или 1. Вычислен этот скор по recall и precision с фокусом на recall.
После обучения пайплайн Intent Recognizer стал выглядеть так:

Как видно на схеме, классификатор расположили перед основным классификатором на базе модели Roberta large. Цель — как можно раньше определить, произнёс ли пользователь фразу, которая содержит нескольких команд. Если да, реплика сразу уходит в GigaNLP. Таким образом снижается вероятность, что она в ходе прохождения пайплайна будет переадресована в другом направлении. Следовательно, теперь классификатор перенаправляет реплики, содержащие несколько любых команд (не только умного дома) в GigaNLP.
Как GigaNLP работает с многозадачными фразами
Каждую реплику, которая уходит в GigaNLP, многозадачную или нет, встречает так называемый ранжировщик. Его задача — помочь определить, какие функции потребуется GigaChat для этого запроса. С технической точки зрения ранжировщик — это код плюс специально обученная модель эмбеддера. Код вызывает эмбеддер; тот методом косинусной близости матчит реплики диалога с описаниями функций ассистента; код проверяет список функций от эмбеддера и при необходимости добавляет или убирает некоторые.
В обеих своих частях ранжировщик опирается на набор флагов о состоянии устройства (device_state), сформированный исходя из функциональности, которую должна поддерживать модель. Код на логике if/else проверяет каждый флаг: true или false? True — нужно добавить функцию в список, если её ещё там нет. False — исключить. К примеру, если активирован флаг «Звонит будильник», стоит предложить модели функцию stop_alarm, даже если эмбеддер не сматчил слово «Замолчи» с описанием функции будильника. Если работает робот-пылесос, эмбеддер, не зная названий устройств, не сматчит команду «Вася, на базу» с необходимостью вернуть устройство на место.
По сути задача эмбеддера — снизить latency, ранжировщика — подстраховать эмбеддер от ошибок. Плюс вся конструкция позволяет сделать короче запросы к основной модели, ведь каждая потенциальная функция занимает место в контексте.
Вместе с репликой пользователя GigaChat получает от ранжировщика список доступных функций, которые может вызвать для этого запроса. Модель-оркестратор принимает решение, вызывать ли функцию/ функции, формировать ли ответ. Каждая функция с технической точки зрения представляет собой JSON-схему с детальной инструкцией.
Как ранее упоминалось, у команд умного дома есть дополнительная сложность: содержимое умного дома варьируется от пользователя к пользователю. Поэтому вместе с репликой и списком возможных функций GigaChat получает ещё одну — «посмотреть» устройства, сценарии и комнаты юзера. Но перед следующей командой набор устройств и их состояние могут измениться. Поэтому GigaChat выполняет команды в фразе последовательно — ему необходимо после каждой проверять список устройств.
GigaChat знает синонимы различных слов, чтобы, если потребуется, скорректировать запрос. Например, пользователь говорит:
— Салют, выключи свет и терморегулятор в санузле!
Модель видит, что комнаты «санузел» в доме юзера нет. Но есть комната «ванная». Направляя запрос функции, она переформулирует его. Это необходимо, чтобы команды с высокой вероятностью довыполнялись.
Когда функции возвращают модели ответ, она, если нужно, формулирует ответ для пользователя. Если ответ подразумевает каждая команда в фразе — объединяет два ответа в один.
Как дообучить GigaChat для обработки нескольких команд в одной фразе и проверить результат
Обработка команд умного дома с помощью GigaChat потребовала дополнительного обучения большой модели. Мы применили метод supervised fine tuning, для которого создали соответствующие диалоги с помощью специальных конвейеров подготовки данных. Уже рассказывали о них, сейчас кратко:
часть разнотиповых обучающих диалогов генерируем через самые большие модели линейки GigaChat с опорой на несколько разработанных пайплайнов для предразметки.
Часть готовим через проекты разметки AI-тренерами. Одна группа тренеров формирует различные диалоги по сценариям, другая валидирует и классифицирует их.
Подготовленные диалоги мы разделили на категории — запросы к нескольким устройствам/сценариям, запросы к умному дому и другим навыкам — и провели обучение. Ещё тестовые сеты с множественными вызовами понадобились для валидации качества выполнения нескольких команд. Мы проверяли все вызовы поочерёдно и текстовый ответ, чтобы убедиться, что модель делает верное количество вызовов с аргументами, соответствующими запросу.
В целом мы выделили основные метрики качества многозадачности умных колонок, которые замеряются после каждого релиза. На ИФТ-стенде ставим прогоны датасета, затем отдаём разметчикам из TagMe. Метрики и результаты в таблице ниже.
Метрика |
Значение |
Результат |
GigaNLP share |
Доля запросов, которые благодаря классификатору попадают в NLP |
95.9 ± 2.1% |
GigaChat total |
Качество работы модели GigaChat в совокупности выбора функций и заполнения слотов для функций |
95.5 ± 2.3% |
Слоты — это параметры, нужные для функции. Так, для функции погоды слоты — это location и time: в каком месте и на какое время запросили прогноз.
Кроме того, мы замеряем вспомогательные метрики — например, среднюю релевантность ответов на все запросы и среднюю релевантность ответов на запросы, обрабатываемые GNLP; качество работы Intent Recognizer и т.д.
Дополнительно многозадачность прошла end-to-end тестирование на колонках. Тестировщикам раздали умные колонки с привязанными виртуальными устройствами умного дома различных типов — освещение, датчики, умная бытовая техника. Они оценивали успешность прохождение всего сценария: произносили фразы, которые содержали несколько команд к умному дому, и отслеживали, что состояния устройств меняются правильно, а модель верно озвучивает результаты.
Заключение
Опция многозадачности в умных колонках позволила быстрее выполнять несколько команд — но это только одна причина реализовать её. Есть ещё вторая: новые функции GigaChat для управления умным домом делают его стало более естественным и органичным для языка. Пользователь говорит, что сделать, точно так же, как мог бы попросить человека, с которым живёт: «Выключи, пожалуйста, свет и включи кондиционер». А значит, умный дом становится ещё ближе, ещё понятнее.
В подготовке статьи участвовали: Илья Расторгуев, Анатолий Востряков, Андрей Квасов, Владимир Карлов, Юрий Федоров, Михаил Голобоков, Ксения Вороная
MountainGoat