Sorani Zipformer2 · Streaming ASR
Central Kurdish speech → text, running locally on your CPU.
Run B is a causal Zipformer2 trained from scratch on 188.70 hours of human, pseudo-labeled, and synthetic speech. This release contains one checkpoint: the development-selected running-model average spanning epochs 17–24.
66.14M parameters · 512-piece BPE · 320 ms chunks · 2.56 s left context
Quick start
Use Python 3.12 and a fresh environment:
python3.12 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip huggingface_hub
hf download Amin-khattab/sorani-zipformer2-streaming --local-dir sorani-model
pip install -r sorani-model/requirements.txt
python sorani-model/transcribe.py recording.wav
Add --partials to display changing text as chunks are processed. WAV and FLAC
are recommended; the script converts to mono and resamples to 16 kHz.
The verified runtime is Mac CPU. Other platforms have not been tested.
Use in your application
From the downloaded sorani-model directory:
import numpy as np
from transcribe import Recognizer
model = Recognizer(".") # load once
stream = model.create_stream() # new stream per utterance
# Replace silence with mono float32 microphone PCM at 16 kHz, in [-1, 1].
pcm = np.zeros(5120, dtype=np.float32) # 320 ms packet
print(stream.accept(pcm)) # repeat for each incoming packet
print(stream.accept(np.empty(0, dtype=np.float32), final=True))
Each stream retains its encoder/decoder state. final=True flushes the last
words using 500 ms of silence. Resample microphone input before feeding it;
convert int16 PCM to float32 and divide by 32768.
Format: TorchScript (torch.jit.load), not a Transformers pipeline() model.
The script provides greedy decoding; microphone capture and a hosted API are
not included. Output is Sorani text without punctuation restoration.
Test results
2,014 held-out utterances · 3.014328 hours · cached streaming greedy decoding
| Model | WER ↓ | CER ↓ |
|---|---|---|
| Run A · Common Voice only | 41.24% | 12.14% |
| Run B · this release | 23.69% | 4.54% |
42.55% relative WER reduction over Run A. Both models used the same test set and decoder. WER uses whitespace-separated words; CER uses Unicode codepoints excluding whitespace. Scores use corpus edit totals without text normalization.
Development results were 21.40% WER / 4.13% CER, using four-path modified beam search. Those are separate development scores, not test results. Selection used development data only. Audio hashes and utterance IDs were checked for split overlap; speaker-disjointness is not established because speaker metadata was unavailable.
Training & limitations
30 epochs · 20,938 updates · RTX 3060 12 GB · FP16 · ScaledAdam + Eden. SpecAugment enabled; MUSAN/noise mixing and speed perturbation disabled. The tokenizer was trained only on Common Voice training transcripts.
Accuracy on other languages, noise, code-switching, and uncommon names is not established. No diarization, timestamps, or automatic endpointing is included. Chunk size is not measured latency: formal RTF and first-partial/finalization latencies remain unbenchmarked. Verify important transcriptions manually.
Technical details cover data proportions, architecture, averaging, feature settings, and runtime differences. evaluation.json contains the aggregate scores; SHA256SUMS verifies the release files.
License: a reuse license for these weights has not yet been specified. Contact Amin Khattab for licensing; public access does not grant unrestricted reuse. Built with Icefall / Zipformer2, whose upstream code is Apache-2.0 licensed.