← Blog
AI17 min czytania

Chatterbox TTS — własny serwer syntezy mowy z API zgodnym z OpenAI

Serwer FastAPI stawiający modele Chatterbox od Resemble AI za jednym API zgodnym z OpenAI, z panelem webowym, przełączaniem silników bez restartu i dzieleniem tekstu na potrzeby audiobooków. Model wielojęzyczny obsługuje polski, a wagi są na MIT. Omawiamy też znakowanie wodne obecne w każdym wygenerowanym pliku oraz to, czego dokumentacja nie mówi o zgodzie na klonowanie głosu.

Synteza mowy jako usługa jest tania, dopóki nie liczy się jej w milionach znaków. Audiobook, system zapowiedzi telefonicznych albo lektor do kilkuset materiałów szkoleniowych przekraczają ten próg szybko — a wtedy pojawiają się dwa pytania, które klient zadaje w tej samej rozmowie: ile to będzie kosztować miesięcznie i gdzie trafiają teksty, które wysyłamy do przetworzenia.

Na oba jest jedna odpowiedź: własny serwer syntezy mowy. Problem polega na tym, że modele TTS są rozprowadzane jako biblioteki do Pythona, a nie jako usługi — i droga od „mamy wagi modelu" do „mamy endpoint, do którego strzela aplikacja" bywa dłuższa, niż wygląda.

Chatterbox TTS Server (github.com/devnen/Chatterbox-TTS-Server) jest tą drogą skróconą do jednego polecenia: serwer FastAPI wystawiający modele Chatterbox od Resemble AI przez API zgodne z OpenAI, z panelem webowym, przełączaniem silników bez restartu i obsługą tekstów o długości książki.

Dwie warstwy i dwie licencje do sprawdzenia

Przy narzędziach opartych na modelach trzeba zawsze rozdzielić kod od wag, bo licencje bywają różne. Tutaj sprawdziłem obie i wynik jest nietypowo prosty.

Model — resemble-ai/chatterbox, 26 331 gwiazdek, ostatni push z lipca 2026, licencja MIT. Co ważniejsze: wagi na Hugging Face też są na MIT i nie są objęte bramką — model podstawowy ma tam 1,8 miliona pobrań. To rzadka sytuacja, bo większość otwartych modeli mowy chodzi na licencjach niekomercyjnych albo wymaga akceptacji warunków przed pobraniem.

Serwer — devnen/Chatterbox-TTS-Server, 1438 gwiazdek i 354 forki, repozytorium założone 31 maja 2025, kod w Pythonie, licencja MIT, 53 otwarte zgłoszenia, ostatni push z 26 maja 2026. Commity z ostatnich tygodni przed tą datą pochodzą w dużej części od osób z zewnątrz, w tym od inżyniera AMD dokładającego obsługę architektury RDNA4 w Dockerze.

Cztery miesiące bez pushu przy projekcie opakowującym cudzy model mają jedną konkretną konsekwencję, którą trzeba znać: Resemble AI wydało w lipcu 2026 modele Multilingual V3 oraz Nano, a README serwera nie wspomina ani o jednym, ani o drugim. Sprawdziłem to wprost — w dokumentacji serwera nie ma ani jednego wystąpienia tych nazw. Serwer obsługuje rodzinę w składzie z wersji 2.0: Original, Multilingual i Turbo.

Rodzina modeli i co z niej wybrać

  • Original Chatterbox — 0,5 mld parametrów, szkielet LLaMA, tylko angielski, sterowanie przesadą emocjonalną, trenowany na 0,5 mln godzin oczyszczonych danych,
  • Chatterbox Multilingual — ta sama wielkość, 23 języki, klonowanie głosu bez uczenia i sterowanie emocjami. Polski jest na liście — obok arabskiego, chińskiego, duńskiego, niderlandzkiego, angielskiego, fińskiego, francuskiego, niemieckiego, greckiego, hebrajskiego, hindi, włoskiego, japońskiego, koreańskiego, malajskiego, norweskiego, portugalskiego, rosyjskiego, hiszpańskiego, szwedzkiego, suahili i tureckiego,
  • Chatterbox-Turbo — 350 mln parametrów, z dekoderem zdestylowanym z dziesięciu kroków do jednego, co usuwa główne wąskie gardło generowania. Do tego znaczniki paralingwistyczne wpisywane wprost w tekst: [laugh], [cough], [chuckle],
  • Chatterbox-Nano — 110 mln parametrów, ta sama architektura co Turbo, trzy razy szybciej niż w czasie rzeczywistym na ośmiu rdzeniach procesora. Model dla wdrożeń bez karty graficznej — ale, jak wyżej, serwer go jeszcze nie obsługuje,
  • Single Language Pack — sześć dedykowanych dostrojeń dla wybranych języków i wariantów regionalnych.

