Transkrypcja mowy na tekst w czasie rzeczywistym poniżej 200 ms: przewodnik po architekturze
- Opublikowano
- Ostatnia aktualizacja
PosłuchajPosłuchaj tego artykułu
Zamiana mowy na tekst w czasie rzeczywistym (STT) aktywnie transkrybuje dźwięk, gdy osoba mówi, zwracając jej słowa jako tekst w ciągu kilkuset milisekund. Utrzymanie niskich opóźnień STT to jednak problem zarówno architektury, jak i modelu. Deweloperzy muszą zaplanować transport, dzielenie na fragmenty, wykrywanie końca wypowiedzi i ścieżkę przechwytywania — każdy z tych elementów zwiększa opóźnienie. Niewydajność choćby jednego z nich może przekroczyć budżet 200 ms.
Ten przewodnik przedstawia praktyczny sposób budowy potoków zamiany mowy na tekst w czasie rzeczywistym — od warstwy transportu. Skupimy się na Scribe v2 Realtime, który generuje częściowe transkrypcje przy opóźnieniu modelu wynoszącym około 150 ms, obsługuje ponad 90 języków, przyjmuje dźwięk PCM (8–48 kHz) i mu-law oraz oferuje Voice Activity Detection i ręczne zatwierdzanie finalizacji segmentów.
Pokażemy, jak dźwięk trafia na serwer, jak hipotezy zmieniają się w zatwierdzony tekst, ile kosztują funkcje w strumieniu oraz jak poprawnie przechwytywać i przekazywać dźwięk.
Podsumowanie
- Tworzenie systemów zamiany mowy na tekst w czasie rzeczywistym wymaga dopracowania architektury, by opóźnienia pozostały niskie w całym potoku.
- WebSocket to właściwy domyślny wybór dla większości potoków, choć WebRTC oferuje kilka korzyści kosztem większej złożoności.
- Voice Activity Detection obsługuje segmentację bez użycia rąk, a ręczne zatwierdzanie pozwala aplikacji ją nadpisać, gdy wie, że tura się skończyła.
- Wyniki częściowe są tymczasowe, a końcowe zatwierdzone, więc należy wyświetlać je inaczej.
- Małe fragmenty PCM, około 100 ms, skracają opóźnienie do pierwszego wyniku częściowego.
WebSocket czy WebRTC dla zamiany mowy na tekst w czasie rzeczywistym
Zanim rozpocznie się transkrypcja, dźwięk musi dotrzeć ze źródła do rozpoznawacza. Wybrany kanał wyznacza minimalne opóźnienie dla wszystkiego, co dzieje się dalej. Dźwięk może dotrzeć do warstwy transkrypcji na dwa sposoby.
WebSocket to trwały, uporządkowany, niezawodny i dwukierunkowy kanał oparty na TCP. Otwierasz połączenie, wysyłasz binarne ramki audio i odbierasz zdarzenia transkrypcji. Jest prosty po stronie klienta i serwera, przechodzi przez firmowe proxy i zapory, które już zezwalają na HTTPS, a obsługuje go każda przeglądarka i środowisko serwerowe.
Ograniczenie WebSocket wynika z działania na TCP. Gdy pakiet zginie, TCP przesyła go ponownie i wstrzymuje późniejsze dane, aż luka zostanie uzupełniona. W dobrych warunkach sieciowych jest to niezauważalne. Przy utracie pakietów powoduje blokowanie head-of-line: krótkie zatrzymanie, podczas którego dźwięk się kumuluje, a potem przychodzi falą.
WebRTC stworzono do mediów w czasie rzeczywistym. Przesyła media przez UDP (za pośrednictwem SRTP), więc utracony pakiet nie zatrzymuje strumienia — potok działa dalej. Obejmuje bufor jittera, który niweluje różnice w czasie nadejścia pakietów, negocjuje przejście przez NAT za pomocą ICE/STUN/TURN, aby połączyć urządzenia za routerami, oraz ma własne mechanizmy przechwytywania i kodowania audio.
Zwykle potrzebujesz serwerów TURN dla klientów, którzy nie mogą połączyć się bezpośrednio, a serwer musi zakończyć strumień mediów, zamiast odczytywać strumień bajtów.
Najważniejsze różnice:
W większości przypadków właściwym wyborem jest WebSocket. Używaj go, gdy klienci mają dobre połączenie i kontrolujesz ścieżkę przechwytywania: w potokach serwer-serwer, aplikacjach desktopowych, aplikacjach przeglądarkowych na łączach szerokopasmowych oraz w większości backendów contact center, gdzie dźwięk już trafia na serwer inną drogą.
Wybierz WebRTC, gdy przechwytujesz dźwięk bezpośrednio z urządzeń konsumenckich w zawodnych sieciach mobilnych, masz już stos WebRTC do dwukierunkowego audio (na przykład agenta głosowego, który też odpowiada głosem) lub gdy działanie w czasie rzeczywistym mimo strat jest ważniejsze niż prostota wdrożenia.
W dalszej części przewodnika używamy WebSocket do połączenia z rozpoznawaczem, ponieważ ułatwia to analizę komponentów i jest dobrym punktem startowym dla większości zespołów. Nic nie jest tu specyficzne dla WebSocket, więc później możesz dodać przed nim warstwę mediów WebRTC, zdekodować dźwięk do PCM na serwerze i przekazywać te same fragmenty do potoku.
Wyniki częściowe i końcowe transkrypcje: wyjaśnienie
Rozpoznawacz działający w czasie rzeczywistym nie czeka z wynikiem na całe zdanie. Zamiast tego wysyła ciąg przypuszczeń, które stają się dokładniejsze wraz z napływem dźwięku, a następnie je zatwierdza. Zrozumienie różnicy między tymi stanami odróżnia transkrypcję, która wydaje się żywa, od takiej, która sprawia wrażenie zepsutej.
Hipoteza częściowa (tymczasowa) to najlepsze przypuszczenie modelu na podstawie otrzymanego dotąd dźwięku. Wyniki częściowe są z założenia niestabilne. Gdy napływa więcej audio, model poprawia wcześniejsze słowa: „Chcę” może zmienić się w „Chcę dwa bilety”, gdy późniejszy kontekst rozwiąże niejednoznaczność. Pojawiają się szybko (do tego odnosi się opóźnienie około 150 ms) i są przeznaczone do nadpisywania.
Hipoteza końcowa to zatwierdzony segment, który już się nie zmieni. Gdy segment zostanie sfinalizowany, rozpoznawacz przechodzi dalej, a kolejne hipotezy dotyczą późniejszego dźwięku. Wyniki końcowe zapisujesz, wysyłasz do LLM lub przechowujesz jako transkrypcję.
Rozróżnienie wyników częściowych i końcowych wpływa na trzy obszary, które pomylisz, jeśli je zatrzesz:
- Doświadczenie użytkownika: Wyświetlanie wyników częściowych sprawia, że transkrypcja wydaje się aktywna: użytkownik widzi słowa w trakcie mówienia, więc wie, że mikrofon działa, a system słucha.
- Wykrywanie końca wypowiedzi: Wyniki częściowe zapewniają ciągły sygnał aktywności mowy. W połączeniu z VAD pozwalają określić, kiedy mówca faktycznie skończył.
- Czas kolejnych etapów: W potoku agenta głosowego kolejne kroki to audio na wejściu, zamiana mowy na tekst, LLM, zamiana tekstu na mowę i audio na wyjściu. Możesz rozpocząć spekulacyjną pracę na wynikach częściowych i potwierdzać ją po wynikach końcowych, skracając odczuwalny czas odpowiedzi kosztem okazjonalnego odrzucania tej pracy.
Wyświetlaj wyniki częściowe i końcowe inaczej. Prostym, skutecznym wzorcem jest utrzymywanie jednej zmiennej „bieżącej linii” powiązanej z najnowszym wynikiem częściowym i dodawanie jej do transkrypcji tylko do dopisywania, gdy przyjdzie wynik końcowy:
Wizualnie wyświetlaj zatwierdzony tekst w normalnym stylu, a bieżący jaśniej lub kursywą, aby użytkownik wiedział, że może się jeszcze zmienić.
Wykrywanie końca wypowiedzi i wykrywanie aktywności głosowej (VAD)
Wiedza o tym, co zostało powiedziane, to tylko połowa zadania. Rozpoznawacz musi też wiedzieć, kiedy myśl dobiegła końca. Ta decyzja określa, kiedy finalizujesz segment, a w agencie — kiedy system zaczyna odpowiadać.
Wykrywanie końca wypowiedzi to decyzja, że wypowiedź się skończyła. Zbyt wczesna finalizacja przerywa użytkownikowi w połowie zdania. Zbyt późna sprawia, że agent milczy, mimo że użytkownik wyraźnie już skończył.
Scribe v2 Realtime oferuje dwa uzupełniające się mechanizmy:
- Voice Activity Detection segmentuje audio na podstawie ciszy: Rozpoznawacz wykrywa, gdy mowa ustępuje dłuższej ciszy, i automatycznie używa tej granicy do finalizacji segmentu. VAD to dobry domyślny wybór dla interfejsów konwersacyjnych, ponieważ dostosowuje się do naturalnego rytmu mowy bez ręcznego śledzenia czasu.
- Ręczne zatwierdzanie: Ręczne zatwierdzanie pozwala aplikacji określić, kiedy sfinalizować bieżący segment, niezależnie od ciszy. Wysyłasz sygnał zatwierdzenia, rozpoznawacz zamyka bieżący segment i zwraca wynik końcowy. To właściwe narzędzie, gdy aplikacja już wie, że tura się skończyła: po zwolnieniu przycisku push-to-talk, akcji „wyślij” lub na podstawie zewnętrznej reguły zmiany tury.
Oba mechanizmy dobrze ze sobą współpracują. Typowy agent głosowy używa VAD do obsługi bez użycia rąk i oferuje ręczne zatwierdzanie jako nadpisanie. Dzięki temu użytkownik, który zatrzymuje się, by pomyśleć, nie zostanie przerwany, a użytkownik naciskający przycisk otrzyma natychmiastową granicę segmentu.
Próg ciszy to rzeczywisty kompromis — nie ma jednej poprawnej wartości:
- Krótki limit czasu po zakończeniu mowy (na przykład finalizacja po około 200–400 ms ciszy) sprawia, że system wydaje się responsywny. Może jednak przerywać użytkownikom, którzy naturalnie robią pauzy między częściami zdania, dzieląc jedną myśl na kilka segmentów i, w przypadku agenta, wywołując przedwczesną odpowiedź.
- Długi limit czasu (na przykład około 800–1200 ms) toleruje naturalne pauzy i zachowuje całe wypowiedzi, kosztem zauważalnego opóźnienia reakcji systemu.
Nie ma tu uniwersalnej stałej — dostosuj próg do interakcji:
- Dyktowanie i robienie notatek tolerują dłuższe pauzy, ponieważ użytkownicy zastanawiają się w trakcie zdania. Ustaw dłuższe limity i oprzyj się na VAD.
- Agenci do wydawania poleceń i obsługi transakcji korzystają z krótszych limitów oraz ręcznego zatwierdzania, ponieważ tury są krótkie i konkretne.
- Osoby mówiące w wielu językach lub nie w swoim języku ojczystym częściej robią pauzy, więc uwzględnij więcej ciszy przed finalizacją.
Te wskazówki pomogą ci zbudować skuteczny system wykrywania końca wypowiedzi i zbliżyć się do zamiany mowy na tekst w czasie rzeczywistym.
Funkcje w strumieniu: wykrywanie języka i diarizacja mówców
Rozpoznawanie strumieniowe potrafi więcej niż generować słowa. Każdy dodatkowy sygnał wpływa jednak na opóźnienie i stabilność. Zasadą jest włączanie tylko tego, czego potrzebuje działanie na żywo, a resztę pozostawić do przetwarzania wsadowego.
Automatyczne rozpoznawanie języka pozwala Scribe v2 Realtime wykryć język mówiony spośród ponad 90 obsługiwanych języków, bez podawania go z góry. Model potrzebuje jednak krótkiego fragmentu dźwięku, aby pewnie go określić, więc pierwsze wyniki częściowe strumienia mogą być mniej stabilne, zanim język zostanie ustalony. Jeśli znasz język, jego wskazanie usuwa tę niejednoznaczność i zwykle daje stabilniejsze początkowe wyniki częściowe.
Diarizacja mówców przypisuje mowę do różnych osób, wskazując, kto co powiedział. W transkrypcji wsadowej jest to stosunkowo łatwe, bo model widzi cały plik. W strumieniu jest trudniej: rozpoznawacz musi przypisać etykietę mówcy na podstawie dotychczasowego audio, a etykieta nadana wczesnej części dźwięku może wymagać zmiany po usłyszeniu większej części głosu tej osoby. Etykiety mówców w strumieniu traktuj tak jak tekst częściowy: jako tymczasowe, dopóki segment nie zostanie sfinalizowany.
Czasy na poziomie słów i kontekst encji działają na tej samej zasadzie. Im więcej metadanych na token zamawiasz, tym więcej musi obsłużyć model i przesłać połączenie. W większości interfejsów działających w czasie rzeczywistym potrzebujesz tylko tekstu i granic segmentów na żywo, a szczegółowe metadane możesz odłożyć do wsadowego przetwarzania po rozmowie w Scribe v2.
Formaty audio dla streamingu: PCM i mu-law
Transport i logika rozpoznawania przyciągają najwięcej uwagi, ale zaskakująco wiele błędów w praktyce powstaje warstwę niżej — w sposobie kodowania i dzielenia audio na fragmenty. Poprawny format i rozmiar fragmentu to najtańszy sposób na skrócenie opóźnienia zamiany mowy na tekst.
PCM (liniowy, 16-bitowy ze znakiem, little-endian) to format, którego używaj, gdy kontrolujesz przechwytywanie. Wyższe częstotliwości próbkowania niosą więcej szczegółów akustycznych: 16 kHz to standardowe minimum dla rozpoznawania mowy i zwykle wystarcza; 8 kHz ma jakość telefoniczną i traci wysokie częstotliwości. Używaj częstotliwości zgodnej ze źródłem. Zwiększanie próbkowania audio telefonicznego 8 kHz do 48 kHz nie daje korzyści, bo brakujących informacji nie da się odzyskać.
Mu-law przy 8 kHz to format telefoniczny. Jeśli odbierasz rozmowy od dostawcy takiego jak Twilio, audio przychodzi w formacie mu-law 8 kHz i należy przekazywać je w tym formacie, zamiast transkodować je dwukrotnie. Dopasowanie formatu źródła pozwala uniknąć artefaktów resamplingu i zbędnego kroku konwersji.
Rozmiar fragmentów najbardziej bezpośrednio wpływa na odczuwalne opóźnienie. Wysyłasz audio we fragmentach, a rozpoznawacz generuje wyniki częściowe, gdy one docierają. Mniejsze fragmenty oznaczają częstsze aktualizacje i krótsze opóźnienie do pierwszego wyniku częściowego; większe to mniej wiadomości i nieco więcej kontekstu na wnioskowanie. Praktyczny zakres to 20–250 ms audio na fragment. Dla przykładu: przy mono PCM 16-bit i 16 kHz sekunda audio ma 32 000 bajtów, więc fragment 100 ms to około 3200 bajtów.
Przechwytywanie wejścia mikrofonowego w przeglądarce
W przeglądarce właściwym narzędziem jest Web Audio API z AudioWorklet. Worklet działa w wątku renderowania audio, odbiera dźwięk w małych ramkach i nie jest narażony na zacięcia głównego wątku, jak starszy ScriptProcessorNode. Jego zadaniem jest konwersja natywnych próbek float z przeglądarki do 16-bitowego PCM i przekazanie ich do głównego wątku, który wysyła je przez WebSocket.
Podstawą procesora worklet jest konwersja float na PCM:
Potok w kodzie
Potok ma trzy elementy: klienta przeglądarkowego, który przechwytuje mikrofon i przesyła PCM na twój serwer, serwer Node przekazujący audio do Scribe v2 Realtime i transkrypcje z powrotem oraz skryptowalnego klienta, który przesyła PCM z pliku lub mostka telefonicznego.
Serwer pośredniczy zamiast udostępniać rozpoznawacz bezpośrednio przeglądarce z jednego ważnego powodu: twój klucz API ElevenLabs jest tajny i nigdy nie może znaleźć się w kodzie po stronie klienta. Klucz pozostaje na serwerze. Jeśli przeglądarka musi komunikować się z rozpoznawaczem bezpośrednio, wygeneruj po stronie serwera krótkotrwały token jednorazowy i przekaż go klientowi zamiast klucza API.
Klient przeglądarkowy
Klient otwiera WebSocket do twojego serwera, przechwytuje mikrofon przez opisany wyżej worklet i przekazuje każdą ramkę PCM zaraz po jej utworzeniu. Przychodzące zdarzenia (już znormalizowane przez serwer do { type, text }) sterują opisanym wcześniej stanem częściowym/końcowym:
Pośrednik serwerowy
Serwer otwiera jedno połączenie z rozpoznawaczem na klienta, przechowuje klucz API na serwerze, przekazuje binarne PCM bez zmian i normalizuje zdarzenia rozpoznawacza do stabilnego formatu { type, text }, którego używa klient:
Wszystko, co zależy od endpointu, znajduje się w dwóch funkcjach adaptera poniżej. Zastąp nazwy pól dokładnymi nazwami z dokumentacji Speech to Text; reszta potoku się nie zmienia:
Skryptowalny klient backendowy
W potokach backendowych i w poniższym benchmarku to samo połączenie z rozpoznawaczem działa bez przeglądarki: odczytaj PCM z dowolnego źródła, wysyłaj je w rytmie fragmentów czasu rzeczywistego i odbieraj zdarzenia. Klucz API i URL pochodzą ze środowiska, tak jak na serwerze.
Benchmark opóźnienia zamiany mowy na tekst i współczynnika błędów słów
Opóźnienie i współczynnik błędów słów zależą od mówcy, języka, warunków akustycznych, długości audio, trasy sieciowej do najbliższego regionu każdego dostawcy oraz bieżącego obciążenia usług.
Wynik zmierzony na laptopie w jednym mieście nie musi mieć zastosowania do infrastruktury produkcyjnej w innym. Uruchamiaj testy z infrastruktury podobnej do produkcyjnej, na audio podobnym do rzeczywistego wejścia, i raportuj zakresy oraz rozkłady zamiast pojedynczych wartości.
Liczą się tylko wartości opóźnienia i dokładności zmierzone na twoim audio z infrastruktury podobnej do produkcyjnej. Oto przewodnik po benchmarkingu opóźnienia zamiany mowy na tekst.
Co mierzyć w opóźnieniu zamiany mowy na tekst
Poniżej znajdziesz najważniejsze metryki do zmierzenia podczas benchmarkingu opóźnienia zamiany mowy na tekst w czasie rzeczywistym:
- Czas do pierwszego wyniku częściowego: Od wysłania pierwszego fragmentu audio do odebrania pierwszego niepustego wyniku częściowego.
- Opóźnienie od wyniku częściowego do końcowego: Od ostatniego fragmentu audio wypowiedzi do hipotezy końcowej.
- Współczynnik błędów słów (WER): WER sfinalizowanej transkrypcji względem referencji stworzonej przez człowieka, liczony identycznie dla wszystkich systemów.
- Zmiany stabilności: Liczba wyników częściowych nadpisanych przed finalizacją. Ta miara pokazuje, jak bardzo będzie się zmieniać interfejs na żywo.
Warunki kontrolne
Aby uniknąć niewiarygodnych danych, wprowadź do eksperymentu kilka warunków kontrolnych, które zapewnią spójność.
Oto główne warunki kontrolne w benchmarkingu opóźnienia zamiany mowy na tekst:
- Identyczne audio: Używaj tych samych plików, tej samej częstotliwości próbkowania i tego samego kodowania dla każdego systemu.
- Identyczne tempo wysyłania: Przesyłaj do każdego systemu fragmenty w tym samym rytmie czasu rzeczywistego (na przykład co 100 ms).
- Powtarzaj i raportuj rozkłady:Uruchamiaj każdy plik wielokrotnie w ciągu dnia; raportuj medianę i wartości skrajne (p50/p95).
- Identyczne referencje i ocena:Przed obliczeniem WER normalizuj tekst tak samo (wielkość liter, interpunkcja, liczby).
- Podaj region i sieć:Wskaż, gdzie uruchomiono testy i jaką trasą łączono się z każdym dostawcą.
Utrzymując wszystkie te elementy bez zmian, uzyskasz dokładniejsze metryki.
Szkielet testu
Rdzeń pomiaru przyjmuje adapter dostawcy i rejestruje czas do pierwszego wyniku częściowego, opóźnienie finalizacji oraz zmiany wyników częściowych:
Współczynnik błędów słów to standardowa odległość Levenshteina na poziomie tokenów dla znormalizowanego tekstu. Przed obliczeniem zamień tekst na małe litery i usuń interpunkcję w taki sam sposób w referencji i hipotezie, inaczej zmierzysz normalizator, a nie model. Uruchom ten pomiar w pętli około 10 razy dla każdego pliku i dostawcy, a następnie raportuj medianę czasu do pierwszego wyniku częściowego i medianę WER (p50/p95), ponieważ pojedyncza próbka jest silnie zależna od zmienności sieci.
Aby to uruchomić, potrzebujesz dwóch rzeczy. Po pierwsze, napisz jeden adapter StreamFn dla każdego systemu. Powyższy klient skryptowalny już nim jest, a adaptery dla pozostałych powinny stosować ten sam kontrakt (audioPath, onEvent, result) i ustawiać result.lastChunkSentAt przy wysłaniu ostatniego fragmentu audio. Po drugie, wczytaj pliki audio i referencje, a następnie wywołaj pomiary dla nich wszystkich. Uruchom test na maszynie odpowiadającej twojemu wdrożeniu, na audio podobnym do tego od użytkowników, a uzyskasz porównanie, które da się odtworzyć.
Podsumowanie: jak osiągnąć zamianę mowy na tekst w czasie rzeczywistym
W tym artykule omówiliśmy wiele zmian architektonicznych, które pozwalają stopniowo ulepszać system i zbliżyć się do zamiany mowy na tekst w czasie rzeczywistym.
Produkcyjny system STT działający w czasie rzeczywistym sprowadza się do kilku decyzji:
- Transport: Wybierz WebSocket dla prostoty i kontrolowanych sieci, a WebRTC, gdy potrzebujesz odporności na straty i przechwytujesz dźwięk z urządzeń konsumenckich.
- Wyniki częściowe i końcowe: Traktuj wyniki częściowe jako tymczasowe, a końcowe jako zatwierdzone, i wyświetlaj je inaczej, aby użytkownicy ufali tekstowi na żywo.
- Wykrywanie końca wypowiedzi: Używaj VAD do segmentacji bez użycia rąk, ręcznego zatwierdzania jako nadpisania i dostosowuj próg ciszy do interakcji, zamiast stosować stałą wartość.
- Funkcje w strumieniu: Włączaj funkcje w strumieniu tylko tam, gdzie są potrzebne na żywo, a resztę odłóż do przetwarzania wsadowego w Scribe v2.
- Format audio: Przechwytuj małe ramki PCM, wysyłaj fragmenty około 100 ms i dopasuj format źródła dla telefonii.
- Benchmarking: Ustal empirycznie kompromis między dokładnością a opóźnieniem na własnym audio i względem docelowej metryki.
- Bezpieczeństwo API: Przechowuj swój klucz API na serwerze lub generuj tokeny jednorazowe dla bezpośrednich połączeń klientów.
Jeśli chcesz zobaczyć, jak zoptymalizować opóźnienie w agencie głosowym, przygotowaliśmy też przewodnik.
Twórz systemy zamiany mowy na tekst w czasie rzeczywistym z Scribe v2 Realtime
Scribe v2 Realtime generuje wyniki częściowe przy opóźnieniu modelu wynoszącym około 150 ms. To, czy użytkownicy odczują właśnie takie opóźnienie, czy większe, zależy od otaczającej go architektury — a nad nią masz kontrolę. Dzięki strategiom opisanym w tym artykule zbudujesz lepszą architekturę potoku, która zmniejsza opóźnienia i poprawia doświadczenie klientów.
Aby dowiedzieć się więcej, zobacz omówienie możliwości Speech to Text, przeczytaj naszą dokumentację modeli z pełną listą funkcji i języków oraz odwiedź strony produktów czasu rzeczywistego: Speech to Text API w czasie rzeczywistym i Speech to Text w czasie rzeczywistym.
Gdy będziesz gotowy do działania, utwórz darmowe konto ElevenLabs i prześlij dziś swoją pierwszą transkrypcję.

.webp&w=3840&q=80)
.webp&w=3840&q=80)
.webp&w=3840&q=80)
