OmniVoice Real-Time TTS dla Polskiego

Porównanie OmniVoice z Chatterbox na RTX 5090 — opóźnienia, streaming, klonowanie głosu i jakość audio.

Dlaczego polski? — Wszystkie testy przeprowadzono w języku polskim, który jest jednym z najtrudniejszych języków dla systemów syntezy mowy. Polski charakteryzuje się złożonymi grupami spółgłoskowymi (szcz, prz, trz, dż, dź, dz), samogłoskami nosowymi (ą, ę), palatalizacją zależną od kontekstu, wyjątkami od akcentowania oraz rozbudowaną fleksją zmieniającą końcówki wyrazów w zależności od przypadku, rodzaju i liczby. Te wyzwania fonologiczne czynią polski doskonałym testem obciążeniowym dla każdego modelu TTS — jeśli radzi sobie dobrze z polskim, większość innych języków europejskich będzie łatwiejsza.

Modele

OmniVoice

autor: k2-fsa · Apache-2.0 · arXiv:2604.00688

Najnowocześniejszy wielojęzyczny model TTS zero-shot obsługujący ponad 600 języków — najszersza obsługa językowa wśród modeli TTS zero-shot. Wykorzystuje architekturę dyfuzyjnego modelu językowego z 8-warstwowym hierarchicznym koderem audio.

  • Architektura: backbone Qwen3-0.6B (~600M parametrów), iteracyjne dekodowanie dyfuzyjne z maskowaniem
  • Klonowanie głosu: zero-shot na podstawie nagrania referencyjnego + transkrypcji
  • Projektowanie głosu: kontrola płci, wieku, wysokości, akcentu, dialektu, szeptu przez instrukcje tekstowe
  • Paralingwistyka: [laughter], [breath] oraz korekcja wymowy
  • Szybkość: RTF nawet 0.025 (40x szybciej niż w czasie rzeczywistym)
  • Dostępny na: HuggingFace, CLI (omnivoice-infer), demo Gradio

Chatterbox

autor: Resemble AI · Licencja MIT

Rodzina trzech modeli TTS open-source (Chatterbox, Chatterbox-Multilingual, Chatterbox-Turbo) zaprojektowanych do generowania naturalnej mowy z klonowaniem głosu. Wbudowany znak wodny Perth do wykrywania audio generowanego przez AI.

  • Architektura: autoregresywny tokenizer mowy + dekoder mel-spektralny, 350M–500M parametrów
  • Klonowanie głosu: zero-shot na podstawie nagrania referencyjnego
  • Wariant Turbo: 350M parametrów, destylowany do 1-krokowego dekodowania dla agentów głosowych
  • Paralingwistyka: natywne tagi [laugh], [cough], [chuckle]
  • Języki: 23+ (angielski, hiszpański, francuski, niemiecki, polski, chiński, japoński, arabski, hindi itd.)
  • Znak wodny: Perth — przetrwa kompresję MP3, ~100% skuteczności wykrywania
  • Dostępny na: pip install chatterbox-tts, HuggingFace

Przegląd architektury

ChatterboxOmniVoice
Typ modeluAutoregresywny (token po tokenie)Dyfuzja z maskowaniem (iteracyjne odmaskowanie)
BackboneWłasny dekoder T3Qwen3-0.6B LLM (~600M parametrów)
Kodek audioPojedynczy strumień kodowy8-warstwowy hierarchiczny (8×1025 tokenów)
StreamingPrawdziwy streaming token-po-tokenieBrak natywnego streamingu — pełna sekwencja na wywołanie
Klonowanie głosuWarunkowanie embeddingamiTokenizacja audio referencyjnego + prefiks
JęzykiPolski + podstawowy wielojęzyczny600+ języków natywnie

Kluczowa różnica architektoniczna

Chatterbox działa w czasie rzeczywistym, ponieważ streamuje token po tokenie – dekoder autoregresywny emituje tokeny sekwencyjnie, każdy może być natychmiast dekodowany do audio i wysłany. TTFA = czas do wygenerowania pierwszych kilku tokenów.

