Skip to main content
Glama

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:

  1. .venv mit Python 3.11, torch 2.8.0 für MPS/CPU

  2. klont das Upstream-Repository nach vendor/FireRedTTS3 auf dem festgepinnten Commit 00570ad

  3. patcht es für Apple Silicon – siehe unten

  4. 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

llm/fireredtts3_base.py:49

attn_implementation: flash_attention_2

sdpa

redae/redae.py:37,122

dasselbe, ×2

sdpa

base.py:143, instruct.py:142, redae.py:470

@torch.autocast(device_type='cuda')

dynamisches Gerät

base.py:267, instruct.py:319

self.device = torch.device('cuda')

aus FIRERED_DEVICE

utils/utils.py:8,9

torch.cuda.manual_seed ohne Prüfung

unter if cuda.is_available()

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:8020

Ein 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

GET

/health

Status, Gerät, welches Modell im Speicher ist

GET

/voices

Stimmnamen wie bei den Nachbarn (Filter gender, language; full=1 → mit Metadaten)

GET

/languages

24 Sprachen + 21 Dialekt

POST

/clone_voice

Referenz + Transkript → Stimme

DELETE

/voices/{name}

Stimme löschen (Originalaufnahme bleibt unberührt)

POST

/tts

Text → Audio-Bytes in der Antwort

POST

/synthesize

Text → Datei in DATA_DIR, JSON mit Pfad

POST

/voice_design

Stimmbeschreibung → Audio (instruct)

POST

/edit

Aufnahme bearbeiten: semantic | acoustic (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.mp3

MCP

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.py

Werkzeuge: 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 – base oder instruct; 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.sh sperrt 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 – int8 auf 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:

  1. den Text direkt in Worten schreiben;

  2. LLM-TN aktivieren – FIRERED_TN_API_URL / _API_KEY / _MODEL in .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.

F
license - not found
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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

View all related MCP servers

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

View all MCP Connectors

Latest Blog Posts

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