Vi presenterar Eleven v4Möt Eleven v4, vår mest uttrycksfulla modell hittills. Med 3× fler krediter inkluderade i Creator+ till och med den 12 oktober

Hoppa till innehållet

Tal till text i realtid under 200 ms: En arkitekturguide

Publicerad
Senast uppdaterad

LyssnaLyssna på den här artikeln

Tal till text (STT) i realtid transkriberar aktivt ljud medan en person talar och återger orden som text inom några hundra millisekunder. Men att hålla STT-latensen låg är lika mycket en arkitekturfråga som en modelfråga. Utvecklare måste planera för transport, chunking, slutpunktsdetektering och inspelningskedjan, som alla bidrar till latensen. Ineffektivitet i någon av dessa kan spräcka din budget på 200 ms.

Den här guiden ger dig ett praktiskt system för att bygga pipelines för tal till 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, har stöd för över 90 språk, tar emot PCM-ljud (8–48 kHz) och mu-law-ljud samt erbjuder Voice Activity Detection samt manuell commit-kontroll för att slutföra segment.

Vi följer hur ljudet når servern, hur hypoteser utvecklas till bekräftad text, vad funktioner i strömmen kostar och hur du fångar in och vidarebefordrar ljud korrekt.

Sammanfattning

  • Att skapa system för tal till text i realtid kräver arkitekturell finjustering för att hålla latensen låg genom hela pipelinen.
  • WebSocket är rätt standardval för de flesta pipelines, även om WebRTC erbjuder flera fördelar men är mer komplext.
  • Voice Activity Detection hanterar handsfree-segmentering, medan manuell commit ger dina applikationer möjlighet att åsidosätta den när de vet att turen är slut.
  • Partiella resultat är preliminära och slutliga resultat är bekräftade, vilket innebär att du bör visa dem 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 tal till text i realtid

Innan transkriberingen kan börja 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å genomförbara sätt 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 transkriptionshändelser nedströms. Den är enkel på både klient- och serversidan, passerar företagsproxyservrar och brandväggar som redan tillåter HTTPS, och stöds av alla webbläsare och servermiljöer.

Begränsningen med WebSocket är att det körs över TCP. Om ett paket försvinner skickar TCP om det och håller tillbaka senare data tills luckan är fylld. Under goda nätverksförhållanden märks detta inte. Vid paketförlust uppstår head-of-line-blockering: ett kort stopp där ljudet köas upp och sedan anländer 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, förhandlar 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 serversidan måste avsluta en mediaström i stället för att läsa en byteström.

Här är avvägningen i korthet:

WebSocket
Transport
TCP (reliable, ordered)
Behavior under packet loss
Head-of-line blocking, bursty recovery
Jitter handling
Your responsibility
NAT traversal
Not needed (client-initiated)
Browser support
Universal, trivial
Server complexity
Low
WebRTC
Transport
UDP/SRTP (real-time, loss-tolerant)
Behavior under packet loss
Graceful degradation
Jitter handling
Built-in jitter buffer
NAT traversal
Requires ICE/STUN/TURN
Browser support
Universal, but more API surface
Server complexity
High (media server or SFU)

För de flesta användningsfall är WebSocket rätt val. Använd det när dina klienter har bra uppkoppling och du kontrollerar inspelningskedjan: server-till-server-pipelines, skrivbordsappar, webbläsarappar på bredband och de flesta kontaktcenter-backends där ljudet redan når din server på något annat sätt.

Välj WebRTC när du spelar in 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å talar tillbaka, eller när realtidsbeteende med låg paketförlust är viktigare än enkel implementering.

Resten av guiden använder WebSocket-transport för anslutningen till igenkännaren, eftersom den gör delarna 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 vidarebefordra samma chunkar till pipelinen.

Partiella och slutliga transkript: preliminära resultat förklarade

En igenkännare i realtid väntar inte på en hel mening innan den ger resultat. I stället skickar den ut en löpande ström av gissningar som skärps när mer ljud anländer och sedan låses. 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, eller preliminär, hypotes är modellens bästa gissning baserat på ljudet som hittills tagits emot. Partiella resultat är avsiktligt instabila. När mer ljud kommer reviderar modellen tidigare ord: ”Jag vill ha” kan bli ”Jag vill ha två biljetter” när senare kontext löser tvetydigheten. De kommer snabbt – det är vad siffran på omkring 150 ms latens beskriver – och är avsedda att skrivas över.