Dla polskich projektów wybór jest więc w praktyce jeden: Multilingual. Warto to powiedzieć wprost, bo Turbo i Nano — czyli modele szybkie i tanie w zasobach — są tylko angielskie.

Co dodaje serwer

Sam model jest biblioteką. Serwer dokłada warstwę, która zamienia go w usługę:

  • Endpoint zgodny z OpenAI — /v1/audio/speech oraz /v1/audio/voices do listowania głosów. To jest najważniejsza funkcja z punktu widzenia integracji: kod, który dziś woła API OpenAI, wystarczy przestawić na inny adres bazowy. Żadnej zmiany w aplikacji,
  • Własny endpoint /tts wystawiający wszystkie parametry generowania, plus interaktywna dokumentacja pod /docs,
  • Panel webowy z selektorem silnika u góry — przełączanie między trzema modelami bez restartu i bez zmian w konfiguracji. Do testów porównawczych jakości i szybkości jest to różnica między pięcioma minutami a godziną,
  • Dzielenie długich tekstów na fragmenty po granicach zdań, generowanie osobno i sklejanie — z parametrami split_text i chunk_size (od 50 do 500, domyślnie 120). To jest mechanizm, na którym stoi generowanie audiobooków,
  • Przetwarzanie końcowe — opcjonalne obcinanie ciszy, naprawa pauz wewnętrznych i usuwanie długich fragmentów bezdźwięcznych oraz artefaktów,
  • Powtarzalność — głosy predefiniowane albo klonowanie z ustalonym ziarnem losowym dają ten sam głos w kolejnych przebiegach. Przy audiobooku generowanym przez kilka dni jest to warunek konieczny,
  • Presety ładowane z pliku ui/presets.yaml, odtwarzacz z przebiegiem falowym, tryb ciemny i zapamiętywanie ostatnich ustawień.

Wydanie 2.0: rzeczy operacyjne

Ostatnie duże wydanie jest w większości o rzeczach, które widać dopiero przy prawdziwym obciążeniu:

  • Strumieniowanie — parametr stream: true na /tts zwraca odpowiedź strumieniową, wypychając bajty WAV po każdym fragmencie, z przejściami krzyżowymi o długości 20 ms. Domyślne zachowanie pozostaje bez zmian,
  • Pamięć podręczna warunkowania głosem — powtórne żądania z tym samym głosem odniesienia pomijają ponowne kodowanie. Klucz to trójka: ścieżka, czas modyfikacji pliku i wartość przesady emocjonalnej. Czyszczona automatycznie przy przeładowaniu modelu,
  • Wnioskowanie w BF16 — zmienna TTS_BF16=on albo =auto daje około 40% większą przepustowość na kartach obsługujących ten format. Domyślnie wyłączone, żeby aktualizacja nie zmieniła zachowania, a różnica w wyjściu jest opisana jako zwykle niesłyszalna,
  • HTTPS bez odwrotnego proxy — wystarczy podać w konfiguracji ścieżki do certyfikatu i klucza,
  • /api/unload — zwolnienie pamięci karty graficznej bez restartu serwera. Przy jednej karcie dzielonej między usługi jest to funkcja pierwszej potrzeby,
  • Poprawka dzielenia tekstu — pauzy myślnikowe w tekście narracyjnym przestały być traktowane jako punkty listy pochłaniające resztę akapitu.

Sprzęt i instalacja: jedna twarda wersja Pythona

Macierz zgodności sprzętowej jest nietypowo szczegółowa i sama w sobie mówi, ile pracy zajmuje utrzymanie takiego opakowania:

  • tylko procesor — bez wymagań sterowników,
  • NVIDIA RTX 20/30/40 — sterownik 525 lub nowszy,
  • NVIDIA Blackwell (RTX 5090, sm_120) — osobny zestaw zależności z PyTorch 2.9 i CUDA 12.8, sterownik 570+,
  • NVIDIA DGX Spark (sm_121) — CUDA 13.0 i PyTorch 2.10, tylko przez Dockera,
  • AMD RX 6000/7000 na Linuksie — ROCm 6.4+; Strix Halo i RDNA4 — ROCm 7.2, również tylko w Dockerze,
  • Apple Silicon — instalacja ręczna, macOS 12.3+.

