CoolFace
Modelpublic

ValentinWeyer/parakeet-primeline-de-coreml

sourceHugging Facecc-by-4.0updated 2mo agoView on Hugging Face
1likes
Model Card

parakeet-primeline-de-coreml

An unofficial CoreML conversion of `primeline/parakeet-primeline` — a German fine-tune of `nvidia/parakeet-tdt-0.6b-v3` — for offline speech-to-text on Apple Neural Engine via FluidAudio.

All credit for the model itself goes to primeline (German fine-tuning) and NVIDIA (base FastConformer-TDT architecture and pretraining). This repository only provides a CoreML/ANE re-export of their weights; no retraining or fine-tuning was done here.

Why this exists

nvidia/parakeet-tdt-0.6b-v3 auto-detects language per utterance with no way to force it, so short German commands are sometimes misdecoded as English. primeline's fine-tune fixes this and improves German WER generally (see benchmarks below, reproduced from the primeline/parakeet-primeline model card). This repo makes that fine-tune usable on-device on Apple Silicon through FluidAudio's CoreML pipeline, instead of via NeMo/PyTorch on GPU.

ModelAll (Avg)Tuda-DeMultilingual LibriSpeechCommon Voice 19.0
primeline-parakeet2.954.112.603.03
nvidia-parakeet-tdt-0.6b-v33.647.052.953.70

Conversion

Converted with FluidInference's own mobius export tooling (models/stt/parakeet-tdt-v3-0.6b/coreml/convert-parakeet.py), pointed at primeline's .nemo checkpoint instead of the base NVIDIA model — no changes to the conversion script were needed, since primeline's fine-tune uses an unmodified tokenizer and architecture (verified byte-identical against the base model's vocabulary before conversion). Exported at FP16, iOS17 deployment target, fixed 15-second audio window per FluidAudio's v3 contract.

Validated after conversion: exported component shapes match FluidAudio's expected Preprocessor / Encoder / Decoder / JointDecisionv3 I/O contract exactly (including the top_k_ids/top_k_logits outputs FluidAudio's v3 decode path requires). See Benchmarks below for the accuracy validation — full German test sets, cross-checked against unconverted NeMo/PyTorch inference on the same checkpoint.

conversion_metadata.json in this repo records the exact export settings.

Benchmarks

Ran the full Tuda-De (4,096 utterances), Multilingual LibriSpeech German (3,394), and Common Voice 19.0 German (16,188) test sets — no sampling — through this converted CoreML model, and cross-checked against native NeMo/PyTorch inference on the same unconverted checkpoint (no CoreML anywhere in that second run) to isolate conversion fidelity from everything else.

CorpusPublished (primeline card)This CoreML/ANE modelNative NeMo/PyTorch (same checkpoint)
Tuda-De4.115.215.46
Multilingual LibriSpeech2.605.445.25
Common Voice 19.03.035.165.15
Average2.955.275.29

WER%, umlaut-folded (ä→ae, ö→oe, ü→ue, ß→ss — our own normalization, since primeline didn't publish theirs; unfolded numbers run ~1-1.5pp higher and are in the eval scripts referenced below).

Reading this table: the CoreML conversion and the untouched original checkpoint land within a quarter point of each other on every corpus (average delta −0.02pp) — that's the number that matters for trusting this repo's export, and it's as clean a "no conversion damage" result as this kind of test produces. The ~2.3pp gap between both of our measurements and the primeline card's published average is real but external to this conversion: it's differences in decode configuration and/or WER text-normalization methodology that were never published, not a degraded model. If you're deciding whether to trust this conversion, compare column 2 to column 3, not to column 1.

This model was built for a Home Assistant Wyoming-protocol STT server; the scoring script and German text normalization used above will be published alongside that project.

Usage

Drop-in for FluidAudio's AsrModels.load(from:version:.v3, ...) — same file layout as `FluidInference/parakeet-tdt-0.6b-v3-coreml`, just German weights:

swift
import FluidAudio

let models = try await AsrModels.load(
    from: modelsDirectory,   // a local directory literally named `parakeet-tdt-0.6b-v3`
    version: .v3,
    encoderPrecision: .int8,  // filename mapping only — this encoder is FP16, see note below
    encoderComputeUnits: .cpuAndNeuralEngine
)
let manager = AsrManager(config: .default)
try await manager.loadModels(models)

Note on the directory name: FluidAudio's loader derives the model folder name from its internal Repo enum and expects it to be exactly parakeet-tdt-0.6b-v3, regardless of which weights are inside. Place these files in a folder with that exact name.

Note on precision: encoderPrecision: .int8 selects the filename FluidAudio looks for (Encoder.mlmodelc), not the actual on-disk precision — this export is FP16, not int8-quantized, so it will be larger (~1.2 GB) than FluidAudio's official English encoder (~425 MB, which is quantized). Int8 quantization was not applied here to avoid an extra accuracy-validation pass; feel free to quantize further at your own risk.

Set `DownloadUtils.enforceOffline = true` before loading if you're pointing at a private local path — otherwise a load failure will cause FluidAudio to delete the folder and attempt to re-download the official English v3 from HuggingFace.

Files

FileDescription
Preprocessor.mlmodelcMel-spectrogram frontend
Encoder.mlmodelcFastConformer encoder (FP16)
Decoder.mlmodelcTDT prediction network
JointDecisionv3.mlmodelcJoint + greedy decision head (incl. top-K for FluidAudio's language-script filter)
parakeet_vocab.jsonSentencePiece vocabulary (identical to base v3's, 8192 tokens)
conversion_metadata.jsonExport settings and component I/O shapes from the conversion run

License

CC-BY-4.0, inherited from primeline's fine-tune (itself CC-BY-4.0, derived from NVIDIA's CC-BY-4.0 base model). Attribution: