Técnico

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

OpenWhispr

Engenharia

18 de julho de 2026
Í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 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

Microphone16kHz PCM via AudioWorklet
Local WebSocket127.0.0.1, float32 frames
Nemotron 0.6Bsherpa-onnx, INT8, CPU
Partial resultsJSON per chunk
Live previewText replaced in place
  • 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ê querEscolha
Prévia em inglês ao vivo durante o ditadoNemotron 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 vivoParakeet Unified EN 0.6B
Um idioma fora do conjunto da NVIDIAWhisper (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.