Jest natomiast jedno wymaganie bezwzględne, o które łatwo się rozbić: Python 3.10 i tylko 3.10. Dokumentacja uzasadnia to konkretnie — jest to jedyna wersja, dla której istnieją gotowe pakiety binarne wszystkich zależności, a na 3.11 i nowszych instalacja potrafi się wywalić na braku kół. Z tego samego powodu Chatterbox jest instalowany z flagą --no-deps na wszystkich ścieżkach, a jego zależności są wypisane jawnie z przypiętym onnx==1.16.0. Autor rozwiązał to na Windowsie trybem przenośnym z osadzonym Pythonem 3.10 — cały katalog projektu da się skopiować na pendrive'a i uruchomić na maszynie bez Pythona.

Do tego jest zautomatyzowany program uruchamiający, który tworzy środowisko, dobiera zależności pod sprzęt, pobiera model i otwiera panel, oraz obraz Dockera z trwałymi wolumenami na model, głosy, wyjścia i konfigurację. Modele ściągają się z Hugging Face przy pierwszym starcie — dokumentacja uczciwie ostrzega, że to kilka gigabajtów i kilka minut, a serwer stanie się dostępny dopiero po zakończeniu pobierania.

Bezpieczeństwo: jedna naprawiona luka i wniosek z niej

W wydaniu 2.0 naprawiono przechodzenie po katalogach (CWE-22) w parametrach wskazujących pliki głosów — zarówno na /tts (predefined_voice_id, reference_audio_filename), jak i na /v1/audio/speech (voice). Ścieżki są teraz ograniczone do skonfigurowanych katalogów funkcją safe_resolve_within(), a próby wyjścia poza piaskownicę — także przez ścieżki bezwzględne i odnośniki symboliczne — kończą się kodem 400 bez dostępu do systemu plików. Projekt ma też politykę prywatnego zgłaszania podatności przez zakładkę bezpieczeństwa.

Naprawa jest dobrą wiadomością, ale wniosek z jej istnienia jest ważniejszy: to nie jest usługa do wystawienia w internecie. Serwer nie ma uwierzytelniania, kont ani limitów zapytań. Traktowałbym go tak, jak każdą usługę wewnętrzną z modelem: za odwrotnym proxy z uwierzytelnianiem, w sieci prywatnej, z dostępem tylko dla aplikacji, która go używa.

Znak wodny w każdym pliku

Rzecz, o której warto wiedzieć przed pierwszym wygenerowanym plikiem, bo dotyczy każdego wyjścia bez wyjątku. Każdy plik dźwiękowy wytworzony przez Chatterboksa zawiera znak wodny PerTh — niesłyszalny znak neuronowy wstawiany przez bibliotekę Resemble AI.

Właściwości są opisane wprost i mają praktyczne znaczenie: znak przetrwa kompresję do MP3, edycję dźwięku i typowe manipulacje, zachowując przy tym wykrywalność bliską stu procentom. Wykrycie to kilka linii, z tym samym znakownikiem, którym znak został wstawiony:

watermarked_audio, sr = librosa.load(AUDIO_PATH, sr=None)

watermarker = perth.PerthImplicitWatermarker()
watermark = watermarker.get_watermark(watermarked_audio, sample_rate=sr)

print(f"Extracted watermark: {watermark}")
# 0.0 = brak znaku, 1.0 = plik znakowany

Warto wiedzieć, że biblioteka znakująca jest przy tym częścią ścieżki krytycznej instalacji: dokumentacja serwera wspomina, że program uruchamiający jawnie instaluje setuptools, bo biblioteka perth potrzebuje go w czasie działania, i dodatkowo uodparnia inicjalizację znakownika. Innymi słowy — znakowanie nie jest dodatkiem, który da się po cichu pominąć.

Nie jest to zabezpieczenie, które komukolwiek przeszkadza w pracy — jest to ślad pochodzenia. Warto go rozumieć w obie strony. Z jednej: wygenerowany materiał da się rozpoznać jako syntetyczny, więc nie da się go wiarygodnie podać za nagranie. Z drugiej: jeśli materiał robimy dla klienta jawnie jako syntezę, znak wodny jest raczej zaletą — dowodzi, że plik powstał maszynowo, a nie z nagrania kogoś, kto mógłby mieć do niego prawa.