OmniVoice wykorzystuje dyfuzję z maskowaniem – wszystkie tokeny audio zaczynają jako [MASK] i są iteracyjnie odmaskowane w N krokach. Każdy krok uruchamia pełne przejście przez cały model. Tokeny są ujawniane wg wyniku pewności, nie pozycji. Częściowe audio nie może być dekodowane w trakcie generowania.

Jednak surowa szybkość inferencji OmniVoice jest na tyle duża (RTF 0.01–0.04), że chunking na poziomie tekstu osiąga porównywalne lub lepsze TTFA niż streaming tokenowy Chatterboxa.


Test 1: Bazowa latencja

Pełne generowanie, klonowany głos, bez chunkingu. Całkowity czas od wywołania generate() do zwrócenia tensora.

TekstZnakiAudio32 kroki16 kroków8 kroków
mini121.2–1.5s269ms (RTF 0.222)136ms (RTF 0.094)72ms (RTF 0.054)
krótki664.3s298ms (RTF 0.069)151ms (RTF 0.035)80ms (RTF 0.019)
średni19612.6s503ms (RTF 0.040)255ms (RTF 0.020)137ms (RTF 0.011)
długi48828.5–28.9s849ms (RTF 0.030)446ms (RTF 0.015)255ms (RTF 0.009)
Bazowy — Mini
32 kroki
16 kroków
8 kroków
Bazowy — Krótki
32 kroki
16 kroków
8 kroków
Bazowy — Średni
32 kroki
16 kroków
8 kroków
Bazowy — Długi
32 kroki
16 kroków
8 kroków
  • RTF poprawia się przy dłuższym tekście (stały narzut amortyzowany na więcej audio).
  • 16 kroków to optimum: ~2x szybciej niż 32, degradacja jakości jest minimalna.
  • Przy 8 krokach RTF spada do 0.009–0.054 – 18–110x szybciej niż w czasie rzeczywistym.

Test 2: Streaming chunkowany (pomiar TTFA)

Symulacja streamingu: podział tekstu na granicach zdań, niezależne generowanie każdego chunka, pomiar czasu do pierwszego gotowego chunka.

Tekst średni (196 znaków, 2 chunki)

KrokiTTFA (chunk 0)Audio chunk 0Gen chunk 1Audio chunk 1Łącznie
32335ms7.00s327ms5.80s662ms
16169ms7.00s165ms5.80s333ms
888ms7.00s86ms5.80s173ms
Chunkowany — Średni
32 kroki (2 chunki)
16 kroków (2 chunki)
8 kroków (2 chunki)

Tekst długi (488 znaków, 5 chunków)

KrokiTTFA (chunk 0)ChunkiGen łącznieAudio łącznieRTF
32331ms51605ms29.6s0.054
16168ms5813ms29.6s0.027
887ms5423ms29.6s0.014

Rozkład po chunkach (tekst długi, 16 kroków):

ChunkCzas gen.AudioTreść
0168ms7.00s"Poważny błąd w obiegu dokumentów..."
1165ms5.80s"Przez pomyłkę dokumentacja..."
2150ms4.08s"Incydent został zgłoszony..."
3171ms7.44s"Linia lotnicza przeprosiła..."
4159ms5.32s"Związki zawodowe domagają się..."
Chunkowany — Długi
32 kroki (5 chunków)
16 kroków (5 chunków)
8 kroków (5 chunków)
  • Przy 16 krokach TTFA wynosi 169ms – 32% szybciej niż typowe 250ms Chatterboxa.
  • Każdy chunk generuje ~4–7s audio w ~150–170ms. Bufor odtwarzania jest ogromny.
  • Narzut chunkingu jest minimalny: całkowity czas generowania ~30% wyższy niż single-shot, ale korzyści ze streamingu zdecydowanie to rekompensują.

Test 3: Cache promptu klonowania głosu

create_voice_clone_prompt() wstępnie koduje audio referencyjne do wielokrotnego użycia.

TrybCzas generowania
Surowa ścieżka ref_audio (kodowanie przy każdym wywołaniu)264ms
Wstępnie zcachowany VoiceClonePrompt255ms
Koszt utworzenia promptu37ms (jednorazowo)
Oszczędność na wywołanie9ms (3%)

Kodowanie promptu jest już szybkie (37ms). Cache jest nadal warty implementacji na serwerze, aby uniknąć redundantnego kodowania.


