firered-tts
FireRedTTS3 — многоязычный TTS (24 языка, вкл. украинский)
Локальный сервис синтеза речи на FireRedTTS3 с HTTP-API и MCP-сервером, на порту :8020.
Модель вышла 13.08.2026, лицензия Apache 2.0, веса публичные.
Что стоит знать перед стартом
Пресетных голосов нет. Пустая библиотека = синтезировать нечем. Сначала
заводишь голос из любой записи речи (add_firered_voice), дальше
используешь его по имени. Модель клонирует zero-shot прямо во время синтеза.
Нужен транскрипт референса. Модели мало самого аудио — нужен ещё текст того, что в нём звучит. Не передашь — распознаем Whisper'ом, но свой текст всегда точнее.
Ударений нет. Ни словаря, ни ByT5-фолбека, ни ручного Му+дрого.
Ударения модель ставит сама из контекста и на омографах (за́мок/замо́к)
будет путаться. Это принципиальное ограничение многоязычной модели.
Related MCP server: STT2TTS MCP
Установка
cd /Users/admin/Projects/firered-tts
./setup.sh # venv + залежності + апстрім + патч + вагиsetup.sh делает четыре вещи: поднимает .venv с Python 3.11 и torch 2.8.0
под MPS/CPU, клонирует апстрим в vendor/FireRedTTS3 на зафиксированном коммите
00570ad, патчит его под Apple Silicon (см. ниже) и тянет веса
base+redae (~11.4 ГБ) в pretrained_models/.
Веса отдельно (долго — лучше detached):
nohup ./download-weights.sh base > data/download.log 2>&1 &
./download-weights.sh instruct # +7.9 ГБ, для дизайну голосу й редагуванняЗачем патч
Апстрим написан исключительно под NVIDIA и на Mac не запускается вообще:
flash_attn на Metal не собирается в принципе, устройство зашито как cuda,
autocast прибит гвоздями к CUDA. Патч заменяет flash_attention_2 на sdpa
(работает везде, в т.ч. на NVIDIA), делает устройство динамическим и добавляет
оптимизации из раздела о скорости. Полный список — в шапке
src/patch_upstream.py.
Патч идемпотентен и падает, если замена не попала — если апстрим изменился, ты узнаешь об этом сразу, а не CUDA-ошибкой на первом синтезе.
Запуск
./run.sh # http://localhost:8020Отдельно запускать не обязательно — MCP-сервер поднимет бекенд сам. Бекенд выключается после простоя и освобождает память.
HTTP API
Метод | Эндпойнт | Что делает |
|
| статус, устройство, какая модель в памяти |
|
| имена голосов (фильтры |
|
| 24 языка + 21 диалект |
|
| референс + транскрипт → голос |
|
| удалить голос (оригинал записи не трогается) |
|
| текст → аудио-байты в ответе |
|
| текст → файл в |
|
| описание голоса → аудио (instruct) |
|
| правка записи: |
# 1) завести голос
curl -X POST localhost:8020/clone_voice -H 'Content-Type: application/json' -d '{
"audio": "prompts/зразок.wav", "name": "Богдан",
"prompt_text": "Це зразок мого голосу для клонування.",
"language": "Ukrainian", "gender": "male"}'
# 2) озвучити
curl -X POST localhost:8020/tts -H 'Content-Type: application/json' -d '{
"text": "Сьогодні чудова погода, ходімо гуляти в парк.",
"voice": "Богдан", "format": "mp3"}' -o out.mp3
# Або one-shot — без реєстрації голосу: передай reference_audio замість voice,
# транскрипт зробить Whisper (перший виклик +~30с, далі кешується)
curl -X POST localhost:8020/tts -H 'Content-Type: application/json' -d '{
"text": "Сьогодні чудова погода.", "reference_audio": "prompts/зразок.mp3",
"format": "mp3"}' -o out.mp3MCP
См. mcp_server/README.md. Кратко:
claude mcp add firered-tts -- /Users/admin/Projects/firered-tts/.venv/bin/python \
/Users/admin/Projects/firered-tts/mcp_server/server.pyИнструменты: firered_backend_status, list_firered_voices,
add_firered_voice, delete_firered_voice, synthesize_firered_speech,
design_firered_voice, edit_firered_speech.
Память
Mac mini M4, 16 ГБ. Веса на диске: base (7.9) + redae (3.5) = 11.4 ГБ.
В памяти меньше — LLM-бекбон живёт в half (4.2 вместо 8.4 ГБ), — но на
16 ГБ это всё равно впритык. Последствия, заложенные в код:
в памяти живёт ровно одна модель —
baseилиinstruct; переключение = полная перезагрузка (минуты, громко логируется);синтез сериализован глобальным локом — два параллельных запроса на 16 ГБ дают OOM, а не ускорение;
автоостановка по простою 1800с — долго намеренно: рестарт стоит ~40с компиляции шейдеров, так что держать процесс живым выгоднее;
Whisper для автотранскрипта —
int8на CPU, выгружается сразу после распознавания.
Скорость и четыре оптимизации
Наивный запуск апстрима на M4 давал ×186 реального времени — 3 секунды
украинского считались 9 минут. После четырёх исправлений стало ×3.0,
то есть в ~60 раз быстрее. Что именно было не так (всё замерено
tools/profile_steps.py):
1. Autocast на шаге AR-цикла — главная беда. Апстрим вешает
@torch.autocast декоратором на _backbone_one_step, то есть регион
открывается и закрывается на КАЖДОМ шаге авторегрессии. Кеш перекастов весов
в torch живёт ровно внутри региона, так что 1.7B параметров fp32 перегонялись в
half на каждом шаге. Шаг бекбона: 19000 → 2710 мс. Теперь autocast выключен, а
каст делается явно на границе бекбона.
2. Бекбон в fp32. Веса сохранены в float32 (3.0B параметров), что на 16 ГБ означает своп. Переводим в half только LLM-бекбон (4.2 ГБ вместо 8.4), а redae и flow-декодер оставляем fp32 — half ломает там MPS-matmul. Шаг: 2710 → 1387 мс.
3. Референс кодировался заново на каждое предложение. generate() вызывается
на каждое предложение текста, и каждый вызов прогонял redae-энкодер по тому же
референсному записи: 5.6с каждый раз, независимо от длины текста. Теперь
кеш с ключом по содержимому аудио. На 6.6 мин аудио — 30 попаданий против 2
промахов, ~11% времени прогона.
4. Компиляция Metal-шейдеров. Самая большая часть «медлительности» оказалась
разовой: Metal компилирует ядра при первом выполнении. Поштучные замеры шага
бекбона: 9873, 2104, 120, 93, 96, 97… мс. Поэтому сервис делает прогрев на
старте (FIRERED_WARMUP=1) и имеет долгий таймаут простоя.
Замерено на Mac mini M4 / 16 ГБ, 3.0с украинского, прогретая модель:
n_timesteps | Время | ×реального времени | Качество |
10 (дефолт) | 12 с | ×4.0 | эталон |
6 | 10 с | ×3.0 | разница едва слышна |
4 | 7 с | ×2.3 | заметно грубее |
2 | 6 с | ×1.9 | заметные артефакты |
Профиль прогретой генерации: flow-декодер 57%, бекбон 18%, redae 11% —
самый действенный рычаг именно n_timesteps. Real-time нет, но это уже рабочий
инструмент, а не «запусти на ночь».
Text normalization
Встроенный TN (wetext) знает только китайский и английский, так что для
украинского он бесполезен, и мы его не ставим. 19:30, 250 грн, 2026 р.
модель озвучит как получится. Два выхода: писать текст сразу словами, или
включить LLM-TN — FIRERED_TN_API_URL / _API_KEY / _MODEL в .env.
Годится любой OpenAI-совместимый эндпойнт, включая локальный
(llama.cpp / vLLM / Ollama) — тогда всё остаётся офлайн.
Лицензия
Код и веса — Apache 2.0. В README апстрима отдельно написано, что zero-shot клонирование «solely for academic research purposes» — это противоречит Apache 2.0 и на коммерческое использование клонированных голосов смотри осторожно. Для домашнего использования вопрос не стоит.
This server cannot be deployed
Maintenance
Related MCP Connectors
Hosted text-to-speech MCP server: 66 voices in 9 languages, long-form narration, podcasts.
71AI voice generation: text-to-speech and voice cloning from any MCP client.
MCP server for Text-to-Speech
- AudexumOAuthcom.audexum
Text to speech and transcription for any AI model: MP3 voiceovers, audio and YouTube to text.
Related MCP Servers
- AlicenseAqualityDmaintenanceA Model Context Protocol server for FlowSpeech text-to-speech. It lets MCP-compatible clients generate human-like audio with context-aware emotion control, pause control, multi-speaker dialogue, and 30+ available voices.317 npmMIT
- AlicenseNot gradedqualityDmaintenanceLocal-first speech-to-text and text-to-speech MCP server. Hot-swappable engines via config.yaml — no code changes, no API keys required.2MIT
- AlicenseNot gradedqualityBmaintenanceA text-to-speech MCP server with 48 voices across 9 languages, supporting emotion spans, SFX tags, and multi-speaker dialogue. Deployable via a single npx command with built-in guardrails and swappable backends.MIT
- AlicenseNot gradedqualityDmaintenanceMCP server for Vietnamese text-to-speech with voice cloning, 10 built-in voices, text normalization, and long-form queuing, running 100% locally.Apache 2.0