Klonowanie głosu, czyli część, której dokumentacja nie napisała

Serwer oferuje klonowanie głosu z pojedynczego pliku odniesienia i robi to jednym przesłaniem pliku. Przeszukałem dokumentację pod kątem słów o zgodzie, legalności i etyce — nie ma tam ani jednego takiego akapitu. Repozytorium modelu ma jedno zdanie zastrzeżenia sprowadzające się do prośby, żeby nie robić z nim złych rzeczy. To za mało dla kogokolwiek, kto ma to wdrożyć u klienta, więc uzupełniam.

Głos jest daną osobową. W realiach RODO nagranie głosu identyfikowalnej osoby jest jej daną osobową, a przetworzenie go w model umożliwiający syntezę wypowiedzi tej osoby jest przetwarzaniem wymagającym podstawy prawnej. W praktyce oznacza to zgodę wyrażoną wprost, obejmującą określony cel, zakres i czas — nie zgodę domniemaną z faktu, że nagranie było dostępne.

Do tego dochodzą prawa niezależne od ochrony danych. Głos lektora albo aktora jest przedmiotem praw pokrewnych i warunków umowy, a nagranie reklamowe czy szkoleniowe zwykle jest licencjonowane na konkretne użycie. Wytworzenie z niego modelu i wygenerowanie nowych zdań jest użyciem, którego ta umowa nie przewidywała.

Praktyczne reguły, które stosowałbym w projekcie agencyjnym:

  • Do materiałów produkcyjnych używaj głosów predefiniowanych, dostarczonych z narzędziem. Nie wymagają niczyjej zgody i są powtarzalne,
  • Klonowanie tylko na podstawie pisemnej zgody osoby, z wpisanym celem, zakresem materiałów i czasem obowiązywania,
  • Nigdy z nagrań znalezionych — z wywiadów, nagrań ze spotkań, materiałów w mediach społecznościowych klienta,
  • Informuj odbiorcę, że materiał jest syntezą, jeśli mógłby uznać go za nagranie człowieka. To jest zresztą kierunek, w którym idzie regulacja europejska,
  • Traktuj pliki odniesienia jak dane osobowe: katalog reference_audio podlega tym samym zasadom retencji i zabezpieczenia co każdy inny zbiór danych klienta.

Pułapki

  • Python 3.10 i tylko 3.10. Najczęstsza przyczyna nieudanej instalacji,
  • Turbo i Nano są wyłącznie angielskie. Do polskiego zostaje Multilingual, czyli model większy i wolniejszy,
  • Serwer nie zna jeszcze modeli V3 i Nano wydanych w lipcu 2026 — sprawdzone, w dokumentacji nie ma o nich wzmianki,
  • Brak uwierzytelniania. Serwer jest przeznaczony do sieci wewnętrznej; naprawiona luka przechodzenia po katalogach jest przypomnieniem, dlaczego,
  • Nowsze karty NVIDIA i AMD wymagają Dockera — DGX Spark, Strix Halo i RDNA4 nie mają ścieżki instalacji lokalnej,
  • Pierwszy start pobiera kilka gigabajtów i do tego czasu serwer nie odpowiada,
  • Spójność głosu przy dzieleniu tekstu nie jest dana. Panel ma na to osobne okno ostrzeżenia — przy audiobooku ustalone ziarno losowe i większe fragmenty pomagają, ale różnice między fragmentami trzeba odsłuchać,
  • BF16 zmienia wyjście numerycznie. Zwykle niesłyszalnie, ale jeśli materiał ma być bit w bit powtarzalny, zostaw wyłączone,
  • Każdy plik jest znakowany wodno — to nie jest opcja do wyłączenia w konfiguracji,
  • Klonowanie głosu bez zgody jest problemem prawnym, nie technicznym, a narzędzie o tym nie ostrzega,
  • To wciąż opakowanie cudzego modelu. Cztery miesiące bez pushu przy tempie wydawania modeli przez Resemble AI oznacza opóźnienie, które będzie rosło albo nie — zależnie od jednej osoby utrzymującej projekt.