En slutlig hypotes är ett bekräftat segment som inte ändras. När ett segment har slutförts går igenkännaren vidare, och efterföljande hypoteser beskriver senare ljud. Det är de slutliga resultaten du sparar, skickar till en LLM eller lagrar som ett 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 avgöra när talaren faktiskt har slutat.
  • Tidpunkt i efterföljande steg: I en pipeline för röstagenter är stegen ljud in, sedan tal till text, sedan en LLM, sedan text till tal, sedan ljud ut. Du kan påbörja spekulativt arbete baserat på partiella resultat och bekräfta det vid slutliga resultat, vilket minskar den upplevda svarstiden men ibland innebär att spekulativt arbete måste kasseras.

Visa partiella och slutliga resultat på olika sätt. Ett enkelt och effektivt mönster är att behålla 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:

type TranscriptState = {
  committed: string[]; // finalized segments, never rewritten
  current: string;     // latest partial, overwritten on each update
};

const onPartial = (s: TranscriptState, text: string): TranscriptState =>
  ({ ...s, current: text });

const onFinal = (s: TranscriptState, text: string): TranscriptState =>
  ({ committed: [...s.committed, text], current: "" });

Visa visuellt 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 röstaktivitetsdetektering (VAD)

Att veta vad som sades är bara halva jobbet. En igenkännare måste också veta när en tanke är avslutad. Det avgör när du slutför ett segment 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 avbryts användare mitt i en mening. Om du slutför för sent förblir en agent tyst efter att användaren tydligt har talat klart.

Scribe v2 Realtime ger dig två kompletterande mekanismer att arbeta med:

  • 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 konversationsgränssnitt eftersom den anpassar sig till naturlig talrytm utan att du behöver hålla koll på tid manuellt.
  • Manuell commit-kontroll: Med manuell commit-kontroll kan din applikation avgöra 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 turordning.

De två fungerar bra tillsammans. En typisk röstagent använder VAD för handsfree-drift och erbjuder manuell commit som åsidosättning, så att en användare som pausar för att tänka inte avbryts, medan en användare som trycker på en knapp får en omedelbar gräns.

Tystnadströskeln är en verklig avvägning utan ett 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. Men den avbryter också användare som naturligt pausar mellan satser, delar upp en tanke i flera segment och kan, för en agent, utlösa ett för tidigt svar.
  • En lång timeout, till exempel omkring 800–1 200 ms, tolererar naturliga pauser och håller yttranden intakta, men till priset av en märkbar fördröjning innan systemet reagerar.

Det finns ingen global konstant att använda här; anpassa 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 har nytta av kortare timeouter tillsammans med manuell commit, eftersom turerna är korta och tydliga.
  • Flerspråkiga talare eller personer som inte talar sitt modersmål pausar mer, så avsätt mer tystnad innan slutförande.

Med de här råden kan du bygga ett effektivt system för slutpunktsdetektering och komma närmare tal till 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 ber om påverkar latens och stabilitet. Tumregeln är att bara aktivera det som liveupplevelsen behöver och skjuta upp resten till en batchkörning.

Automatisk språkidentifiering låter Scribe v2 Realtime identifiera det talade språket bland de över 90 språk som stöds, i stället för att du behöver ange det i förväg. Kostnaden ä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 vet språket tar en specificering bort den osäkerheten och ger ofta stabilare tidiga partiella resultat.

Talardiarisering kopplar tal till olika talare och identifierar vem som sa vad. I batchtranskribering är detta jämförelsevis enkelt eftersom modellen ser hela filen. Vid strömning är det svårare: igenkännaren måste tilldela en talaretikett utifrån enbart ljudet som hittills kommit in, och en etikett för tidigt ljud kan behöva revideras när mer av talarens röst hörs. Behandla talaretiketter vid strömning 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 realtidsgränssnitt behöver du bara texten och segmentgränserna live, och kan skjuta upp detaljerad metadata till en batchkörning efter samtalet med Scribe v2.

Ljudformat för strömning: PCM och mu-law

Transport- och igenkänningslogik får mest uppmärksamhet, men en förvånansvärt stor del av verkliga buggar uppstår ett lager längre ned, i hur du kodar och delar upp ljudet. Att få formatet och chunkstorleken rätt är den billigaste förbättringen du kan göra för latensen i tal till text.

