v39: Whisper proxy via Flask+gunicorn, blobToWav revert, syllabification, isAnalyzing flag, timing logs
This commit is contained in:
@@ -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
|
||||
```
|
||||
Reference in New Issue
Block a user