Trascrizione vocale in tempo reale sotto i 200 ms: guida all’architettura
- Pubblicato
- Ultimo aggiornamento
AscoltaAscolta questo articolo
La trascrizione vocale in tempo reale (STT) trascrive attivamente l'audio mentre una persona parla, restituendone le parole in formato testo entro poche centinaia di millisecondi. Tuttavia, mantenere bassa la latenza STT è tanto un problema architetturale quanto di modello. Gli ingegneri devono pianificare trasporto, chunking, end-pointing e percorso di acquisizione, poiché ciascuno aggiunge latenza. L'inefficienza di uno solo di questi elementi può superare il budget di 200 ms.
Questa guida offre un sistema pratico per creare pipeline di trascrizione vocale in tempo reale, partendo dal livello di trasporto. Useremo come riferimento Scribe v2 Realtime, che produce trascrizioni parziali con una latenza del modello di circa 150 ms, supporta oltre 90 lingue, accetta audio PCM (8 kHz-48 kHz) e mu-law e offre Voice Activity Detection e controllo di commit manuale per finalizzare i segmenti.
Vedremo come l'audio raggiunge il server, come le ipotesi diventano testo confermato, quanto incidono le funzionalità in-stream e come acquisire e inoltrare correttamente l'audio.
In sintesi
- Per creare sistemi di trascrizione vocale in tempo reale è necessaria una messa a punto dell'architettura, così da mantenere bassa la latenza nell'intera pipeline.
- WebSocket è l'opzione predefinita adatta alla maggior parte delle pipeline, mentre WebRTC offre diversi vantaggi ma è più complesso.
- Voice Activity Detection gestisce la segmentazione hands-free, mentre il commit manuale consente alle applicazioni di intervenire quando sanno che il turno è terminato.
- I parziali sono provvisori, mentre i finali sono confermati: devi quindi visualizzarli in modo diverso.
- Piccoli chunk PCM di circa 100 ms riducono al minimo la latenza fino al primo risultato parziale.
WebSocket e WebRTC per la trascrizione vocale in tempo reale
Prima che avvenga qualsiasi trascrizione, l'audio deve viaggiare dalla sorgente al riconoscitore. Il canale scelto stabilisce la latenza minima per tutto ciò che segue. Esistono due opzioni valide per portare l'audio al livello di trascrizione.
WebSocket è un canale TCP bidirezionale, affidabile, ordinato e persistente. Apri una connessione, invii frame audio binari e ricevi eventi della trascrizione. È semplice sia sul client sia sul server, attraversa proxy e firewall aziendali che già consentono HTTPS ed è supportato da ogni browser e runtime server.
Il limite di WebSocket è che utilizza TCP. Se un pacchetto va perso, TCP lo ritrasmette e trattiene i dati successivi finché il vuoto non viene colmato. In buone condizioni di rete non si nota. In presenza di perdita di pacchetti, genera head-of-line blocking: una breve pausa in cui l'audio si accumula e arriva poi a raffica.
WebRTC è progettato per i media in tempo reale. Trasporta i media su UDP, tramite SRTP, quindi un pacchetto perso non blocca lo stream e la pipeline continua. Include un jitter buffer che assorbe le variazioni nei tempi di arrivo dei pacchetti, negozia l'attraversamento NAT con ICE/STUN/TURN per consentire la connessione di peer dietro router e integra meccanismi di acquisizione e codifica audio.
In genere servono server TURN per i client che non possono connettersi direttamente, e il lato server deve terminare uno stream multimediale anziché leggere uno stream di byte.
Ecco il compromesso in breve:
Nella maggior parte dei casi d'uso, WebSocket è l'opzione giusta. Usalo se i client hanno una buona connettività e controlli il percorso di acquisizione: pipeline server-to-server, app desktop, app browser su connessioni a banda larga e la maggior parte dei backend dei contact center, in cui l'audio raggiunge già il server in altro modo.
Scegli WebRTC quando acquisisci direttamente da dispositivi consumer su reti mobili inaffidabili, se usi già uno stack WebRTC per l'audio bidirezionale, ad esempio un agente vocale che risponde a voce, oppure se il comportamento in tempo reale tollerante alle perdite conta più della semplicità di implementazione.
Il resto di questa guida usa il trasporto WebSocket per la connessione al riconoscitore, perché rende visibili le singole parti ed è il punto di partenza giusto per la maggior parte dei team. Nulla è specifico di WebSocket: in seguito puoi aggiungere a monte una tratta multimediale WebRTC, decodificare l'audio in PCM sul server e inoltrare gli stessi chunk nella pipeline.
Risultati parziali e trascrizioni finali: i risultati intermedi spiegati
Un riconoscitore in tempo reale non aspetta una frase completa prima di produrre testo. Emette invece un flusso continuo di ipotesi che diventano più precise man mano che arriva altro audio, per poi confermarle. Capire la differenza tra questi due stati distingue una trascrizione viva da una che sembra difettosa.
Un'ipotesi parziale, o intermedia, è la migliore stima del modello in base all'audio ricevuto finora. I parziali sono instabili per natura. Quando arriva altro audio, il modello rivede le parole precedenti: "Vorrei" può diventare "Vorrei due biglietti" quando il contesto successivo risolve l'ambiguità. Arrivano rapidamente, ed è ciò che descrive la latenza di circa 150 ms, e sono pensati per essere sovrascritti.
Un'ipotesi finale è un segmento confermato che non cambierà. Una volta finalizzato un segmento, il riconoscitore prosegue e le ipotesi successive descrivono l'audio seguente. I finali sono quelli che salvi, invii a un LLM o archivi come trascrizione.
La distinzione tra parziali e finali determina tre aspetti che sbaglierai se la confondi:
- Esperienza utente: mostrare i parziali rende la trascrizione viva: l'utente vede comparire le parole mentre parla e capisce che il microfono funziona e il sistema sta ascoltando.
- End-pointing: i parziali forniscono un segnale continuo dell'attività vocale. Insieme al VAD, consentono di stabilire quando chi parla ha effettivamente smesso.
- Tempistiche a valle: in una pipeline di un agente vocale i passaggi sono: audio in ingresso, trascrizione vocale, LLM, sintesi vocale e audio in uscita. Puoi iniziare un'elaborazione speculativa sui parziali e confermarla sui finali, riducendo il tempo di risposta percepito al costo di dover occasionalmente scartare il lavoro speculativo.
Visualizza parziali e finali in modo diverso. Un modello semplice ed efficace consiste nel mantenere un'unica "riga corrente" modificabile, associata all'ultimo parziale, e aggiungerla a una trascrizione append-only quando arriva un finale:
A livello visivo, mostra il testo confermato con uno stile normale e quello corrente con uno stile più leggero o corsivo, così l'utente capisce che potrebbe ancora cambiare.
End-pointing e rilevamento dell'attività vocale (VAD)
Sapere cosa è stato detto è solo metà del lavoro. Un riconoscitore deve anche sapere quando un pensiero è terminato. Questa decisione determina quando finalizzare un segmento e, in un agente, quando il sistema inizia a rispondere.
L'end-pointing è la decisione che stabilisce che un enunciato è terminato. Finalizzare troppo presto interrompe gli utenti a metà frase. Farlo troppo tardi lascia un agente in silenzio dopo che l'utente ha chiaramente finito.
Scribe v2 Realtime offre due meccanismi complementari:
- Voice Activity Detection segmenta l'audio in base al silenzio: il riconoscitore rileva quando il parlato lascia spazio a un silenzio prolungato e usa quel confine per finalizzare automaticamente un segmento. Il VAD è l'opzione predefinita ideale per le interfacce conversazionali, perché si adatta al ritmo naturale del parlato senza dover monitorare manualmente le tempistiche.
- Controllo di commit manuale: il controllo di commit manuale consente all'applicazione di decidere quando finalizzare il segmento corrente, indipendentemente dal silenzio. Inviando un segnale di commit, il riconoscitore chiude il segmento corrente ed emette un finale. È lo strumento giusto quando l'applicazione sa già che il turno è terminato: al rilascio di un pulsante push-to-talk, con un'azione "invia" o in base a una policy esterna di gestione dei turni.
I due meccanismi funzionano bene insieme. Un tipico agente vocale usa il VAD per il funzionamento hands-free e offre il commit manuale come override, così un utente che si ferma per pensare non viene interrotto, mentre chi tocca un pulsante ottiene un confine immediato.
La soglia di silenzio è un compromesso reale e non esiste un valore universalmente corretto:
- Un timeout breve di fine parlato, ad esempio la finalizzazione dopo circa 200-400 ms di silenzio, rende il sistema reattivo. Può però interrompere gli utenti che fanno pause naturali tra le proposizioni, dividendo un pensiero in più segmenti e, in un agente, attivando una risposta prematura.
- Un timeout lungo, ad esempio circa 800-1200 ms, tollera le pause naturali e mantiene intatti gli enunciati, ma introduce un ritardo percepibile prima che il sistema reagisca.
Non esiste una costante globale da usare: adatta la soglia all'interazione:
- La dettatura e la presa di appunti tollerano pause più lunghe perché gli utenti riflettono a metà frase. Privilegia timeout più lunghi e affidati al VAD.
- Gli agenti transazionali e di comando e controllo traggono vantaggio da timeout più brevi e dal commit manuale, perché i turni sono brevi e netti.
- Chi parla più lingue o una lingua non madre fa più pause: prevedi quindi più silenzio prima di finalizzare.
Questi suggerimenti ti aiutano a creare un sistema di end-pointing efficace e ad avvicinarti alla trascrizione vocale in tempo reale.
Funzionalità in-stream: rilevamento della lingua e diarizzazione dei parlanti
Il riconoscimento in streaming può fare più che produrre parole. Tuttavia, ogni segnale aggiuntivo richiesto influisce sulla latenza e sulla stabilità. Come regola generale, attiva solo ciò che serve all'esperienza live e rimanda il resto a un'elaborazione batch.
Il riconoscimento automatico della lingua consente a Scribe v2 Realtime di identificare la lingua parlata tra le oltre 90 supportate, senza doverla dichiarare in anticipo. Il modello deve però ricevere una breve porzione di audio per determinarla con sicurezza, quindi i primi parziali di uno stream possono essere meno stabili mentre la lingua viene definita. Se conosci già la lingua, specificarla elimina questa ambiguità e tende a produrre parziali iniziali più stabili.
La diarizzazione dei parlanti attribuisce il parlato a parlanti distinti, identificando chi ha detto cosa. Nella trascrizione batch è relativamente semplice, perché il modello vede l'intero file. In streaming è più difficile: il riconoscitore deve assegnare un'etichetta del parlante basandosi solo sull'audio ricevuto fino a quel momento, e un'etichetta assegnata all'audio iniziale può dover essere rivista quando sente più voce di quel parlante. Tratta le etichette dei parlanti in streaming come il testo parziale: sono provvisorie finché il segmento non viene finalizzato.
La temporizzazione a livello di parola e il contesto delle entità seguono la stessa logica. Più metadati per token richiedi, più dati devono gestire sia il modello sia la rete. Per la maggior parte delle UI in tempo reale servono il testo e i confini dei segmenti, nulla di più; puoi rimandare i metadati dettagliati a un'elaborazione batch post-chiamata con Scribe v2.
Formati audio per lo streaming: PCM e mu-law
La logica di trasporto e riconoscimento riceve gran parte dell'attenzione, ma molti bug reali hanno origine a un livello inferiore, nel modo in cui codifichi e suddividi l'audio in chunk. Scegliere formato e dimensione dei chunk corretti è il modo più economico per ridurre la latenza della trascrizione vocale.
PCM, lineare, signed a 16 bit e little-endian, è il formato da usare quando controlli l'acquisizione. Frequenze di campionamento più alte offrono maggiori dettagli acustici: 16 kHz è lo standard minimo per il riconoscimento vocale ed è in genere sufficiente; 8 kHz è di qualità telefonica e perde i contenuti ad alta frequenza. Usa la frequenza che corrisponde alla sorgente. Non ha senso effettuare l'upsampling dell'audio telefonico a 8 kHz fino a 48 kHz, perché non contiene le informazioni da recuperare.
Il mu-law a 8 kHz è il formato telefonico. Se acquisisci chiamate da un provider come Twilio, l'audio arriva in mu-law a 8 kHz e dovresti inoltrarlo in quel formato invece di transcodificarlo due volte. Corrispondere al formato della sorgente evita artefatti di ricampionamento e un passaggio di conversione superfluo.
La dimensione dei chunk è il fattore che determina più direttamente la latenza percepita. Invi l'audio in chunk e il riconoscitore produce parziali quando questi arrivano. Chunk più piccoli offrono aggiornamenti più frequenti e minore latenza fino al primo parziale; chunk più grandi comportano meno messaggi e un po' più contesto per ogni inferenza. Un intervallo pratico va da 20 a 250 ms di audio per chunk. Per riferimento, con PCM mono a 16 bit e 16 kHz, un secondo di audio equivale a 32.000 byte, quindi un chunk di 100 ms è di circa 3.200 byte.
Acquisire l'input del microfono nel browser
Nel browser, lo strumento giusto è la Web Audio API con un AudioWorklet. Il worklet viene eseguito nel thread di rendering audio, riceve l'audio in piccoli frame e non è soggetto ai rallentamenti del main thread come il precedente ScriptProcessorNode. Il suo compito è convertire i campioni float nativi del browser in PCM a 16 bit e passarli al main thread, che li inoltra tramite WebSocket.
Il fulcro del processore worklet è la conversione da float a PCM:
La pipeline nel codice
La pipeline ha tre componenti: un client browser che acquisisce il microfono e trasmette PCM al server, un server Node che inoltra l'audio a Scribe v2 Realtime e rimanda le trascrizioni, e un client scriptabile che trasmette PCM da un file o un bridge telefonico.
Il server agisce da relay anziché esporre direttamente il riconoscitore al browser per un motivo importante: la chiave API di ElevenLabs è segreta e non deve mai comparire nel codice lato client. La chiave resta sul server. Se il browser deve comunicare direttamente con il riconoscitore, genera lato server un token monouso a breve durata e passa quello al client invece della chiave API.
Client browser
Il client apre un WebSocket verso il server, acquisisce il microfono tramite il worklet sopra e inoltra ogni frame PCM appena viene prodotto. Gli eventi in arrivo, già normalizzati dal server nel formato { type, text }, gestiscono lo stato parziale/finale descritto in precedenza:
Relay del server
Il server apre una connessione al riconoscitore per ogni client, conserva la chiave API sul server, inoltra direttamente il PCM binario e normalizza gli eventi del riconoscitore nella struttura stabile { type, text } usata dal client:
Tutto ciò che è specifico dell'endpoint è limitato alle due funzioni adapter qui sotto. Sostituisci i nomi dei campi con quelli esatti nel Riferimento API di Speech to Text; il resto della pipeline non cambia:
Client backend scriptabile
Per le pipeline backend e per il benchmark qui sotto, la stessa connessione al riconoscitore funziona senza browser: leggi PCM da qualsiasi sorgente, invialo alla cadenza dei chunk in tempo reale e ricevi gli eventi. La chiave API e l'URL arrivano dall'ambiente, come sul server.
Benchmark della latenza della trascrizione vocale e del tasso di errore delle parole
La latenza e il tasso di errore delle parole variano in base al parlante, alla lingua, alle condizioni acustiche, alla durata dell'audio, al percorso di rete verso la regione più vicina di ogni provider e al carico corrente di ciascun servizio.
Un risultato misurato da un laptop in una città non è generalizzabile alla tua infrastruttura di produzione in un'altra. Esegui l'harness da un'infrastruttura simile a quella di produzione, su audio simile al tuo input reale, e riporta intervalli e distribuzioni anziché singoli valori.
Le uniche metriche di latenza e accuratezza rilevanti sono quelle che misuri sul tuo audio, da un'infrastruttura simile alla produzione. Ecco una guida per eseguire il benchmark della latenza della trascrizione vocale.
Cosa misurare per la latenza della trascrizione vocale
Di seguito trovi le principali metriche da misurare durante il benchmark della latenza della trascrizione vocale in tempo reale:
- Tempo al primo parziale: dall'invio del primo chunk audio alla ricezione del primo parziale non vuoto.
- Ritardo da parziale a finale: dall'ultimo chunk audio di un enunciato all'ipotesi finale.
- Tasso di errore delle parole (WER): WER della trascrizione finalizzata rispetto a un riferimento umano, calcolato in modo identico in tutti i sistemi.
- Variazione della stabilità: quante volte i parziali vengono riscritti prima della finalizzazione. Questa misura indica quanto la UI live sembrerà cambiare.
Controlli
Per evitare dati inaffidabili, implementa diversi controlli nell'esperimento per mantenere la coerenza.
Ecco i principali controlli da usare per il benchmark della latenza di Speech to Text:
- Audio identico: usa gli stessi file, la stessa frequenza di campionamento e la stessa codifica per ogni sistema.
- Cadenza identica: trasmetti ogni sistema alla stessa cadenza dei chunk in tempo reale, ad esempio chunk da 100 ms.
- Ripeti e riporta le distribuzioni: esegui ogni file molte volte durante la giornata; riporta mediana e coda (p50/p95).
- Riferimenti e valutazione identici: normalizza il testo allo stesso modo, incluse maiuscole/minuscole, punteggiatura e numeri, prima di calcolare il WER.
- Indica regione e rete: specifica dove è stato eseguito l'harness e il percorso verso ogni provider.
Mantenendo invariati tutti questi elementi, otterrai metriche più precise.
Struttura dell'harness
Il nucleo della misurazione riceve un adapter del provider e registra il tempo al primo parziale, il ritardo di finalizzazione e la variazione dei parziali:
Il tasso di errore delle parole è una distanza di Levenshtein standard a livello di token sul testo normalizzato. Applica minuscole e rimuovi la punteggiatura in modo identico sia dal riferimento sia dall'ipotesi prima di calcolarlo, altrimenti misurerai il normalizzatore anziché il modello. Inserisci questa misura in un ciclo che esegua ogni file circa 10 volte per provider e riporti il tempo mediano al primo parziale e il WER mediano (p50/p95), poiché un singolo campione è dominato dalla variabilità della rete.
Per eseguirlo, servono due elementi. Innanzitutto, scrivi un adapter StreamFn per ogni sistema. Il client scriptabile sopra è già uno di questi; gli adapter per gli altri seguono lo stesso contratto (audioPath, onEvent, result) e impostano result.lastChunkSentAt quando viene inviato il chunk audio finale. Poi carica file audio e riferimenti e chiama la misura su tutti gli elementi. Eseguilo da una macchina rappresentativa del deployment, con audio rappresentativo degli utenti, e avrai un confronto riproducibile.
Riepilogo: come ottenere la trascrizione vocale in tempo reale
In questo articolo abbiamo trattato molti cambiamenti architetturali che ti consentono di migliorare iterativamente il sistema e avvicinarti alla trascrizione vocale in tempo reale.
Un sistema STT in tempo reale pronto per la produzione dipende da alcune decisioni chiave:
- Trasporto: scegli WebSocket per semplicità e reti controllate, e WebRTC quando hai bisogno di tolleranza alle perdite e acquisisci da dispositivi consumer.
- Parziali e finali: tratta i parziali come provvisori e i finali come confermati, visualizzandoli in modo diverso affinché gli utenti si fidino del testo live.
- End-pointing: usa il VAD per la segmentazione hands-free, il commit manuale come override e adatta la soglia di silenzio all'interazione anziché a una costante.
- Funzionalità in-stream: attivale solo quando servono all'esperienza live e rimanda il resto a un'elaborazione batch con Scribe v2.
- Formato audio: acquisisci piccoli frame PCM, invia chunk di circa 100 ms e usa il formato della sorgente per la telefonia.
- Benchmark: imposta empiricamente i parametri di accuratezza e latenza in base al tuo audio e alla metrica di riferimento.
- Sicurezza API: mantieni la tua chiave API sul server, oppure genera token monouso per connessioni dirette dei client.
Se vuoi scoprire come ottimizzare la latenza di un agente vocale, abbiamo scritto anche una guida dedicata.
Crea sistemi di trascrizione vocale in tempo reale con Scribe v2 Realtime
Scribe v2 Realtime produce parziali con una latenza del modello di circa 150 ms. Il fatto che gli utenti percepiscano questo valore o uno più alto dipende dall'architettura che lo circonda, la parte che controlli tu. Usando le strategie descritte in questo articolo, creerai un'architettura della pipeline migliore, che riduce la latenza e migliora l'esperienza cliente.
Per approfondire, scopri la panoramica delle funzionalità di Speech to Text, consulta il nostro riferimento dei modelli per l'elenco completo di funzionalità e lingue, quindi visita le pagine dei prodotti in tempo reale: API Speech to Text in tempo reale e Speech to Text in tempo reale.
Quando sei pronto a iniziare, crea gratuitamente un account ElevenLabs e trasmetti oggi la tua prima trascrizione.



