firered-tts
FireRedTTS3 — TTS multilingüe (24 idiomas, incl. ucraniano)
Servicio local de síntesis de voz basado en FireRedTTS3
con API HTTP y servidor MCP. El tercero de la serie junto a ukrainian-tts (StyleTTS2, :8000)
y HolosTTS (:8010); este — en :8020.
El modelo salió el 13.08.2026, licencia Apache 2.0, pesos públicos.
En qué se diferencia de los vecinos
ukrainian-tts | HolosTTS | firered-tts | |
Idiomas | ucraniano | ucraniano | 24 + 21 dialectos |
Voces predefinidas | sí | 27 | ninguna |
Clonación | no | sí (vector de estilo) | sí (zero-shot) |
Transcripción de referencia necesaria | — | no | sí |
Diseño de voz por descripción | no | no | sí (instruct) |
Edición de grabación | no | no | sí (instruct) |
Tamaño en memoria | ~1 GB | ~4 GB | ~7.7 GB de pesos, ~13 GB con proceso |
Acentos (ucraniano) | diccionario + ByT5 | diccionario + ByT5 | ninguno |
Tres cosas que conviene entender antes de empezar:
1. No hay voces predefinidas. La biblioteca vacía = no hay nada que sintetizar.
Primero introduces una voz a partir de cualquier grabación de habla (add_firered_voice),
y luego la usas por nombre. El modelo clona zero-shot directamente durante la síntesis.
2. Se necesita la transcripción de la referencia. Al modelo no le basta el audio — necesita también el texto de lo que se oye en él. Si no se la das, la reconocemos con Whisper, pero tu propio texto siempre es más preciso.
3. No hay acentos. Ni diccionario, ni fallback de ByT5, ni acento manual Mu+dro,
como en los vecinos. El modelo pone los acentos solo a partir del contexto, y en homógrafos
(za'mok/za'mok) los confundirá. Es una limitación fundamental
del modelo multilingüe — si los acentos son críticos, HolosTTS sigue siendo la mejor opción
para ucraniano puro.
Related MCP server: STT2TTS MCP
Instalación
cd /Users/admin/Projects/firered-tts
./setup.sh # venv + залежності + апстрім + патч + вагиsetup.sh hace cuatro cosas:
.venvcon Python 3.11, torch 2.8.0 para MPS/CPUclona el upstream en
vendor/FireRedTTS3en el commit fijado00570adle aplica el parche para Apple Silicon — ver más abajo
descarga los pesos base+redae (~11.4 GB) en
pretrained_models/
Los pesos por separado (mejor en modo detached):
nohup ./download-weights.sh base > data/download.log 2>&1 &
./download-weights.sh instruct # +7.9 ГБ, для дизайну голосу й редагуванняPara qué sirve el parche
El upstream está escrito exclusivamente para NVIDIA y en Mac no funciona en absoluto:
Lugar | Antes | Después |
|
|
|
| lo mismo, ×2 |
|
|
| dispositivo dinámico |
|
| desde |
|
| bajo |
flash_attn — solo CUDA, en Metal no compila en principio; sdpa funciona
en todas partes, incluso en NVIDIA, así que el parche no rompe nada.
El décimo cambio está aparte: base.py:317 — no es portabilidad, sino
rendimiento (caché de codificación de referencia, ver «Rendimiento» más abajo).
src/patch_upstream.py es idempotente y falla si el reemplazo no ha acertado —
si el upstream cambia, te enteras de inmediato, no con un error de CUDA en la
primera síntesis.
Ejecución
./run.sh # http://localhost:8020No hace falta ejecutarlo por separado — el servidor MCP levantará el backend solo. El backend
se apaga tras 1800s de inactividad (IDLE_SHUTDOWN_SECONDS) y libera memoria.
run.sh toma el lock del puerto (data/.start-<puerto>.lock): un segundo lanzamiento con el
servicio vivo simplemente termina con código 0. Es intencionado — el autostart lo invocan
varios clientes a la vez, y /health calla durante los ~90s de carga.
API HTTP
Método | Endpoint | Qué hace |
|
| estado, dispositivo, qué modelo hay en memoria |
|
| nombres de voces, como en los vecinos (filtros |
|
| 24 idiomas + 21 dialectos |
|
| referencia + transcripción → voz |
|
| eliminar voz (la grabación original no se toca) |
|
| texto → bytes de audio en la respuesta |
|
| texto → archivo en |
|
| descripción de voz → audio (instruct) |
|
| edición de grabación: |
# 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
Ver mcp_server/README.md. En resumen:
claude mcp add firered-tts -- /Users/admin/Projects/firered-tts/.venv/bin/python \
/Users/admin/Projects/firered-tts/mcp_server/server.pyHerramientas: firered_backend_status, list_firered_voices,
add_firered_voice, delete_firered_voice, synthesize_firered_speech,
design_firered_voice, edit_firered_speech.
Memoria y velocidad
Mac mini M4, 16 GB. En disco base (7.9) + redae (3.5) = 11.4 GB, pero en
memoria caben ~7.7 GB: el backbone LLM se carga en fp16 (4.2 en lugar de 8.4 —
ver optimización 2 más abajo), el resto permanece en fp32.
Los pesos no son toda la historia. Medido en un proceso vivo tras la síntesis:
phys_footprint: 13 ГБ
phys_footprint_peak: 14 ГБLa diferencia entre 7.7 y 13 — caché del asignador MPS, caché KV y activaciones de generación. En
16 GB esto va justo incluso con un solo proceso, y ps/RSS aquí miente (muestra
décimas de gigabyte: los buffers MPS en memoria unificada no aparecen en RSS). Mide
footprint, no ps.
Consecuencias incorporadas en el código:
en memoria vive exactamente un modelo —
baseoinstruct; cambiar = recarga completa (minutos, se registra en el log ruidosamente);la síntesis está serializada con un lock global — dos peticiones paralelas en 16 GB dan OOM, no aceleración;
run.shtoma el lock del puerto — si no, varios clientes que hacen autostart a la vez levantan una copia del backend cada uno (caso real: siete procesos en 16 GB);autoapagado por inactividad de 1800s — más largo que el de los vecinos a propósito: reiniciar cuesta ~40s de compilación de shaders, así que mantener el proceso vivo sale más rentable;
Whisper para la transcripción automática —
int8en CPU, se descarga inmediatamente después del reconocimiento.
Velocidad y cuatro optimizaciones
La ejecución ingenua del upstream en M4 daba ×189 del tiempo real — 3 segundos
de ucraniano tardaban 9.5 minutos. Tres correcciones dieron ×4.0, es decir, 48
veces más rápido; la cuarta lo llevó a ×2.7. Qué estaba mal exactamente (medido
con tools/profile_steps.py e instrumentación):
1. Autocast en el paso del bucle AR — el mayor problema. El upstream cuelga
@torch.autocast como decorador en _backbone_one_step, es decir, la región autocast
se abre y se cierra en CADA paso de la autorregresión. La caché de recasteo de pesos
en torch vive exactamente dentro de la región, así que 1.7B parámetros fp32 se convertían a
half en cada paso. Paso del backbone: 19000 ms → 2710 ms. Ahora autocast está desactivado
por defecto, y el casteo se hace explícitamente en el límite del backbone.
2. Backbone en fp32. Los pesos están guardados en float32 (3.0B parámetros = 11.4 GB), lo que en 16 GB significa swap. Convertimos a half solo el backbone LLM (4.2 GB en lugar de 8.4), y redae y el decodificador flow los dejamos en fp32 — el upstream ahí trabaja deliberadamente en precisión completa, y half rompe el matmul de MPS. Paso: 2710 → 1387 ms.
3. Compilación de shaders de Metal. La mayor parte de la «lentitud» resultó ser
puntual: Metal compila los kernels en la primera ejecución. Mediciones individuales del paso
del backbone: 9873, 2104, 120, 93, 96, 97… ms. Por eso el servicio hace un calentamiento al
inicio (FIRERED_WARMUP=1) y tiene un timeout de inactividad largo — reiniciar cuesta
~40 segundos de compilación.
4. Caché de codificación de referencia. generate() se llama en CADA frase, y
cada llamada volvía a pasar el codificador redae por la grabación de referencia — 5.58s
cada vez, independientemente de la longitud del texto. La clave de la caché es el contenido del audio, no el id
del tensor, así que no puede sustituir la voz. En una ejecución de 6.6 min de audio (14 fragmentos):
30 aciertos contra 2 fallos ≈ 150s, es decir, ~11% del tiempo.
Un minuto de audio se calcula en ~2.7 minutos (Mac mini M4 / 16 GB, modelo calentado, caché de referencia caliente; mejor de 5 rondas alternadas sobre 3.0s de ucraniano, la mediana da ×2.9). No hay tiempo real, pero ya es una herramienta de trabajo, no un «déjalo corriendo toda la noche».
Perfil de generación caliente: decodificador flow 57%, backbone 18%, redae 11%.
n_timesteps — pasos de ODE en el decodificador flow, la parte más cara. El parámetro
está disponible en /tts, MCP y FIRERED_N_TIMESTEPS, pero el valor por defecto es 10, como en el
upstream: el upstream no lo documenta ni propone tocarlo en ningún sitio, y por debajo de 4
la calidad se vuelve notablemente más basta. Según la misma medición: 10 → ×2.7, 6 → ×1.9,
4 → ×1.3, 2 → ×1.0. Bájalo solo para una tarea concreta y verificando de oído.
Normalización de texto
El TN integrado (wetext) solo conoce chino e inglés, así que para
ucraniano es inútil y no lo instalamos. 19:30, 250 грн, 2026 р.
el modelo lo vocalizará como salga.
Dos salidas:
escribir el texto directamente con palabras;
activar LLM-TN —
FIRERED_TN_API_URL/_API_KEY/_MODELen.env. Sirve cualquier endpoint compatible con OpenAI, incluido el local (llama.cpp / vLLM / Ollama) — entonces todo permanece offline.
Licencia
Código y pesos — Apache 2.0. En el README del upstream se indica por separado que la clonación zero-shot es «solely for academic research purposes» — esto contradice Apache 2.0 y para el uso comercial de voces clonadas mira con cuidado. Para uso doméstico la cuestión no se plantea.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseAqualityCmaintenanceA 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.322MIT
- AlicenseNot gradedqualityBmaintenanceLocal-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 gradedqualityCmaintenanceA 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 gradedqualityCmaintenanceHeadless text-to-speech and speech-to-text server with REST and MCP API, supporting Kokoro TTS and Whisper STT.MIT
Related MCP Connectors
Hosted pay-per-use TTS: 54 neural voices, 9 languages incl. Brazilian Portuguese. $10 free credits.
MCP server exposing the AceDataCloud Fish Audio API (text-to-speech with voice conditioning)
MCP server for Kling AI video generation
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/taral14/firered-tts'
If you have feedback or need assistance with the MCP directory API, please join our Discord server