Diarized transcription.
Every speaker named.
From a meeting recording or a call file to a fully-attributed transcript — speech recognition, speaker diarization, and speaker identification stitched into one on-device pipeline. No cloud APIs, no per-minute pricing, no data leaving the device.
Four shapes of the same pipeline.
Each shape stitches an ASR + a diarizer + an optional speaker-ID enrolment store. The components are interchangeable; what you choose depends on the audio source and your latency budget.
"Alice said …" / "Bob said …" attribution from a single Zoom export.
Agent vs. caller turns, sentiment per speaker, on-device for compliance.
Host + guests identified across the episode, word-level timestamps.
Court-grade attribution with no audio ever leaving the device.
Each stage runs on-device.
Defaults are tuned for accuracy on cleanly-recorded audio. Swap in the alternatives when your input differs (noisy room, streaming pipeline, long-tail language, iOS Neural Engine constraints).
| Stage | Default | Alternatives | When |
|---|---|---|---|
| Pre-clean (optional) | DeepFilterNet3 | — | Noisy room, phone audio, far-field mics. |
| Speech recognition | Qwen3-ASR 0.6B | Qwen3-ASR 1.7B, Parakeet TDT, Omnilingual, Nemotron | 1.7B for lowest WER, Parakeet for iOS, Omnilingual for long-tail languages, Nemotron for streaming. |
| Speaker diarization | Pyannote (default) | Community-1 (full pipeline), Sortformer (streaming) | Community-1 adds bounded speaker counts and returned centroids with native PLDA/VBx, but uses substantially more memory and latency than the default Pyannote engine. |
| Speaker identification | WeSpeaker ResNet34 | CAM++ | 256-d vs 192-d embeddings — cosine match against enrolled voices. |
| Word-level alignment | Forced Aligner | Built into Qwen3-ASR / Parakeet outputs | Use forced alignment for retroactive word timing. |
Transcribe words and inspect speaker segments.
After installing the CLI on Apple Silicon, transcribe a recording and inspect speaker segments with separate commands.
Print the recognized words in Terminal.
speech transcribe meeting.wavInspect speaker labels and time ranges as JSON, or use --rttm for RTTM.
speech diarize meeting.wav --jsonThese commands return separate results. They do not produce a transcript with speaker labels or match enrolled voices.
Save one plain-text transcript per WAV recording in a folder:
speech transcribe-batch recordings/ --extensions wav --output-dir transcripts/Pick the engine that matches your audio.
All ASR models work with the same diarization + speaker-ID pipeline, so swapping is a one-flag change.
| Need | Pick | Why | Backend |
|---|---|---|---|
| Best accuracy | Qwen3-ASR 1.7B 8-bit | Lowest WER across 52 languages | MLX |
| Whisper baseline | Whisper Large-v3 Turbo | Native CoreML runtime in speech-swift; ONNX exports for speech-core | CoreML, ONNX |
| Real-time streaming | Nemotron Streaming | RNN-T, sub-100 ms per chunk, native punctuation | CoreML |
| iOS / Neural Engine | Parakeet TDT | FastConformer, 32× real-time, runs on the Apple Neural Engine | CoreML |
| Long-tail languages | Omnilingual ASR | 1,672 languages via Meta wav2vec2 + CTC | CoreML, MLX |
| Android / Linux / Windows | Parakeet TDT v3 | 114 languages, INT8; platform setup and model matrix | ONNX Runtime |
Component guides.
Architecture, CLI, Swift API, benchmarks.
Native speech-swift CoreML bundle.
Streaming + iOS Neural Engine.
1,672 languages, 300M–7B variants.
Published CoreML + PLDA/VBx bundle.
Community-1, Pyannote, and Sortformer pipelines.
WeSpeaker / CAM++ for enrolment + ID.
Word-level timestamps via CTC, 80 ms.
DeepFilterNet3 at 48 kHz.
RNN-T with native punctuation.