Test 4: Współbieżna inferencja

Ten sam tekst, 3 zapytania

TrybCzas całkowityNa zapytaniePrzyspieszenie
Sekwencyjnie767ms255ms każde1.0x
3x równolegle (pula wątków + strumienie CUDA)462ms436–460ms każde1.66x

Różne długości tekstu, 3 równolegle

ZapytanieTekstLatencjaAudio
0mini (12 znaków)408ms1.51s
1średni (196 znaków)502ms12.58s
2długi (488 znaków)555ms28.61s
Czas całkowity558ms
  • GIL + współdzielone wagi modelu ograniczają prawdziwy paralelizm do ~1.66x przyspieszenia dla 3 wątków.
  • Latencja pojedynczego zapytania wzrasta ~1.8x pod obciążeniem.
  • Wzorzec InferenceSlot + SlotPool z Chatterboxa poprawiłby to dalej.

Test 5: Rozkład pipeline’u

Szczegółowa instrumentacja każdego etapu, średnia z 5 uruchomień na konfigurację. RTX 5090, float16, klonowany głos.

Gdzie idą milisekundy

Pipeline OmniVoice ma 7 etapów. Etapy 1–4 (preprocessing) są pomijalne. Etap 5 (iteracyjne dekodowanie) dominuje – 87–97% całkowitego czasu.

EtapKrótki (66 zn., 4.4s audio)Średni (196 zn., 12.6s audio)
32 kroki16 kr.8 kr.32 kroki16 kr.8 kr.
1. Preprocess/resolve0.0ms0.0ms0.0ms0.0ms0.0ms0.0ms
2. Estymacja czasu trwania0.0ms0.0ms0.0ms0.0ms0.0ms0.0ms
3. Tokenizacja tekstu + wejścia0.4ms0.4ms0.4ms0.5ms0.6ms0.5ms
4. Konstrukcja batcha (CFG)0.2ms0.2ms0.2ms0.2ms0.2ms0.2ms
5. Iteracyjne dekodowanie357ms182ms88ms521ms264ms130ms
   5a. Forward pass LLM330ms166ms82ms491ms246ms122ms
   5b. CFG + wybór tokenów27ms16ms7ms30ms17ms7ms
6. Dekodowanie audio (wokoder)5.5ms3.7ms3.6ms12.3ms8.6ms8.3ms
7. Post-processing3.3ms3.2ms3.1ms9.9ms9.8ms9.7ms
ŁĄCZNIE367ms190ms96ms544ms283ms148ms

Tekst długi (488 zn., 28.5s audio, 950 tokenów)

Etap32 kroki% całkowitego
5a. Forward pass LLM818ms90.5%
5b. CFG + wybór tokenów40ms4.5%
6. Dekodowanie audio (wokoder)21ms2.3%
7. Post-processing24ms2.6%
ŁĄCZNIE905ms100%

Koszt per krok

Każdy krok dyfuzji uruchamia pełny forward pass Qwen3-0.6B na całej sekwencji. Koszt skaluje się z długością sekwencji:

TekstDługość sekwencjiKoszt per krok
Krótki (66 zn.)220 tokenów~11ms
Średni (196 zn.)465 tokenów~16ms
Długi (488 zn.)950 tokenów~27ms

Wszystkie kroki mają jednakowy koszt – żaden nie jest istotnie droższy. Zmniejszenie liczby kroków o połowę zmniejsza czas LLM prawie dokładnie o połowę.

Kluczowe wnioski

  • Forward pass LLM = 87–91% całkowitego czasu. Reszta to szum pomiarowy.
  • Tokenizacja tekstu: <1ms. Pomijalna nawet dla długiego tekstu.
  • Estymacja czasu trwania: <0.1ms. Reguły, bez sieci neuronowej.
  • CFG + wybór tokenów: 5–8%. Matematyka classifier-free guidance, próbkowanie Gumbela, top-k.
  • Dekodowanie audio (wokoder): 4–21ms. HiggsAudioV2 na GPU. Skaluje się z czasem trwania audio.
  • Post-processing: 3–24ms. Usuwanie ciszy przez pydub (CPU). Liniowo z długością audio.
  • Cel optymalizacji: Zmniejszenie kosztu forward pass (kwantyzacja, flash attention, KV caching) dałoby prawie liniowe przyspieszenie.

