Voz em texto por streaming na sua CPU: NVIDIA Nemotron em um app para desktop
Como o OpenWhispr mostra texto enquanto você fala — com um modelo por streaming com cache num WebSocket local, sem GPU e sem nuvem — e a engenharia necessária para tornar isso confiável.
OpenWhispr
Engenharia
Índice
A voz em texto por streaming transcreve o áudio enquanto você ainda fala, sem esperar a gravação terminar. Desde a versão 1.7.6, o OpenWhispr faz isso inteiramente no dispositivo: os modelos Nemotron por streaming da NVIDIA (600M parâmetros, quantizados em INT8) rodam na CPU por um servidor WebSocket sherpa-onnx local; a prévia do ditado se atualiza com os resultados parciais e o texto do fluxo vira a transcrição assim que você para. Sem GPU, sem ambiente Python e sem áudio saindo da máquina.
Este é o relato de engenharia: por que a antiga prévia parecia lenta, o que streaming com cache significa na prática, como o pipeline cabe num app Electron, o erro de fixação de versão que decodificava tudo errado e como deixamos de recodificar cada gravação para confirmar o próprio fluxo. Para comparar os modelos, consulte Parakeet vs Whisper vs Nemotron.
Última atualização em 18 de julho de 2026. Os detalhes se referem à transcrição por streaming lançada no OpenWhispr 1.7.6; tudo pode ser inspecionado no repositório de código aberto.
Verificação rápida (fontes primárias)
- O FastConformer com cache do Nemotron processa apenas o áudio novo e reutiliza o contexto armazenado do codificador, com trechos configuráveis em execução de 80ms a 1.12s. Ficha do Nemotron Streaming EN · NVIDIA sobre streaming com cache
- O modelo inglês registra em média 6.93% WER no streaming com trechos de 1.12s; o modelo multilíngue 3.5 cobre 40 combinações de idioma e região com detecção automática. Ficha do Nemotron 3.5 ASR
- Toda inferência passa pelo sherpa-onnx, um runtime ONNX nativo sem dependência de Python, usando seu servidor WebSocket online (streaming). Fixamos e incluímos a versão 1.13.4. sherpa-onnx no GitHub
- Os modelos ocupam 632MB (inglês) e 650MB (multilíngue) em disco como ONNX INT8, são baixados uma vez e ficam no cache local. Registro de modelos do OpenWhispr (código aberto) · Página de modelos do OpenWhispr
O problema: uma prévia ao vivo baseada num modelo em lote
O OpenWhispr sempre teve uma prévia de transcrição: uma pequena janela que mostra o que o modelo ouviu durante o ditado. Antes da 1.7.6, ela usava a única forma de dar aparência ao vivo a um modelo em lote: armazenar cerca de 1.5 segundo do microfone, transcrever o trecho inteiro, acrescentar o texto e repetir.
A abordagem tem três problemas estruturais. Primeiro, latência: as palavras só aparecem depois que o buffer enche, então a prévia fica um segundo e meio mais o tempo de inferência atrás. Segundo, limites: uma palavra dividida entre dois trechos é cortada e nenhum pode corrigi-la, pois são transcritos separadamente. Terceiro, contexto: o quinto trecho não sabe o que houve no quarto, e o modelo resolve as mesmas ambiguidades de novo a cada 1.5 segundo.
Trechos menores parecem mais rápidos, mas derrubam a precisão: menos contexto e mais limites. Sobrepor trechos corrige os cortes, mas transcreve o mesmo áudio duas vezes. O necessário é um modelo treinado para transcrever um fluxo. Esse modelo é o Nemotron.
O que streaming com cache realmente significa
Um modelo por streaming com cache mantém o estado interno entre trechos. Quando chega o próximo áudio, o codificador não relê tudo: processa só os novos quadros e consulta o contexto já calculado no cache. É o mesmo recurso que acelera chatbots (cache KV), aplicado a um codificador de voz.
Isso traz duas consequências. O custo deixa de crescer com a duração: cada trecho custa o mesmo após dez segundos ou dez minutos, tornando viável o streaming só com CPU. E o contexto continua disponível: o modelo usa tudo que já foi dito e revisa palavras anteriores quando o áudio posterior elimina ambiguidades. Por isso o texto “se estabiliza” logo depois da fala; não é um erro, mas uma revisão com evidências melhores.
A latência é ajustável: o Nemotron aceita trechos de 80ms (mais rápido, menos contexto por etapa) a 1.12s (maior precisão — média de 6.93% WER nos conjuntos do leaderboard, cerca de um ponto dos melhores modelos em lote). O treinamento usa o FastConformer com cache da NVIDIA e um decodificador transdutor; o artigo técnico explica a teoria em detalhes.
A arquitetura dentro do OpenWhispr
O fluxo de streaming ao vivo no 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.
O pipeline é propositalmente simples. Um AudioWorklet captura PCM do microfone a 16kHz. Os quadros viram o formato float32 e seguem por WebSocket para um servidor online sherpa-onnx — binário nativo iniciado localmente pelo OpenWhispr e acessado em 127.0.0.1, com uma conexão persistente por gravação. O servidor executa Nemotron com pesos INT8 e retorna resultados parciais JSON; a prévia substitui o texto em vez de acrescentá-lo.
Por que um servidor separado? Isolamento. Runtimes nativos podem travar; uma alocação ruim num kernel ONNX não deve derrubar todo o app. Com um processo auxiliar, uma falha exige reconexão, não perde o ditado. O código nativo também fica fora do processo principal do Electron: o app fala o protocolo, o auxiliar calcula.
O mesmo padrão executa nossa diarização local de falantes — uma cadeia sherpa-onnx, várias tarefas, tudo no dispositivo.
O que falhou no caminho
A versão do runtime importou mais do que esperávamos. Nemotron requer sherpa-onnx 1.13.4 ou posterior para decodificar corretamente. No runtime antigo incluído para Parakeet, não havia erro claro: a transcrição saía ruim. A correção foi comum — atualizar e refixar os binários de cada plataforma —, mas a lição é geral: “executa” e “está correto” são testes diferentes, e só o segundo conta.
Fluxos falham, então mantivemos o caminho antigo. Uma porta pode estar ocupada, o modelo pode faltar ou o servidor cair durante a gravação. Se o fluxo persistente não iniciar, a prévia volta automaticamente aos trechos em buffer: mais lenta, mas nunca vazia. Modelos offline (Parakeet, Whisper) preservam essa prévia; cada modelo declara seu runtime como online ou offline, e o app escolhe o caminho certo.
Resultados parciais exigiram outra renderização. O caminho por trechos acrescenta texto; uma hipótese por streaming se revisa, então a interface substitui toda a prévia a cada parcial. Acrescentar uma hipótese mutável cria duplicatas gaguejantes — o resumo de um problema real de UX que corrigimos cedo.
Confirmando o fluxo: de duas passagens para uma
A primeira versão tratava streaming como prévia: ao parar, o app recodificava a gravação inteira e colava esse resultado. Era seguro, pois a passagem final tinha todo o contexto, mas cada ditado pagava duas decodificações e esperava uma segunda opinião quase sempre igual ao texto já estabilizado na tela.
Na mesma versão, tornamos o fluxo a fonte oficial. O ditado usa a conexão persistente com a prévia aberta ou fechada e, ao parar, o app esvazia a cauda do modelo e confirma diretamente o texto do fluxo, sem segunda decodificação. A latência final cai para um esvaziamento e o custo de CPU por ditado fica aproximadamente pela metade.
A proteção virou fallback. O esvaziamento detecta truncamentos e estende o prazo enquanto chegam resultados. Se algo falhar — conexão perdida ou resultado cortado —, o app descarta o fluxo e executa o método clássico de gravar e depois transcrever o áudio completo. O caminho rápido só vale quando também está correto.
Desempenho e recursos
- Modelos: Nemotron Speech Streaming EN 0.6B (632MB) e Nemotron 3.5 ASR Streaming 0.6B (650MB, 15 idiomas prontos para transcrição, detecção automática) — ONNX INT8, baixados uma vez e armazenados localmente.
- Runtime: sherpa-onnx 1.13.4, binário nativo independente. Não requer Python, PyTorch nem CUDA.
- Hardware: streaming em tempo real na CPU de um notebook moderno; Apple Silicon e x86 recentes acompanham a fala com folga.
- Sensação: o texto parcial chega bem menos de um segundo após a voz; ao parar, um único esvaziamento confirma a transcrição, sem segunda decodificação.
Esse caminho não toca a Internet. O app fala com o servidor por 127.0.0.1 (no Windows, uma regra restrita de firewall também fecha a porta para a rede), os modelos ficam no cache local e o áudio nunca sai da máquina — a mesma postura de privacidade do restante da nossa estrutura de transcrição local.
Limitações sem rodeios
- Streaming troca um pouco de precisão por imediatismo. ~6.9% no streaming contra 5.91% do melhor modelo inglês em lote da NVIDIA nos mesmos benchmarks. Como a transcrição confirmada agora vem do fluxo, esse é o compromisso. Se só o resultado final importa, um Parakeet offline continua sendo a opção mais precisa.
- A cobertura de idiomas é menor que a do Whisper. 15 idiomas prontos no modelo multilíngue contra 99 do Whisper. Streaming em mandarim ou tailandês ainda não está disponível.
- O texto parcial muda. A hipótese é revisada com o contexto. Consideramos útil vê-la estabilizar; se isso distrair, desative a prévia e dite exatamente como antes.
- São mais 650MB em disco se você já possui um modelo offline — o custo de um segundo mecanismo ajustado para outra tarefa.
Escolhendo um modelo no OpenWhispr
| Você quer | Escolha |
|---|---|
| Prévia em inglês ao vivo durante o ditado | Nemotron Speech Streaming EN 0.6B |
| Prévia ao vivo em espanhol, japonês, árabe, hindi… | Nemotron 3.5 ASR Streaming 0.6B |
| Máxima precisão em inglês, sem precisar de texto ao vivo | Parakeet Unified EN 0.6B |
| Um idioma fora do conjunto da NVIDIA | Whisper (turbo ou large) |
Todos aparecem num menu em Configurações; o catálogo completo, com tamanhos e concessões, está na página de modelos. O OpenWhispr é gratuito, de código aberto e está disponível para macOS, Windows e Linux.
Perguntas frequentes
O que é voz em texto por streaming?
A voz em texto por streaming (ou “online”) transcreve o áudio enquanto a pessoa ainda fala e emite resultados parciais dentro de uma latência fixa, normalmente de 80 milissegundos a cerca de um segundo. Modelos em lote (“offline”), como Whisper, esperam a gravação terminar e processam tudo de uma vez. É o streaming que permite legendas ao vivo, agentes de voz e prévias de ditado que aparecem conforme você fala.
Posso executar voz em texto por streaming localmente e sem GPU?
Sim. Os modelos Nemotron por streaming da NVIDIA têm 600M parâmetros, vêm como arquivos ONNX quantizados em INT8 de cerca de 650MB e rodam em tempo real numa CPU moderna pelo sherpa-onnx, um binário nativo sem Python nem PyTorch. O OpenWhispr oferece essa configuração no macOS, Windows e Linux.
O que é ASR por streaming com cache?
É uma arquitetura — o FastConformer com cache da NVIDIA — em que o modelo preserva o estado interno do codificador entre trechos de áudio. Cada trecho novo é processado uma única vez com o contexto já armazenado, em vez de recodificar janelas de áudio sobrepostas. Assim, o streaming de baixa latência fica leve o bastante para a CPU de um notebook.
Por que o texto da prévia muda depois de aparecer?
Modelos por streaming revisam a hipótese quando chega mais áudio: o contexto posterior pode resolver o limite de uma palavra ou um homófono, por isso os resultados parciais são substituídos no mesmo lugar. Isso é intencional. Ao parar, o OpenWhispr esvazia a cauda do modelo e confirma o texto estabilizado como transcrição; se essa etapa for interrompida ou truncada, ele recodifica automaticamente a gravação inteira. Um fluxo instável nunca vira o texto colado.
A transcrição por streaming é menos precisa que a transcrição em lote?
Um pouco, porque um modelo por streaming não conhece o áudio futuro. O modelo inglês por streaming do Nemotron registra em média 6.93% de taxa de erro por palavra com trechos de 1.12 segundo nos conjuntos do Open ASR Leaderboard. É muito próximo dos modelos em lote, mas fica atrás dos 5.91% do melhor modelo inglês em lote da NVIDIA. O streaming troca essa pequena diferença por texto ao vivo e transcrição imediata ao parar; se a precisão máxima for prioritária, escolha um modelo Parakeet offline.
Quais idiomas o streaming aceita no OpenWhispr?
Há dois modelos Nemotron: um só em inglês e o Nemotron 3.5, com 15 idiomas prontos para transcrição (inglês, espanhol, francês, italiano, português, neerlandês, alemão, turco, russo, árabe, hindi, japonês, coreano, vietnamita e ucraniano) e detecção automática. Modelos offline como Parakeet e Whisper cobrem mais idiomas, mas usam trechos em buffer na prévia, não um fluxo ao vivo.