Rhasspy на сервере: частые ошибки и решения
Rhasspy обещает голосовое управление умным домом без единой записи, улетающей в чужое облако, — и это работает, пока весь стек крутится на одном слабом одноплатнике и упирается в тормоза распознавания при каждой фразе. Стоит вынести «мозги» на отдельный сервер, а микрофоны оставить в комнатах, как всплывает новый набор проблем: аудио не долетает по сети, wake word не триггерится, русская речь распознаётся через раз. Ниже — конкретные причины этих ошибок и рабочие фиксы, а не общий совет «перезапустите контейнер».
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Архитектура master/satellite: что выносить на сервер
Rhasspy собран из независимых модулей — запись звука, wake word (детектор ключевого слова), распознавание речи (STT), разбор интентов, синтез речи (TTS) — и каждый модуль можно запустить на отдельной машине. Это ключевая вещь, которую многие упускают: пытаются гонять весь стек на Raspberry Pi 3 в углу комнаты и удивляются, почему ответ на команду приходит через несколько секунд, а при двух одновременных запросах из разных комнат интерфейс подвисает целиком.
Правильная схема для дома с несколькими точками:
- Сателлиты — дешёвые устройства с микрофоном и динамиком в каждой комнате (Raspberry Pi Zero 2 W, старый Pi 3, или ESP32-плата с прошивкой-клиентом). Их задача — держать wake word и стримить звук, больше ничего тяжёлого.
- Мастер (сервер) — один более мощный узел, который держит STT-движок, разбор интентов и TTS. Именно его разумно вынести на арендованный VPS или выделенный сервер в сети — там нет ограничений по CPU и RAM, характерных для одноплатников.
Обмен между сателлитом и мастером идёт по протоколу Hermes поверх MQTT — это отдельный движущийся элемент, который и порождает большинство «сетевых» ошибок из следующих разделов. Если вы только присматриваетесь к локальным голосовым ассистентам и ещё не решили, с чего начать, обзорная статья про свой голосовой ассистент на базе локальной модели поможет сориентироваться в вариантах до того, как углубляться в конкретно Rhasspy.
Установка в Docker: типовые грабли на старте
Официальный образ rhasspy/rhasspy разворачивается через Docker без проблем, но на сервере (не одноплатнике с реальным микрофоном) в конфиг часто копируют лишнее из туториалов, рассчитанных на десктопную установку:
services:
rhasspy:
image: rhasspy/rhasspy:latest
container_name: rhasspy
restart: unless-stopped
ports:
- "12101:12101"
- "12183:12183"
volumes:
- ./profiles:/profiles
command: --user-profiles /profiles --profile ru
Частая ошибка — добавить devices: - /dev/snd на голом VPS, где физически нет звуковой карты. Контейнер падает в рестарт-луп сразу после старта, а docker logs rhasspy показывает ошибку инициализации ALSA-устройства. Если сервер выполняет только роль мастера (STT/TTS/интенты), а звук пишут и играют сателлиты — секцию devices в compose-файле мастера просто не добавляйте.
Вторая грабля — не примонтировать /profiles отдельным volume. Rhasspy при первом запуске скачивает акустические модели и словари для выбранного языка (для ru это не самый маленький архив), и без персистентного тома всё это утягивается заново при каждом пересоздании контейнера — первый запуск после docker compose up на новом сервере ощутимо дольше, чем последующие, и это нормально, а не зависание.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверАудио между сателлитом и сервером: Hermes/MQTT
Сателлит и мастер общаются через MQTT-брокер по протоколу Hermes (топики вида hermes/audioServer/<siteId>/audioFrame). Брокер — обычно отдельный контейнер Mosquitto:
services:
mosquitto:
image: eclipse-mosquitto:2
restart: unless-stopped
ports:
- "1883:1883"
volumes:
- ./mosquitto/config:/mosquitto/config
Самая частая жалоба — «сателлит подключён, в логах тишина, команды не долетают до сервера». Обычно это firewall: порт 1883 закрыт на входящие от IP сателлита, либо сервер и сателлиты живут в разных сетях (дом и дата-центр), и без туннеля MQTT просто не достучится. Если мастер вынесен на арендованный сервер, а сателлиты остались дома, разумно поднять между ними WireGuard-туннель и слушать MQTT только на внутреннем интерфейсе — открывать 1883 в публичный интернет небезопасно, брокер без аутентификации превращается в открытый микрофон для кого угодно. Разобраться, почему контейнер не видит нужную сеть или порт снаружи не пробрасывается, помогает статья про отсутствие доступа к сети из контейнера — грабли там пересекаются напрямую.
Второй источник проблем — рассинхрон параметров аудиопотока. Rhasspy ожидает конкретный формат (обычно 16-бит PCM, 16000 Гц, моно), и если на сателлите он задан иначе (например, стрим в 44100 Гц со стерео-микрофона USB-гарнитуры без ресемплинга), STT на сервере получает искажённый по таймингу поток и либо возвращает пустую строку, либо распознаёт случайный мусор. Проверяется явным указанием sample rate в настройках микрофона сателлита и логами hermes/audioServer — там видно фактическую частоту входящих фреймов.
Распознавание речи (STT): Kaldi, Whisper и русский язык
По умолчанию профиль Rhasspy предлагает Pocketsphinx — он лёгкий, но качество распознавания русской речи у него откровенно слабое, годится разве что для десятка жёстко заданных команд. Для нормального русского STT есть два реалистичных пути:
- Kaldi — встроенный движок Rhasspy с готовым русским профилем. Разумный баланс: работает на CPU без GPU, но требует, чтобы после смены языка профиля на
ruвы явно скачали именно русскую акустическую модель через веб-интерфейс (Settings → Speech to Text) — простая смена языка в конфиге без повторного скачивания моделей оставляет старые английские файлы, и распознавание либо молчит, либо выдаёт бессмыслицу. - Whisper через внешний STT-мост — заметно точнее на живой речи и с акцентами, но и заметно тяжелее по ресурсам: без GPU обработка идёт на CPU, и чем крупнее модель (small/medium/large), тем дольше сервер думает над одной фразой. На арендованном сервере без видеокарты разумный старт — модель
smallилиbase; переход на более тяжёлые модели стоит проверять на своей нагрузке, точных цифр по задержке я тут намеренно не привожу — они сильно зависят от процессора и длины фразы.
Отдельная категория ошибок — нехватка памяти. Kaldi- и тем более Whisper-модели вместе с профилем и словарями требовательны к RAM, и на сервере с урезанным тарифом контейнер может тихо перезапускаться под OOM killer без явной ошибки в интерфейсе Rhasspy. Признак — в dmesg или journalctl -k находится строка про Killed process с именем процесса STT-движка, а docker ps показывает недавний рестарт контейнера. Лечится либо увеличением RAM на сервере, либо переходом на более компактную модель.
Wake word: ложные срабатывания и мёртвая тишина
За детекцию ключевого слова («Окей, дом» или что вы задали) отвечает отдельный движок — Porcupine, Snowboy или Precise, и здесь свои грабли:
- Porcupine требует access key от Picovoice. Если ключ не указан, истёк или превышен лимит бесплатного тарифа, движок на сателлите падает молча — сателлит слушает, но никогда не активируется. Проверяется в логах сателлита строкой с упоминанием
AccessKey. - Snowboy формально не поддерживается автором уже давно, но собранные бинарники по-прежнему используются в готовых образах. На нестандартной архитектуре (например, при попытке пересобрать под свежий Raspberry Pi OS) типична ошибка несовместимости wheel-пакета — проще переключиться на Porcupine или Precise, чем воевать со сборкой устаревшего движка.
- Ложные срабатывания и «глухота» регулируются параметром sensitivity в настройках wake word. Слишком высокая чувствительность в шумной кухне даёт срабатывания на посторонние звуки, слишком низкая — ассистент не слышит команду с первого раза. Настраивается отдельно на каждом сателлите, единого значения на все комнаты обычно не существует — акустика разная.
Отдельно стоит держать в голове честный нюанс: активная разработка самого Rhasspy 2.x идёт заметно медленнее, чем несколько лет назад — часть внимания сообщества сместилась в сторону протокола Wyoming и голосового пайплайна самого Home Assistant. Rhasspy при этом продолжает исправно работать и обновляться силами сообщества, но при выборе новых компонентов (особенно wake word и STT) стоит проверять, поддерживается ли конкретный движок сейчас, а не полагаться на старые мануалы без оглядки на дату.
Интеграция с Home Assistant и Node-RED
Распознанный интент Rhasspy отправляет либо напрямую в Home Assistant через intent_script/conversation API, либо в MQTT-топик hermes/intent/<name>, откуда его может забрать Node-RED для более гибкой логики. Частые ошибки на этом стыке:
- HA получает интент, но ничего не происходит. Проверьте
base_urlи токен в настройках Rhasspy-интеграции с HA — просроченный long-lived token не даёт явной ошибки в Rhasspy, зато в логах HA появляется401 Unauthorized. - Несовпадение слотов. Если в
sentences.iniзаданы слоты (например,{room}для команды «включи свет в {room}»), а вintent_script.yamlна стороне HA ожидается другое имя переменной, HA падает сKeyErrorв момент выполнения — сам интент при этом «успешно распознан», ошибка видна только в логах Home Assistant, не в Rhasspy. - Сложную логику проще собирать в Node-RED, подписавшись на топик
hermes/intent/#, чем городить её внутриintent_script. Готовый compose-файл для развёртывания разобран в статье про Node-RED в Docker Compose, а сам Home Assistant в контейнерном варианте — в статье Home Assistant в Docker Compose.
Если HA и Rhasspy стоят в разных сетевых режимах Docker (например, HA в network_mode: host, а Rhasspy в обычном bridge), MQTT-брокер может быть недоступен одной из сторон — симптом тот же, что в разделе про аудио: интент виден в интерфейсе Rhasspy, но никуда не долетает.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Можно ли обойтись без отдельного сервера и держать всё на одном Raspberry Pi?
Можно для одной комнаты с простыми командами и Pocketsphinx/лёгким Kaldi-профилем. Как только добавляются вторая точка прослушивания или более тяжёлый STT-движок, одноплатник начинает упираться в CPU, и вынос мастера на сервер снимает эту проблему целиком.
Почему после смены языка профиля на русский распознавание всё равно работает плохо?
Чаще всего забыли скачать русскую акустическую модель через веб-интерфейс после смены языка — конфиг обновился, а файлы моделей остались от предыдущего профиля.
MQTT без пароля — это вообще безопасно на сервере в интернете?
Нет, открытый брокер без аутентификации на публичном IP — это фактически доступ к аудиопотоку из дома для любого, кто найдёт порт. Либо настройте логин/пароль и TLS в Mosquitto, либо (лучше) закройте порт наружу вовсе и подключайте сателлиты только через VPN-туннель.
Snowboy не собирается на новом сателлите — что делать?
Не тратить на это время: движок официально не поддерживается автором, переключитесь на Porcupine (нужен бесплатный access key от Picovoice) или на Precise, оба развиваются активнее.
Сколько ресурсов закладывать на сервер-мастер?
Зависит от выбранного STT-движка: Kaldi с русским профилем ощутимо легче, чем Whisper-мост на моделях среднего размера без GPU. Точные цифры зависят от числа одновременных сателлитов и длины типичных фраз, поэтому разумно начинать с запаса и смотреть на реальную нагрузку в первую неделю эксплуатации, а не считать заранее «на бумаге».
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →