Własny serwer STT i TTS: Whisper oraz Piper na VPS
Uruchom Whisper i Piper na własnym VPS bez karty GPU. Sprawdź wymagania dyskowe, zużycie CPU oraz konfigurację endpointu kompatybilnego z API OpenAI dla Twoich aplikacji.
Samodzielnie hostowana zamiana mowy na tekst i tekstu na mowę w skrócie
Samodzielnie hostowana zamiana mowy na tekst (STT) oraz tekstu na mowę (TTS) to najtańszy rodzaj sztucznej inteligencji, jaki można uruchomić na własnym serwerze. Transkrypcja wykorzystuje model Whisper poprzez środowisko uruchomieniowe faster-whisper. Synteza obsługiwana jest przez Piper. Oba rozwiązania działają na zwykłym serwerze VPS z procesorem CPU, bez konieczności posiadania karty graficznej GPU. Mały model Whisper wymaga około 484 MB miejsca na dysku, a głos Piper to pojedynczy plik o rozmiarze znacznie poniżej 150 MB.
Dlatego właśnie od audio warto zacząć. Samodzielnie hostowany generator obrazów oraz samodzielnie hostowana generacja wideo wymagają karty GPU, aby w ogóle nadawały się do użytku. Audio nie ma takich wymagań.
Niniejszy przewodnik obejmuje oba kierunki oraz warstwę, która je łączy. Whisper zamienia dźwięk na tekst. Piper zamienia tekst na dźwięk. Serwer HTTP kompatybilny z OpenAI, umieszczony przed oboma rozwiązaniami, pozwala istniejącemu klientowi łączyć się z Twoim serwerem bez żadnych zmian poza adresem URL.
Każda wymieniona tutaj wersja była aktualna na sierpień 2026 roku.
Dlaczego faster-whisper, a nie referencyjny pakiet Whisper
Pakiet whisper firmy OpenAI uruchamia model w środowisku PyTorch. faster-whisper wykorzystuje te same wagi modelu w silniku CTranslate2, zaprojektowanym specjalnie do wnioskowania dla modeli typu transformer. Wagi są identyczne, więc transkrypcja pozostaje taka sama. Różnica dotyczy wyłącznie środowiska uruchomieniowego.
CTranslate2 kwantyzuje wagi podczas ich ładowania, dlatego compute_type="int8" jest pojedynczym argumentem, a nie osobnym krokiem konwersji. Silnik ten nie posiada również zależności od PyTorch. pip install faster-whisper pobiera CTranslate2, tokenizator oraz PyAV do dekodowania dźwięku, dzięki czemu środowisko wirtualne zajmuje setki megabajtów zamiast kilku gigabajtów. Na serwerze VPS z dyskiem 40 GB ta różnica decyduje o komforcie pracy.
Poniżej przedstawiono opublikowane przez autorów projektu dane dla modelu small na procesorze CPU. Benchmark obejmuje transkrypcję 13 minut dźwięku przy użyciu 8 wątków na procesorze Intel Core i7-12700K. Kolumna x_realtime to wynik dzielenia 13 minut przez zmierzony czas: wartość 7.6 oznacza, że 13-minutowe nagranie zostało przetworzone w nieco ponad 1 minutę i 40 sekund.
The data behind this chart
[
{
"label": "openai/whisper, fp32",
"x_realtime": 1.9,
"seconds": 418,
"memory_mb": "2,335"
},
{
"label": "whisper.cpp, fp32",
"x_realtime": 6.2,
"seconds": 125,
"memory_mb": "1,049"
},
{
"label": "faster-whisper, fp32",
"x_realtime": 5.0,
"seconds": 157,
"memory_mb": "2,257"
},
{
"label": "faster-whisper, int8",
"x_realtime": 7.6,
"seconds": 102,
"memory_mb": "1,477"
},
{
"label": "faster-whisper, int8, batch 8",
"x_realtime": 15.3,
"seconds": 51,
"memory_mb": "3,608"
}
]Warto rzetelnie przeanalizować drugi wiersz. Przy fp32, whisper.cpp jest szybszy niż faster-whisper na tym procesorze, osiągając 6.2x w porównaniu do 5.0x, zużywając przy tym mniej niż połowę pamięci. Jest to ta sama rodzina ggml, która stanowi fundament strony llama.cpp w lokalnym stosie LLM. faster-whisper zyskuje przewagę po włączeniu int8 oraz przetwarzania wsadowego (batching), osiągając 15.3x przy zużyciu 3,608 MB pamięci RAM. Podsumowując: wybierz faster-whisper, jeśli potrzebujesz API w języku Python i przetwarzania wsadowego; wybierz whisper.cpp, gdy ograniczenie pamięci RAM jest niemożliwe do obejścia.
Pierwszy wiersz stanowi sedno tej sekcji. Referencyjny pakiet osiąga 1.9x czasu rzeczywistego na tej samej maszynie, co oznacza, że godzina nagrania wymaga pół godziny pracy procesora.
Ile miejsca na dysku wymagają wagi modelu Whisper?
The data behind this chart
[
{
"label": "tiny",
"weights_mb": 75.5
},
{
"label": "base",
"weights_mb": 145
},
{
"label": "small",
"weights_mb": 484
},
{
"label": "medium",
"weights_mb": "1,530"
},
{
"label": "large-v3",
"weights_mb": "3,090"
}
]Powyższe wartości dotyczą konwersji CTranslate2 w formacie float16. Należy zwrócić uwagę, czego compute_type="int8" nie robi: nie zmniejsza rozmiaru pobieranych plików. Wagi są dostarczane w formacie float16, a CTranslate2 kwantyzuje je w pamięci operacyjnej podczas ładowania. Dlatego model large-v3 zajmuje 3,090 MB na dysku, niezależnie od tego, czy uruchamia się go w trybie float16, czy int8. Tryb int8 pozwala zaoszczędzić pamięć RAM i zwiększyć szybkość, ale nie zwalnia miejsca na dysku.
Modele są pobierane przy pierwszym użyciu do katalogu ~/.cache/huggingface/hub. W przypadku serwera VPS z małą partycją główną, należy wskazać lokalizację z odpowiednią ilością wolnego miejsca, używając argumentu download_root lub zmiennej środowiskowej HF_HOME. W przeciwnym razie pierwsze uruchomienie zapełni dysk, co spowoduje przerwanie procesu w trakcie pobierania.
Instalacja faster-whisper bez naruszania systemowego interpretera Python
Systemy Ubuntu 24.04 oraz Debian 13 oznaczają systemowy interpreter Python jako zarządzany zewnętrznie. Uruchomienie pip install faster-whisper poza środowiskiem wirtualnym kończy się natychmiastowym błędem:
error: externally-managed-environmentJest to mechanizm systemu pakietów chroniący pliki, których właścicielem jest apt. Należy użyć środowiska wirtualnego.
sudo apt update
sudo apt install -y python3-venv ffmpeg
python3 -m venv ~/stt
~/stt/bin/pip install --upgrade pip
~/stt/bin/pip install faster-whisper==1.2.1Wersja 1.2.1 to aktualne wydanie, opublikowane w październiku 2025. Biblioteka faster-whisper dekoduje dźwięk za pomocą PyAV, który zawiera własne biblioteki ffmpeg, dzięki czemu odczytuje pliki mp3 lub m4a bez potrzeby posiadania osobnego pliku binarnego ffmpeg. Pakiet ffmpeg wymieniony powyżej jest wymagany do późniejszej obróbki wideo w tym przewodniku.
Przed pobraniem trzech gigabajtów wag modelu należy zweryfikować poprawność instalacji:
~/stt/bin/python -c "from faster_whisper import WhisperModel; print('ok')"Wiersz zawierający ok oznacza, że pakiety typu wheel zostały poprawnie zainstalowane. Komunikat ImportError wskazujący na ctranslate2 oznacza, że pakiet dla danej architektury nie został zainstalowany, co zdarza się w przypadku 32-bitowych obrazów ARM.
Transkrypcja nagrania ze spotkania lub notatki głosowej
Zapisz to jako transcribe.py:
from faster_whisper import WhisperModel
model = WhisperModel("small", device="cpu", compute_type="int8", cpu_threads=4)
segments, info = model.transcribe("meeting.m4a", beam_size=5, vad_filter=True)
print("language: %s (%.2f)" % (info.language, info.language_probability))
for segment in segments:
print("[%.2fs -> %.2fs] %s" % (segment.start, segment.end, segment.text))Uruchom to za pomocą ~/stt/bin/python transcribe.py. Pierwsze uruchomienie pobiera wagi, więc przez pewien czas nic nie jest wyświetlane. Po tym czasie model ładuje się z pamięci podręcznej w kilka sekund.
segments jest generatorem, więc transkrypcja nie rozpocznie się, dopóki nie wykonasz iteracji. Użytkownicy mierzą czas wywołania transcribe(), widzą, że zwraca wynik natychmiast i myślą, że coś jest zepsute. Nic nie jest zepsute. Praca odbywa się w pętli.
vad_filter=True uruchamia najpierw Silero VAD (wykrywanie aktywności głosowej) i pomija fragmenty ciszy, zanim trafią one do Whisper. W przypadku nagrania ze spotkania z długimi przerwami jest to największa możliwa optymalizacja szybkości, ponieważ Whisper nie traci czasu na dźwięk niezawierający mowy. Eliminuje to również powtarzające się pętle zdań, które Whisper generuje, gdy otrzymuje ciszę i próbuje znaleźć w niej słowa.
Ustaw cpu_threads na liczbę rdzeni, które faktycznie posiadasz. Ustawienie wartości powyżej liczby vCPU spowalnia transkrypcję, ponieważ dodatkowe wątki rywalizują o ten sam rdzeń, a scheduler ponosi koszt każdego przełączenia kontekstu.
Napisy dla biblioteki Jellyfin
Jellyfin odczytuje zewnętrzne pliki napisów, które znajdują się obok pliku wideo i mają taką samą nazwę. Dzięki temu Movie (2019).en.srt obok Movie (2019).mkv jest widoczne jako ścieżka angielska bez konieczności transkodowania czy przebudowywania biblioteki.
Najpierw wyodrębnij ścieżkę dźwiękową. Whisper wewnętrznie resampluje wszystko do formatu 16 kHz mono, więc dostarczenie pliku w tym formacie odciąża proces przetwarzania:
ffmpeg -i "Movie (2019).mkv" -vn -ac 1 -ar 16000 -c:a pcm_s16le "Movie (2019).wav"Narzędzie faster-whisper nie posiada wbudowanego modułu zapisu do formatu SRT, więc należy samodzielnie sformatować segmenty. Zapisz poniższy kod jako srt.py:
import sys
from faster_whisper import WhisperModel
def ts(seconds):
ms = int(round(seconds * 1000))
hours, ms = divmod(ms, 3600000)
minutes, ms = divmod(ms, 60000)
secs, ms = divmod(ms, 1000)
return "%02d:%02d:%02d,%03d" % (hours, minutes, secs, ms)
model = WhisperModel("small", device="cpu", compute_type="int8")
segments, info = model.transcribe(sys.argv[1], vad_filter=True)
with open(sys.argv[2], "w", encoding="utf-8") as out:
for index, segment in enumerate(segments, start=1):
out.write("%d\n" % index)
out.write("%s --> %s\n" % (ts(segment.start), ts(segment.end)))
out.write("%s\n\n" % segment.text.strip())Następnie przetwórz całą bibliotekę:
for f in /srv/media/films/*.mkv; do
ffmpeg -nostdin -y -i "$f" -vn -ac 1 -ar 16000 -c:a pcm_s16le "${f%.mkv}.wav"
nice -n 15 ~/stt/bin/python srt.py "${f%.mkv}.wav" "${f%.mkv}.en.srt"
rm -f "${f%.mkv}.wav"
doneParametr -nostdin nie jest opcjonalny. Bez niego ffmpeg odczytuje dane ze standardowego wejścia pętli, co powoduje „pochłonięcie” reszty listy plików i przerwanie działania pętli po pierwszym filmie bez wyświetlenia komunikatu o błędzie.
Przed rozpoczęciem oszacuj czas pracy. Przy współczynniku 7.6x podanym powyżej, 100-minutowy film wymaga około 13 minut czasu procesora, więc przetworzenie biblioteki składającej się z pięćdziesięciu filmów zajmie całą noc. Na planach z współdzielonym vCPU proces ten będzie wolniejszy, do czego służy nice: dzięki niemu zadanie generowania napisów ustępuje miejsca innym procesom wykonywanym przez serwer.
Synteza mowy za pomocą Piper
Piper to neuronowy silnik zamiany tekstu na mowę, który uruchamia model głosowy ONNX na procesorze CPU. Zawiera wbudowany espeak-ng do konwersji tekstu na fonemy, dzięki czemu nie ma potrzeby instalowania oddzielnego fonemizera. Obecne wydanie to 1.6.0, opublikowane w lipcu 2026.
python3 -m venv ~/tts
~/tts/bin/pip install piper-tts==1.6.0
~/tts/bin/python -m piper.download_voices en_US-lessac-medium
~/tts/bin/python -m piper -m en_US-lessac-medium -f test.wav -- 'This is a test.'download_voices zapisuje dwa pliki w katalogu roboczym: wagi .onnx oraz plik konfiguracyjny .onnx.json zawierający częstotliwość próbkowania i listę głosów. Muszą one znajdować się w tym samym miejscu. Jeśli głosy są przechowywane w stałej lokalizacji, należy przekazać flagę --data-dir do obu poleceń, ponieważ w przeciwnym razie odtwarzacz szuka plików w katalogu roboczym i nie znajdzie głosu, jeśli go tam nie ma.
Ważny jest również separator -- przed tekstem. Bez niego każde zdanie rozpoczynające się od myślnika jest interpretowane jako opcja wiersza poleceń.
Głosy są dostępne w kilku poziomach jakości. Średniej jakości głos angielski zajmuje około 60 MB, a wysokiej jakości około dwa razy więcej. Wyższa jakość oznacza większy model i większe zużycie procesora na sekundę mowy, a nie innego lektora.
Nie należy wywoływać CLI w pętli. Ładuje ono model przy każdym wywołaniu, a ładowanie modelu stanowi główny koszt przy krótkich zdaniach. Zamiast tego należy uruchomić serwer HTTP:
~/tts/bin/pip install 'piper-tts[http]==1.6.0'
~/tts/bin/python -m piper.http_server -m en_US-lessac-medium --host 127.0.0.1 --port 5000curl -X POST -H 'Content-Type: application/json' \
-d '{ "text": "This is a test." }' \
-o test.wav localhost:5000/synthesizeJeśli test.wav można odtworzyć, oznacza to, że rozwiązanie działa. Ten punkt końcowy ma własną strukturę Pipera, a nie OpenAI, więc klient oczekujący /v1/audio/speech nie nawiąże z nim komunikacji. Kolejna sekcja rozwiązuje ten problem.
Należy utrzymać działanie procesu za pomocą pliku jednostki, zamiast używać terminala, który zostanie zamknięty:
[Unit]
Description=Piper text to speech HTTP server
After=network-online.target
[Service]
User=piper
ExecStart=/home/piper/tts/bin/python -m piper.http_server -m en_US-lessac-medium --data-dir /home/piper/voices --host 127.0.0.1 --port 5000
Restart=on-failure
[Install]
WantedBy=multi-user.targetsudo systemctl enable --now piper uruchamia usługę i przywraca ją po restarcie systemu. Jeśli powyższe polecenie curl nie zwraca żadnych danych, journalctl -u piper -n 50 zawiera przyczynę błędu; najczęstszą z nich jest brakujący plik głosu.
Struktura serwera zgodnego z OpenAI
Większość oprogramowania obsługującego dźwięk korzysta już z API audio OpenAI: żądanie multipart POST do /v1/audio/transcriptions dla pliku oraz JSON POST do /v1/audio/speech dla tekstu. Obsłuż te dwie ścieżki samodzielnie, a klient będzie wymagał jedynie zmiany adresu bazowego (base URL).
Speaches to serwer obsługujący oba kierunki. Uruchamia on faster-whisper do transkrypcji oraz Piper lub Kokoro do syntezy mowy, udostępniając je pod ścieżkami OpenAI. Obecne wydanie to v0.9.0-rc.3 z grudnia 2025 roku; jest to wersja przed 1.0, dlatego należy przypiąć tag obrazu i zapoznać się z informacjami o wydaniu przed aktualizacją.
curl --silent --remote-name https://raw.githubusercontent.com/speaches-ai/speaches/master/compose.yaml
curl --silent --remote-name https://raw.githubusercontent.com/speaches-ai/speaches/master/compose.cpu.yaml
export COMPOSE_FILE=compose.cpu.yaml
docker compose up --detachForma pojedynczego kontenera, jeśli nie chcesz zarządzać plikami compose:
docker run --rm --detach --publish 8000:8000 --name speaches \
--volume hf-hub-cache:/home/ubuntu/.cache/huggingface/hub \
ghcr.io/speaches-ai/speaches:latest-cpuNazwany wolumen jest elementem, o którym użytkownicy często zapominają. Bez niego pamięć podręczna modeli znajduje się wewnątrz kontenera, więc każdy restart powoduje ponowne pobieranie gigabajtów wag przed udzieleniem pierwszej odpowiedzi.
Aby /v1/audio/speech mogło odpowiedzieć, mowa wymaga wcześniejszego pobrania głosu:
uvx speaches-cli model download speaches-ai/Kokoro-82M-v1.0-ONNXPo tym kroku każdy klient OpenAI będzie działał po zmianie adresu bazowego:
from pathlib import Path
from openai import OpenAI
openai = OpenAI(base_url="http://localhost:8000/v1", api_key="cant-be-empty")
res = openai.audio.speech.create(
model="speaches-ai/Kokoro-82M-v1.0-ONNX",
voice="af_heart",
input="Hello, world!",
response_format="mp3",
speed=1,
)
with Path("output.mp3").open("wb") as f:
f.write(res.response.read())Symbol zastępczy api_key jest wymagany, ponieważ biblioteka klienta OpenAI odmawia wysłania żądania bez niego. Serwer ignoruje tę wartość, dopóki nie skonfigurujesz rzeczywistego klucza.
vox-box to drugi projekt wart wzmianki. Jest to pakiet Python, a nie kontener, który udostępnia te same ścieżki, wykorzystując Whisper, FunASR, Bark, Dia lub CosyVoice. Obecna wersja to 0.0.21 z grudnia 2025 roku, wymagająca języka Python 3.10 lub nowszego.
python3 -m venv ~/voice
~/voice/bin/pip install vox-box==0.0.21
~/voice/bin/vox-box start --huggingface-repo-id Systran/faster-whisper-small \
--data-dir ~/voice/data --host 127.0.0.1 --port 8010Przykład projektu wiąże port 80, co wymaga uprawnień root. Na serwerze wykonującym inne zadania lepszym rozwiązaniem jest użycie wysokiego portu za reverse proxy. vox-box start obsługuje jeden model, więc obsługa obu kierunków wymaga drugiej instancji na drugim porcie z identyfikatorem repozytorium mowy.
Zapytaj serwer, co załadował, a następnie użyj tego identyfikatora w polu model:
curl http://127.0.0.1:8010/v1/modelscurl http://127.0.0.1:8010/v1/audio/transcriptions \
-H "Content-Type: multipart/form-data" \
-F file="@voice-note.m4a" \
-F model="faster-whisper-small"Treść JSON w formacie {"text": "..."} oznacza, że cała ścieżka działa poprawnie. Błąd 404 przy nazwie modelu oznacza, że nazwa została odgadnięta zamiast odczytana z wyjścia /v1/models.
Żaden z tych serwerów nie włącza domyślnie uwierzytelniania. Powiąż je z 127.0.0.1 i uzyskuj do nich dostęp przez VPN lub reverse proxy wymagające poświadczeń. Otwarty port /v1/audio/transcriptions na publicznym adresie IP to darmowa moc obliczeniowa dla każdego, kto go znajdzie, a z pewnością zostanie znaleziony.
Interfejs głosowy dla asystenta hostowanego lokalnie
Gdy oba kierunki komunikacji odpowiadają na ścieżkach OpenAI, można nimi sterować za pomocą interfejsu czatu. Open WebUI i jego alternatywy akceptują w ustawieniach bazowy adres URL zgodny z OpenAI dla dźwięku, dzięki czemu jedna maszyna może uruchomić lokalny model LLM za pomocą Ollama i zamknąć pętlę głosową po obu stronach.
Należy rzetelnie oszacować opóźnienia, ponieważ te trzy kroki wykonywane są sekwencyjnie na tych samych rdzeniach procesora. 10-sekundowe pytanie wymaga około 1,3 sekundy na transkrypcję przy współczynniku 7.6x podanym powyżej, a dzieje się to zanim model odczyta choćby jeden token. Po dodaniu czasu generowania tokenów przez procesor, czas pełnego cyklu jest na tyle długi, że testerzy mogą założyć, iż usługa uległa awarii. Transkrypcja wsadowa działa wydajnie na procesorze. Rozmowa w czasie rzeczywistym już nie, i to jest moment, w którym serwer VPS z GPU zaczyna uzasadniać swój koszt.
Kiedy GPU faktycznie się opłaca?
The data behind this chart
[
{
"label": "openai/whisper, fp16",
"x_realtime": 5.5,
"seconds": 143,
"memory_mb": "4,708"
},
{
"label": "faster-whisper, fp16",
"x_realtime": 12.4,
"seconds": 63,
"memory_mb": "4,525"
},
{
"label": "faster-whisper, int8",
"x_realtime": 13.2,
"seconds": 59,
"memory_mb": "2,926"
},
{
"label": "faster-whisper, int8, batch 8",
"x_realtime": 48.8,
"seconds": 16,
"memory_mb": "4,500"
}
]Na GPU duży model w formacie int8 działa z prędkością 13.2x czasu rzeczywistego, zajmując 2,926 MB VRAM, a przy przetwarzaniu wsadowym osiąga 48.8x. Należy zwrócić szczególną uwagę na to, czego nie pokazują te dwa wykresy. Uruchamiają one różne modele: wiersze dla GPU dotyczą large-v2, a wiersze dla CPU modelu small. GPU nie sprawia, że model small działa sześciokrotnie szybciej. Sprawia, że model o wysokiej dokładności staje się użyteczny.
Skąd pochodzą te liczby
Oba wykresy powielają benchmark opublikowany w pliku README projektu faster-whisper. Plik audio to pojedyncze nagranie trwające 13 minut. Wiersze dla CPU wykorzystywały 8 wątków procesora Intel Core i7-12700K, a wiersze dla GPU korzystały z CUDA 12.4 na karcie NVIDIA RTX 3070 Ti z 8 GB VRAM. Kolumny z sekundami i pamięcią zawierają opublikowane wartości. Kolumna x_realtime to wynik obliczeń: 780 sekund nagrania podzielone przez zmierzony czas, zaokrąglone do jednego miejsca po przecinku. Kolumna pamięci odnosi się do pamięci RAM systemu dla wykresu CPU oraz do VRAM dla wykresu GPU.
Plan z współdzielonym vCPU nie osiągnie wyników dla CPU. Wspomniany benchmark miał do wyłącznej dyspozycji 8 wątków wydajnego procesora desktopowego. Traktuj 7.6x jako górną granicę, a przed zaplanowaniem czegokolwiek przetestuj własną maszynę za pomocą time na rzeczywistym nagraniu.
Cztery praktyczne zasady:
- Okazjonalna transkrypcja własnych nagrań: CPU, model small, int8. Wystarczą dwa dedykowane vCPU.
- Przetwarzanie wsadowe w nocy, na przykład generowanie napisów: CPU, model small lub medium, int8, uruchomione w
nice. - Wszystko, co wymaga interakcji, lub cała biblioteka nagrań w jeden wieczór: GPU.
- Piper: CPU, zawsze. Model głosowy tej wielkości niemal nie zyskuje na użyciu GPU.
Jeśli zastanawiasz się, co jeszcze może obsłużyć ten sam sprzęt, szersze zagadnienie modeli AI, które można hostować samodzielnie omawia rozmiary modeli, które mieszczą się w pamięci, oraz te, które się w niej nie mieszczą.
Tryby awarii i towarzyszące im komunikaty
error: externally-managed-environment podczas instalacji. Systemowy Python jest chroniony przez dystrybucję. Należy utworzyć wirtualne środowisko, zgodnie z powyższym opisem.
Niezgodność cuDNN na serwerze z GPU. Błąd wygląda następująco:
Unable to load any of {libcudnn_ops.so.9.1.0, libcudnn_ops.so.9.1, libcudnn_ops.so.9, libcudnn_ops.so}
Invalid handle. Cannot load symbol cudnnCreateTensorDescriptorCTranslate2 w wersji 4.5.0 i nowszych wymaga cuDNN 9 dla CUDA 12, a host posiada cuDNN 8. Należy zainstalować cuDNN 9 lub przypiąć starsze środowisko uruchomieniowe za pomocą pip install --force-reinstall ctranslate2==4.4.0. Należy wykonać tylko jedną z tych czynności. Wykonanie obu przywraca stan początkowy.
This CTranslate2 package was not compiled with CUDA support to inny błąd o podobnych objawach. Zainstalowany pakiet typu wheel to wersja przeznaczona wyłącznie dla procesora (CPU). Należy przebudować wirtualne środowisko na hoście z GPU i pozwolić pip ponownie wybrać odpowiedni pakiet.
Powtarzające się frazy w transkrypcji. Zdanie zapętlone dziesięć razy prawie zawsze oznacza, że cisza lub muzyka zostały błędnie zinterpretowane jako mowa. W pierwszej kolejności należy włączyć vad_filter=True. Jeśli problem nadal występuje, należy odsłuchać dany fragment: dźwięk zbliżony do ciszy nie daje modelowi Whisper punktu zaczepienia, więc powtarza on ostatnią pewną frazę.
Błędnie wykryty język. Whisper dokonuje detekcji na podstawie pierwszych 30 sekund nagrania. Wartość info.language_probability znacznie poniżej 1.0 oznacza brak pewności, co zdarza się, gdy nagranie rozpoczyna się od muzyki lub rozmów w tle. Jeśli język jest znany, należy użyć language="en".
Proces wypisuje Killed i kończy działanie. Jest to mechanizm jądra OOM (out-of-memory) killer, a dmesg wyświetli odpowiedni wpis o przerwaniu procesu. Model large-v3 wymaga ponad 3 GB pamięci tylko na wagi, przed przydzieleniem pamięci roboczej. Na serwerze VPS z 2 GB pamięci RAM, największym modelem, który się uruchomi, jest small w formacie int8.
Piper nie może odnaleźć głosu. Odtwarzacz przeszukuje katalog roboczy, chyba że zostanie użyta flaga --data-dir. Należy uruchomić ls w oczekiwanym katalogu i potwierdzić, że zarówno .onnx, jak i .onnx.json znajdują się wewnątrz, ponieważ brak jednego z nich powoduje błąd tak samo skutecznie, jak brak obu.
FAQ
Czy mogę uruchomić zamianę mowy na tekst na VPS bez GPU?
Tak, w przypadku przetwarzania wsadowego jest to rozsądny wybór. Używając faster-whisper z modelem small w kwantyzacji int8, opublikowany benchmark projektu transkrybuje 13 minut nagrania w 102 sekund na 8 wątkach procesora desktopowego i7, co daje około 7.6x czasu rzeczywistego przy zużyciu 1,477 MB pamięci RAM. Plan z współdzielonym vCPU będzie działał wolniej, dlatego należy przeprowadzić pomiary na własnej maszynie. Zamiana tekstu na mowę za pomocą Piper jest jeszcze prostsza i w żadnych okolicznościach nie wymaga GPU.
Którego rozmiaru modelu Whisper powinienem użyć?
Należy zacząć od modelu small w wersji int8. Zajmuje on 484 MB na dysku i dobrze radzi sobie z wyraźnie nagraną mową. Warto przejść na medium, gdy akcenty lub szum tła powodują błędy, których nie można zaakceptować, a na large-v3 tylko wtedy, gdy dokładność jest ważniejsza niż wszystko inne, ponieważ wymaga on 3,090 MB miejsca na dysku i ponad 3 GB pamięci RAM. W drugą stronę, model tiny o rozmiarze 75.5 MB jest przydatny do wykrywania języka i testowania potoku przetwarzania, a nie do transkrypcji przeznaczonych do czytania przez ludzi.
Dlaczego faster-whisper działa szybciej niż oryginalny pakiet Whisper?
Model jest ten sam, ale środowisko uruchomieniowe różni się. Pakiet referencyjny uruchamia Whisper w PyTorch, podczas gdy faster-whisper uruchamia te same wagi na CTranslate2 – silniku stworzonym do wnioskowania (inference) modeli typu transformer, który kwantyzuje wagi podczas ładowania i nie wymaga instalacji PyTorch. W opublikowanym benchmarku CPU wynik wynosi 1.9x czasu rzeczywistego dla pakietu referencyjnego w porównaniu do 7.6x dla faster-whisper w int8, przy mniejszym zużyciu pamięci.
Dlaczego moja transkrypcja powtarza to samo zdanie w kółko?
Whisper interpretuje ciszę lub muzykę jako mowę i wraca do swojego ostatniego pewnego przypuszczenia. Należy ustawić vad_filter=True w wywołaniu transcribe(), co uruchamia detekcję aktywności głosowej Silero przed modelem i usuwa fragmenty ciszy, zanim model je przetworzy. Jeśli powtórzenia nadal występują, należy sprawdzić poziom dźwięku, ponieważ nagranie, które jest niemal całkowicie ciche, nie dostarcza modelowi danych do pracy.
Jak uzyskać punkt końcowy audio zgodny z OpenAI na własnym serwerze?
Należy uruchomić serwer implementujący POST /v1/audio/transcriptions oraz POST /v1/audio/speech, a następnie wskazać na niego klienta za pomocą nowego adresu bazowego (base URL). Speaches jest jedną z opcji, publikowaną jako obraz kontenera z kompilacją CPU, wykorzystującą faster-whisper do transkrypcji oraz Piper lub Kokoro do mowy. vox-box to kolejna opcja, instalowana za pomocą pip install vox-box i uruchamiana przez vox-box start --huggingface-repo-id, która obsługuje jeden model na proces. Żadne z tych rozwiązań nie włącza domyślnie uwierzytelniania, dlatego należy powiązać usługę z localhost i umieścić przed nią proxy lub VPN.