Views
No views yet
coreai-torch (LLMs: coreai.llm.export) into .aimodel bundles that run on the GPU or the Neural Engine, e.g. Qwen3-8B 4-bit decodes at 94 tok/s on an M4 Max GPU, MLX 90 under the same protocol (apple-silicon-llm-bench, macOS 27 beta, 2026-06).nvidia/nemotron-3.5-asr-streaming-0.6b
(OpenMDW-1.1 — commercial use OK, 600M) converted to Apple Core AI .aimodel — the first
STREAMING ASR in the zoo: live
microphone transcription in 320 ms chunks, on-device, any audio length (no 30 s bucket).ja-JP, en-US,
zh-CN, … or auto for built-in language ID), switchable per session at run time.mel chunk (25 frames first, then 32) [host: preemphasis→STFT→slaney mel→log, NO normalization]
1. stream_pre_first / stream_pre : mel + 3 conv caches → embeds[1,4,1024] + caches (fp16, 9 MB)
2. stream_conformer_a : x + neg_mask[1,1,4,60]
+ k/v_cache[12,8,56,128] + conv_cache[12,1024,8]
→ x + updated caches (layers 0-11, fp16, 605 MB)
3. stream_conformer_b : x + one_hot[1,128] + neg_mask + caches
→ enc_proj[1,4,640] + updated caches (layers 12-23 + prompt fusion
+ projector, fp16, 615 MB)
host greedy RNN-T over the 4 new frames:
4. predict : token[1,1] i32 · h,c[2,1,640] → dec_out[1,640] · h',c' (fp32, 61 MB)
5. joint : dec_out + enc_frame[1,640] → token_logits[1,13088] (fp32, 34 MB)
blank(13087) advances a frame; a token emits + steps the predictor; 10/frame capresources.bin)
fails to load on-device (instant POSIX-2 from the loader — bisected: identical topology at
1 and 12 layers loads fine), so each half stays ~1.1 GB compiled, for one extra ~1 ms call
per chunk. Platform subtrees: macos/ (JIT .aimodel) and ios/ (the halves AOT-compiled
to h18p.aimodelc — big graphs' on-device JIT aborts; iPhone 17 Pro / A19 Pro).
ModelID.nemotronASRStreaming picks the right one automatically.use_cache=True oracle == offline), and again token-exact through Swift CoreAIKit
(KitNemotronModel, packet-size-independent mel frontend). blank 13087 · vocab 13088 ·
max 10 symbols/frame · 16 kHz.1let nemotron = try await KitNemotronModel(model: .nemotronASRStreaming)
2
3// LIVE: feed mic packets as they arrive; the transcript grows while you speak.
4let session = try nemotron.makeSession(language: "en-US") // or "ja-JP", … or "auto"
5for await packet in micPackets { // 16 kHz mono Float, any packet size
6 let partial = try await session.feed(samples: packet)
7}
8let result = try await session.finish()
9
10// OFFLINE: any-length clip through the same streaming pipeline.
11let result = try await nemotron.transcribe(samples: pcm16kMono, language: "en-US")| per 320 ms chunk (warm) | real-time factor | |
|---|---|---|
| M4 Max (GPU) | ~26 ms | 0.08 (12× real-time) |
| iPhone 17 Pro (GPU, AOT) | ~53 ms | 0.167 (6.0× real-time) |
lookahead=3) + chunk compute.
The checkpoint also supports lookahead 0/6/13 (80 ms – 1.12 s); those variants re-export with a
parameter change in the conversion scripts.conversion/nemotron_asr/
— streaming oracle (gen_oracle_streaming.py, HF chunked use_cache=True), cache-explicit
re-author + export (export_encoder_streaming.py), token-exact gates (gate_e2e_streaming.py,
gate_mel_swift_streaming.py).LICENSE) — the upstream NVIDIA model's license; this conversion redistributes
the weights unchanged in a different serialization.