Nemotron Streaming

Nemotron-Speech-Streaming-0.6B é o ASR de streaming em inglês de baixa latência da NVIDIA: um codificador FastConformer com cache acoplado a um decodificador RNN-T, com pontuação e capitalização emitidas como tokens BPE normais. O pacote CoreML disponibilizado aqui traz um codificador paletizado em INT8 e roda no Apple Neural Engine.

Visão geral

Arquitetura

Três modelos CoreML encadeados por bloco de áudio:

ComponentDescription
Codificador24-layer cache-aware FastConformer, 1024 hidden. Takes a 17-frame mel chunk (160 ms default) plus five state tensors — attention KV cache [24, 1, 70, 1024], depthwise conv cache [24, 1, 1024, 8], and a pre_cache mel loopback that prepends recent-past audio so chunk boundaries stay continuous.
DecodificadorTwo-layer LSTM prediction network, 640 hidden. Consumes the previous non-blank token, emits an embedding plus updated (h, c) state.
JointFuses encoder and decoder outputs into logits over 1024 BPE tokens + blank. Punctuation and capitalization are just more tokens in the BPE vocab — no extra heads.

Sem cabeça EOU

Ao contrário do Parakeet-EOU, o Nemotron não emite um token dedicado de fim de enunciado. Duas formas de segmentar áudio contínuo em enunciados:

  1. VAD externo — combine a sessão com o Silero VAD; em silêncio prolongado, chame finalize() para confirmar o enunciado atual e createSession() para o próximo.
  2. Fronteira de pontuação — quando a transcrição parcial termina em ., ? ou !, trate como um sinal natural de confirmação. Sem modelo extra, mas depende do áudio realmente induzir a pontuação terminal.

Modelo

ComponentSizeHuggingFace
Encoder (INT8)562 MBaufklarer/Nemotron-Speech-Streaming-0.6B-CoreML-INT8
Decoder14 MB
Joint3.3 MB

Upstream: nvidia/nemotron-speech-streaming-en-0.6b (checkpoint .nemo do NeMo).

Início rápido — transcrição em lote

Segue o protocolo SpeechRecognitionModel, então encaixa em qualquer código que aceite um modelo STT genérico:

import NemotronStreamingASR

let model = try await NemotronStreamingASRModel.fromPretrained()
let text = try model.transcribeAudio(audioSamples, sampleRate: 16000)

Início rápido — streaming assíncrono

for await partial in model.transcribeStream(audio: samples, sampleRate: 16000) {
    if partial.isFinal { print("FINAL: \(partial.text)") }
    else               { print("... \(partial.text)") }
}

Cada PartialTranscript traz text, isFinal (true apenas no último parcial após finalize()), confidence e um segmentIndex monotônico.

API de sessão persistente (entrada de microfone)

let session = try model.createSession()

// each mic chunk:
let partials = try session.pushAudio(float32Chunk16kHz)
for p in partials { showPartial(p.text) }   // isFinal is false mid-stream

// when the utterance ends (VAD silence or explicit stop):
let trailing = try session.finalize()
for p in trailing { commit(p.text) }

CLI

audio transcribe recording.wav --engine nemotron                    # batch
audio transcribe recording.wav --engine nemotron --stream           # streaming final
audio transcribe recording.wav --engine nemotron --stream --partial # with partials

Nemotron vs Parakeet-EOU

Nemotron Streaming 0.6BParakeet-EOU 120M
Parâmetros600M120M
Encoder24-layer FastConformer, 1024 hidden17-layer FastConformer, 512 hidden
Decoder2-layer LSTM, RNN-T1-layer LSTM, RNN-T
Detecção de EOUExterna (VAD ou pontuação)Token <EOU> embutido
PontuaçãoTokens BPE nativos inlineNão (pós-processamento)
IdiomasSomente inglês25 europeus
Bloco padrão160 ms320 ms
Tamanho do pacote~580 MB~150 MB
Escolha Nemotron quando…

…você quiser uma transcrição em inglês de maior qualidade com pontuação e capitalização prontas para uso, e estiver confortável em segmentar enunciados sozinho (VAD ou pista de pontuação). Para ditado iOS restrito com um sinal EOU integrado, Parakeet-EOU ainda é a escolha menor e mais simples.