Nemotron Streaming
Dois modelos NVIDIA de ASR em streaming compartilham o target Swift NemotronStreamingASR. Ambos são encoders FastConformer cache-aware de 600M parâmetros emparelhados com um decoder RNN-T, ambos emitem pontuação e capitalização nativamente como tokens BPE comuns, ambos rodam no Apple Neural Engine via CoreML, e a variante multilíngue traz adicionalmente bundles MLX para inferência residente em GPU. Escolha a que combina com sua aplicação:
| Variante | Cobertura | Chunk padrão | Upstream |
|---|---|---|---|
| Nemotron 3.5 Multilíngue | 40 locales linguísticos (en-US, en-GB, es-ES, fr-FR, de-DE, ja-JP, ko-KR, zh-CN, hi-IN, ar, …) | 320 ms | nvidia/nemotron-3.5-asr-streaming-0.6b |
| Nemotron Speech Streaming (Inglês) | Só inglês — bundle menor, menor latência padrão | 160 ms | nvidia/nemotron-speech-streaming-en-0.6b |
Propriedades compartilhadas
- Pontuação e capitalização nativas — não precisa pós-processador; pontos, vírgulas e caixa fazem parte do vocabulário
- 600M parâmetros — encoder FastConformer cache-aware de 24 camadas + decoder LSTM RNN-T de 2 camadas + joint network
- Streaming cache-aware — caches de attention e conv fluem entre chunks para preservar contexto contínuo entre fronteiras
- Vários tamanhos de chunk — multilíngue: 80, 320, 560, 1120 ms (320 ms padrão); inglês: 80, 160, 560, 1120 ms (160 ms padrão)
- Apenas multilíngue: um prompt kernel (Linear 1152→2048→1024) injeta um slot one-hot de idioma em cada frame codificado, portanto os mesmos pesos servem aos 40 locales. A variante só-inglês não tem prompt kernel.
Arquitetura
Três modelos CoreML em pipeline por chunk de áudio:
| Componente | Descrição |
|---|---|
| Encoder | FastConformer cache-aware de 24 camadas, 1024 hidden. Recebe um chunk mel de 32 frames (320 ms padrão) mais seis tensores de estado — cache attention KV [24, 1, 56, 1024], cache conv depthwise [24, 1, 1024, 8], loopback mel pre_cache, e uma one-hot language_mask de 128 slots que alimenta o prompt kernel. |
| Prompt kernel | Linear(1152→2048) → ReLU → Linear(2048→1024) — injeta o one-hot de idioma em cada frame codificado, de modo que os mesmos 600M pesos servem aos 40 locales linguísticos. |
| Decoder | Rede de predição LSTM de duas camadas, 640 hidden. Consome o token não-blank anterior, emite um embedding mais estado (h, c) atualizado. |
| Joint | Funde saídas de encoder e decoder em logits sobre 13 087 tokens BPE + blank. Pontuação, capitalização e tags por idioma são apenas mais tokens no vocabulário BPE — sem heads adicionais. |
Sem head EOU
Diferente de Parakeet-EOU, Nemotron não emite um token dedicado de fim de enunciado. Duas formas de segmentar áudio contínuo em enunciados:
- VAD externo — emparelhe a sessão com Silero VAD; em silêncio prolongado, chame
finalize()para confirmar o enunciado atual ecreateSession()para o próximo. - Fronteira de pontuação — quando o transcript parcial termina em
.,?ou!, trate como um sinal natural de commit. Sem modelo extra, mas depende de o áudio realmente induzir pontuação final.
Bundles
Quatro variantes publicadas de Nemotron-3.5-ASR-Streaming-0.6B, mais o modelo só-inglês mais antigo no mesmo target Swift:
| Variante | Em disco | Pico streaming (M5 Pro) | HuggingFace |
|---|---|---|---|
| CoreML INT8 (padrão) | 612 MB | 1238 MB | aufklarer/Nemotron-3.5-ASR-Streaming-0.6B-CoreML-INT8 |
| MLX bf16 | 1217 MB | 1474 MB | aufklarer/…MLX-bf16 |
| MLX 8-bit | 732 MB | 997 MB | aufklarer/…MLX-8bit |
| MLX 4-bit | 473 MB | 747 MB | aufklarer/…MLX-4bit |
| Só inglês (CoreML INT8) | ~580 MB | — | aufklarer/Nemotron-Speech-Streaming-0.6B-CoreML-INT8 |
Upstream: nvidia/nemotron-3.5-asr-streaming-0.6b (multilíngue) e nvidia/nemotron-speech-streaming-en-0.6b (só inglês).
A quantização é essencialmente sem perdas: CoreML INT8, MLX bf16 e MLX 8-bit ficam dentro de ±0,3 pp WER em relação à fonte fp32 NeMo. MLX 4-bit custa ~6 pp de WER médio em troca do menor tamanho em disco e RSS de streaming.
Início rápido — transcrição em lote
Conforma com SpeechRecognitionModel, então encaixa em qualquer caminho de código que receba um modelo STT genérico:
import NemotronStreamingASR
let model = try await NemotronStreamingASRModel.fromPretrained()
let text = try model.transcribeAudio(audioSamples, sampleRate: 16000, language: "en-US")
Início rápido — streaming assíncrono
for await partial in model.transcribeStream(audio: samples, sampleRate: 16000, language: "ja-JP") {
if partial.isFinal { print("FINAL: \(partial.text)") }
else { print("... \(partial.text)") }
}
Cada PartialTranscript carrega text, isFinal (true apenas no último parcial após finalize()), confidence e um segmentIndex monotonamente crescente.
API de sessão longa (entrada do microfone)
let session = try model.createSession(language: "en-US")
// 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
speech transcribe recording.wav --engine nemotron --language en-US # batch
speech transcribe recording.wav --engine nemotron --language en-US --stream # streaming final
speech transcribe recording.wav --engine nemotron --language ja-JP --stream --partial # partials
speech transcribe meeting.wav --engine nemotron --language de-DE # any of the 40 locales
Nemotron vs. Parakeet-EOU
| Nemotron Streaming 0.6B | Parakeet-EOU 120M | |
|---|---|---|
| Parâmetros | 600M | 120M |
| Encoder | FastConformer de 24 camadas, 1024 hidden | FastConformer de 17 camadas, 512 hidden |
| Decoder | 2-layer LSTM, RNN-T | 1-layer LSTM, RNN-T |
| Detecção EOU | Externa (VAD ou pontuação) | Token <EOU> embutido |
| Pontuação | Tokens BPE nativos inline | Não (pós-processamento) |
| Idiomas | 40 locales linguísticos (en-US, en-GB, es-ES, fr-FR, de-DE, ja-JP, ko-KR, zh-CN, hi-IN, ar, …) | 25 europeus |
| Chunk padrão | 320 ms | 320 ms |
| Tamanho do bundle | 612 MB (CoreML INT8); 473 MB (MLX 4-bit) | ~150 MB |
…precisar de transcrição em streaming multilíngue (qualquer um dos 40 locales) com pontuação e capitalização prontas, e estiver OK em segmentar enunciados por conta própria (VAD ou sinal de pontuação). Para ditado iOS com recursos restritos, só em inglês e com sinal EOU embutido, Parakeet-EOU continua sendo a escolha menor.