Test 6: Streaming zoptymalizowany pod pierwszy chunk

Najlepsza strategia: podział na pierwszym zdaniu, generowanie krótkiego pierwszego chunka dla minimalnego TTFA, reszta generuje się podczas odtwarzania pierwszego chunka.

KrokiTTFAPierwszy chunk graCzas gen. resztyPrzerwa?
32335ms7.00s700msNie — reszta gotowa 6.3s wcześniej
16169ms7.00s357msNie — reszta gotowa 6.6s wcześniej
887ms7.00s185msNie — reszta gotowa 6.8s wcześniej
Zoptymalizowany streaming — Tekst długi
32 kroki
16 kroków
8 kroków

Nawet dla najdłuższego tekstu (488 znaków, 29s audio) nie ma żadnej przerwy w odtwarzaniu przy żadnej liczbie kroków. Pierwszy chunk generuje 7s audio, zapewniając ogromne okno buforowania. Margines wynosi 6–7 sekund – wystarczająco na jitter sieciowy, kodowanie i buforowanie po stronie klienta.


Test 7: Profil pamięci GPU

ScenariuszSzczytowy VRAM
Model załadowany (idle)5.41 GB
1 inferencja5.61 GB
3 równoległe inferencje5.87 GB
Zapas na 32 GB26.1 GB wolne
Szacowane max równoległych~5

Przyrostowy koszt na równoległą inferencję to ~150 MB. Duży zapas na dodatkowe instancje modelu lub równoległe zapytania.


OmniVoice vs Chatterbox

MetrykaChatterboxOmniVoice (16 kroków)Zwycięzca
TTFA~250ms169msOmniVoice
RTF (tekst średni)0.05–0.100.020OmniVoice
Typ streaminguPrawdziwy token-po-tokenieNa poziomie chunkówChatterbox
Przerwy w odtwarzaniuBrakBrak (bufor 7s)Remis
Jakość głosuDobraDoskonałaOmniVoice
Klonowanie głosuWarunkowanie embeddingamiAudio ref. + tekstOmniVoice
JęzykiPolski + ograniczone600+OmniVoice
Zużycie VRAM4–6 GB5.6 GBRemis
Równoległych użytkowników3–4 z pulą slotów3–5 na jednym GPURemis

Chatterbox vs OmniVoice – odsłuch (głos weronika)

Ten sam tekst, ten sam głos (weronika), ten sam GPU. Chatterbox wygenerowany przez serwer produkcyjny. OmniVoice przy 16 krokach (rekomendowane) i 32 krokach (najlepsza jakość).

Mini – “Dzień dobry.”

Chatterbox

OmniVoice 16 kroków

Krótki – zdanie informacyjne (66 znaków)

Chatterbox

OmniVoice 16 kroków

Średni – incydent PLL LOT (196 znaków)

Chatterbox

OmniVoice 16 kroków

Chatterbox (ten sam)

OmniVoice 32 kroki

Długi – pełna wiadomość (488 znaków)

Chatterbox

OmniVoice 16 kroków

Chatterbox (ten sam)

OmniVoice 32 kroki


Porównania wewnętrzne OmniVoice

Kompromisy między liczbą kroków a chunkingiem.

32 vs 16 kroków (tekst średni)

32 kroki (referencyjna jakość)

16 kroków (rekomendowane)

Bazowy vs Chunkowany (tekst średni, 16 kroków)

Bazowy (pojedyncze generowanie)

Chunkowany (2 chunki, symulacja streamingu)

Dolna granica jakości – 8 kroków (tekst średni)

32 kroki (najlepsza jakość)

8 kroków (najszybsze, 87ms TTFA)

Zoptymalizowany streaming vs Bazowy (tekst długi)

Bazowy 16 kroków (single shot)

Zoptymalizowany 16 kroków (chunked stream)


Paralingwistyka: tagi dźwięków niewerbalnych

OmniVoice obsługuje ekspresyjne tagi niewerbalne osadzone bezpośrednio w tekście. Wszystkie próbki: polski, głos klonowany (weronika), 16 kroków.

