first commit
This commit is contained in:
+124
@@ -0,0 +1,124 @@
|
||||
# BLIND — передаточный конспект (продолжение с другого компьютера)
|
||||
|
||||
Обновлён: 2026-09-11 (вечер). Читай этот файл первым — он заменяет всю историю чата.
|
||||
|
||||
## Что это за проект
|
||||
|
||||
Голосовой AI-ассистент для незрячего пожилого человека (отца юзера), живущий на ПК.
|
||||
Отец управляет ТОЛЬКО ГОЛОСОМ: говорит wake-word «Марта» → ассистент просыпается
|
||||
(куи «Ассистент готов к диалогу») → диалог → «до свидания» → куи «Спасибо, до новых
|
||||
встреч» и снова ждёт слова. Вне диалога микрофон слушает тихо и реагирует только на
|
||||
wake-word (фоновый ТВ/разговоры не будят — проверено).
|
||||
|
||||
## Архитектура (модули = законченные проверяемые единицы)
|
||||
|
||||
```
|
||||
микрофон → Silero-VAD (тишина 2с = конец фразы) → faster-whisper (STT, small/int8)
|
||||
→ OpenRouter (LLM: gemma-3-27b обычно / glm-5.3-flash:online для погоды-курсов-новостей)
|
||||
→ edge-tts (голос Svetlana, темп +15%) → стриминговая озвучка чанками-предложениями
|
||||
```
|
||||
|
||||
- `modules/stt/` — faster-whisper 1.2.1, small/int8/CPU, RTF ~0.15. Фолбэк: Vosk (не реализован).
|
||||
- `modules/tts/` — edge-tts 7.2.8 (Svetlana, TTS_RATE=+15) + офлайн-фолбэк piper 1.8.0
|
||||
(голоса в models/piper/: dmitri, irina — irina проверена, 0.21 c синтез). Фабрика `make_tts()` из .env.
|
||||
Параллельные запросы по предложениям + кэш коротких фраз → типичный ответ синтезируется 0.5 c.
|
||||
- `modules/tts/provider_edge.py` → `stream(text)` — генератор чанков-предложений
|
||||
( Assistant играет чанк сразу, не дожидаясь всего ответа).
|
||||
- `modules/audio_io/` — Recorder (push-to-talk резерв), HandsFreeRecorder (VAD-режим,
|
||||
pre-buffer 0.4 c, noise gate RMS>0.006, suppress во время собственной речи), Player
|
||||
(stop = «Замолчи» за 8 мс; lead_silence 0.1 c против съедания первого слова), codec (mp3 через PyAV).
|
||||
- `modules/brain/` — OpenRouter через openai-клиент (RF-нюансы: openai/* модели блокируются
|
||||
ToS OpenAI по аккаунту; прокси http://192.168.0.246:8887 → egress Италия 85.137.175.114).
|
||||
Маршрутизация online/offline: хинты (погод|курс|доллар|новост|спорт...) + контекст последних
|
||||
4 реплик + маркеры уточнения. Промпт: короткие ответы, НО стихи/сказки целиком, многочастность
|
||||
[ЧАСТЬ i ИЗ n] с продолжением по «дальше», на уточнения — ответ по существу без извинений.
|
||||
- `modules/assistant/` — машина состояний idle/listening/thinking/speaking, перебивание
|
||||
(поколенческий счётчик _generation), память между сессиями (data/memory.md, конспект по
|
||||
«до свидания»), куи-файлы (start/end/error/unclear), wake_word.py, errors.py (классификация).
|
||||
- `modules/hotkeys/` — бэкенды: console (readchar, пробел работает без Enter; Linux без root)
|
||||
и keyboard_hook (Windows, глобальные клавиши из любого окна). Wake-word — основной способ.
|
||||
|
||||
## Ключевые решения и грабли (обязательно прочти)
|
||||
|
||||
1. **Веб-поиск**: суффикс `:online` у OpenRouter (веб-плагин), НЕ свойство модели. Маршрутизация
|
||||
в `_needs_online(question, history)` — смотрит текущую фразу + историю + маркеры уточнения.
|
||||
Уточнение «я поэтому и спрашиваю...» после вопроса про акции → online-модель (фикс «извиняется, а не отвечает»).
|
||||
2. **GLM reasoning**: z-ai/glm-* тратят max_tokens на размышления → при малом бюджете content пустой.
|
||||
max_tokens=2000.
|
||||
3. **Silero-VAD**: только CPU-torch (GPU-пакеты 2.5 ГБ не нужны); модель принимает ТОЛЬКО torch.Tensor;
|
||||
на белом шуме даёт prob 0.86! → обязательный noise gate по RMS.
|
||||
4. **Колбэки рук**: Assistant присваивает recorder.on_phrase (публичный атрибут!) — не спрятать в _private,
|
||||
иначе фразы уходят в никуда (уже ловили).
|
||||
5. **Wake-word matching**: whisper ломает имена («Ага-то», «А гата», «Агад») → normalize склеивает дефисы,
|
||||
проверяется первое слово И склейка первых двух, обрубки-префиксы ок, но «мартовские» — нет (граница слова).
|
||||
6. **.env**: при добавлении строк через `>>` файл может не кончаться \n → строки склеиваются, ключ ломается.
|
||||
После любой записи в .env проверяй длину ключа (sk-or-v1 = 73 симв).
|
||||
7. **Стриминг**: Player.play() с lead_silence; чанки по 1 предложению; «Отвечаю...» печатается до синтеза.
|
||||
8. Сегфолты в смоук-тестах — из-за реального звука из нескольких потоков; в тестах глушить play/play_file.
|
||||
|
||||
## Конфиг (.env) — создаётся из .env.example
|
||||
|
||||
OPENROUTER_API_KEY (ключ юзера), OPENROUTER_PROXY=http://192.168.0.246:8887,
|
||||
OPENROUTER_MODEL=google/gemma-3-27b-it, OPENROUTER_MODEL_ONLINE=z-ai/glm-5.3-flash:online,
|
||||
TTS_PROVIDER=edge, TTS_VOICE=ru-RU-SvetlanaNeural, TTS_RATE=+15,
|
||||
PIPER_MODEL=models/piper/ru_RU-dmitri-medium.onnx, WAKE_WORD=марта,
|
||||
HOTKEY_DIALOG=space, HOTKEY_TALK=num 0, HOTKEY_STOP=esc, HOTKEY_REPEAT=enter.
|
||||
|
||||
## Окружение (на этой машине)
|
||||
|
||||
- .venv на python3.13 (Debian: venv без pip — ставить `python3 -m pip --python .venv install ...`).
|
||||
- torch 2.14.0+cpu, torchaudio 2.11.0+cpu (CPU-варианты!), silero-vad 6.2.1, faster-whisper 1.2.1,
|
||||
edge-tts 7.2.8, piper-tts 1.8.0, sounddevice 0.5.6 (Linux: нужен apt-пакет libportaudio2),
|
||||
keyboard 0.13.5, readchar 4.2.2, openai 3.13.0.
|
||||
- Модели: ~/.cache/huggingface (whisper small), models/piper/ (121 МБ).
|
||||
- Первый старт whisper качает модель ~460 МБ (если HF недоступен: HF_ENDPOINT=https://hf-mirror.com).
|
||||
|
||||
## Как запускать (проверенные команды)
|
||||
|
||||
```bash
|
||||
cd ~/cloud/AI/Blind
|
||||
source .venv/bin/activate # или .venv/bin/python напрямую
|
||||
|
||||
# Живой ассистент (wake-word «Марта», всё голосом):
|
||||
.venv/bin/python modules/assistant/test_free.py
|
||||
# «Марта» → диалог → «До свидания». Консоль: s/r/пробел/q (readchar, без Enter)
|
||||
|
||||
# Регресс модулей:
|
||||
.venv/bin/python modules/stt/test_stt.py --make-sample # STT
|
||||
.venv/bin/python modules/audio_io/test_audio_io.py auto # аудио
|
||||
.venv/bin/python modules/brain/test_brain.py clean # очистка MD (офлайн)
|
||||
.venv/bin/python modules/brain/test_brain.py ask # LLM
|
||||
.venv/bin/python modules/tts/test_tts.py --play # TTS
|
||||
|
||||
# Перегенерация куи (после смены голоса/темпа):
|
||||
.venv/bin/python assets/earcons/generate_cues.py --force
|
||||
```
|
||||
|
||||
## Пользовательские решения (зафиксировано)
|
||||
|
||||
- Голос: **edge-tts Svetlana, темп +15%** («женский приятный»); Piper dmitri/irina — фолбэк (быстрее, но не понравился темп/голос).
|
||||
- Wake-word: **«Марта»** (пробовали «Агата» — whisper искажал «Агад»).
|
||||
- Свободный режим принят: «значительно лучше, чем нажимать кнопки».
|
||||
- Тумблер диалога: пробел (дублируется wake-word), куи из готовых wav.
|
||||
|
||||
## ЧТО ДАЛЬШЕ (по порядку)
|
||||
|
||||
1. **Модуль 6: Telegram** — мост сын↔ассистент: сообщения юзера озвучиваются отцу
|
||||
(«Пришло сообщение от Александра: …»), отец отвечает голосом → в чат юзеру.
|
||||
Нужен токен бота (@BotFather → /newbot) → в .env TG_BOT_TOKEN. Библиотека aiogram 3.x
|
||||
(крутить в отдельном потоке; в edge-TTS уже учтён чужой event loop — _run_async).
|
||||
2. **Модуль 7: Earcons** — короткие музыкальные сигналы на статусы (думаю/готов/ошибка)
|
||||
вместо длинных фраз; ассистент уже вызывает on_state_change(state, note) — вешать на него.
|
||||
3. **Модуль 8: Сборка exe для Windows** — PyInstaller; глобальные клавиши (HOTKEY_* уже в .env);
|
||||
Silero-VAD заменить на ONNX-версию (2 МБ, без torch); тест на ПК отца.
|
||||
4. Хвосты: живой тест памяти «2 запуска» юзером; паузы между строфами стихов (по желанию).
|
||||
|
||||
## Известные открытые мелочи
|
||||
|
||||
- Стриминговый путь: история/конспект пополняются до стрима — маркер [ЧАСТЬ i ИЗ n] в
|
||||
_last_speech для «Повтори» не сохраняется из чанков (повтор последней ЧАСТИ, а не всего текста).
|
||||
- Веб-поиск медленный (5–10 c) — если раздражает, ускорять стримингом или мини-моделью.
|
||||
- edge-tts нестабилен исторически (неофициальный API MS) — фолбэк Piper готов, переключение 1 строкой в .env.
|
||||
- Vosk-фолбэк для STT не реализован (решение отложить до замеров на слабом ПК отца).
|
||||
- Развертывание A (монолит Windows) vs B (гибрид Docker) — НЕ выбрано окончательно; код кроссплатформенный,
|
||||
интерфейсы провайдеров позволяют вариант B (provider_http + FastAPI на сервере юзера).
|
||||
@@ -0,0 +1,98 @@
|
||||
# Анализ стека — интерфейс для незрячего (AI Blind)
|
||||
|
||||
Дата: 2026-09-10. Принцип: только бесплатные / open-source библиотеки, каждый модуль —
|
||||
законченная проверяемая единица. Целевая платформа — Windows (ПК отца), разработка — Linux/кроссплатформенный код.
|
||||
|
||||
---
|
||||
|
||||
## 1. Модуль STT (речь → текст)
|
||||
|
||||
| Кандидат | Версия | Лицензия | Русский | Скорость CPU | Комментарий |
|
||||
|---|---|---|---|---|---|
|
||||
| **faster-whisper** | 1.2.1 (окт 2025) | MIT | ✅ отлично | small/int8: 13 мин аудио ≈ 1 мин 42 с (i7-12700K) → короткая фраза 5 с ≈ 1–2 с | FFmpeg не нужен (PyAV внутри), Silero-VAD встроен, модель качается с HuggingFace автоматически |
|
||||
| Vosk | стабильная | Apache 2.0 | ✅ (small-ru 45 МБ WER ~22–30%, big-ru 1.8 ГБ WER ~5–11%) | быстрее Whisper, стриминг | Запасной вариант для слабого ПК; точность small ниже |
|
||||
| openai-whisper / transformers | — | MIT | ✅ | медленно на CPU | Не берём — быстрее-whisper строго лучше |
|
||||
|
||||
**Вердикт: faster-whisper**, модель `small` или `base` c `compute_type="int8"` на CPU.
|
||||
- Для голосовых фраз 2–15 с задержка 1–3 с — приемлемо.
|
||||
- Размер: small ≈ 460 МБ (int8 ~150 МБ в RAM), base ≈ 145 МБ.
|
||||
- Фолбэк: Vosk small-ru, если ПК отца слабый (замерим на Module 1 и решим).
|
||||
|
||||
## 2. Модуль TTS (текст → звук)
|
||||
|
||||
| Кандидат | Версия | Лицензия | Русский | Онлайн/офлайн | Комментарий |
|
||||
|---|---|---|---|---|---|
|
||||
| **edge-tts** | 7.2.8 (мар 2026) | LGPL | ✅ ru-RU-SvetlanaNeural / DmitryNeural | онлайн (бесплатный сервис MS, без ключа) | rate/volume/pitch настраиваются → «−15% скорости» из ТЗ поддерживается нативно |
|
||||
| **Piper** (`piper-tts`) | 1.8.0 (активно развивается, переехал в OHF-Voice/piper1-gpl) | GPL-3.0 | ✅ голоса ru_RU (denis, dmitri, irina, ruslan) | офлайн | Фолбэк: работает без интернета, быстрый на CPU |
|
||||
|
||||
**Вердикт: edge-tts основной + Piper фолбэк.** Риск edge-tts: неофициальный эндпоинт Microsoft,
|
||||
исторически ломался (403). Архитектура TTS-модуля сразу делается с интерфейсом «провайдер»,
|
||||
чтобы переключение на Piper было правкой конфига.
|
||||
|
||||
## 3. Модуль записи/воспроизведения звука
|
||||
|
||||
- **sounddevice 0.5.6** (авг 2026, свежий), MIT, PortAudio в комплекте, numpy-массивы.
|
||||
- Запись push-to-talk: буфер в RAM пока удерживается клавиша → float32/int16 → wav в памяти.
|
||||
- Воспроизведение: `sd.play()` / `sd.stop()` — мгновенная остановка для клавиши «Замолчи». Идеально.
|
||||
- soundfile — для сохранения wav при отладке.
|
||||
- **VAD: silero-vad 6.2.1** (фев 2026), MIT, ~2 МБ, <1 мс на чанк 30 мс, ONNX-режим.
|
||||
Использование: отрезать тишину перед STT (меньше галлюцинаций Whisper), позже — режим «свободного разговора».
|
||||
|
||||
## 4. Модуль горячих клавиш
|
||||
|
||||
| Кандидат | Статус | Windows | Suppression | Комментарий |
|
||||
|---|---|---|---|---|
|
||||
| **keyboard 0.13.5** | мёртв с 2020, но стабильный и широко используемый | ✅ глобальный хук без админ-прав | ✅ (только Windows) | Умеет press/hold/release события — ровно то, что нужно push-to-talk |
|
||||
| pynput | живой | ✅ | ❌ подавления нет | Запасной вариант |
|
||||
|
||||
**Вердикт: keyboard** (раскладка: дублируем NumPad и основные клавиши: Num0/Пробел — слушать,
|
||||
NumDel/Esc — замолчать, NumEnter/Enter — повторить). Риск: библиотека не развивается —
|
||||
при проблемах переходим на pynput или WinAPI-хук; API модуля изолируем.
|
||||
|
||||
## 5. Модуль «мозга» (LLM)
|
||||
|
||||
- **OpenRouter** через `openai`-совместимый клиент (base_url = https://openrouter.ai/api/v1) —
|
||||
без новых зависимостей. Модель выбирается в конфиге.
|
||||
- Очистка Markdown — собственный regex-модуль (звёздочки, решётки, списки, ссылки).
|
||||
- Системный промпт: «отвечай коротко, простыми предложениями, без списков и разметки» —
|
||||
это дешевле, чем чистка сложного текста.
|
||||
|
||||
## 6. Модуль Telegram
|
||||
|
||||
- **aiogram 3.x** (актуальная), отдельный asyncio-поток/задача.
|
||||
- События: входящее сообщение от сына → озвучка; ответ отца (надиктован через основной цикл) → отправка.
|
||||
|
||||
## 7. Прочее
|
||||
|
||||
- **Earcons** (звуковые маркеры): генерируем свои короткие wav (numpy → файлы в `assets/earcons/`),
|
||||
играем через sounddevice. Никаких внешних ассетов не нужно.
|
||||
- **Сборка для Windows**: PyInstaller → один exe. Проверим на Module 7.
|
||||
- **Конфиг**: TOML/JSON + `.env` для ключей (OPENROUTER_API_KEY, TG_BOT_TOKEN).
|
||||
|
||||
---
|
||||
|
||||
## Итоговый стек v1
|
||||
|
||||
```
|
||||
faster-whisper==1.2.1 # STT (fallback: vosk)
|
||||
edge-tts==7.2.8 # TTS (fallback: piper-tts==1.8.0)
|
||||
sounddevice==0.5.6 # запись/воспроизведение
|
||||
soundfile # wav I/O
|
||||
numpy # аудио-буферы, earcons
|
||||
silero-vad==6.2.1 # VAD (опционально)
|
||||
keyboard==0.13.5 # глобальные клавиши (Windows)
|
||||
openai (client) # OpenRouter
|
||||
aiogram>=3 # Telegram
|
||||
pyinstaller # упаковка exe (этап сборки)
|
||||
```
|
||||
|
||||
Python ≥ 3.9 (лучше 3.11/3.12). Все пакеты кроссплатформенные, разработку ведём здесь (Linux),
|
||||
деплой — на Windows (звук/клавиши тестируются там).
|
||||
|
||||
## Риски и смягчение
|
||||
|
||||
1. **edge-tts отвалится** → Piper фолбэк встроен в дизайн модуля.
|
||||
2. **keyboard мёртв** → работает сегодня; изоляция API, запасной pynput.
|
||||
3. **Whisper медленный на слабом ПК** → замер на Module 1; если плохо — Vosk small-ru.
|
||||
4. **Задержка пайплайна** STT→LLM→TTS ≈ 1+2+1 с → смягчаем: короткие фразы (base-модель,
|
||||
дешёвая быстрая LLM, edge-tts), звуковой маркер «думаю» сразу после отпускания клавиши.
|
||||
Reference in New Issue
Block a user