# Использование и развёртывание

## Установка

> Рекомендуется Python 3.11. Python 3.14+ пока не имеет совместимых wheel для
> `torch`, поэтому используйте 3.10–3.12.

```bash
# Клонировать / перейти в директорию проекта
cd voice

# Создать виртуальное окружение
python3.11 -m venv .venv
source .venv/bin/activate  # Windows: .venv\Scripts\activate

# Установить PyTorch с CUDA 12.6 (обязательно первым)
pip install torch torchaudio --index-url https://download.pytorch.org/whl/cu126

# Установить остальные зависимости
pip install -r requirements.txt

# (Опционально) скопировать настройки
cp .env.example .env
```

## Запуск сервера

```bash
# Основной режим: Fish Speech 1.5 на GPU (по умолчанию)
python -m voice_tts.main

# С настроенным референсом и warm-up (рекомендуется)
TTS_BACKEND=fish_speech \
DEFAULT_VOICE_REF=voices/self_ref_clean.wav \
DEFAULT_REF_TEXT="Добрый вечер, меня зовут Евгений." \
WARMUP=true \
python -m voice_tts.main

# Быстрый вариант XTTS-v2
TTS_BACKEND=xtts_v2 \
DEFAULT_VOICE_REF=voices/self_ref_clean.wav \
python -m voice_tts.main

# Тестовый режим без модели
TTS_BACKEND=dummy python -m voice_tts.main
```

Сервер поднимется на `ws://localhost:8765/ws`.

## Проверка работоспособности

```bash
curl http://localhost:8765/health
# {"status":"ok","backend":"fish_speech"}
```

## Клиенты

В директории `examples/` лежат готовые клиенты:

- `examples/client_python.py` — Python-клиент с воспроизведением через `sounddevice`.
- `examples/client_browser.html` — HTML/JS клиент для браузера с `AudioContext`.

### Python-клиент

```bash
pip install websockets sounddevice
python examples/client_python.py --uri ws://localhost:8765/ws "Привет, мир!"
```

Опции:

```bash
python examples/client_python.py \
  --uri ws://localhost:8765/ws \
  --voice-ref voices/self_ref_clean.wav \
  --language ru \
  --speed 1.0 \
  "Это тестовая фраза для проверки."
```

Клиент:
1. Отправляет `init` с настройками.
2. Разбивает текст на слова и шлёт их как потоковые `text`.
3. Отправляет `flush`.
4. Получает `audio`-чанки, декодирует base64 PCM16 и складывает в аудиобуфер.
5. `sounddevice` воспроизводит аудио в реальном времени из callback.
6. По `Ctrl+C` отправляет `stop` и выходит.

### Браузерный клиент

```bash
# 1. Терминал 1: запустить TTS сервер (dummy — без GPU, любой бэкенд по выбору)
TTS_BACKEND=dummy python -m voice_tts.main

# 2. Терминал 2: открыть клиент через HTTP (file:// не даёт WebSocket в некоторых браузерах)
python -m http.server 8080 --directory examples/
# Открыть http://localhost:8080/client_browser.html
```

Нажмите **Connect**, затем **Speak streaming**. Клиент:

1. Шлёт `init` с настройками (язык, скорость, эмоция).
2. Шлёт слова по одному как потоковые `text` с задержкой 120 мс.
3. Завершает `flush`.
4. Получает `audio`-чанки с динамическим `sample_rate` (поддерживается любой бэкенд).
5. Декодирует PCM16 из base64 и ставит в очередь `AudioBuffer` для бесшовного воспроизведения.

Кнопка **Stop** отправляет `stop`. Кнопка **Test audio** проверяет звук в браузере независимо от сервера.

## Настройка через переменные окружения (.env)

| Переменная | Описание | По умолчанию |
|------------|----------|--------------|
| `HOST` | Хост сервера | `0.0.0.0` |
| `PORT` | Порт сервера | `8765` |
| `LOG_LEVEL` | Уровень логирования | `INFO` |
| `TTS_BACKEND` | Бэкенд (`dummy` / `fish_speech` / `xtts_v2`) | `fish_speech` |
| `TTS_MODEL_PATH` | Папка с checkpoint Fish Speech / XTTS | — |
| `TTS_VOCAB_PATH` | Исходники Fish Speech v1.5.1 | `models/fish-speech-v1.5.1` |
| `TTS_SAMPLE_RATE` | Частота дискретизации | `44100` |
| `TTS_SPEED` | Множитель скорости речи | `1.2` |
| `VOICES_DIR` | Директория с референсами | `voices` |
| `DEFAULT_VOICE_REF` | Референс по умолчанию | — |
| `DEFAULT_REF_TEXT` | Точный текст референса (skip Whisper) | — |
| `MIN_SEGMENT_LENGTH` | Мин. длина сегмента | `30` |
| `MAX_SEGMENT_LENGTH` | Макс. длина сегмента | `200` |
| `MAX_BUFFER_WAIT_MS` | Макс. ожидание перед flush | `500` |
| `DEVICE` | `cuda` или `cpu` | `cuda` |
| `DTYPE` | `bfloat16` / `float16` / `float32` | `bfloat16` |
| `FISH_COMPILE` | `torch.compile` для Fish Speech | `false` |
| `FISH_CHUNK_LENGTH` | Длина LLM-чанка Fish Speech | `200` |
| `FISH_USE_MEMORY_CACHE` | Кэшировать VQ референса | `on` |
| `WARMUP` | Прогреть CUDA и кэшировать референс | `false` |
| `WARMUP_TEXT` | Текст для warm-up | `Привет. Это тестовая фраза.` |

## Модели

### Fish Speech 1.5

По умолчанию используется локальный checkpoint `models/fishaudio_fish-speech-1.5/`:

- `model.pth` — LLaMA языковая модель,
- `firefly-gan-vq-fsq-8x1024-21hz-generator.pth` — VQ-GAN декодер,
- `tokenizer.tiktoken`, `config.json`, `special_tokens.json`.

Исходный код Fish Speech v1.5.1 должен лежать в `models/fish-speech-v1.5.1/`,
чтобы Python мог импортировать нужные модули.

### XTTS-v2

Coqui-модель `tts_models/multilingual/multi-dataset/xtts_v2` скачивается
автоматически при первом запуске `TTS_BACKEND=xtts_v2`. Можно указать
локальный путь через `TTS_MODEL_PATH`.

## Референсные аудио

Поместите файлы в директорию `voices/`:

```
voices/
├── self_ref_clean.wav
├── self_ref_clean.lab
├── default_neutral.wav
├── default_happy.wav
├── default_sad.wav
└── ...
```

Требования к референсу:
- WAV или другой формат, читаемый `torchaudio`.
- Моно, 16+ кГц.
- Длина 5–15 секунд для Fish Speech, 3–10 секунд для XTTS-v2.
- Чистая речь одного спикера без фонового шума.
- Для Fish Speech рядом с `.wav` можно положить `.lab` с точным транскриптом.
  Иначе сервер использует `DEFAULT_REF_TEXT` или Whisper-транскрипцию.

## Тесты

```bash
# Быстрые тесты без загрузки тяжёлых моделей
python -m pytest tests/ -v
```

Для запуска в CI рекомендуется отдельно прогонять быстрые и тяжёлые тесты:

```bash
python -m pytest tests/test_segmenter.py tests/test_server.py -v
python -m pytest tests/test_fish_speech_backend.py -v
```
