Локален гласов асистент на български: STT → LLM → TTS
Как правим гласов асистент, който чува, мисли и говори на български — на собствен сървър. От малкото устройство с микрофон през частна VPN връзка до веригата реч → текст → езиков модел → реч, плюс настройките, без които асистентът мълчи или отговаря на китайски.
bg_BG-dimitar-medium.
Числата в таблицата с паметта са видеопамет (VRAM), не RAM.
Не цитираме измерени числа, които нямаме: нито грешка на разпознаването за български, нито точно време за отговор. Времето на студен старт е наше наблюдение, не измерване.
Добавихме: Speech-to-Phrase няма български; предупреждение, че бекендът не е пригоден за отворен интернет; етикет (⚠️) върху всичко, което не успяхме да потвърдим в публична документация.
01Какво ще научиш
- Как изглежда веригата реч → текст → езиков модел → реч и кой инструмент е за коя част.
- Защо понякога между устройството и сървъра трябва мост и как да го направиш безопасно.
- Кои настройки са задължителни, за да не мълчи асистентът и да не отговаря на грешен език.
- Кое от веригата е истински локално и кое е облачна услуга под друго име.
- Какъв е алтернативният път през Home Assistant.
02Преди да започнеш
- Сървър с видеокарта (GPU) и Docker — моделите живеят във видеопамет (VRAM), не в обикновената RAM.
- Малко устройство с микрофон и говорител, например платка с ESP32-S3, работеща с проекта xiaozhi-esp32.
- Частна VPN връзка, ако устройството и сървърът са в различни мрежи.
- Готовност да сверяваш настройките с документацията на проекта — той се развива бързо.
03Стъпки
-
Архитектура: защо има релей
Устройството често е на едно място (вкъщи), а сървърът с моделите — на друго (офис). Те не се виждат директно. Решението е частна VPN връзка плюс малък релей на постоянно включена машина (например socat контейнер), който препраща връзката. Така устройството говори с един адрес, а релеят я пренасочва по VPN към сървъра.
схемаустройство (микрофон + говорител) → релей на малка машина → частна VPN връзка → сървър: реч → текст (STT) → езиков модел (LLM) → текст → реч (TTS) → обратно към устройството⛔Не към отворения интернетПроектът xiaozhi-esp32-server сам предупреждава, че не е минал проверка за мрежова сигурност и не е за производствена среда. Държи го само зад частната VPN връзка — не публикувай порта му в интернет. -
Веригата на сървъра
Всичко е в контейнери (
--network host,restart unless-stopped). Оркестраторът свързва трите части и чете един конфигурационен файл.Роля Инструмент Бележка Оркестратор xiaozhi-esp32-server 🔒 локално свързва STT, LLM и TTS; чете data/.config.yamlРеч към текст (STT) speaches + faster-whisper large-v3 🔒 локално сървър, съвместим с API на OpenAI; език bgЕзиков модел (LLM) Ollama с gemma3 (27b) 🔒 локално не qwen3 — виж капаните Текст към реч (TTS) Piper, глас bg_BG-dimitar-medium🔒 локалномалка обвивка: текстът влиза през STDIN, излиза WAV Топлене скрипт-пинг към модела keep_alive: -1на всеки ~240 s → моделът стои във VRAMТопленето е наше наблюдение: без него първият въпрос след пауза чака 15–30 секунди, докато моделът се зареди. Не е измерване — провери при себе си (⚠️).
bash · проверка и подготовка# кои контейнери работят (филтрирай по имената на твоите услуги) docker ps --format '{{.Names}}\t{{.Status}}' # адрес за активиране на устройството (завършващият слаш е задължителен) http://<адрес-на-релея>:<порт>/xiaozhi/ota/ # свали STT модела предварително, иначе първата заявка върна 500 — официалният начин по документацията на speaches curl -X POST "http://<stt-сървър>:<порт>/v1/models/Systran/faster-whisper-large-v3" # провери, че е свален curl "http://<stt-сървър>:<порт>/v1/models" -
Задължителни настройки (и защо)
Конфигурационният файл
data/.config.yamlсе качва със scp, не през heredoc — в нашата проба heredoc счупи кирилицата. Настройките долу не са по избор: без тях асистентът мълчи или говори на грешен език. Опциите съществуват в документацията на проекта; поведението е от нашата проба (⚠️).⚠️Intent = nointentИначе оркестраторът праща на модела описания на инструменти → gemma3 връща „400 does not support tools“ → асистентът мълчи.nointentе режим „без разпознаване на намерение“ — връща се директно отговорът на разговора.⚠️Memory = nomemЛокалният модул за кратка памет в нашата проба искаше облачен ключ и се срина на кирилица. Изключи паметта на оркестратора (nomem) и ако ти трябва памет, добави я отделно.⚠️language — вътре в TTS блокаИначе моделът отговаря на КИТАЙСКИ. В нашата проба оркестраторът четеше езика само отTTS.<блок>.language— сложи го точно там.✅gemma3, не qwen3qwen3 изговаря на глас собствения си<think>блок. Ползвай gemma3.yaml · data/.config.yaml (само задължителните ключове)# качи през scp, НЕ през heredoc selected_module: Intent: nointent Memory: nomem LLM: <блок-на-езиковия-модел> TTS: <блок-на-tts> TTS: <блок-на-tts>: language: "Bulgarian (български)"bash · качване и рестартscp data/.config.yaml <потребител>@<сървър>:<папка-на-проекта>/data/.config.yaml docker restart <контейнер-на-оркестратора> -
Реалността на TTS и STT: кое е локално
🌐edge-tts не е локаленБиблиотеката edge-tts вика онлайн услугата на Microsoft 🌐 облачен. В нашите проби безплатният ѝ ендпойнт периодично се блокираше — минахме на локален Piper с глас dimitar (мъжки) 🔒 локално. Женски български глас още не сме решили: XTTS-v2 няма български, а MMS-TTS за български е само кандидат, който не сме пробвали (⚠️).⚠️STT иска пред-сваляне и записваем кешМоделът трябва да е свален предварително, а кешът му — записваем (контейнерът като root плюс именуван том). Иначе първата заявка върна 500.🇧🇬Какво поддържа Home Assistant на българскиПо таблицата на езиците на Home Assistant: Whisper — да, Piper — да, Speech-to-Phrase — не. Затова за реч към текст на български Whisper е единственият локален избор.Не цитираме процент грешки при разпознаването: за български нямаме собствено измерване, а публичната документация на Whisper показва грешките по езици само като графика. Мери с твоя микрофон и в твоята стая.
-
Алтернативен път: Home Assistant Assist
Устройството може да е и сателит на Home Assistant Assist (ESPHome): Whisper → езиков модел през Home Assistant → Piper, без препрограмиране на оригиналния фирмуер. Капан: вграденият микрофон на платката може да иска инициализация на аудио кодека (при нашата платка — ES8311/ES7210) — фирмуерът на производителя я прави, нашата ESPHome конфигурация не я направи. Пълният път е в Обучение 2 · Локално гласово управление с Whisper.
04Проверка
1. Защо между устройството и сървъра има релей по частна VPN връзка?
2. Ако настройката за език не е в TTS блока, какво става (в нашата проба)?
3. Защо е нужно Intent: nointent?
4. Какво е вярно за edge-tts?
05Какво следва
06Източници
- xiaozhi-esp32-server — оркестраторът; README описва поддържаните Ollama, OpenAI-съвместим ASR, режимите
nointentиnomem, EdgeTTS и предупреждението за производство. - speaches — OpenAI-съвместим сървър за STT и TTS (faster-whisper, Piper, Kokoro); Model Discovery — как се сваля модел (
POST /v1/models/…). - Piper: глас bg_BG-dimitar-medium — българският глас.
- Piper — двигателят за текст към реч.
- faster-whisper — по-бързата реализация на Whisper.
- Ollama: gemma3 — езиковият модел.
- edge-tts — библиотеката, която вика онлайн услугата на Microsoft.
- Home Assistant: таблица на езиците — поддръжка на български (Whisper, Piper; не Speech-to-Phrase).
- Собствени проби на КАГАМИ — наблюденията за настройките и гласовете; не са измервания.