Перейти к содержанию
Публикация AiManual

Локальный голосовой ассистент вместо Alexa: как собрать домашнюю AI-систему на ESP32 и собственном сервере

Схема с ESP32 в комнатах и AI на своём сервере рабочая: разбираем готовые open-source проекты, выбор STT и TTS, требования к VRAM и реальные подводные камни сбо

Коротко

Что будет в материале

  1. 01

    Короткий ответ: да, схема рабочая, и почти всё уже написано

  2. 02

    Готовые open-source проекты для локального голосового ассистента

  3. 03

    STT: чем распознавать речь локально

  4. 04

    TTS и LLM: как ассистент отвечает и понимает команды

Короткий ответ: да, схема рабочая, и почти всё уже написано

Архитектура «тонкие клиенты на ESP32 в комнатах плюс один сервер, который делает всю тяжёлую работу» это ровно то, как устроены зрелые open-source проекты для локального голосового ассистента. Писать с нуля не придётся.

Стартовая точка, закрывающая задачу целиком, это Home Assistant с голосовым пайплайном. Сервер принимает аудио от ESP32-устройств, прошитых ESPHome, распознаёт речь моделью Whisper, понимает команду и отвечает голосом Piper. Каждый модуль подключается по протоколу Wyoming, поэтому STT и TTS меняются на другие без переписывания логики. Рядом стоят Willow, заточенный под ESP32-S3-BOX и низкую задержку, OpenVoiceOS с модульной архитектурой и меньшим сообществом, а также Rhasspy, чьи компоненты в значительной степени перешли в экосистему Home Assistant.

Компромисс, который разумно принять сразу: задержка и качество ответов зависят от сервера, а не от микроконтроллера. ESP32 не потянет ни STT, ни LLM, ни TTS, и не должен. Его работа - снять звук с микрофона по I2S, отправить на сервер и воспроизвести то, что сервер вернул. Дешёвый и надёжный аудиотерминал, вся нагрузка ложится на машину с GPU.

Решения «поставил и работает за пять минут» нет. Настройка Home Assistant, аддонов и YAML-конфигов для ESPHome займёт время, особенно если нужен русский язык на входе и на выходе.

Что именно описано в исходном запросе и почему это стандартная архитектура

Запрос на Reddit сформулирован в этих же терминах. Пользователь /u/SaturnsVoid хочет собрать домашнего ассистента уровня Alexa, который не отправляет данные в чужое облако, и предлагает поставить ESP32 с динамиками и микрофонами в комнатах, а обработку AI отдать центральному серверу (обсуждение в r/LocalLLaMA). Он не уверен, что такой проект уже существует, но не считает задачу слишком сложной.

Оценка справедливая. Схема повторяет то, что делают Espressif и сообщество Home Assistant: устройство в комнате выполняет только ввод и вывод звука, а распознавание, генерация ответа и синтез идут на сервере. Опыт с локальными LLM у автора запроса уже есть, он использует модели вроде Qwen3.8-27B для помощи в программировании, а с голосовыми моделями не работал (исходный тред). Позиция удачная: самая дорогая по ресурсам часть стека знакома, добавить нужно STT, TTS, wake word и оркестрацию.

Готовые open-source проекты для локального голосового ассистента

Home Assistant + Wyoming: самый практичный путь

Home Assistant чаще воспринимают как платформу для умного дома, но внутри есть полноценный голосовой пайплайн. Он разбивает задачу на три шага: определение активации (wake word), распознавание речи и синтез ответа. Каждый шаг это отдельный сервис, который общается с ядром по протоколу Wyoming. Whisper меняется на Vosk, Piper на другой синтезатор, автоматизации остаются на месте.

Сборка выглядит так: на сервере поднимаются аддоны Whisper для STT, Piper для TTS и openWakeWord для активации. ESP32-устройства прошиваются ESPHome voice assistant, который стримит аудио на сервер и проигрывает ответ. Конфигурация устройства это YAML-файл, код на C++ писать не нужно.

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

Willow и другие нишевые проекты

Willow это отдельный проект для ESP32-S3-BOX, который делает ставку на низкую задержку и локальную обработку. Он проще и легче Home Assistant, но менее гибок: расширять сценарии сложнее, чем в HA-автоматизациях.

OpenVoiceOS даёт больше контроля над каждым этапом и явно ориентирован на офлайн-работу, но требует больше ручной настройки. Rhasspy исторически развивался как самостоятельный офлайн-ассистент, сейчас его наработки и модели живут внутри экосистемы Home Assistant.

Общий риск нишевых проектов: темп разработки зависит от нескольких человек, и через пару лет репозиторий может заглохнуть. Для системы, которая должна работать годами, Home Assistant даёт лучшую страховку.

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

STT: чем распознавать речь локально

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

Whisper, faster-whisper и whisper.cpp: что выбрать