PCM (linjär, 16-bitars signerad, little-endian) är formatet att använda när du kontrollerar inspelningen. Högre samplingsfrekvenser ger mer akustisk detalj: 16 kHz är standardminimum för taligenkänning och räcker vanligtvis; 8 kHz är telefonkvalitet och förlorar högfrekvent innehåll. Använd frekvensen som matchar din källa. Det finns ingen fördel med att sampla upp telefoni-ljud på 8 kHz till 48 kHz, eftersom informationen inte finns där att återställa.

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 omsamplingsartefakter och ett onödigt konverteringssteg.

Chunkstorlek är reglaget som mest direkt formar den upplevda latensen. Du skickar ljud i chunkar, och igenkännaren producerar partiella resultat när chunkarna anländer. 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 är en sekund ljud i mono, 16-bitars PCM vid 16 kHz 32 000 byte, så en chunk på 100 ms är omkring 3 200 byte.

Fånga mikrofoninmatning i webbläsaren

I webbläsaren är rätt verktyg Web Audio API med en AudioWorklet. Workleten körs på tråden för ljudrendering, tar emot ljud i små ramar och påverkas inte av hack i huvudtråden på samma sätt som den äldre ScriptProcessorNode. Dess uppgift är att konvertera webbläsarens inbyggda flyttalsprover till 16-bitars PCM och lämna dem till huvudtråden, som skickar dem vidare över WebSocket.

Kärnan i worklet-processorn är konverteringen från flyttal till PCM:

// pcm-worklet.ts - registered via audioContext.audioWorklet.addModule()
class PCMWorklet extends AudioWorkletProcessor {
  process(inputs: Float32Array[][]) {
    const channel = inputs[0]?.[0]; // mono; Float32, range [-1, 1]
    if (!channel) return true;
    const pcm = new Int16Array(channel.length);
    for (let i = 0; i < channel.length; i++) {
      const s = Math.max(-1, Math.min(1, channel[i]));
      pcm[i] = s < 0 ? s * 0x8000 : s * 0x7fff;
    }
    // Transfer the buffer to the main thread without copying.
    this.port.postMessage(pcm.buffer, [pcm.buffer]);
    return true;
  }
}
registerProcessor("pcm-worklet", PCMWorklet);

Pipelinen i kod

Pipelinen har tre rörliga 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 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 finnas i kod på klientsidan. Servern har nyckeln. Om du behöver att webbläsaren kommunicerar direkt med igenkännaren skapar du en kortlivad engångstoken på serversidan och ger klienten den 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 så snart den produceras. Inkommande händelser, som redan normaliserats av servern till { type, text }, styr tillståndet för partiella och slutliga resultat från tidigare:

// client.ts - runs in the browser. ws is an open WebSocket to your server.
const audioContext = new AudioContext({ sampleRate: 16000 });
await audioContext.audioWorklet.addModule("pcm-worklet.js");

const mediaStream = await navigator.mediaDevices.getUserMedia({
  audio: { channelCount: 1, echoCancellation: true, noiseSuppression: true },
});

const source = audioContext.createMediaStreamSource(mediaStream);
const worklet = new AudioWorkletNode(audioContext, "pcm-worklet");

// Forward each PCM frame to the server the moment it is produced.
worklet.port.onmessage = (e: MessageEvent<ArrayBuffer>) => {
  if (ws.readyState === WebSocket.OPEN) ws.send(e.data);
};
source.connect(worklet);

// Manual commit: tell the server to finalize the current segment.
const commit = () => ws.send(JSON.stringify({ type: "commit" }));

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:

// server.ts - Node, using the `ws` library. ELEVENLABS_API_KEY and the
// recognizer URL come from the environment; see the Speech to Text reference
// for the exact path and query parameters.
import { WebSocketServer, WebSocket } from "ws";

new WebSocketServer({ port: 8080 }).on("connection", (client) => {
  // The API key stays on the server, never on the wire to the browser.
  const recognizer = new WebSocket(process.env.RECOGNIZER_WSS_URL!, {
    headers: { "xi-api-key": process.env.ELEVENLABS_API_KEY! },
  });

  // Browser -> recognizer: forward binary PCM, translate control messages.
  client.on("message", (data, isBinary) => {
    if (recognizer.readyState !== WebSocket.OPEN) return;
    if (isBinary) recognizer.send(data); // raw PCM bytes
    else if (JSON.parse(data.toString()).type === "commit")
      recognizer.send(sendCommit());
  });

  // Recognizer -> browser: normalize events into a stable shape.
  recognizer.on("message", (raw) => {
    const event = parseRecognizerEvent(raw.toString());
    if (event && client.readyState === WebSocket.OPEN)
      client.send(JSON.stringify(event));
  });

  // ... open handshake, queueing pre-open audio, and teardown on close/error
});

Allt som är specifikt för endpointen är begränsat till de två adapterfunktionerna nedan. Ersätt fältnamnen med de exakta namnen från Speech to Text-referensen; resten av pipelinen ändras inte:

// The single place that knows the recognizer's wire format.
const sendCommit = (): string => JSON.stringify({ type: "commit" });

type NormalizedEvent =
  | { type: "partial"; text: string }
  | { type: "final"; text: string }
  | { type: "vad"; speaking: boolean };

function parseRecognizerEvent(raw: string): NormalizedEvent | null {
  const msg = JSON.parse(raw);
  if (msg.is_final === true || msg.type === "final")
    return { type: "final", text: msg.text ?? "" };
  if (msg.type === "vad") return { type: "vad", speaking: !!msg.speaking };
  if (typeof msg.text === "string")
    return { type: "partial", text: msg.text };
  return null;
}

Skriptbar backendklient

För backend-pipelines och för benchmarken nedan fungerar samma igenkännaranslutning utan webbläsare: läs PCM från valfri källa, skicka den i samma takt som realtidschunkar och läs tillbaka händelser. API-nyckeln och URL:en kommer från miljön, precis som på servern.

// stream-stt.ts - pace ~100ms chunks at real time, then commit the tail.
const SAMPLE_RATE = 16000, CHUNK_MS = 100;
const CHUNK_BYTES = (SAMPLE_RATE * 2 * CHUNK_MS) / 1000; // 3200 bytes
const ws = new WebSocket(process.env.RECOGNIZER_WSS_URL!, {
  headers: { "xi-api-key": process.env.ELEVENLABS_API_KEY! },
});

// Send: walk the PCM buffer in 100ms chunks, sleeping between to mimic a
// live source. For audio that already arrives in real time, drop the sleep.
async function sendAudio(pcm: Buffer) {
  for (let off = 0; off < pcm.length; off += CHUNK_BYTES) {
    ws.send(pcm.subarray(off, off + CHUNK_BYTES));
    await new Promise((r) => setTimeout(r, CHUNK_MS));
  }
  ws.send(JSON.stringify({ type: "commit" })); // finalize the trailing segment
}

// Receive: print partials in place, append finals.
ws.on("message", (raw) => {
  const e = parseRecognizerEvent(raw.toString());
  if (e?.type === "final") console.log(`[final]   ${e.text}`);
  else if (e?.type === "partial") process.stdout.write(`[partial] ${e.text}\r`);
});

Benchmarking av latens för tal till text och ordfelfrekvens

Både latens och ordfelfrekvens varierar med talaren, språket, de akustiska förhållandena, ljudets längd, din nätverksväg till varje leverantörs närmaste region och den aktuella belastningen på varje tjänst.

Ett resultat som mäts från en laptop i en stad kan inte generaliseras till din produktionsmiljö i en annan. Kör testverktyget från infrastruktur som liknar produktion, med ljud som liknar din verkliga 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 för benchmarking av latens för tal till text.

Vad du ska mäta för latens i tal till text

Nedan är de viktigaste måtten att mäta vid benchmarking av latens för tal till text i realtid:

  • Tid till första partiella resultat: Från att den första ljudchunken skickas till att 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.
  • Ordfelfrekvens (WER): WER för det slutförda 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 före slutförandet. Detta mått är en indikator på hur mycket livegränssnittet kommer att se ut att ändras.

Kontroller

För att undvika opålitliga data bör du införa flera kontroller i experimentet för att hålla förutsättningarna konsekventa.

Här är de viktigaste kontrollerna vid benchmarking av latens för tal till text:

  • Identiskt ljud: Använd samma filer, samma samplingsfrekvens och samma kodning för varje system.
  • Identisk takt: Strömma varje system med samma takt för realtidschunkar, till exempel chunkar på 100 ms.
  • Upprepa och rapportera fördelningar: Kör varje fil många gånger under dagen; rapportera median och svansvärden (p50/p95).
  • Identiska referenser och poängsättning: Normalisera text på samma sätt – versaler/gemener, skiljetecken och siffror – innan du beräknar WER.
  • Redovisa region och nätverk: Ange var testverktyget kördes och vägen till varje leverantör.

Genom att hålla alla dessa delar lika får du mer precisa mått.

Testverktygets grundstruktur

Mätkärnan tar emot en leverantörsadapter och registrerar tid till första partiella resultat, fördröjning till slutförande och förändringar i partiella resultat:

// benchmark.ts - measurement core; one StreamFn adapter per provider.
type StreamFn = (
  audioPath: string,
  onEvent: (kind: "partial" | "final", text: string) => void,
  result: RunResult
) => Promise<void>; // adapter sets result.lastChunkSentAt on the final chunk

interface RunResult {
  firstPartialMs?: number;
  finalLagMs?: number;
  hypothesis: string;
  partialEdits: number;
  lastChunkSentAt: number;
  startedAt: number;
}

async function measure(streamFn: StreamFn, audioPath: string): Promise<RunResult> {
  const result: RunResult = {
    hypothesis: "", partialEdits: 0, lastChunkSentAt: 0,
    startedAt: performance.now(),
  };
  let prevPartial = "";

  await streamFn(audioPath, (kind, text) => {
    const now = performance.now();
    if (kind === "partial") {
      if (text && result.firstPartialMs === undefined)
        result.firstPartialMs = now - result.startedAt;
      if (text !== prevPartial) { result.partialEdits++; prevPartial = text; }
    } else { // final
      result.hypothesis = result.hypothesis ? `${result.hypothesis} ${text}` : text;
      if (result.lastChunkSentAt)
        result.finalLagMs = now - result.lastChunkSentAt;
    }
  }, result);

  return result;
}

Ordfelfrekvens är ett standardiserat Levenshtein-avstånd på tokennivå över normaliserad text. Använd gemener och ta bort skiljetecken på exakt samma sätt i både referens och hypotes innan du beräknar den, annars mäter du din normaliserare i stället för 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 resultat och median-WER (p50/p95), eftersom ett enskilt prov domineras av nätverksvariation.

För att få detta att köra behöver du två saker. Skriv först en StreamFn-adapter per system. Den skriptbara klienten ovan är redan en sådan, och adaptrarna för de andra följer samma kontrakt, (audioPath, onEvent, result), samt sätter result.lastChunkSentAt när den sista ljudchunken skickas. Ladda sedan dina ljudfiler och referenser och kör mätningar 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 tal till text i realtid

Vi har gått igenom många arkitekturella förändringar i den här artikeln, så att du stegvis kan förbättra ditt system och närma dig tal till text i realtid.

Ett STT-system för realtid i produktion handlar om några få beslut:

  • Transport: Välj WebSocket för enkelhet och kontrollerade nätverk, och WebRTC när du behöver tåla paketförluster och fångar ljud från konsumentenheter.
  • Partiella och slutliga resultat: Behandla partiella resultat som preliminära och slutliga som bekräftade, och visa dem olika så att användarna litar på live-texten.
  • Slutpunktsdetektering: Använd VAD för handsfree-segmentering, manuell commit som åsidosättning och anpassa tystnadströskeln efter interaktionen i stället för efter en konstant.
  • Funktioner i strömmen: Aktivera funktioner i strömmen bara där liveupplevelsen behöver dem, och skjut upp resten till en batchkörning med Scribe v2.
  • Ljudformat: Fånga ljud i små PCM-ramar, skicka chunkar på omkring 100 ms och matcha källformatet för telefoni.
  • Benchmarking: Ställ in reglagen mellan noggrannhet och latens empiriskt utifrån ditt eget ljud och ditt mått.
  • API-säkerhet: Behåll din API-nyckel på servern, eller skapa engångstoken för direkta klientanslutningar.

Om du vill se hur du kan optimera latens i en röstagent, har vi också skrivit en guide för det.

Bygg system för tal till text 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. Med strategierna i den här artikeln bygger du en bättre pipelinearkitektur som minskar latensen och förbättrar kundupplevelsen.

Om du vill gå djupare kan du läsa översikten över Speech to Text-funktioner, läsa vår modellreferens för en fullständig lista över funktioner och språk samt 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 kan du skapa ett kostnadsfritt ElevenLabs-konto och strömma ditt första transkript redan i dag.

Vanliga frågor om latens för tal till text i realtid

Skriven av

Tadas Petra är Developer Relations Engineer och hjälper utvecklare att bygga med ElevenLabs produkter. Han är också grundare av Hungrimind, en plattform för utvecklarutbildning. Tidigare var han Lead Developer Advocate på Agora och instruktör på Zero To Mastery.

Liknande artiklar

Skapa med AI-ljud av högsta kvalitet