From a73cd82ab5c01baacd787b238e37fa0624b63d68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CNaeel=E2=80=9D?= Date: Fri, 22 May 2026 14:13:50 +0400 Subject: [PATCH] v39: Whisper proxy via Flask+gunicorn, blobToWav revert, syllabification, isAnalyzing flag, timing logs --- doc/ARCHITECTURE.md | 103 +++++++++++++ index.html | 345 +++++++++++++++++++++++++++++++++----------- 2 files changed, 363 insertions(+), 85 deletions(-) create mode 100644 doc/ARCHITECTURE.md diff --git a/doc/ARCHITECTURE.md b/doc/ARCHITECTURE.md new file mode 100644 index 0000000..56478bd --- /dev/null +++ b/doc/ARCHITECTURE.md @@ -0,0 +1,103 @@ +# Lyngvo — архитектура и инфраструктура + +## Что это + +Одностраничное веб-приложение (SPA) для тренировки итальянского произношения. +URL: `https://capire.kube5s.ru` + +--- + +## Стек + +| Компонент | Технология | +|---|---| +| Frontend | Single HTML file (`index.html`), vanilla JS, Web Audio API | +| Хостинг | Kubernetes (kube5s), namespace `default`, deploy `lyngvo` | +| Конфиг | ConfigMap `lyngvo-html` (index.html) + `lyngvo-nginx` (nginx.conf) | +| Ingress | `capire.kube5s.ru` | +| AI: распознавание речи | Groq Whisper (`whisper-large-v3`) | +| AI: перевод | Groq LLaMA (`llama-3.3-70b-versatile`) | +| TTS | Groq TTS (через тот же прокси) | + +--- + +## Groq API прокси + +Groq API заблокирован в России. Все запросы идут через немецкий сервер. + +``` +Браузер (Россия) + → HTTPS → proxy.kube5s.ru (Германия, 95.179.252.111) + nginx (TLS termination, port 443) + → localhost:8765 (Python HTTP сервер) + → HTTPS → api.groq.com +``` + +### Компоненты на немецком сервере + +| Файл/сервис | Назначение | +|---|---| +| `/opt/groq-proxy/proxy.py` | Python HTTP сервер, универсальный форвардер | +| `groq-proxy.service` (systemd) | Автозапуск proxy.py | +| `/etc/nginx/conf.d/groq-proxy.conf` | TLS + проброс на localhost:8765 | +| Let's Encrypt cert | `proxy.kube5s.ru` | + +**Почему Python, а не nginx proxy_pass:** +nginx не может надёжно проксировать большие multipart/form-data (аудио) в Groq/Cloudflare — соединение обрывается с 408/502. Python `requests` делает нормальный HTTP-запрос от имени сервера. + +--- + +## Деплой + +```bash +bash ~/lang/deploy_lang.sh +``` + +Что делает скрипт: +1. Читает Groq API ключ из `~/lang/token.txt` +2. Вшивает ключ в `index.html` через `sed` (в HTML ключ всегда пустая строка) +3. rsync всей папки на ВМ (`5.172.178.213`) +4. `kubectl apply` configmap + deployment + ingress +5. `kubectl rollout restart deploy/lyngvo` + +**Groq ключ** хранится только в `~/lang/token.txt` (в `.gitignore`), в репо не коммитится. + +--- + +## Файлы репо + +``` +index.html — вся логика приложения (один файл) +deploy_lang.sh — скрипт деплоя +nginx.conf — конфиг nginx внутри k8s пода +k8s/ + deployment.yaml — Deployment + Service + ingress.yaml — Ingress capire.kube5s.ru +token.txt — Groq API ключ (в .gitignore) +doc/ + ARCHITECTURE.md — этот файл +``` + +--- + +## Что живёт внутри index.html + +- `VERSION` — строка версии, отображается в заголовке +- **phoneticAnalysis(blob)** — фонетический анализ аудио через Web Audio API (pitch, стабильность, артикуляция, качество окончания) +- **transcribe(blob)** — отправка аудио в Groq Whisper, возвращает распознанный текст +- **translateToRussian(text)** — перевод через Groq LLaMA +- **doCompare(blob, text, duration)** — параллельный запуск transcribe + phoneticAnalysis, формирует результат +- **История записей** — IndexedDB (`lyngvo_recs`), кнопки ▶ / 🎧 / 📊 / 🗑 +- **История фраз** — localStorage, последние 5 фраз + +--- + +## SSH доступ + +```bash +# ВМ (Kubernetes) +ssh -i ~/.ssh/naeel_vm_id_ed25519 -o StrictHostKeyChecking=no naeel@5.172.178.213 + +# Немецкий сервер (Groq прокси) +ssh -i ~/.ssh/vultr_openssh -o StrictHostKeyChecking=no root@95.179.252.111 +``` diff --git a/index.html b/index.html index 7e47b65..4b56c5e 100644 --- a/index.html +++ b/index.html @@ -9,7 +9,7 @@