Оригинальный Whisper от OpenAI остаётся эталоном качества на множестве языков, включая русский, но требует PyTorch и заметно нагружает память. faster-whisper переписывает инференс на CTranslate2: те же веса, но быстрее, с поддержкой int8-квантизации, что позволяет держать модели уровня small и medium на CPU. whisper.cpp это минимальный C++-порт без Python-зависимостей, он хорошо идёт на CPU и Apple Silicon и удобен для встраивания в собственный сервис.

Уровни tiny и base дают много ошибок на русском, и морфология языка это усугубляет. Модели small и medium - разумный старт для дома, large имеет смысл, если на сервере есть GPU с запасом VRAM.

Для потоковой работы нужен детектор речевой активности (VAD). Whisper обрабатывает аудио окнами, и без VAD он будет либо резать фразу посреди слова, либо ждать лишнюю тишину. Модель вроде silero-vad определяет начало и конец реплики и отдаёт в STT готовый фрагмент, это напрямую снижает задержку. Отдельная проблема качества ASR: модель может пропустить ключевое слово, и вся цепочка дальше пойдёт не туда (разбор барьеров голосового AI).

Vosk и Silero: когда они уместны

Vosk распознаёт речь потоково и работает на слабом железе, включая одноплатные компьютеры. Есть русская модель, требования к RAM низкие. Плата за это - заметно больший WER, чем у Whisper средних размеров. Если сервер слабый или нужна минимальная задержка на коротких командах, Vosk оправдан.

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

ВариантГде работаетСильная сторонаОграничение
Whisper (оригинал)GPU, частично CPUВысокое качество, много языковPyTorch, высокий расход памяти
faster-whisperCPU и GPUБыстрее, int8-квантизацияТребует CTranslate2
whisper.cppCPU, Apple SiliconБез Python, легко встроитьМеньше готовых серверных обвязок
VoskCPU, слабое железоПотоковое распознавание, малые требованияТочность ниже Whisper
Silero STTCPUОриентация на русский языкМеньше примеров и интеграций

TTS и LLM: как ассистент отвечает и понимает команды

Piper против Coqui/XTTS

Piper это лёгкий нейросетевой синтезатор. Работает на CPU, генерирует звук быстрее реального времени, имеет русские голоса и подключается к Home Assistant как Wyoming-сервис. Для диалога, где важен отклик, это выбор по умолчанию.

Coqui TTS и XTTS звучат естественнее, умеют клонировать голос по короткому образцу, но требуют GPU и заметно больше времени на генерацию. Для ответов в пару предложений разница в задержке чувствуется сразу. Если задача другая, например озвучка длинных текстов, критерии выбора смещаются (как выбирать TTS с эмоциями и интонациями).

Зачем нужен intent-слой поверх LLM

LLM генерирует текст, а не управляет устройствами. Чтобы фраза «включи свет в спальне» привела к действию, нужен слой, который превращает текст в вызов функции. В Home Assistant это intents: набор предопределённых команд с параметрами (сущность, область, значение). Такой парсер срабатывает быстро и предсказуемо, для типовых команд его достаточно.

Для сложных запросов подключают LLM: Ollama или llama.cpp запускают Qwen либо Llama локально, а function calling (tool use) позволяет модели вернуть вызов инструмента с аргументами. Сервер проверяет и исполняет этот вызов.

Здесь кроется главная опасность. LLM галлюцинирует: может «вызвать» несуществующее устройство, перепутать комнату или придумать команду, которой нет. Нужен валидирующий слой, который проверяет, что сущность существует и действие допустимо. Без него ассистент начнёт уверенно сообщать о выполненных действиях, которых не было.

Роли распределяются так: STT распознаёт реплику, intent-парсер обрабатывает простые команды, LLM с инструментами берёт сложные вопросы, TTS озвучивает результат. Каскад из отдельных моделей предсказуемее и проще в отладке, чем end-to-end voice-to-voice (разбор каскадной архитектуры Parlor v2).

Требования к серверу: сколько железа реально нужно

Нагрузка распределяется неравномерно. STT на Whisper это самый тяжёлый этап по вычислениям, особенно на длинных фразах. LLM основной потребитель VRAM. TTS на Piper почти незаметен в общей картине.

Ориентиры по железу, которые разумно воспринимать как отправную точку, а не как гарантию: 8-12 ГБ VRAM хватает на Whisper уровня medium вместе с LLM 7-14B в 4-битной квантизации; 16-24 ГБ позволяют держать Whisper large и модель класса 27B одновременно. Сценарий без GPU возможен на faster-whisper small и LLM 7B в Q4, но задержка вырастет, и ответ придёт через несколько секунд после вопроса. Apple Silicon хорошо работает с whisper.cpp и Ollama за счёт объединённой памяти, однако тяжёлые модели упираются в её пропускную способность.

Qwen3.8-27B, на которой автор запроса уже работает, сама занимает солидный кусок VRAM. Если сервер одновременно занят код-ассистентом, место под Whisper придётся планировать заранее: держать модели в разной квантизации, выгружать неиспользуемые или ставить вторую GPU.

