Files

6.1 KiB
Executable File
Raw Permalink Blame History

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/status
  • tts_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']))
"