6.1 KiB
Executable File
6.1 KiB
Executable File
Silero TTS API
REST-сервис синтеза русской речи. Silero v5.5 + автостресс + GPU/CPU. Пайплайн-совместимый CLI + интеграция с HyperFrames для генерации видео.
⚡ Быстрый старт
Способ 1: CLI (рекомендуется)
# Проверка
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
# 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: Запуск сервера
# Локально (порт 8001)
pip install -e .
cp .env.example .env
python3 run.py
# 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
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/statustts_synthesis_seconds— задержка синтеза (гистограмма)tts_audio_size_bytes— размер аудио (гистограмма)tts_errors_total— ошибки по типу
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
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) |
📋 Чек-лист готовности
- Автоопределение GPU
- CPU-режим с JIT
- CORS middleware
- Request logging
- Валидация текста
- Валидация голоса
- WAV response (не JSON)
- LRU-кэш
- Graceful shutdown
- Docker GPU/CPU
- .gitignore
- 16 unit-тестов
- Prometheus метрики
- Rate limiting
- Streaming TTS
- 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
# 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 композиции и отрендерить:
npx hyperframes preview # предпросмотр
npx hyperframes render --output demo.mp4 # рендер
🔄 Пайплайны
# Конвейер: 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']))
"