initial: silero-tts-service + README

This commit is contained in:
Никита Тарасов committed 2026-08-24 21:28:44 +05:00
1 parent 8c60c25ad2
commit 984b1fec6d
18 files changed
+2080

No files matched your search

+204
View File
@@ -0,0 +1,204 @@
# Silero TTS API
REST-сервис синтеза русской речи. Silero v5.5 + автостресс + GPU/CPU.
Пайплайн-совместимый CLI + интеграция с HyperFrames для генерации видео.
## ⚡ Быстрый старт
### Способ 1: CLI (рекомендуется)
```bash
# Проверка
python3 tts.py health
# Голоса
python3 tts.py voices
# Синтез в файл
python3 tts.py speak "Привет, мир!" --voice xenia --output hello.wav
# Гиперфреймс: аудио для видео + HTML-сниппет
python3 tts.py hyperframes "Текст озвучки" --voice xenia -o narration.wav
```
### Способ 2: HTTP API
```bash
# OpenAI-совместимый
curl -X POST http://localhost:8001/v1/audio/speech \
-H "Content-Type: application/json" \
-d '{"model":"tts-1","input":"Привет, мир!","voice":"xenia","response_format":"wav"}' \
--output hello.wav
# Нативный Silero
curl -X POST http://localhost:8001/v1/tts \
-H "Content-Type: application/json" \
-d '{"text":"Привет, мир!","speaker":"xenia"}' \
--output hello.wav
```
### Способ 3: Запуск сервера
```bash
# Локально (порт 8001)
pip install -e .
cp .env.example .env
python3 run.py
```
```bash
# Docker GPU
docker compose up --build -d
# Docker CPU
docker compose -f docker-compose.yml -f docker-compose.cpu.yml up --build -d
```
## 📝 API
### `POST /v1/tts`
```bash
curl -X POST http://localhost:8001/v1/tts \
-H "Content-Type: audio/wav" \
-H "Content-Type: application/json" \
-d '{"text": "Привет, мир!", "speaker": "aidar"}' \
-o output.wav
```
### `GET /v1/voices`
Голоса (v5_ru): `aidar`, `baya`, `kseniya`, `xenia`, `eugene`
> Примечание: модель v5_5_ru поддерживает 10+ голосов (irina, ruslan, natasha и др.).
> Для переключения на v5_5_ru нужно скачать модель и обновить config.py.
### `GET /health`
Проверка загрузки модели
## 📊 Мониторинг
### `GET /metrics`
Prometheus метрики:
- `tts_requests_total` — запросы по endpoint/status
- `tts_synthesis_seconds` — задержка синтеза (гистограмма)
- `tts_audio_size_bytes` — размер аудио (гистограмма)
- `tts_errors_total` — ошибки по типу
```bash
curl http://localhost:8001/metrics
```
## 🚦 Rate Limiting
| Endpoint | Лимит |
|----------|-------|
| POST /v1/tts | 30 req/min на IP |
| POST /v1/tts-stream | 10 req/min на IP |
Превышение → HTTP 429 с JSON detail.
## 🎙️ Streaming
### `POST /v1/tts-stream`
Синтез в MP3 192kbps (chunked transfer).
- Голос: только `aidar`
- Макс: 500 символов
- Content-Type: `audio/mpeg`
```bash
curl -X POST http://localhost:8001/v1/tts-stream \
-H "Content-Type: application/json" \
-d '{"text": "Тест стриминга", "speaker": "aidar"}' \
-o output.mp3
```
## 🔧 Режимы
| Режим |DEVICE|Скорость/100 слов|Память|Голоса|
|-------|------|----------------|------|------|
| GPU | `cuda:0` | 0.5–1s | 2.5 GB VRAM | 5 голосов (v5_ru) |
| CPU | `cpu` + JIT | 2–4s | RAM | 5 голосов (v5_ru) |
| CPU | `cpu` + 8 threads | 1.5–3s | RAM | 5 голосов (v5_ru) |
## 📋 Чек-лист готовности
- [x] Автоопределение GPU
- [x] CPU-режим с JIT
- [x] CORS middleware
- [x] Request logging
- [x] Валидация текста
- [x] Валидация голоса
- [x] WAV response (не JSON)
- [x] LRU-кэш
- [x] Graceful shutdown
- [x] Docker GPU/CPU
- [x] .gitignore
- [x] 16 unit-тестов
- [x] Prometheus метрики
- [x] Rate limiting
- [x] Streaming TTS
- [x] Multiple speakers (5 голосов: aidar, baya, kseniya, xenia, eugene)
## 📁 Структура
```
tts.py ← CLI-инструмент (speak, pipe, hyperframes, health, voices)
app/
main.py — FastAPI + lifespan + CORS + metrics endpoint
api.py — Роуты /v1/tts, /tts-stream, /voices, /health, /v1/audio/speech
engine.py — Загрузка моделей (GPU/CPU)
pipeline.py — Синтез (async + executor)
validators.py — Валидация текста/голоса (изолирована)
metrics.py — Prometheus метрики + rate limiter
config.py — Настройки (.env)
tests/
test_validation.py — 16 тестов валидации
test_api.py — Тесты API (mock)
```
## 🎬 Интеграция с HyperFrames
```bash
# 1. Сгенерировать аудио и HTML-сниппет
python3 tts.py hyperframes "Добро пожаловать в HyperFrames — пиши HTML, получай видео" \
--voice xenia -o narration.wav
# Вывод:
# ✅ Аудио: narration.wav (84.2 KB, 5.12 сек)
#
# ─── HTML-сниппет для HyperFrames ───
# <audio id="narration"
# data-start="0"
# data-duration="5.1"
# data-track-index="0"
# data-volume="1.0"
# src="narration.wav">
# </audio>
```
Вставить сниппет в `index.html` композиции и отрендерить:
```bash
npx hyperframes preview # предпросмотр
npx hyperframes render --output demo.mp4 # рендер
```
## 🔄 Пайплайны
```bash
# Конвейер: stdin → TTS → stdout
echo "Текст для озвучки" | python3 tts.py pipe --voice aidar > output.wav
# JSON-вывод для API-интеграций
python3 tts.py speak "Текст" --json | jq '.audio_base64' | base64 -d > output.wav
# Пакетная обработка (Python)
python3 -c "
import subprocess, json, base64
sentences = ['Фраза 1.', 'Фраза 2.', 'Фраза 3.']
for i, s in enumerate(sentences):
r = subprocess.run(['python3', 'tts.py', 'speak', s, '--voice', 'xenia', '--json'], capture_output=True, text=True)
data = json.loads(r.stdout)
with open(f'chunk_{i:03d}.wav', 'wb') as f:
f.write(base64.b64decode(data['audio_base64']))
"
```