Цель: создать API на своем сервере с функциями озвучки текста TTS (Text To Speech).
Покупаем Cервер + Docker.
Параметры:
- ЦП 2 ядра
- ОЗУ 2 Гб (потом расширил до 8 Гб)
- Размер накопителя 30 Гб NVMe
Англоязычную версию накатал через Docker (Grok помог) и запустил быстро, а потом пошли танцы с бубнами с мультиязычной версией. Что только не пробовал — не работает, и на запрос логов — пусто.
Содержание
Как быстро получилось запустить Coqui на своем сервере
Я выбрал 2 Гб и 2 ядра (2 Ядра CPU / 2 ГБ RAM / 30 ГБ NVMe / Standard 3+ GHz) и установку Docker. Надо установить туда Сoйui и настроить его как api чтобы с одного веб приложения обрабатывать текст в голос.
Привет! Отлично, что ты выбрал VPS-2 с 2 ГБ RAM и 2 ядрами на Beget с предустановленным Docker. Теперь давай настроим Coqui TTS как API, чтобы твое веб-приложение могло отправлять текст и получать голос (аудиофайл). Я проведу тебя через процесс шаг за шагом.
Что будем делать?
- Подключимся к VPS и проверим Docker.
- Запустим Coqui TTS в Docker с сервером API.
- Настроим доступ, чтобы веб-приложение могло обращаться к API.
- Протестируем API и дадим пример, как использовать его с веб-приложения.
Шаг 1: Подключись к VPS
- После заказа VPS Beget прислал тебе IP-адрес и root-пароль.
- На Mac открой Терминал и подключись по SSH:
ssh root@<IP-адрес>
. Введи пароль, который дали.
- Проверь, что Docker работает
docker --version
Если всё ок, увидишь что-то вроде Docker version 20.10.x. Если нет — пиши, разберёмся.
Шаг 2: Запусти Coqui TTS как API в Docker
Coqui TTS имеет встроенный сервер, который работает как API. Мы запустим его в контейнере.
-
- Скачай и запусти контейнер:
docker run -d -p 5002:5002 --name tts-server ghcr.io/coqui-ai/tts-cpu python3 TTS/server/server.py --model_name tts_models/en/vctk/vits
-
- -d: Запуск в фоновом режиме.
- -p 5002:5002: Проброс порта 5002 (по умолчанию для Coqui TTS API).
- —name tts-server: Имя контейнера, чтобы потом было проще управлять.
- tts_models/en/vctk/vits: Модель английского языка (VITS, хорошее качество). Если нужен русский, позже поменяем на tts_models/ru/ljspeech/vits.
- Проверь, что контейнер работает:
docker ps
Увидишь строчку с tts-server. Если контейнер не запустился (статус Exited), проверь логи:
docker logs tts-server
Убедись, что API доступен:
-
- На своём Mac в браузере введи: http://<IP-адрес>:5002.
- Должен открыться веб-интерфейс Coqui TTS (простая страничка с полем ввода текста). Если не открывается, проверь порт (см. шаг 4).
Шаг 3: Настройка доступа
Чтобы веб-приложение могло обращаться к API, нужно открыть порт и проверить сетевые настройки.
Открой порт 5002:
-
- На Beget по умолчанию порты могут быть закрыты. Настрой брандмауэр:
ufw allow 5002 ufw status
Убедись, что порт 5002 в списке разрешённых.
- На Beget по умолчанию порты могут быть закрыты. Настрой брандмауэр:
-
- Если ufw не установлен:
apt install ufw -y ufw enable ufw allow 22 # Для SSH ufw allow 5002
Проверь внешний доступ:
- Снова зайди с Mac на http://<IP-адрес>:5002. Если работает — всё ок.
- Если нет, обратись в поддержку Beget, чтобы убедиться, что порт 5002 открыт на их стороне (иногда VPS требует ручного проброса портов в панели).
- Если ufw не установлен:
Шаг 4: Использование API с веб-приложения
Coqui TTS API принимает POST-запросы для генерации речи. Вот как это работает:
- Пример API-запроса:
- Эндпоинт: http://<IP-адрес>:5002/api/tts
- Метод: POST
- Тело запроса (JSON):
{ "text": "Hello, this is a test!", "speaker_id": "p225" // ID спикера для VITS, можно опустить }
-
- Ответ: Аудиофайл в формате WAV.
Русский голос: Если нужен русский, перезапусти контейнер с другой моделью:
docker stop tts-server docker rm tts-server docker run -d -p 5002:5002 --name tts-server ghcr.io/coqui-ai/tts-cpu python3 TTS/server/server.py --model_name tts_models/ru/ljspeech/vits
Попробуй запустить по шагам выше. Если что-то не сработает (порт не открывается, API не отвечает), пиши — разберёмся! Какое у тебя веб-приложение, кстати? Flask, Django или что-то другое? Могу дать более точный пример под него.
Итог
- Ты настроил Coqui TTS как API на порту 5002.
- Веб-приложение может отправлять POST-запросы на http://<IP-адрес>:5002/api/tts и получать аудио.
- Если нужен русский или другая модель, просто меняешь параметр —model_name.
Попробуй запустить по шагам выше. Если что-то не сработает (порт не открывается, API не отвечает), пиши — разберёмся! Какое у тебя веб-приложение, кстати? Flask, Django или что-то другое? Могу дать более точный пример под него.
Как мы потом мучались с установкой мультиязычной модели
И только на второй день Grok додумался подсказать что надо Coqui запустить в интерактивном режиме.
Далее выдержка из диалогов.
Grok, можешь поискать в интернете почему еще могут отсутствовать логи в coqui , или как думаешь, это может быть единственная причина? и как обстоят дела с другими русскими моделями coqui?
Привет! Отсутствие логов в Coqui TTS — это действительно интересная проблема, и я постараюсь разобраться, почему это может происходить, помимо уже выявленной причины с speaker_wav/speaker_idx у xtts_v2. Я также посмотрю, что можно найти в интернете, и добавлю свои мысли. Потом расскажу про другие русские модели в Coqui.
Почему могут отсутствовать логи в Coqui TTS?
На основе нашего опыта и поисков в интернете (GitHub Issues, форумы, документация), вот возможные причины отсутствия логов:
- Тихий выход процесса (silent failure):
- Если server.py сталкивается с ошибкой до того, как успевает что-то записать в логи (например, при загрузке модели), процесс может завершаться без вывода. Это часто связано с:
- Недостаток параметров: Как мы видели с xtts_v2, отсутствие speaker_wav или speaker_idx приводит к ValueError, но если ошибка происходит раньше инициализации логгера, она не попадёт в docker logs.
- Проблемы с зависимостями: Например, несовместимость версий torch или numpy может приводить к краху без сообщений.
- Если server.py сталкивается с ошибкой до того, как успевает что-то записать в логи (например, при загрузке модели), процесс может завершаться без вывода. Это часто связано с:
- Логирование через print вместо logging:
- В старых версиях Coqui TTS (до 0.14.x) логирование шло через print, а не через стандартный модуль logging (см. Issue #1691). Если в твоём образе используется старая версия, вывод может не перенаправляться в docker logs, особенно в фоновом режиме (-d).
- Ограничения Docker:
- Docker может не захватывать вывод, если:
- Процесс завершается слишком быстро (до буферизации логов).
- Используется нестандартный вывод (например, stderr вместо stdout), а он не перенаправлен.
- Решение: запуск в интерактивном режиме (-it) обычно показывает больше деталей.
- Docker может не захватывать вывод, если:
- Нехватка ресурсов:
- Хотя у тебя теперь 8 ГБ RAM, если модель всё равно упирается в лимит (например, из-за других процессов на VPS), она может зависнуть или упасть без логов. Мы видели это с xtts_v2 на 4 ГБ — процесс просто умирал.
- Баги в server.py:
- В Issue #3454 упоминается, что сервер может не стартовать из-за проблем с мультиспикерными моделями. Если сервер не доходит до строки > Running on http://0.0.0.0:5002, логов не будет.
- Устаревший образ:
- Ты используешь ghcr.io/coqui-ai/tts-cpu, но Coqui официально закрылся в 2024 году (Issue #3488). Если образ старый, он может содержать баги, которые исправлены в форках вроде idiap/coqui-tts.
Единственная ли это причина?
Нет, отсутствие speaker_wav/speaker_idx — не единственная возможная причина. Это специфично для xtts_v2, но другие факторы (ресурсы, баги, логирование) тоже могут играть роль. Чтобы точно понять, нужно:
- Запустить в интерактивном режиме:
docker run -it --rm -e COQUI_TOS_AGREED=1 tts-cpu-xtts-v2-preloaded python3 TTS/server/server.py --model_path /root/.local/share/tts/tts_models--multilingual--multi-dataset--xtts_v2/model.pth --config_path /root/.local/share/tts/tts_models--multilingual--multi-dataset--xtts_v2/config.json
- Проверить ошибки напрямую.
Как обстоят дела с другими русскими моделями Coqui?
Coqui TTS не имеет отдельных «русских» моделей, но поддерживает русский язык через мультиязычные модели. Давай посмотрим, что доступно:
- xtts_v2:
- Поддерживает русский («ru» в languages в config.json).
- Плюсы: Высокое качество, клонирование голоса через speaker_wav.
- Минусы: Требует спикера, сложнее запустить сервер (как у нас). На 8 ГБ RAM работает, но медленно без GPU.
- xtts_v1.1:
- Тоже мультиязычная, включая русский.
- Отличия: Меньше языков (13 против 17 в v2), чуть ниже качество, но легче по ресурсам (4-6 ГБ RAM достаточно).
- Запуск: Аналогичен v2, нужен speaker_wav.
- YourTTS:
- Мультиязычная модель, поддерживает русский через обучение или клонирование.
- Плюсы: Хорошо работает с небольшими датасетами.
- Минусы: Качество ниже xtts, сложнее настроить для русского без файнтюнинга (Discussion #1759).
- Bark:
- Генеративная модель, есть в Coqui (tts_models/multilingual/multi-dataset/bark).
- Поддерживает русский «из коробки» без speaker_wav.
- Плюсы: Простота (только текст), не требует спикера.
- Минусы: Качество ниже, чем у xtts, и медленнее (на CPU 8 ГБ — предел, генерация 5 секунд может занять минуту).
- Состояние:
- После закрытия Coqui в 2024 году официальные модели не обновляются. Форк idiap/coqui-tts (PyPI: coqui-tts) поддерживает их дальше, добавляя улучшения (например, OpenVoice в 0.25.0).
- Русский в этих моделях работает, но для идеального результата лучше использовать speaker_wav с русским голосом или файнтюнинг.
Что делать дальше?
- Диагностика логов:
- Запусти xtts_v2 в -it режиме (выше) и пришли вывод. Это покажет, где именно падает сервер.
- Попробовать Bark:
- Проверь список моделей
- Если Bark есть, запусти
- Тест
- Пришли данные:
-
- Вывод —list_models.
- Логи и статус Bark или xtts_v2.
-
-
Bark может быть проще для старта, а с xtts_v2 мы разберёмся с логами. Жду твоих результатов!
docker run -it —rm -e COQUI_TOS_AGREED=1 tts-cpu-xtts-v2-preloaded python3 TTS/server/server.py —model_path /root/.local/share/tts/tts_models—multilingual—multi-dataset—xtts_v2/model.pth —config_path /root/.local/share/tts/tts_models—multilingual—multi-dataset—xtts_v2/config.json
usage: tts [-h] [—list_models [LIST_MODELS]] [—model_info_by_idx MODEL_INFO_BY_IDX] [—model_info_by_name MODEL_INFO_BY_NAME] [—text TEXT] [—model_name MODEL_NAME] [—vocoder_name VOCODER_NAME] [—config_path CONFIG_PATH] [—model_path MODEL_PATH] [—out_path OUT_PATH] [—use_cuda USE_CUDA] [—device DEVICE] [—vocoder_path VOCODER_PATH] [—vocoder_config_path VOCODER_CONFIG_PATH] [—encoder_path ENCODER_PATH] [—encoder_config_path ENCODER_CONFIG_PATH] [—pipe_out [PIPE_OUT]] [—speakers_file_path SPEAKERS_FILE_PATH] [—language_ids_file_path LANGUAGE_IDS_FILE_PATH] [—speaker_idx SPEAKER_IDX] [—language_idx LANGUAGE_IDX] [—speaker_wav SPEAKER_WAV [SPEAKER_WAV …]] [—gst_style GST_STYLE] [—capacitron_style_wav CAPACITRON_STYLE_WAV] [—capacitron_style_text CAPACITRON_STYLE_TEXT] [—list_speaker_idxs [LIST_SPEAKER_IDXS]] [—list_language_idxs [LIST_LANGUAGE_IDXS]] [—save_spectogram SAVE_SPECTOGRAM] [—reference_wav REFERENCE_WAV] [—reference_speaker_idx REFERENCE_SPEAKER_IDX] [—progress_bar PROGRESS_BAR] [—source_wav SOURCE_WAV] [—target_wav TARGET_WAV] [—voice_dir VOICE_DIR] tts: error: unrecognized arguments: python3 TTS/server/server.py
Привет! Ошибка tts: error: unrecognized arguments: python3 TTS/server/server.py возникла из-за неправильного порядка в команде Docker. Ты случайно указал python3 TTS/server/server.py как аргументы для утилиты tts, а не как точку входа. В Docker нужно явно разделять команду (entrypoint) и её аргументы. Давай исправим и запустим сервер xtts_v2 правильно в интерактивном режиме, чтобы увидеть, что происходит.
Исправляем команду
Правильный синтаксис:
docker run -it --rm -e COQUI_TOS_AGREED=1 --entrypoint python3 tts-cpu-xtts-v2-preloaded TTS/server/server.py --model_path /root/.local/share/tts/tts_models--multilingual--multi-dataset--xtts_v2/model.pth --config_path /root/.local/share/tts/tts_models--multilingual--multi-dataset--xtts_v2/config.json
- —entrypoint python3: Указывает, что мы запускаем Python.
- tts-cpu-xtts-v2-preloaded: Образ.
- TTS/server/server.py …: Аргументы для python3.
Что произойдёт?
- Команда запустит сервер xtts_v2 в интерактивном режиме (-it), и ты увидишь вывод напрямую в терминале.
- Ожидаемый результат:
&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; Using model: xtts &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; Running on http://0.0.0.0:5002
- Если есть ошибка (например, ValueError из-за отсутствия speaker_wav), она тоже появится.
Что делать дальше?
- Запусти исправленную команду:
docker run -it --rm -e COQUI_TOS_AGREED=1 --entrypoint python3 tts-cpu-xtts-v2-preloaded TTS/server/server.py --model_path /root/.local/share/tts/tts_models--multilingual--multi-dataset--xtts_v2/model.pth --config_path /root/.local/share/tts/tts_models--multilingual--multi-dataset--xtts_v2/config.json
- Пришли полный вывод:
- Если сервер стартует, ты увидишь Running on http://0.0.0.0:5002.
- Если ошибка, напиши её целиком.
- Если сервер запустится:
- Оставь его работать в одном терминале.
- В другом терминале протестируй:
curl -X POST -H "Content-Type: application/json" -d '{"text":"Привет, это тест!","language":"ru","speaker_idx":"claribel"}' http://127.0.0.1:5002/api/tts -o output.wav
Почему это важно?
- Интерактивный режим покажет, где именно падает сервер, и мы поймём, почему в фоновом режиме (-d) логи пустые.
- Если проблема в speaker_wav, добавим его и запустим в фоновом режиме.
Жду твой вывод! Это ключевой шаг к разгадке пустых логов.
docker run -it —rm -e COQUI_TOS_AGREED=1 —entrypoint python3 tts-cpu-xtts-v2-preloaded TTS/server/server.py —model_path /root/.local/share/tts/tts_models—multilingual—multi-dataset—xtts_v2/model.pth —config_path /root/.local/share/tts/tts_models—multilingual—multi-dataset—xtts_v2/config.json
> Using model: xtts
Traceback (most recent call last):
File «/root/TTS/server/server.py», line 104, in <module>
synthesizer = Synthesizer(
File «/root/TTS/utils/synthesizer.py», line 93, in __init__
self._load_tts(tts_checkpoint, tts_config_path, use_cuda)
File «/root/TTS/utils/synthesizer.py», line 192, in _load_tts
self.tts_model.load_checkpoint(self.tts_config, tts_checkpoint, eval=True)
File «/root/TTS/tts/models/xtts.py», line 771, in load_checkpoint
checkpoint = self.get_compatible_checkpoint_state_dict(model_path)
File «/root/TTS/tts/models/xtts.py», line 714, in get_compatible_checkpoint_state_dict
checkpoint = load_fsspec(model_path, map_location=torch.device(«cpu»))[«model»] File «/root/TTS/utils/io.py», line 46, in load_fsspec
with fsspec.open(
File «/usr/local/lib/python3.10/site-packages/fsspec/core.py», line 103, in __enter__
f = self.fs.open(self.path, mode=mode)
File «/usr/local/lib/python3.10/site-packages/fsspec/implementations/cached.py», line 436, in <lambda>
return lambda *args, **kw: getattr(type(self), item).__get__(self)(
File «/usr/local/lib/python3.10/site-packages/fsspec/spec.py», line 1295, in open
f = self._open(
File «/usr/local/lib/python3.10/site-packages/fsspec/implementations/cached.py», line 436, in <lambda>
return lambda *args, **kw: getattr(type(self), item).__get__(self)(
File «/usr/local/lib/python3.10/site-packages/fsspec/implementations/cached.py», line 675, in _open
fn = self._make_local_details(path)
File «/usr/local/lib/python3.10/site-packages/fsspec/implementations/cached.py», line 436, in <lambda>
return lambda *args, **kw: getattr(type(self), item).__get__(self)(
File «/usr/local/lib/python3.10/site-packages/fsspec/implementations/cached.py», line 598, in _make_local_details
«uid»: self.fs.ukey(path),
File «/usr/local/lib/python3.10/site-packages/fsspec/spec.py», line 1334, in ukey
return sha256(str(self.info(path)).encode()).hexdigest()
File «/usr/local/lib/python3.10/site-packages/fsspec/implementations/local.py», line 83, in info
out = os.stat(path, follow_symlinks=False)
NotADirectoryError: [Errno 20] Not a directory: ‘/root/.local/share/tts/tts_models—multilingual—multi-dataset—xtts_v2/model.pth/model.pth’
Привет! Отлично, что мы наконец-то получили вывод в интерактивном режиме — это даёт нам ясность. Ошибка NotADirectoryError: [Errno 20] Not a directory: ‘/root/.local/share/tts/tts_models—multilingual—multi-dataset—xtts_v2/model.pth/model.pth’ указывает на проблему с путём к файлу модели. Давай разберём, почему это произошло, и исправим.
Что случилось?
- Ошибка: NotADirectoryError говорит, что система ожидала директорию, а наткнулась на файл или неправильный путь.
- Проблемный путь: /root/.local/share/tts/tts_models—multilingual—multi-dataset—xtts_v2/model.pth/model.pth.
- Здесь model.pth дублируется, что неверно. Правильный путь должен быть просто /root/.local/share/tts/tts_models—multilingual—multi-dataset—xtts_v2/model.pth.
- Причина: Когда мы указывали —model_path, Coqui TTS, вероятно, автоматически добавляет /model.pth к пути, если его нет в конце, но в нашем случае мы уже вручную добавили model.pth, что привело к дублированию.
Почему это важно?
- Это объясняет пустые логи в фоновом режиме (-d): сервер падал сразу из-за неверного пути, не успевая ничего записать.
- Теперь, когда мы нашли ошибку, можем её исправить и запустить сервер.
Исправляем запуск
Шаг 1: Проверим правильные пути
- Запусти контейнер для проверки файлов:
docker run -it --rm --entrypoint /bin/bash tts-cpu-xtts-v2-preloaded
- Посмотри содержимое:
ls -l /root/.local/share/tts/tts_models--multilingual--multi-dataset--xtts_v2/
- Должны быть файлы вроде model.pth, config.json, vocab.json, и т.д.
- Запомни точное имя файла модели (обычно model.pth).
- Выйди:
exit
Шаг 2: Исправленный запуск в интерактивном режиме
Попробуем без дублирования model.pth в пути:
docker run -it --rm -e COQUI_TOS_AGREED=1 --entrypoint python3 tts-cpu-xtts-v2-preloaded TTS/server/server.py --model_path /root/.local/share/tts/tts_models--multilingual--multi-dataset--xtts_v2 --config_path /root/.local/share/tts/tts_models--multilingual--multi-dataset--xtts_v2/config.json