Tal till text i realtid under 200 ms: En arkitekturguide
- Publicerad
- Senast uppdaterad
LyssnaLyssna på den här artikeln
Speech to Text (STT) i realtid transkriberar aktivt ljud medan en person talar och returnerar orden som text inom några hundra millisekunder. Men att hålla STT-latensen låg är lika mycket en arkitekturfråga som en modellfråga. Utvecklare måste planera för transport, chunkning, slutpunktsdetektering och inspelningskedjan – som alla bidrar till latensen. Ineffektivitet i bara en av dem kan spräcka din budget på 200 ms.
Den här guiden ger dig ett praktiskt ramverk för att bygga pipelines för Speech to Text i realtid, från transportlagret och uppåt. Vi utgår från Scribe v2 Realtime, som producerar partiella transkriberingar med ungefär 150 ms modellatens, stöder fler än 90 språk, tar emot PCM-ljud (8–48 kHz) och mu-law-ljud samt erbjuder Voice Activity Detection och manuell commit-kontroll för att slutföra segment.
Vi följer hur ljudet når servern, hur hypoteser blir bekräftad text, vad funktioner i strömmen kostar och hur du fångar upp och vidarebefordrar ljud på rätt sätt.
Sammanfattning
- För att skapa Speech to Text-system i realtid krävs justeringar av arkitekturen så att latensen hålls låg genom hela pipelinen.
- WebSocket är rätt standardval för de flesta pipelines, medan WebRTC erbjuder flera fördelar men är mer komplext.
- Voice Activity Detection hanterar handsfree-segmentering, medan manuell commit ger din applikation möjlighet att åsidosätta detta när den vet att turen är slut.
- Partiella resultat är preliminära och slutliga resultat är bekräftade, så de bör visas på olika sätt.
- Små PCM-chunkar på omkring 100 ms minimerar latensen till det första partiella resultatet.
WebSocket jämfört med WebRTC för Speech to Text i realtid
Innan någon transkribering kan ske måste ljudet färdas från källan till igenkännaren. Kanalen du väljer sätter lägstanivån för latensen i allt som följer. Det finns två användbara alternativ för att få ljudet till transkriberingslagret.
WebSocket är en långlivad, ordnad, tillförlitlig och dubbelriktad kanal över TCP. Du öppnar en anslutning, skickar binära ljudramar uppströms och läser transkriberingshändelser nedströms. Den är enkel på både klient och server, fungerar genom företagsproxyer och brandväggar som redan tillåter HTTPS, och stöds av alla webbläsare och servermiljöer.
Begränsningen med WebSocket är att den använder TCP. Om ett paket går förlorat skickar TCP om det och håller tillbaka senare data tills luckan har fyllts. Under goda nätverksförhållanden märks detta inte. Vid paketförlust uppstår head-of-line-blockering: ett kort avbrott där ljudet köas upp och sedan kommer fram i en klump.
WebRTC är byggt för realtidsmedia. Det kör media över UDP (via SRTP), så ett förlorat paket stoppar inte strömmen – pipelinen fortsätter. Det innehåller en jitterbuffert som absorberar variationer i paketens ankomsttid, hanterar NAT-traversering med ICE/STUN/TURN så att parter bakom routrar kan ansluta och har egna funktioner för ljudinsamling och kodning.
Du behöver vanligtvis TURN-servrar för klienter som inte kan ansluta direkt, och serverdelen måste terminera en medieström i stället för att läsa en byteström.
Här är avvägningen i korthet:
För de flesta användningsfall är WebSocket rätt val. Använd det när dina klienter har stabil anslutning och du kontrollerar inspelningskedjan: server-till-server-pipelines, skrivbordsappar, webbläsarappar med bredbandsanslutning och de flesta kontaktcenter-backendmiljöer där ljudet redan når servern på något annat sätt.
Välj WebRTC när du fångar upp ljud direkt från konsumentenheter på opålitliga mobilnät, när du redan kör en WebRTC-stack för tvåvägsljud – till exempel en röstagent som också svarar med tal – eller när realtidsbeteende med låg paketförlust är viktigare än enkel implementation.
Resten av den här guiden använder WebSocket-transport för igenkännaranslutningen, eftersom den gör delarna i systemet tydliga och är rätt startpunkt för de flesta team. Inget av detta är specifikt för WebSocket, så du kan senare lägga till ett WebRTC-medialed framför, avkoda ljudet till PCM på servern och skicka samma chunkar vidare in i pipelinen.
Partiella och slutliga transkript: förklaring av interimistiska resultat
En igenkännare i realtid väntar inte på en fullständig mening innan den ger resultat. I stället skickar den en löpande ström av gissningar som blir skarpare när mer ljud kommer in och sedan låses fast. Att förstå skillnaden mellan dessa två tillstånd är det som skiljer ett levande transkript från ett som känns trasigt.
En partiell hypotes är modellens bästa gissning utifrån ljudet den har tagit emot hittills. Partiella resultat är medvetet instabila. När mer ljud kommer in reviderar modellen tidigare ord: ”Jag vill ha” kan bli ”Jag vill ha två biljetter” när senare sammanhang löser tvetydigheten. De kommer snabbt – det är vad latenssiffran på omkring 150 ms beskriver – och är avsedda att skrivas över.
En slutlig hypotes är ett bekräftat segment som inte kommer att ändras. När ett segment har slutförts går igenkännaren vidare och efterföljande hypoteser beskriver senare ljud. Slutliga resultat är det du sparar, skickar till en LLM eller lagrar som transkript.
Skillnaden mellan partiella och slutliga resultat styr tre saker som du kommer att hantera fel om du blandar ihop dem:
- Användarupplevelse: Att visa partiella resultat gör att ett transkript känns levande: användaren ser ord visas medan hen talar, vilket bekräftar att mikrofonen fungerar och att systemet lyssnar.
- Slutpunktsdetektering: Partiella resultat ger dig en kontinuerlig signal om talaktivitet. Tillsammans med VAD kan de hjälpa dig att avgöra när talaren faktiskt har slutat.
- Tajming nedströms: I en pipeline för röstagenter är stegen ljud in, sedan Speech to Text, sedan en LLM, sedan Text to Speech, och därefter ljud ut. Du kan påbörja spekulativt arbete utifrån partiella resultat och bekräfta det med slutliga resultat. Det minskar den upplevda svarstiden, men innebär att du ibland behöver kasta spekulativt arbete.
Visa partiella och slutliga resultat på olika sätt. Ett enkelt och effektivt mönster är att ha en enda föränderlig ”aktuell rad” som är kopplad till det senaste partiella resultatet och lägga till den i ett transkript som bara utökas när ett slutligt resultat kommer:
Visa bekräftad text som fastställd och den aktuella texten i en ljusare eller kursiv stil, så att användaren förstår att den fortfarande kan ändras.
Slutpunktsdetektering och Voice Activity Detection (VAD)
Att veta vad som sades är bara halva jobbet. En igenkännare måste också veta när en tanke har avslutats. Det avgör när ett segment slutförs och, för en agent, när systemet börjar svara.
Slutpunktsdetektering är beslutet att ett yttrande har avslutats. Om du slutför för tidigt avbryter du användare mitt i meningen. Om du slutför för sent förblir agenten tyst trots att användaren tydligt har talat färdigt.
Scribe v2 Realtime ger dig två kompletterande mekanismer:
- Voice Activity Detection segmenterar ljud baserat på tystnad: Igenkännaren upptäcker när tal övergår i ihållande tystnad och använder den gränsen för att automatiskt slutföra ett segment. VAD är rätt standardval för samtalsgränssnitt eftersom den anpassar sig till den naturliga talrytmen utan att du behöver hålla reda på tid manuellt.
- Manuell commit-kontroll: Med manuell commit-kontroll avgör din applikation när det aktuella segmentet ska slutföras, oberoende av tystnad. Du skickar en commit-signal, igenkännaren stänger det aktuella segmentet och skickar ett slutligt resultat. Det är rätt verktyg när applikationen redan vet att turen är slut: när en push-to-talk-knapp släpps, vid en ”skicka”-åtgärd eller enligt en extern policy för turtagning.
De två fungerar bra tillsammans. En typisk röstagent använder VAD för handsfree-användning och erbjuder manuell commit som en åsidosättning. Då avbryts inte en användare som pausar för att tänka, medan en användare som trycker på en knapp får en omedelbar gräns.
Tystnadströskeln är en verklig avvägning utan något universellt korrekt värde:
- En kort timeout efter avslutat tal – till exempel slutförande efter omkring 200–400 ms tystnad – gör att systemet känns responsivt. Den avbryter dock också användare som naturligt pausar mellan satser, delar upp en tanke i flera segment och kan få en agent att svara för tidigt.
- En lång timeout – till exempel omkring 800–1 200 ms – tolererar naturliga pauser och håller ihop yttranden, men medför en märkbar fördröjning innan systemet reagerar.
Det finns ingen global konstant att använda här. Anpassa i stället tröskeln efter interaktionen:
- Diktering och anteckningar tolererar längre pauser eftersom användare tänker mitt i meningen. Välj längre timeouter och förlita dig på VAD.
- Kommando- och kontrollagenter samt transaktionsagenter gynnas av kortare timeouter och manuell commit, eftersom turerna är korta och tydliga.
- Flerspråkiga talare och personer som inte talar sitt modersmål pausar mer, så avsätt mer tystnad innan du slutför.
Med de här råden kan du bygga ett effektivt system för slutpunktsdetektering och komma närmare Speech to Text i realtid.
Funktioner i strömmen: språkidentifiering och talardiarisering
Strömmande igenkänning kan göra mer än att producera ord. Men varje extra signal du begär påverkar latens och stabilitet. Tumregeln är att bara aktivera det som upplevelsen i realtid behöver och skjuta upp resten till en batchkörning.
Automatisk språkigenkänning låter Scribe v2 Realtime identifiera det talade språket bland fler än 90 språk som stöds, i stället för att du behöver ange det i förväg. Nackdelen är att modellen behöver ett kort ljudavsnitt för att avgöra språket säkert, så de första partiella resultaten i en ström kan vara mindre stabila medan språket fastställs. Om du redan känner till språket tar en specifikation bort den osäkerheten och ger vanligtvis stabilare tidiga partiella resultat.
Talardiarisering kopplar tal till olika talare och identifierar vem som sa vad. Vid batchtranskribering är detta jämförelsevis enkelt eftersom modellen ser hela filen. Vid streaming är det svårare: igenkännaren måste tilldela en talaretikett baserat enbart på ljudet hittills, och en etikett för tidigt ljud kan behöva ändras när mer av talarens röst har hörts. Hantera talaretiketter vid streaming på samma sätt som partiell text: som preliminära tills segmentet slutförs.
Tidsangivelser på ordnivå och entitetskontext följer samma logik. Ju mer metadata per token du begär, desto mer måste både modellen och överföringen bära. För de flesta användargränssnitt i realtid behöver du bara texten och segmentgränserna direkt, och kan skjuta upp detaljerad metadata till en batchkörning efter samtalet med Scribe v2.
Ljudformat för streaming: PCM och mu-law
Transport och igenkänningslogik får mest uppmärksamhet, men förvånansvärt många verkliga buggar uppstår ett lager längre ned: i hur du kodar och chunkar ljudet. Att få rätt format och chunkstorlek är den billigaste möjliga förbättringen för Speech to Text-latens.
PCM (linjärt, 16-bitars signerat, little-endian) är formatet att använda när du kontrollerar inspelningen. Högre samplingsfrekvenser innehåller mer akustisk detalj: 16 kHz är standardlägstanivån för taligenkänning och räcker vanligtvis; 8 kHz har telefonikvalitet och förlorar högfrekvent innehåll. Använd den frekvens som matchar din källa. Det finns ingen vinst med att sampla upp telefoniljud på 8 kHz till 48 kHz, eftersom informationen inte finns där att återskapa.
Mu-law vid 8 kHz är telefoniformatet. Om du tar emot samtal från en leverantör som Twilio kommer ljudet som mu-law på 8 kHz, och du bör vidarebefordra det i det formatet i stället för att omkoda det två gånger. Att matcha källformatet undviker artefakter från omsampling och ett onödigt konverteringssteg.
Chunkstorleken är den faktor som mest direkt formar den upplevda latensen. Du skickar ljud i chunkar, och igenkännaren producerar partiella resultat när chunkarna kommer in. Mindre chunkar innebär tätare uppdateringar och lägre latens till det första partiella resultatet; större chunkar innebär färre meddelanden och något mer kontext per inferens. Ett praktiskt intervall är 20–250 ms ljud per chunk. Som konkret riktmärke: vid mono-PCM på 16 kHz och 16 bitar är en sekund ljud 32 000 byte, så en chunk på 100 ms är omkring 3 200 byte.
Fånga mikrofonljud i webbläsaren
I webbläsaren är rätt verktyg Web Audio API med en AudioWorklet. Workleten körs på ljudrenderingstråden, tar emot ljud i små ramar och påverkas inte av lagg på huvudtråden som den äldre ScriptProcessorNode gjorde. Dess uppgift är att konvertera webbläsarens ursprungliga float-samplingar till 16-bitars PCM och skicka dem till huvudtråden, som vidarebefordrar dem över WebSocket.
Kärnan i worklet-processorn är konverteringen från float till PCM:
Pipelinen i kod
Pipelinen har tre delar: en webbläsarklient som fångar mikrofonen och strömmar PCM till din server, en Node-server som vidarebefordrar ljud till Scribe v2 Realtime och skickar tillbaka transkript samt en skriptbar klient som strömmar PCM från en fil eller telefonibrygga.
Servern vidarebefordrar ljudet i stället för att exponera igenkännaren direkt för webbläsaren av en viktig anledning: din ElevenLabs API-nyckel är hemlig och får aldrig förekomma i kod på klientsidan. Nyckeln ligger på servern. Om webbläsaren måste kommunicera direkt med igenkännaren, skapa en kortlivad token för engångsanvändning på servern och ge den till klienten i stället för API-nyckeln.
Webbläsarklient
Klienten öppnar en WebSocket till din server, fångar mikrofonen via workleten ovan och vidarebefordrar varje PCM-ram när den produceras. Inkommande händelser – som servern redan har normaliserat till { type, text } – styr tillståndet för partiella och slutliga resultat från tidigare:
Serverrelä
Servern öppnar en igenkännaranslutning per klient, behåller API-nyckeln på servern, vidarebefordrar binär PCM direkt och normaliserar igenkännarhändelser till det stabila formatet { type, text } som klienten använder:
Allt som är specifikt för endpointen är begränsat till de två adapterfunktionerna nedan. Ersätt fältnamnen med de exakta namnen i Speech to Text-referensen. Resten av pipelinen ändras inte:
Skriptbar backendklient
För backendpipelines och benchmarken nedan fungerar samma igenkännaranslutning utan en webbläsare: läs PCM från valfri källa, takta den enligt chunkkadensen i realtid och läs tillbaka händelser. API-nyckeln och URL:en hämtas från miljön, precis som på servern.
Benchmarking av Speech to Text-latens och word error rate
Både latens och word error rate varierar beroende på talaren, språket, de akustiska förhållandena, ljudets längd, nätverksvägen till varje leverantörs närmaste region och den aktuella belastningen på varje tjänst.
Ett resultat som mäts från en bärbar dator i en stad kan inte generaliseras till din produktionsmiljö i en annan. Kör testmiljön från infrastruktur som liknar produktion, med ljud som liknar din faktiska indata, och rapportera intervall och fördelningar i stället för enskilda siffror.
De enda siffrorna för latens och noggrannhet som spelar roll är de du mäter på ditt eget ljud från infrastruktur som liknar produktion. Här är en guide till att benchmarka Speech to Text-latens.
Vad du ska mäta för Speech to Text-latens
Nedan följer de viktigaste mätvärdena när du benchmarkar Speech to Text-latens i realtid:
- Tid till första partiella resultatet: Från att den första ljudchunken skickas tills det första icke-tomma partiella resultatet tas emot.
- Fördröjning från partiellt till slutligt resultat: Från den sista ljudchunken i ett yttrande till den slutliga hypotesen.
- Word error rate (WER): WER för det slutliga transkriptet jämfört med en mänsklig referens, beräknad på samma sätt för alla system.
- Stabilitetsförändringar: Hur många partiella resultat som skrivs om innan de slutförs. Detta mått visar ungefär hur mycket användargränssnittet i realtid kommer att förändras.
Kontroller
För att undvika opålitliga data bör du införa flera kontroller i experimentet för att hålla allt konsekvent.
Här är de viktigaste kontrollerna för benchmarking av Speech to Text-latens:
- Identiskt ljud: Använd samma filer, samplingsfrekvens och kodning för varje system.
- Identisk taktning: Strömma till varje system med samma realtidskadens för chunkar, till exempel chunkar på 100 ms.
- Upprepa och rapportera fördelningar: Kör varje fil många gånger under dagen och rapportera median och svansvärden (p50/p95).
- Identiska referenser och bedömning: Normalisera texten på samma sätt – versaler/gemener, interpunktion och siffror – innan du beräknar WER.
- Ange region och nätverk: Ange var testmiljön kördes och vägen till varje leverantör.
Genom att hålla alla dessa delar lika får du mer precisa mätvärden.
Grundstruktur för testmiljön
Mätkärnan tar en leverantörsadapter och registrerar tid till första partiella resultatet, fördröjning till slutförande och förändringar i partiella resultat:
Word error rate är ett standardmått baserat på Levenshtein-avstånd på tokennivå över normaliserad text. Konvertera till gemener och ta bort interpunktion på exakt samma sätt i både referensen och hypotesen innan du beräknar det, annars mäter du din normaliserare snarare än modellen. Lägg måttet i en loop som kör varje fil omkring 10 gånger per leverantör och rapporterar medianen för tid till första partiella resultatet och median-WER (p50/p95), eftersom ett enskilt prov domineras av nätverksvariation.
För att köra det behöver du två saker. Först skriver du en StreamFn-adapter per system. Den skriptbara klienten ovan är redan en sådan, och adaptrar för de andra följer samma kontrakt för (audioPath, onEvent, result) och sätter result.lastChunkSentAt när den sista ljudchunken skickas. Sedan laddar du dina ljudfiler och referenser och anropar måtten för dem. Kör det från en dator som representerar din driftsättning, med ljud som representerar dina användare, så får du en jämförelse som går att reproducera.
Sammanfattning: så uppnår du Speech to Text i realtid
Vi har gått igenom många arkitekturförändringar i den här artikeln som låter dig förbättra systemet stegvis och komma närmare Speech to Text i realtid.
Ett STT-system för produktion i realtid handlar om en handfull beslut:
- Transport: Välj WebSocket för enkelhet och kontrollerade nätverk, och WebRTC när du behöver tålighet mot paketförlust och fångar upp ljud från konsumentenheter.
- Partiella och slutliga resultat: Hantera partiella resultat som preliminära och slutliga resultat som bekräftade, och visa dem på olika sätt så att användarna litar på texten i realtid.
- Slutpunktsdetektering: Använd VAD för handsfree-segmentering, manuell commit som en åsidosättning och anpassa tystnadströskeln efter interaktionen i stället för en fast konstant.
- Funktioner i strömmen: Aktivera bara funktioner i strömmen när upplevelsen i realtid behöver dem och skjut upp resten till en batchkörning med Scribe v2.
- Ljudformat: Fånga upp små PCM-ramar, skicka chunkar på omkring 100 ms och matcha källformatet för telefoni.
- Benchmarking: Ställ in avvägningarna mellan noggrannhet och latens empiriskt mot ditt eget ljud och ditt målmått.
- API-säkerhet: Behåll din API-nyckel på servern, eller skapa tokens för engångsanvändning vid direkta klientanslutningar.
Om du vill se hur du kan optimera latensen i en röstagent, har vi också skrivit en guide om det.
Bygg Speech to Text-system i realtid med Scribe v2 Realtime
Scribe v2 Realtime producerar partiella resultat med ungefär 150 ms modellatens. Om dina användare upplever den siffran eller något högre beror på arkitekturen runt omkring, vilket är den del du kontrollerar. Genom att använda strategierna i den här artikeln bygger du en pipelinearkitektur som minskar latensen och förbättrar kundupplevelsen.
Vill du gå djupare kan du läsa översikten över Speech to Text-funktioner, gå igenom vår modellreferens för en fullständig lista över funktioner och språk, och besöka produktsidorna för realtid: Speech to Text API i realtid och Speech to Text i realtid.
När du är redo att bygga, skapa ett kostnadsfritt ElevenLabs-konto och strömma ditt första transkript redan i dag.

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