Gdzie to ma sens w naszej pracy

  • Audiobooki i materiały szkoleniowe. Dzielenie tekstu, powtarzalne ziarno i sklejanie z przetwarzaniem końcowym są zrobione właśnie pod to. Koszt to prąd i karta graficzna, nie stawka za znak,
  • Zapowiedzi i komunikaty w systemach telefonicznych. Zamiast nagrywać lektora przy każdej zmianie cennika, generujesz nową wersję z tego samego głosu predefiniowanego,
  • Podmiana usługi bez zmiany kodu. Endpoint zgodny z OpenAI znaczy, że migracja z usługi płatnej na własną jest zmianą adresu bazowego — i tak samo łatwy jest powrót, jeśli jakość nie wystarczy,
  • Projekty z wymogiem nieopuszczania danych. Teksty do syntezy bywają wrażliwe — dokumentacja medyczna, komunikaty do klientów, materiały przed premierą. Model działający na maszynie klienta zdejmuje ten problem w całości,
  • Dostępność. Odczytywanie treści serwisu jako uzupełnienie wersji tekstowej — z polskim w zestawie języków jest to realne,
  • Prototypowanie agentów głosowych, jeśli ograniczasz się do angielskiego, gdzie Turbo daje generowanie w jednym kroku dekodera.

Czego to nie zastąpi: lektora w materiale, w którym głos jest częścią wartości — w reklamie, w filmie, w materiale wizerunkowym. I nie zastąpi usługi hostowanej tam, gdzie liczy się opóźnienie poniżej wartości, którą da się osiągnąć na własnej karcie, albo gdzie klient wymaga umowy o poziomie usług.

Podsumowanie

  • Kod serwera, kod modelu i wagi — wszystko na MIT, wagi na Hugging Face bez bramki. Rzadka i wygodna sytuacja,
  • Endpoint zgodny z OpenAI sprowadza migrację do zmiany adresu bazowego,
  • Do polskiego wybierasz Multilingual; Turbo i Nano są tylko angielskie,
  • Trzy silniki przełączane w panelu bez restartu — testy porównawcze zajmują minuty,
  • Dzielenie tekstu, ustalone ziarno i przetwarzanie końcowe to zestaw pod audiobooki,
  • Python 3.10, nie nowszy; na Windowsie tryb przenośny z osadzonym interpreterem,
  • Strumieniowanie, pamięć podręczna głosu i BF16 to trzy pokrętła wydajności z wydania 2.0,
  • Nie wystawiaj tego w internecie — brak uwierzytelniania, a luka przechodzenia po katalogach była realna,
  • Każdy plik nosi niesłyszalny znak wodny przetrwający kompresję i edycję,
  • Klonowanie głosu wymaga zgody — narzędzie o tym nie mówi, a RODO i prawa pokrewne mówią,
  • Serwer jest o kilka miesięcy za modelem; przy wyborze sprawdź, którą wersję rodziny faktycznie obsługuje.

Licencja: zarówno serwer, jak i model Chatterbox są na MIT, a — co przy modelach jest najważniejsze i najczęściej pomijane — na MIT są też same wagi opublikowane na Hugging Face, bez bramki wymagającej akceptacji warunków. Znaczy to, że wolno używać komercyjnie, modyfikować, dostrajać, wdrażać u klientów i redystrybuować, przy zachowaniu noty licencyjnej; nie ma tu klauzul niekomercyjnych, ograniczeń na liczbę użytkowników ani wymogu zgłaszania zastosowań, które w licencjach modeli otwartych są normą. Trzy rzeczy warto natomiast rozdzielić od licencji. Po pierwsze, zastrzeżenie autorów modelu sprowadzające się do „nie używaj tego do złych rzeczy" nie jest warunkiem licencyjnym — jest prośbą, a granice wyznaczają przepisy, nie ten plik. Po drugie, Resemble AI sprzedaje usługę hostowaną tego samego rodzaju i odsyła do niej w dokumentacji; wybór między własnym wdrożeniem a ich API jest decyzją operacyjną, nie licencyjną. Po trzecie i najważniejsze przy wdrożeniu u klienta: licencja modelu nie mówi nic o prawach do głosu, który sklonujesz. Wolność korzystania z narzędzia i prawo do wykorzystania czyjegoś głosu to dwie zupełnie różne sprawy — pierwszą reguluje MIT, drugą RODO, prawa pokrewne i umowa z osobą, której głos brzmi w pliku odniesienia.