Голос: от звука к намерению
Как отличить «включи свет» от «включи подсветку»?
Для команды «включи свет» важнее правильно выбрать объект, чем сгенерировать длинный красивый ответ.
Распознавание речи возвращает текст, а не готовое разрешение на управление. Дальше нужно определить действие, найти объект в доступной комнате, проверить неоднозначность и полномочия.
«Свет» и «освещение» могут быть синонимами одной роли. «Подсветка» может обозначать другой прибор или сразу несколько. Поэтому словарь связан с реестром комнаты, а уточняющий вопрос является нормальным результатом, не неудачей голосового интерфейса.
Голосовой тракт состоит из захвата, обнаружения речи, распознавания, разрешения намерения, проверки полномочий, исполнения и ответа. Каждый этап имеет отдельную ошибку и метрику. Объединение всего в один запрос к большой модели затрудняет проверку и делает простую команду дороже.
Кандидаты распознавания#
| Стек | Когда полезен | Что проверить |
|---|---|---|
| whisper.cpp, multilingual-модель | Универсальные RU/EN-фразы и разные формулировки | Задержка, память, ложный текст на тишине, выбранный backend |
| sherpa-onnx | Потоковые и специализированные speech-пайплайны | Конкретная модель, лицензия, streaming и endpointing |
| Vosk | Небольшой офлайн-словарь и грамматика команд | Качество имён устройств и смешанной речи |
| Candle / собственный Rust-worker | Более единая среда Rust | Поддержка нужной модели и оптимизаций |
Эти проекты предоставляют разные реализации и модели. Для русского нельзя случайно выбрать англоязычную.en-модель и затем оценивать весь подход как неработающий. Скорость зависит от весов, квантования, CPU/GPU и длины аудио; готовые репозитории служат основой эксперимента, а не обещанием конкретной задержки. [61] [62][73][99]
VAD и конец фразы#
VAD определяет, есть ли речь, а не смысл команды. Silero VAD — один из доступных кандидатов. Он помогает не отправлять в STT непрерывную тишину и шум, но может обрезать тихое начало или конец. Нужен небольшой pre-roll и согласованная задержка завершения. [63]
Конец фразы — компромисс: слишком короткая пауза обрежет «включи… подсветку за монитором», слишком длинная сделает интерфейс медленным. Отдельно измеряются время после окончания речи и полное время до физического результата. Пользователь воспринимает именно последнюю цепочку.
Намерение и объект#
После текста формируется структура: действие, объект, помещение, параметры и контекст. Слова «включи свет» и «включи освещение» могут указывать на основной светильник. «Включи подсветку» указывает на другой capability или сцену, если она существует. Если в комнате две подсветки, требуется уточнение.
Для первого экземпляра полезен ограниченный intent-parser со словарём синонимов, именами устройств и шаблонами параметров. Он проще тестируется и не требует большой LLM. Контекст включает выбранную комнату, источник микрофона и текущий диалог уточнения. Предположение о комнате не должно быть скрытым.
Где уместна языковая модель#
LLM может преобразовать разнообразную фразу в ограниченную структуру или объяснить причину действия. Ей передаётся только разрешённый каталог объектов и операций. Выход валидируется по схеме, правам, диапазонам и актуальному состоянию. Никакого shell, SQL или прямого GPIO из сгенерированного текста.
llama.cpp и Candle — варианты локального вывода, но наличие такого runtime не создаёт безопасный агент само по себе. Для команды с побочным эффектом особенно важно отделить предложение от исполнения. [66][73]
Ответ и озвучивание#
Короткий ответ сообщает результат: «Основной свет включён» после подтверждения; «Команда отправлена, подтверждение не пришло» при неопределённости. Не следует всегда говорить «готово» сразу после приёма звука. Для простых случаев достаточно заранее подготовленных фраз; локальный TTS добавляет гибкость.
Piper — кандидат синтеза, при этом лицензия программы и конкретных голосов проверяется отдельно. Первые RU/EN-ответы можно сделать текстовыми, чтобы не смешивать ошибки распознавания и акустическое эхо динамика. [65]
Корпус команд для проверки#
Набор включает разные голоса, темп, расстояния, шум, отрицания и похожие имена: «не включай свет», «выключи подсветку», «включи свет в коридоре», «set the desk light to…», «turn off the backlight». Отдельно записываются обычный разговор и телевизор/ музыка, которые не должны запускать действия.
Главные показатели: доля правильно выбранных действий и объектов, ложные исполнения, запросы уточнения и время до результата. WER текста полезен, но не равен безопасности: одна ошибка в слове «не» опаснее нескольких ошибок в необязательной части фразы.
Мощность и конкуренция#
Speech-worker имеет ограничение числа запросов. Устройство сначала возвращает короткое подтверждение захвата, затем результат. Большая модель не должна задерживать выключение реле или блокировать БД. При перегрузке голос может перейти на меньшую модель или сообщить о временной недоступности; уже работающие правила сохраняются.
Первое сравнение моделей#
На имеющемся ПК записать не менее нескольких десятков RU/EN-команд и негативных примеров. Прогнать два размера Whisper либо Whisper и Vosk/sherpa. Сохранить точность намерений, задержку после конца речи и память. Только после этого выбирать постоянный вычислитель для голоса.
Сравнивать на собственной тишине и собственных словах#
К Whisper добавлены GigaAM и Vosk как кандидаты, а не готовые победители. Грамматически ограниченное распознавание может быть удобно для малого набора команд; возможность менять словарь зависит от модели. Русский и английский проверяются отдельными наборами и смешанными названиями. Лицензия конкретных весов и доступный backend подтверждаются до включения в пакет. [163][164]
Негативный набор включает тишину, вентиляторы, телевизор, музыку, похожие слова, отрицания и оборванную фразу. Метрики различают ложный текст, ложную активацию и ложное физическое исполнение. Первые два не должны автоматически становиться третьим: нужны намерение, допустимый объект, текущие права и проверка команды.
Свободный LLM-парсер не входит в E0. Для E1 небольшой локальный кандидат может использовать constrained decoding, но синтаксически правильный JSON всё равно проходит совместную семантическую проверку. Бюджет вычисления измеряется на выбранном Hub; обещание «модель 1–4B всегда отвечает за 300 мс» не принимается без стенда.