Obsługiwane tagi: [laughter], [sigh], [confirmation-en], [question-ah], [question-oh], [question-ei], [question-yi], [surprise-ah], [surprise-oh], [surprise-wa], [surprise-yo], [dissatisfaction-hnn]

TagTekstGen.Audio
[laughter]"...to się stało [laughter] naprawdę nie mogę."156ms3.91s
[sigh]"No cóż [sigh] trzeba było to przewidzieć."150ms2.41s
[confirmation-en]"[confirmation-en] tak, dokładnie o to mi chodziło."152ms2.77s
[question-ah]"Naprawdę tak uważasz [question-ah] bo ja mam wątpliwości."153ms3.68s
[question-oh]"[question-oh] a to ciekawe, kiedy to się stało?"151ms2.74s
[question-ei]"Mówisz poważnie [question-ei] nie żartujesz?"147ms2.71s
[surprise-ah]"[surprise-ah] nie spodziewałam się tego!"146ms2.61s
[surprise-oh]"[surprise-oh] to niesamowite co się wydarzyło."151ms2.76s
[surprise-wa]"[surprise-wa] ale rewelacja, nie do wiary!"150ms2.30s
[surprise-yo]"Wygraliśmy konkurs [surprise-yo] fantastycznie!"148ms3.08s
[dissatisfaction-hnn]"[dissatisfaction-hnn] no nie wiem, to mnie nie przekonuje."155ms3.38s
Mix (4 tagi)"...co się stało [question-ah] ...wygrali [surprise-oh] ...stracili [sigh] ...[dissatisfaction-hnn] trzeba było..."247ms10.44s
Bez tagów (kontrolna)"Nie mogę uwierzyć, że to się stało, naprawdę nie mogę."153ms3.40s
Emocje i reakcje
"...to się stało [laughter] naprawdę nie mogę."
"No cóż [sigh] trzeba było to przewidzieć."
"[confirmation-en] tak, dokładnie o to mi chodziło."
"[dissatisfaction-hnn] no nie wiem, to mnie nie przekonuje."
Pytania
"Naprawdę tak uważasz [question-ah] bo ja mam wątpliwości."
"[question-oh] a to ciekawe, kiedy to się stało?"
"Mówisz poważnie [question-ei] nie żartujesz?"
Zaskoczenie
"[surprise-ah] nie spodziewałam się tego!"
"[surprise-oh] to niesamowite co się wydarzyło."
"[surprise-wa] ale rewelacja, nie do wiary!"
"Wygraliśmy konkurs [surprise-yo] fantastycznie!"
Mix emocji (4 tagi w jednym zdaniu)
"Słyszałeś co się stało [question-ah] okazuje się że wygrali [surprise-oh] a potem wszystko stracili [sigh] no i co tu dużo mówić [dissatisfaction-hnn] trzeba było lepiej planować."
Kontrolna (bez tagów)
"Nie mogę uwierzyć, że to się stało, naprawdę nie mogę."

Wszystkie tagi generują wyraźne dźwięki niewerbalne w oznaczonych miejscach. Próbka mieszana (4 tagi, 10.44s) demonstruje naturalny przepływ między mową a emocjami. Czas generowania pozostaje stały (~150ms) niezależnie od liczby tagów; próbka mieszana jest dłuższa (247ms) tylko dlatego, że sam tekst jest dłuższy.


Wnioski

OmniVoice jest gotowy do użycia w streamingu TTS w czasie rzeczywistym i przewyższa Chatterbox pod względem surowych metryk szybkości. Architektura dyfuzji z maskowaniem uniemożliwia prawdziwy streaming na poziomie tokenów, ale chunking na poziomie zdań osiąga TTFA 169ms przy 16 krokach z zerowymi przerwami w odtwarzaniu. W połączeniu z doskonałą jakością głosu, obsługą 600+ języków i niskim zużyciem VRAM, OmniVoice jest mocnym kandydatem do produkcyjnego wdrożenia TTS.

W sprawie konsultacji dotyczących integracji TTS w czasie rzeczywistym, architektury streamingu lub inżynierii AI/ML, skontaktuj się z Folx.