Точные цифры задержки зависят от модели, квантизации, длины реплики и железа. Разбор конкретных связок ASR, LLM и TTS с привязкой к 12, 16 и 24 ГБ VRAM есть в отдельном материале (что реально запустить на 12-24 ГБ VRAM).

Где узкое место: STT, LLM или TTS

Если ассистент тормозит, смотреть надо в таком порядке: сначала STT на длинных фразах, затем LLM на генерации ответа, TTS в конце, он почти никогда не ограничивает. Whisper обрабатывает аудио окнами, поэтому задержка растёт вместе с длиной реплики.

Воспринимаемую задержку снижают несколькими приёмами: VAD отрезает тишину и отправляет в модель только речь; стриминг позволяет начинать распознавание, не дожидаясь конца фразы; короткий системный промпт и ограничение длины ответа ускоряют LLM; синтез по предложениям даёт услышать первую часть ответа, пока генерируется остальное.

Железо и прошивки для ESP32-устройств

Брать стоит ESP32-S3: у него больше оперативной памяти и поддержка PSRAM, что важно для аудиобуферов и локального распознавания активации. Обычный ESP32 тоже умеет I2S, но запаса меньше, и уместить на нём всё сразу сложнее.

ESP32-S3-BOX и Korvo: готовые решения

ESP32-S3-BOX-3 это официальный dev-kit Espressif с микрофонами, динамиком и экраном. Аудиоцепочка разведена, эхо-подавление решено на уровне железа и прошивки, есть поддержка в ESPHome и Willow. Серия ESP32-S3-Korvo делает акцент на звуке: аудиокодек, несколько микрофонов и разъёмы под динамики.

Самосбор дешевле: цифровой I2S-микрофон (INMP441 или ICS-43434), усилитель MAX98357A, динамик. Аналоговые модули вроде MAX9814 тоже используют, но им нужен АЦП, и качество записи обычно скромнее. В ESPHome такой набор описывается YAML-конфигом с указанием пинов I2S.

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

ВариантЧто внутриКому подходит
ESP32-S3-BOX-3Микрофоны, динамик, экран, готовая аудиоцепочкаМинимум пайки и настройки
ESP32-S3-KorvoАудиокодек, микрофоны, разъёмы под динамикиАкцент на качестве звука
Самосбор на ESP32-S3I2S-микрофон INMP441 или ICS-43434, усилитель MAX98357A, динамикДешевле, но нужна отладка AEC

Wake word: где его запускать

openWakeWord работает на сервере: гибкий движок, позволяет обучить собственную фразу активации, но каждое устройство гонит аудио потоком на сервер. microWakeWord исполняется прямо на ESP32-S3: устройство просыпается локально и отправляет дальше только саму команду. Это экономит трафик, разгружает сервер и повышает приватность.

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

Насколько это сложно на самом деле: честная оценка

Сложность раскладывается на три уровня, и они сильно отличаются по трудозатратам.

Что можно сделать за выходные, а что займёт недели

Уровень 1. Home Assistant, аддоны Whisper и Piper, один ESP32-S3-BOX, прошитый через ESPHome. Базовые команды и голосовые ответы заработают после настройки Docker и YAML. Основное время уходит на конфигурацию, а не на код.

Уровень 2. Свой wake word, русские модели STT и TTS, тонкая настройка VAD, подключение LLM с инструментами. Здесь уже нужно отлаживать аудио: подбирать пороги активации, смотреть, где теряются слова, проверять, как модель выбирает инструменты.

Уровень 3. Самосбор устройств с эхо-подавлением, несколько комнат с согласованной работой, реакция на прерывание. Это инженерная задача с отладкой на реальном железе и в реальном шуме.

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

Опыт с локальными LLM сокращает путь заметно: запуск моделей, квантизация, расход VRAM уже знакомы, а это половина стека. Новое здесь аудио: буферизация, VAD, эхо-подавление и синхронизация устройств.

Отладку удобно вести поэтапно: сначала проверить STT на записанном файле, затем добавить TTS, потом LLM, и только после этого собирать всё вместе. Как превратить работающее демо в стабильную систему с логами и воспроизводимыми проверками, разобрано отдельно (путь от демо к продакшену голосового AI).

Приватность и что вы теряете по сравнению с Alexa

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

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

Практические меры для домашней сети: держать сервер и ESP32 в отдельном VLAN, не публиковать Home Assistant напрямую в интернет (доступ через VPN), включить шифрование API в ESPHome, чтобы трафик между устройствами не читался в открытой Wi-Fi-сети.

Разумный первый шаг: поднять Home Assistant, подключить Whisper уровня small и Piper, прошить один ESP32-S3-BOX и прогнать десяток своих команд. Это даст честную картину задержки и точности на вашем железе. Расширять систему на все комнаты стоит после того, как один узел заработает стабильно.

Подписаться на канал