Nemotron 3.5 Core ML encoder: FP16 mask experiment

Current main contains a second encoder experiment for speech-swift issue 503. It changes internal audio-length and attention-cache mask calculations from Int32 to FP16 (16-bit floating point). Runtime integer operations drop from 25 to four input/output boundary casts. The public integer feature interface and all 296 published encoder palette lookup tables and index arrays are preserved.

Affected A16/iOS 27.2 validation is pending. The published model and this candidate both transcribe correctly on the available iPhone 16 Pro.

The repository name comes from the first experiment. The earlier iOS 17 candidate changed the deployment target while retaining the integer graph. The reporter confirmed that it still failed. That revision remains available. The current encoder targets iOS 18 and changes the mask calculation types.

Property Value
Architecture Cache-aware FastConformer encoder and RNN-T decoder
Parameters 600 million
Format Three compiled Core ML .mlmodelc models
Encoder weights Published 8-bit palette indices and FP16 lookup tables
Decoder and joint Published FP16 models, unchanged
Runtime file size 612.4 MiB
Audio 16 kHz mono
Streaming chunk / lookahead 320 ms / 240 ms
Minimum deployment target iOS 18
Baseline revision 447095fe87b480b5e6a15367f135303d479de8ac
Status Experimental; test on the affected A16 device before adopting

Files

File Size Purpose
encoder.mlmodelc/ 565.3 MiB Encoder with FP16 length/mask calculations
decoder.mlmodelc/ 28.5 MiB Unchanged published decoder
joint.mlmodelc/ 18.0 MiB Unchanged published joint network
config.json 589 B Unchanged streaming configuration
vocab.json, languages.json, tokenizer.model Unchanged Vocabulary, language prompts and tokenizer
experiment.json JSON Source revisions, graph change and artifact hashes
TESTING.md Guide Revision-pinned device comparison
testing/LoadProbe.swift Swift source Standalone Core ML load/reload and compute-plan report
testing/test_audio.wav 625 KiB Same 20-second mono 16 kHz speech sample as the earlier test
testing/fixture-provenance.json JSON Speech sample provenance and hashes
testing/validation.json JSON Results for this FP16 mask candidate

Validation

  • 17 exporter unit checks passed.
  • All six CPU encoder outputs matched the published encoder bit for bit across 201 calls: speech, silence, partial chunks, all audio lengths 0 through 32 at cache lengths 0, 1, 55 and 56, and two extra language-prompt slots.
  • On M5 Pro/macOS 26.6.2, the English speech sample produced identical transcription tokens with both bundles in CPU-only and CPU+ANE modes.
  • On iPhone 16 Pro/A18 Pro/iOS 26.6, all four native Core ML speech comparisons also produced the same transcript and 29 reference tokens.

These tests used standalone Core ML streaming encoders and greedy RNN-T decoders. The iPhone tests used frozen mel features from the speech sample. The Swift SDK test suite was not rebuilt for this candidate. One English sample and synthetic language prompts do not establish multilingual accuracy.

Observed speech timing

Each row is one pass of the same 20-second sample with CPU+ANE requested. Model loading is excluded. Real-time factor is processing time divided by audio duration; smaller values mean faster processing.

Hardware / OS Bundle Processing time Real-time factor
M5 Pro / macOS 26.6.2 Published 0.690 s 0.035
M5 Pro / macOS 26.6.2 FP16 mask candidate 0.839 s 0.042
A18 Pro / iOS 26.6 Published 1.185 s 0.059
A18 Pro / iOS 26.6 FP16 mask candidate 1.529 s 0.076

The candidate was slower in these single passes. This experiment tests the ANE compiler compatibility hypothesis. A performance improvement has not been established. The published CPU-only phone run logged a BNNS compilation storage error, so its timing is excluded from comparisons. Additional app-restart cache timings on the phone were not completed.

See testing/validation.json for measurements and limitations. Successful tests on M5 Pro and A18 do not establish compatibility with A16/iOS 27.2.

Usage

Resolve and record the test revision before downloading. Keep the published baseline in a separate directory. Follow TESTING.md for the device checks.

import coremltools as ct
from huggingface_hub import HfApi, snapshot_download

repo = "aufklarer/Nemotron-3.5-ASR-Streaming-0.6B-CoreML-INT8-iOS17-Encoder-Test"
revision = HfApi().model_info(repo).sha
bundle = snapshot_download(repo, revision=revision, local_dir="nemotron-fp16-mask-test")
print("Candidate revision:", revision)
encoder = ct.models.CompiledMLModel(
    f"{bundle}/encoder.mlmodelc",
    compute_units=ct.ComputeUnit.CPU_AND_NE,
)

On Apple Silicon macOS, compile the standalone load probe and obtain a JSON report:

swiftc -O -swift-version 6 -target arm64-apple-macosx15.0 -parse-as-library -D LOAD_PROBE_CLI nemotron-fp16-mask-test/testing/LoadProbe.swift -o /tmp/nemotron-load-probe
/tmp/nemotron-load-probe nemotron-fp16-mask-test ane candidate-ane.json

Source and license

Upstream: NVIDIA Nemotron 3.5 ASR Streaming 0.6B, revision f3d333391852ba876df169dcc9ba902d25b6ab0b. The model retains the upstream OpenMDW 1.1 license.

Baseline: published Core ML INT8 bundle, revision 447095fe87b480b5e6a15367f135303d479de8ac.

Links

Downloads last month
31
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for aufklarer/Nemotron-3.5-ASR-Streaming-0.6B-CoreML-INT8-iOS17-Encoder-Test

Finetuned
(64)
this model

Collection including aufklarer/Nemotron-3.5-ASR-Streaming-0.6B-CoreML-INT8-iOS17-Encoder-Test