Speech-to-text in streaming sulla CPU: NVIDIA Nemotron in un’app desktop
Come OpenWhispr mostra il testo mentre parli — con un modello in streaming dotato di cache su un WebSocket locale, senza GPU né cloud — e il lavoro necessario per renderlo affidabile.
OpenWhispr
Ingegneria
Sommario
Lo speech-to-text in streaming trascrive l’audio mentre stai ancora parlando, senza attendere la fine della registrazione. Dalla versione 1.7.6, OpenWhispr lo fa interamente sul dispositivo: i modelli Nemotron in streaming di NVIDIA (600M parametri, quantizzati INT8) girano sulla CPU tramite un server WebSocket sherpa-onnx locale; l’anteprima si aggiorna con i risultati parziali e, quando ti fermi, il testo del flusso viene confermato come trascrizione. Nessuna GPU, nessun ambiente Python e nessun audio fuori dal computer.
Questo è il resoconto tecnico: perché la vecchia anteprima sembrava lenta, cosa significa davvero streaming con cache, come la pipeline si integra in un’app Electron, il bug nel blocco della versione che decodificava tutto male e come siamo passati dal ricodificare ogni registrazione al confermare direttamente il flusso. Per il confronto tra modelli, leggi Parakeet vs Whisper vs Nemotron.
Ultimo aggiornamento: 18 luglio 2026. I dettagli riguardano la trascrizione in streaming introdotta in OpenWhispr 1.7.6; tutto è verificabile nel repository open source.
Verifica rapida (fonti primarie)
- Il FastConformer con cache di Nemotron elabora solo il nuovo audio e riutilizza il contesto dell’encoder già in cache, con segmenti configurabili a runtime da 80ms a 1.12s. Scheda di Nemotron Streaming EN · NVIDIA sullo streaming con cache
- Il modello inglese ottiene in media 6.93% WER in streaming con segmenti da 1.12s; il modello multilingue 3.5 copre 40 combinazioni lingua-area con rilevamento automatico. Scheda di Nemotron 3.5 ASR
- Tutta l’inferenza passa da sherpa-onnx, un runtime ONNX nativo senza dipendenza da Python, tramite il suo server WebSocket online (streaming). Blocchiamo e includiamo la versione 1.13.4. sherpa-onnx su GitHub
- I modelli occupano 632MB (inglese) e 650MB (multilingue) su disco in formato ONNX INT8, vengono scaricati una volta e conservati nella cache locale. Registro modelli OpenWhispr (open source) · Pagina dei modelli OpenWhispr
Il problema: un’anteprima live basata su un modello batch
OpenWhispr ha sempre offerto un’anteprima della trascrizione: una piccola finestra che mostra ciò che il modello sente durante la dettatura. Prima della 1.7.6 funzionava nell’unico modo possibile per far sembrare live un modello batch: accumulare circa 1.5 secondi di audio, trascrivere tutto il segmento, aggiungere il testo e ripetere.
L’approccio ha tre problemi strutturali. Primo, la latenza: le parole appaiono solo quando il buffer è pieno, quindi l’anteprima resta indietro di un secondo e mezzo più l’inferenza. Secondo, i confini: una parola divisa tra due segmenti viene tagliata e nessuno può correggerla, perché sono trascritti separatamente. Terzo, il contesto: il quinto segmento ignora il quarto e il modello deve risolvere di nuovo le stesse ambiguità ogni 1.5 secondi.
Segmenti più brevi sembrano più rapidi, ma riducono la precisione: meno contesto e più confini. Sovrapporli corregge i tagli, ma trascrive due volte lo stesso audio. Serve un modello addestrato a trascrivere un flusso. Questo è Nemotron.
Cosa significa davvero streaming con cache
Un modello in streaming con cache conserva lo stato interno tra i segmenti. Quando arriva il nuovo audio, l’encoder non rilegge tutto: elabora solo i nuovi frame e consulta il contesto già calcolato. È lo stesso meccanismo che accelera i chatbot (cache KV), applicato a un encoder vocale.
Ne derivano due effetti. Il calcolo non cresce più con la durata: ogni segmento costa uguale dopo dieci secondi o dieci minuti, rendendo pratico lo streaming solo su CPU. Inoltre il contesto prosegue: il modello usa tutto ciò che è stato detto e rivede parole precedenti quando l’audio successivo chiarisce un’ambiguità. Per questo il testo si “assesta” poco dopo la voce: non è un bug, ma una revisione basata su dati migliori.
La latenza è regolabile: Nemotron offre segmenti da 80ms (più veloce, meno contesto per passo) a 1.12s (massima precisione — 6.93% WER medio sui dataset del leaderboard, circa un punto dai migliori modelli batch). L’addestramento usa il FastConformer con cache di NVIDIA e un decoder trasduttore; il loro articolo tecnico approfondisce la teoria.
L’architettura dentro OpenWhispr
Il percorso di streaming in tempo reale in OpenWhispr
- •One persistent stream for the whole recording — the encoder cache carries context across chunks.
- •Everything is on-device: the WebSocket server is a local sherpa-onnx binary, not a cloud endpoint.
- •A clean flush at stop commits the streamed text as the final transcript; anything less falls back to a full re-decode.
La pipeline è volutamente semplice. Un AudioWorklet acquisisce il PCM del microfono a 16kHz. I frame vengono convertiti in float32 e inviati via WebSocket a un server online sherpa-onnx: un binario nativo avviato localmente da OpenWhispr e raggiunto su 127.0.0.1, con una connessione persistente per registrazione. Il server esegue Nemotron con pesi INT8 e restituisce risultati parziali JSON; l’anteprima sostituisce il testo invece di aggiungerlo.
Perché un server separato anziché inferenza nello stesso processo? Per isolamento. I runtime nativi possono bloccarsi; una cattiva allocazione in un kernel ONNX non deve chiudere tutta l’app. Con un processo ausiliario, un crash richiede una riconnessione, non fa perdere la dettatura. Inoltre il codice nativo resta fuori dal processo principale di Electron: l’app parla il protocollo, l’ausiliario calcola.
Lo stesso schema gestisce la nostra diarizzazione locale dei parlanti — una toolchain sherpa-onnx, più attività, tutto sul dispositivo.
Cosa si è rotto lungo il percorso
La versione del runtime contava più del previsto. Nemotron richiede sherpa-onnx 1.13.4 o successivo per decodificare correttamente. Con il vecchio runtime incluso per Parakeet non falliva in modo evidente: trascriveva male. La correzione era ordinaria — aggiornare e ribloccare i binari su ogni piattaforma —, ma la lezione è generale: “funziona” ed “è corretto” sono test diversi, e conta solo il secondo.
I flussi possono fallire, quindi il vecchio percorso è rimasto. Una porta può essere occupata, il file del modello può mancare o il server può arrestarsi durante la registrazione. Se il flusso persistente non parte, l’anteprima torna automaticamente ai segmenti in buffer: più lenta, mai vuota. I modelli offline (Parakeet, Whisper) mantengono quel percorso; ogni modello dichiara il runtime online o offline e l’app sceglie quello giusto.
I risultati parziali richiedevano un rendering diverso. Il percorso a segmenti aggiunge testo; un’ipotesi in streaming viene rivista, quindi l’interfaccia sostituisce l’intera anteprima a ogni parziale. Aggiungere un’ipotesi mutevole produce duplicati a scatti: la sintesi di un vero problema UX corretto presto.
Confermare il flusso: da due passaggi a uno
La prima versione trattava lo streaming come anteprima: alla fine della dettatura, l’app ricodificava l’intera registrazione e incollava quel risultato. Era sicuro, perché il passaggio finale vedeva tutto il contesto, ma ogni dettatura pagava due decodifiche e attendeva un secondo parere quasi sempre uguale al testo già stabilizzato sullo schermo.
Nella stessa versione abbiamo reso il flusso la fonte ufficiale. La dettatura usa la connessione persistente con l’anteprima aperta o chiusa e, allo stop, l’app svuota la coda del modello e conferma direttamente il testo, senza seconda decodifica. La latenza finale si riduce a un solo svuotamento e il costo CPU per dettatura si dimezza circa.
La protezione è diventata il fallback. Lo svuotamento rileva i troncamenti e prolunga la scadenza finché arrivano risultati. Se qualcosa non va — connessione persa o risultato tagliato —, l’app scarta il flusso e trascrive l’intera registrazione con il metodo classico. Il percorso rapido si usa solo quando è anche corretto.
Prestazioni e ingombro
- Modelli: Nemotron Speech Streaming EN 0.6B (632MB) e Nemotron 3.5 ASR Streaming 0.6B (650MB, 15 lingue pronte, rilevamento automatico) — ONNX INT8, scaricati una volta e memorizzati localmente.
- Runtime: sherpa-onnx 1.13.4, binario nativo autonomo. Non servono Python, PyTorch o CUDA.
- Hardware: streaming in tempo reale sulla CPU di un portatile moderno; Apple Silicon e x86 recenti seguono agevolmente il parlato.
- Sensazione: il testo parziale arriva ben meno di un secondo dopo la voce; allo stop, un solo svuotamento conferma la trascrizione, senza seconda decodifica.
Questo percorso non tocca Internet. L’app comunica con il server su 127.0.0.1 (su Windows, una regola firewall limitata chiude la porta anche alla rete), i modelli restano nella cache locale e l’audio non lascia mai il computer: la stessa tutela del resto della nostra architettura di trascrizione locale.
Limiti, senza giri di parole
- Lo streaming scambia un po’ di precisione con l’immediatezza. ~6.9% in streaming contro 5.91% del miglior modello inglese batch di NVIDIA sugli stessi benchmark. Poiché la trascrizione confermata ora arriva dal flusso, questo è il compromesso. Se conta solo il risultato finale, un Parakeet offline resta la scelta più precisa.
- La copertura linguistica è inferiore a Whisper. 15 lingue pronte nel modello multilingue contro le 99 di Whisper. Lo streaming in mandarino o thailandese non è ancora disponibile.
- Il testo parziale cambia. L’ipotesi viene rivista con il contesto. Vederla stabilizzarsi per noi è utile; se distrae, disattiva l’anteprima e detta esattamente come prima.
- Sono altri 650MB su disco se possiedi già un modello offline: il costo di un secondo motore ottimizzato per un lavoro diverso.
Scegliere un modello in OpenWhispr
| Obiettivo | Scegli |
|---|---|
| Anteprima live in inglese durante la dettatura | Nemotron Speech Streaming EN 0.6B |
| Anteprima live in spagnolo, giapponese, arabo, hindi… | Nemotron 3.5 ASR Streaming 0.6B |
| Massima precisione in inglese, senza testo live | Parakeet Unified EN 0.6B |
| Una lingua fuori dall’insieme NVIDIA | Whisper (turbo o large) |
Sono tutti selezionabili nelle Impostazioni; il catalogo completo con dimensioni e compromessi è nella pagina dei modelli. OpenWhispr è gratuito, open source e disponibile per macOS, Windows e Linux.
Domande frequenti
Che cos’è lo speech-to-text in streaming?
Lo speech-to-text in streaming (o «online») trascrive l’audio mentre si sta ancora parlando e produce risultati parziali entro una latenza fissa, in genere da 80 millisecondi a circa un secondo. I modelli batch («offline») come Whisper attendono invece la fine della registrazione e la elaborano tutta insieme. Lo streaming rende possibili sottotitoli live, agenti vocali e anteprime di dettatura che mostrano il testo mentre parli.
Posso eseguire lo speech-to-text in streaming in locale senza GPU?
Sì. I modelli Nemotron in streaming di NVIDIA hanno 600M parametri, sono distribuiti come file ONNX quantizzati INT8 da circa 650MB e funzionano in tempo reale su una CPU moderna tramite sherpa-onnx, un binario nativo che non richiede Python o PyTorch. OpenWhispr offre questa configurazione su macOS, Windows e Linux.
Che cos’è l’ASR in streaming con cache?
È un’architettura — il FastConformer con cache di NVIDIA — in cui il modello conserva lo stato interno dell’encoder tra i segmenti audio. Ogni nuovo segmento viene elaborato una sola volta usando il contesto già in cache, invece di ricodificare finestre audio sovrapposte. Così lo streaming a bassa latenza è abbastanza efficiente per la CPU di un portatile.
Perché il testo dell’anteprima cambia dopo essere apparso?
I modelli in streaming rivedono l’ipotesi quando arriva altro audio: il contesto successivo può chiarire il confine di una parola o un omofono, quindi i risultati parziali vengono sostituiti sul posto. È intenzionale. Quando ti fermi, OpenWhispr svuota la coda del modello e conferma il testo stabilizzato come trascrizione; se l’operazione viene interrotta o troncata, ricodifica automaticamente l’intera registrazione. Un flusso instabile non diventa mai il testo incollato.
La trascrizione in streaming è meno precisa di quella batch?
Leggermente, perché un modello in streaming non può conoscere l’audio futuro. Il modello inglese in streaming di Nemotron registra in media un tasso di errore per parola del 6.93% con segmenti da 1.12 secondi sui dataset dell’Open ASR Leaderboard. È molto vicino ai modelli batch, ma resta dietro al 5.91% del miglior modello inglese batch di NVIDIA. Scegliere lo streaming significa accettare il piccolo divario in cambio di testo live e trascrizione immediata allo stop; se conta la massima precisione, scegli un modello Parakeet offline.
Quali lingue supporta lo streaming in OpenWhispr?
Sono disponibili due modelli Nemotron: uno solo inglese e Nemotron 3.5 con 15 lingue pronte per la trascrizione (inglese, spagnolo, francese, italiano, portoghese, olandese, tedesco, turco, russo, arabo, hindi, giapponese, coreano, vietnamita e ucraino) e rilevamento automatico. I modelli offline come Parakeet e Whisper coprono più lingue, ma l’anteprima usa segmenti in buffer anziché un flusso live.