Знакът на КАГАМИ КАГАМИ
kagami.bg/academy · lesson · machine-readable viewVERIFIED 2026-10-01 · UPDATED 2026-10-01
IDENTITY
module
KW I10 · Local Bulgarian voice assistant: STT → LLM → TTS
series
KAGAMI Way · Track I — Infrastructure
level
Intermediate
duration
~10 min
trust_label
VERIFIED 2026-10-01 (project README, speaches docs, Bulgarian voice availability) · UPDATED 2026-10-01 · behavioural findings below come from our own internal trial (no test date recorded, so no TESTED label); items marked (unverified) could not be confirmed in public documentation
language
human view: bg · english edition: /en/academy/moduli/KW_I10_Voice_AI_Stack.html
prev
KW_I9_Video_Pipeline.html
next
KW_I11_Tailscale_Patterns.html · Private VPN patterns
PURPOSE

Run a Bulgarian voice assistant fully on your own server: speech-to-text (STT) → text LLM → text-to-speech (TTS). A small ESP32 device with a microphone and speaker talks to an open-source assistant backend; when the device and the server sit on different networks, a private VPN plus a plain TCP relay bridges them. The module covers the three engines, the mandatory configuration keys without which the assistant stays silent or answers in the wrong language, which parts are local and which are cloud services, and an alternative path through Home Assistant Assist.

KEY CONCEPTS
COMMANDS / PATHS
CHECKLIST
NEXT MODULE

KW_I11_Tailscale_Patterns.html · Private VPN patterns · offer: Quick experiment (kagami.bg/stalbata/)

SOURCES
TAGS
voice-assistantsttttslocal-llmpiperfaster-whisperollamabulgarianesp32vpn
ПРОВЕРЕНО · 01.10.2026 ОБНОВЕНО · 01.10.2026

Локален гласов асистент на български: STT → LLM → TTS

Как правим гласов асистент, който чува, мисли и говори на български — на собствен сървър. От малкото устройство с микрофон през частна VPN връзка до веригата реч → текст → езиков модел → реч, плюс настройките, без които асистентът мълчи или отговаря на китайски.

⏱ ~10 мин Средно Локален AI глас · STT · LLM · TTS
faster-whisper (реч към текст)🔒 локално Ollama + gemma3 (езиков модел)🔒 локално Piper (текст към реч)🔒 локално xiaozhi-esp32-server (оркестратор)🔒 локално edge-tts (само за сравнение)🌐 облачен — Microsoft
🔄
ОБНОВЕНО · 01.10.2026 — какво (обобщено)
Обобщихме урока за публикуване. Махнахме имената на машини, адресите, портовете и вътрешните пътища; връзката между устройството и сървъра е описана като общ модел (частна VPN връзка и прост релей). Вътрешното име на асистента не се споменава. Поправихме „локалния“ глас. edge-tts вика онлайн услугата на Microsoft — не е локален и е отбелязан с 🌐. Локалният глас е Piper с bg_BG-dimitar-medium. Числата в таблицата с паметта са видеопамет (VRAM), не RAM. Не цитираме измерени числа, които нямаме: нито грешка на разпознаването за български, нито точно време за отговор. Времето на студен старт е наше наблюдение, не измерване. Добавихме: Speech-to-Phrase няма български; предупреждение, че бекендът не е пригоден за отворен интернет; етикет (⚠️) върху всичко, което не успяхме да потвърдим в публична документация.
⚠️
Какво не сме потвърдили
Наблюденията за поведението на настройките (мълчане, китайски отговор, срив върху кирилица, студен старт) са от наша вътрешна проба, чиято дата не е записана — затова няма етикет „ТЕСТВАНО“. Тук е сверено с документацията: кои настройки съществуват, кои езикови модели и двигатели се поддържат, кой глас е български. Всичко, което не успяхме да потвърдим, е с (⚠️).

01Какво ще научиш

02Преди да започнеш

03Стъпки

  1. Архитектура: защо има релей

    Устройството често е на едно място (вкъщи), а сървърът с моделите — на друго (офис). Те не се виждат директно. Решението е частна VPN връзка плюс малък релей на постоянно включена машина (например socat контейнер), който препраща връзката. Така устройството говори с един адрес, а релеят я пренасочва по VPN към сървъра.

    схема
    устройство (микрофон + говорител)
       → релей на малка машина
       → частна VPN връзка
       → сървър:  реч → текст (STT)  →  езиков модел (LLM)  →  текст → реч (TTS)
       → обратно към устройството
    ⛔
    Не към отворения интернет
    Проектът xiaozhi-esp32-server сам предупреждава, че не е минал проверка за мрежова сигурност и не е за производствена среда. Държи го само зад частната VPN връзка — не публикувай порта му в интернет.
  2. Веригата на сървъра

    Всичко е в контейнери (--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"
  3. Задължителни настройки (и защо)

    Конфигурационният файл data/.config.yaml се качва със scp, не през heredoc — в нашата проба heredoc счупи кирилицата. Настройките долу не са по избор: без тях асистентът мълчи или говори на грешен език. Опциите съществуват в документацията на проекта; поведението е от нашата проба (⚠️).

    ⚠️
    Intent = nointent
    Иначе оркестраторът праща на модела описания на инструменти → gemma3 връща „400 does not support tools“ → асистентът мълчи. nointent е режим „без разпознаване на намерение“ — връща се директно отговорът на разговора.
    ⚠️
    Memory = nomem
    Локалният модул за кратка памет в нашата проба искаше облачен ключ и се срина на кирилица. Изключи паметта на оркестратора (nomem) и ако ти трябва памет, добави я отделно.
    ⚠️
    language — вътре в TTS блока
    Иначе моделът отговаря на КИТАЙСКИ. В нашата проба оркестраторът четеше езика само от TTS.<блок>.language — сложи го точно там.
    ✅
    gemma3, не qwen3
    qwen3 изговаря на глас собствения си <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 <контейнер-на-оркестратора>
  4. Реалността на 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 показва грешките по езици само като графика. Мери с твоя микрофон и в твоята стая.

  5. Алтернативен път: 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Източници

  1. xiaozhi-esp32-server — оркестраторът; README описва поддържаните Ollama, OpenAI-съвместим ASR, режимите nointent и nomem, EdgeTTS и предупреждението за производство.
  2. speaches — OpenAI-съвместим сървър за STT и TTS (faster-whisper, Piper, Kokoro); Model Discovery — как се сваля модел (POST /v1/models/…).
  3. Piper: глас bg_BG-dimitar-medium — българският глас.
  4. Piper — двигателят за текст към реч.
  5. faster-whisper — по-бързата реализация на Whisper.
  6. Ollama: gemma3 — езиковият модел.
  7. edge-tts — библиотеката, която вика онлайн услугата на Microsoft.
  8. Home Assistant: таблица на езиците — поддръжка на български (Whisper, Piper; не Speech-to-Phrase).
  9. Собствени проби на КАГАМИ — наблюденията за настройките и гласовете; не са измервания.