Files
story-generator/silero-tts-service/README.md
T

205 lines
6.1 KiB
Markdown
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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']))
"
```