firered-tts
FireRedTTS3 — mehrsprachiges TTS (24 Sprachen, inkl. Ukrainisch)
Lokaler Sprachsynthese-Dienst auf Basis von FireRedTTS3 mit HTTP-API und MCP-Server. Der dritte in der Reihe neben ukrainian-tts (StyleTTS2, :8000) und HolosTTS (:8010); dieser hier auf :8020.
Das Modell erschien am 13.08.2026, Lizenz Apache 2.0, die Gewichte sind öffentlich.
Wie es sich von den Nachbarn unterscheidet
ukrainian-tts | HolosTTS | firered-tts | |
Sprachen | Ukrainisch | Ukrainisch | 24 + 21 Dialekt |
Preset-Stimmen | ja | 27 | überhaupt keine |
Klonen | nein | ja (Stilvektor) | ja (Zero-Shot) |
Referenztranskript nötig | — | nein | ja |
Stimmdesign aus Beschreibung | nein | nein | ja (instruct) |
Bearbeitung von Aufnahmen | nein | nein | ja (instruct) |
Speicherbedarf | ~1 GB | ~4 GB | ~7,7 GB Gewichte, ~13 GB Prozessspeicher |
Betonungen (ukr.) | Wörterbuch + ByT5 | Wörterbuch + ByT5 | keine |
Drei Dinge, die man verstehen sollte, bevor man loslegt:
1. Es gibt keine Preset-Stimmen. Leere Bibliothek = nichts zum Synthetisieren. Zuerst legst du eine Stimme aus einer beliebigen Sprachaufnahme an (add_firered_voice), dann nutzt du sie unter ihrem Namen. Das Modell klont Zero-Shot direkt während der Synthese.
2. Ein Referenztranskript ist erforderlich. Das Modell braucht mehr als nur das Audio – es braucht auch den Text dessen, was darin zu hören ist. Wenn du keins übergibst, erkennen wir es mit Whisper, aber der eigene Text ist immer genauer.
3. Es gibt keine Betonungen. Weder Wörterbuch noch ByT5-Fallback noch manuelles Му+дрого wie bei den Nachbarn. Das Modell setzt die Betonungen selbst aus dem Kontext, und bei Homographen (за́мок/замо́к) wird es sie verwechseln. Das ist eine grundsätzliche Einschränkung des mehrsprachigen Modells – wenn Betonungen kritisch sind, ist HolosTTS für reines Ukrainisch immer noch die bessere Wahl.
Related MCP server: STT2TTS MCP
Installation
cd /Users/admin/Projects/firered-tts
./setup.sh # venv + залежності + апстрім + патч + вагиsetup.sh erledigt vier Dinge:
.venvmit Python 3.11, torch 2.8.0 für MPS/CPUklont das Upstream-Repository nach
vendor/FireRedTTS3auf dem festgepinnten Commit00570adpatcht es für Apple Silicon – siehe unten
lädt die Gewichte base+redae (~11,4 GB) nach
pretrained_models/
Die Gewichte separat (dauert lange – besser detached):
nohup ./download-weights.sh base > data/download.log 2>&1 &
./download-weights.sh instruct # +7.9 ГБ, для дизайну голосу й редагуванняWozu der Patch
Das Upstream-Repository ist ausschließlich für NVIDIA geschrieben und läuft auf dem Mac überhaupt nicht:
Stelle | Vorher | Nachher |
|
|
|
| dasselbe, ×2 |
|
|
| dynamisches Gerät |
|
| aus |
|
| unter |
flash_attn ist CUDA-only und lässt sich auf Metal grundsätzlich nicht bauen; sdpa funktioniert überall, auch auf NVIDIA, der Patch bricht also nichts.
Die zehnte Stelle im Patch steht separat: base.py:317 betrifft nicht die Portabilität, sondern die Geschwindigkeit (Cache der Referenzkodierung, siehe „Geschwindigkeit“ unten).
src/patch_upstream.py ist idempotent und schlägt fehl, wenn der Ersatz nicht greift – wenn sich das Upstream-Repository geändert hat, erfährst du das sofort und nicht durch einen CUDA-Fehler bei der ersten Synthese.
Start
./run.sh # http://localhost:8020Ein separater Start ist nicht nötig – der MCP-Server startet das Backend selbst. Das Backend fährt nach 1800 s Inaktivität herunter (IDLE_SHUTDOWN_SECONDS) und gibt den Speicher frei.
run.sh hält eine Sperre auf dem Port (data/.start-<порт>.lock): Ein zweiter Start bei laufendem Dienst endet einfach mit Code 0. Das ist beabsichtigt – den Autostart stoßen mehrere Clients gleichzeitig an, und /health schweigt während der gesamten ~90 s Ladezeit.
HTTP API
Methode | Endpunkt | Funktion |
|
| Status, Gerät, welches Modell im Speicher ist |
|
| Stimmnamen wie bei den Nachbarn (Filter |
|
| 24 Sprachen + 21 Dialekt |
|
| Referenz + Transkript → Stimme |
|
| Stimme löschen (Originalaufnahme bleibt unberührt) |
|
| Text → Audio-Bytes in der Antwort |
|
| Text → Datei in |
|
| Stimmbeschreibung → Audio (instruct) |
|
| Aufnahme bearbeiten: |
# 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
Siehe mcp_server/README.md. Kurz:
claude mcp add firered-tts -- /Users/admin/Projects/firered-tts/.venv/bin/python \
/Users/admin/Projects/firered-tts/mcp_server/server.pyWerkzeuge: firered_backend_status, list_firered_voices, add_firered_voice, delete_firered_voice, synthesize_firered_speech, design_firered_voice, edit_firered_speech.
Speicher und Geschwindigkeit
Mac mini M4, 16 GB. Auf der Platte base (7,9) + redae (3,5) = 11,4 GB, aber in den Speicher gehen ~7,7 GB: Das LLM-Backbone wird in fp16 geladen (4,2 statt 8,4 – siehe Optimierung 2 unten), der Rest bleibt fp32.
Die Gewichte sind nicht das ganze Bild. Gemessen an einem laufenden Prozess nach der Synthese:
phys_footprint: 13 ГБ
phys_footprint_peak: 14 ГБDer Unterschied zwischen 7,7 und 13 ist der MPS-Allokator-Cache, der KV-Cache und die Aktivierungen der Generierung. Bei 16 GB ist das selbst mit einem Prozess knapp, und ps/RSS lügt hier (zeigt Zehntel Gigabyte an: MPS-Puffer im Unified Memory tauchen im RSS nicht auf). Miss den footprint, nicht ps.
Die Konsequenzen, die im Code verankert sind:
Im Speicher liegt genau ein Modell –
baseoderinstruct; das Umschalten bedeutet ein vollständiges Neuladen (Minuten, wird laut protokolliert);Die Synthese ist durch eine globale Sperre serialisiert – zwei parallele Anfragen ergeben bei 16 GB einen OOM, keine Beschleunigung;
run.shsperrt den Port – andernfalls würden mehrere Clients, die gleichzeitig den Autostart auslösen, jeweils eine eigene Backend-Instanz starten (realer Fall: sieben Prozesse bei 16 GB);Automatisches Herunterfahren nach 1800 s Leerlauf – bewusst länger als bei den Nachbarn: Ein Neustart kostet ~40 s Shader-Kompilierung, daher ist es günstiger, den Prozess am Leben zu halten;
Whisper für die Transkription –
int8auf der CPU, wird direkt nach der Erkennung entladen.
Geschwindigkeit und vier Optimierungen
Ein naiver Start des Upstreams auf dem M4 ergab ×189 Echtzeit – 3 Sekunden Ukrainisch wurden in 9,5 Minuten berechnet. Drei Korrekturen ergaben ×4,0, also 48-mal schneller; die vierte brachte es auf ×2,7. Was genau falsch war (gemessen mit tools/profile_steps.py und Instrumentierung):
1. Autocast im AR-Schleifenschritt – das Hauptproblem. Das Upstream-Repository hängt @torch.autocast als Dekorator an _backbone_one_step, d. h. der Autocast-Bereich wird bei JEDEM Autoregressionsschritt geöffnet und geschlossen. Der Cache für das Umwandeln der Gewichte in torch lebt nur innerhalb des Bereichs, also wurden 1,7 Mrd. fp32-Parameter bei jedem Schritt in half umgewandelt. Backbone-Schritt: 19000 ms → 2710 ms. Jetzt ist Autocast standardmäßig deaktiviert und die Umwandlung erfolgt explizit an der Backbone-Grenze.
2. Backbone in fp32. Die Gewichte sind in float32 gespeichert (3,0 Mrd. Parameter = 11,4 GB), was bei 16 GB einen Swap bedeutet. Wir wandeln nur das LLM-Backbone in half um (4,2 GB statt 8,4), lassen aber redae und den Flow-Decoder in fp32 – das Upstream-Repository arbeitet dort bewusst mit voller Genauigkeit, und half bricht MPS-matmul. Schritt: 2710 → 1387 ms.
3. Kompilierung der Metal-Shader. Der größte Teil der „Langsamkeit“ erwies sich als einmalig: Metal kompiliert die Kernel bei der ersten Ausführung. Einzelmessungen des Backbone-Schritts: 9873, 2104, 120, 93, 96, 97… ms. Deshalb macht der Dienst beim Start ein Warm-up (FIRERED_WARMUP=1) und hat ein langes Leerlauf-Timeout – ein Neustart kostet ~40 Sekunden Kompilierzeit.
4. Cache der Referenzkodierung. generate() wird für JEDEN Satz aufgerufen, und jeder Aufruf ließ den Redae-Encoder erneut über die Referenzaufnahme laufen – 5,58 s jedes Mal, unabhängig von der Textlänge. Der Cacheschlüssel ist der Audioinhalt, nicht die Tensor-ID, der Cache kann also keine Stimme austauschen. Bei einem Lauf mit 6,6 min Audio (14 Chunks): 30 Treffer bei 2 Fehlversuchen ≈ 150 s, also ~11 % der Zeit.
Eine Minute Audio wird in ~2,7 Minuten berechnet (Mac mini M4 / 16 GB, vorgewärmtes Modell, warmer Referenzcache; bester von 5 abwechselnden Läufen mit 3,0 s Ukrainisch, der Median ergibt ×2,9). Echtzeit ist das nicht, aber es ist bereits ein Arbeitsgerät und kein „lass es über Nacht laufen“.
Profil der vorgewärmten Generierung: Flow-Decoder 57 %, Backbone 18 %, Redae 11 %.
n_timesteps – ODE-Schritte im Flow-Decoder, dem teuersten Teil. Der Parameter ist in /tts, MCP und FIRERED_N_TIMESTEPS verfügbar, aber der Standardwert ist 10, wie im Upstream: Das Upstream-Repository dokumentiert ihn nicht und schlägt nirgends vor, ihn zu verstellen, und unter 4 wird die Qualität merklich gröber. Nach derselben Messung: 10 → ×2,7, 6 → ×1,9, 4 → ×1,3, 2 → ×1,0. Senke ihn nur für eine konkrete Aufgabe und mit Hörprobe.
Textnormalisierung
Das eingebaute TN (wetext) kann nur Chinesisch und Englisch, für Ukrainisch ist es also nutzlos und wir installieren es nicht. 19:30, 250 грн, 2026 р. spricht das Modell so aus, wie es eben geht.
Zwei Auswege:
den Text direkt in Worten schreiben;
LLM-TN aktivieren –
FIRERED_TN_API_URL/_API_KEY/_MODELin.env. Jeder OpenAI-kompatible Endpunkt funktioniert, auch ein lokaler (llama.cpp / vLLM / Ollama) – dann bleibt alles offline.
Lizenz
Code und Gewichte – Apache 2.0. Im README des Upstreams steht ausdrücklich, dass Zero-Shot-Klonen „solely for academic research purposes“ ist – das widerspricht Apache 2.0, und bei der kommerziellen Nutzung geklonter Stimmen solltest du vorsichtig sein. Für den privaten Gebrauch stellt sich die Frage nicht.
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