--- language: - tr license: cc-by-sa-4.0 library_name: sherpa-onnx pipeline_tag: automatic-speech-recognition base_model: atasoglu/seda-v0.2 tags: - speech - asr - streaming - zipformer - transducer - icefall - sherpa-onnx - onnx - k2 - knowledge-distillation datasets: - issai/Turkish_Speech_Corpus - cloud0day3/alania-synthetic-speech-tr - ysdede/commonvoice_17_tr_fixed - espnet/yodas2 - atasoglu/yodas-tr-whisper-labels model-index: - name: seda-v0.2-tiny results: - task: type: automatic-speech-recognition name: Speech Recognition dataset: type: google/fleurs name: FLEURS (tr_tr), test config: tr_tr split: test metrics: - type: wer value: 10.51 name: WER (mode "accurate") - type: wer value: 11.24 name: WER (mode "balanced", streaming) - type: wer value: 17.30 name: WER (mode "fast", streaming) --- # seda-v0.2-tiny: streaming Turkish speech recognition in 4.5M parameters **seda-v0.2-tiny** is a 15× smaller version of [seda-v0.2](https://huggingface.co/atasoglu/seda-v0.2) for slow CPUs, phones and the browser. It is a streaming Zipformer2 transducer with **4.5M parameters** (seda-v0.2: 66M), distilled from seda-v0.2 and exported to int8 ONNX for [sherpa-onnx](https://github.com/k2-fsa/sherpa-onnx). The acoustic model is about **7 MB**. - **About as accurate as Whisper small on Turkish**, with 50× fewer parameters and streaming output: 11.24 WER on FLEURS-TR test against 11.87 for Whisper small, and 16.88 against 23.25 on broadcast audio (MediaSpeech). - **Better than seda-v0.1** (66M parameters, 11.60 WER), while 15× smaller. - **Runs in a phone's browser:** with sherpa-onnx WASM on one thread of a low-end Android phone, the 0.64 s chunk model with beam search runs at 0.77× real time. - The same language model, voice activity detector and text formatter setup as seda-v0.2, so every [sedalib](https://github.com/atasoglu/seda) mode works. ## Usage With [sedalib](https://github.com/atasoglu/seda) 1.1 or newer: ```bash pip install "sedalib[format]" # without [format]: no punctuation, casing or digits ``` ```python from sedalib import Recognizer, read_wav samples, sample_rate = read_wav("audio.wav") recognizer = Recognizer.from_pretrained("atasoglu/seda-v0.2-tiny", mode="fast") print(recognizer.transcribe(samples, sample_rate)) ``` For live audio, feed the stream small pieces as they arrive: ```python stream = recognizer.stream() for chunk in microphone_chunks(): # e.g. 100 ms of 16 kHz audio print(stream.accept(chunk, sample_rate=16000)) # partial text if stream.is_endpoint: print("final:", stream.end_utterance()) ``` `from_pretrained` downloads only the files of the chosen options: `fast` needs 7 MB, the language model adds 20 MB. The files are plain sherpa-onnx streaming transducer files, so `sherpa_onnx.OnlineRecognizer.from_transducer` loads them directly. The LM settings are `modified_beam_search`, `lm_scale=0.6` and `lodr_scale=-0.5`. ### Modes and chunk sizes | Mode | Decoding | FLEURS test WER | |---|---|---| | `fast` | 0.64 s chunks, greedy | 17.30 | | `balanced` (default) | 1.28 s chunks, beam 4 + LM | 11.24 | | `accurate` | 0.64 s chunks live, then a second pass with full context, beam + LM | 10.51 | Shorter chunks react sooner but cost more CPU per second of audio and are a little less accurate. Pick them with `chunk=`: | Chunk | Directory | FLEURS test WER, greedy | with beam 4 + LM | |---|---|---|---| | 0.16 s (`chunk=8`) | `c8/` | 21.08 | 13.99 | | 0.32 s (`chunk=16`) | `c16/` | 19.20 | 12.85 | | 0.64 s (`chunk=32`) | `c32/` | 17.30 | 11.67 | | 1.28 s (`chunk=64`) | root | 16.50 | 11.24 | - **Measurement:** sherpa-onnx int8 on CPU, audio followed by 1 s of silence. The `accurate` row decodes each utterance with full context (a 20.48 s chunk) and beam 4 + LM. The 0.16 and 0.32 s rows were measured with 0.64 s of left context; the released `c8/` and `c16/` use 1.28 s, which was 0.5 to 0.8 WER better on FLEURS dev. - **Slow devices:** on a low-end Android phone (sherpa-onnx WASM, one thread), 0.16 s chunks with beam search needed 1.07 s of compute per second of audio and fell behind; 0.32 s greedy needed 0.89 s and 0.64 s with beam search 0.77 s. Use 0.32 or 0.64 s chunks there; 0.16 s suits fast CPUs where the earliest reaction matters. ## Evaluation WER (%). Lower is better. References and hypotheses were normalized the same way: lowercase, no punctuation, numbers spelled out. Whisper ran with [faster-whisper](https://github.com/SYSTRAN/faster-whisper) on a GPU and decodes whole recordings offline; seda-v0.1 is in its released setup (0.64 s chunks, beam 4 + LM). | Test set | Whisper small (244M) | seda-v0.1 (66M) | **seda-v0.2-tiny (4.5M)** `balanced` | **`accurate`** | seda-v0.2 (66M) `accurate` | |---|---|---|---|---|---| | FLEURS-TR test (743 utt.) | 11.87 | 11.60 | 11.24 | **10.51** | 6.38 | | MediaSpeech TR (broadcast, 10 h) | 23.25 | 17.50 | **16.88** ¹ | | 11.27 | ¹ 0.64 s chunks, beam 4 + LM. More test sets, 0.64 s chunks: | Test set | Greedy | Beam 4 + LM | seda-v0.2 teacher, greedy | |---|---|---|---| | Khan Academy TR test ² | 14.61 | 11.63 | 8.72 | | ISSAI TSC test | 23.33 | 20.68 | 14.86 | ² Khan Academy is not in this model's training data (it is in seda-v0.2's). **The gap to seda-v0.2 is the price of 15× fewer parameters.** The tiny model makes about 1.6× as many errors as its teacher. Use seda-v0.2 where it fits; use this model where it does not. ## Model details | | | |---|---| | Architecture | Zipformer2 encoder + stateless decoder + joiner (pruned RNN-T), causal, trained with dynamic chunks | | Parameters | 4.49M | | Encoder | 6 stacks, layers `1,1,2,2,1,1`, dim 128, feedforward 256, 4 heads | | Input | 80-dim log-mel fbank, 16 kHz mono (other rates are resampled) | | Output | 500 BPE tokens (the same as seda-v0.2). Lowercase spoken-form Turkish, without punctuation; numbers are words | | Quantization | int8 (dynamic) encoder and joiner, fp32 decoder | | Language model | seda-v0.2's LSTM 2×1024 RNN LM (int8, 17 MB) for shallow fusion, token bigram for LODR | | Formatter | 2-layer Turkish BERT ([ytu-ce-cosmos/turkish-tiny-bert-uncased](https://huggingface.co/ytu-ce-cosmos/turkish-tiny-bert-uncased)) with heads for punctuation, casing and apostrophes; int8, 4.7 MB | ## Files | File | Description | |---|---| | `encoder.int8.onnx`, `decoder.onnx`, `joiner.int8.onnx`, `tokens.txt` | Streaming model, 1.28 s chunks (`balanced`) | | `c32/`, `c16/`, `c8/` | The same weights, exported with 0.64, 0.32 and 0.16 s chunks | | `final/` | The same weights, exported with 5.12 s chunks and 20.48 s left context (second pass of `accurate`) | | `lm/rnnlm.int8.onnx`, `lm/2gram.fst` | LSTM language model and token bigram for LODR, from seda-v0.2 | | `vad/silero_vad.onnx` | Silero VAD v6, 16 kHz (MIT, see `vad/LICENSE`) | | `formatter/` | Text formatter (int8 ONNX token classifier) and its tokenizer | ## Training - **Knowledge distillation from seda-v0.2.** The student learns the transcripts (pruned RNN-T loss) and, with weight 0.5, the teacher's encoder outputs (hidden-state distillation through a linear projection). The teacher's outputs were computed once for all training audio. - **Acoustic data: 1,913 h:** - [ISSAI Turkish Speech Corpus](https://huggingface.co/datasets/issai/Turkish_Speech_Corpus) (209 h) - [Alania synthetic speech](https://huggingface.co/datasets/cloud0day3/alania-synthetic-speech-tr), CC BY 4.0 subset (166 h) - [Common Voice 17](https://huggingface.co/datasets/ysdede/commonvoice_17_tr_fixed) (11 h) - [YODAS2](https://huggingface.co/datasets/espnet/yodas2) Turkish, 1,527 h: YouTube videos under CC BY 3.0, labeled by Whisper large-v3-turbo and filtered by agreement with the video's subtitles. The labels are published as [atasoglu/yodas-tr-whisper-labels](https://huggingface.co/datasets/atasoglu/yodas-tr-whisper-labels). - Evaluation sentences were held out the same way as for seda-v0.2. - **Recipe:** - Trained from scratch for 11 epochs: base LR 0.035, Eden schedule, fp16, max duration 1500 s, utterances up to 30 s. - Chunk sizes 0.16/0.32/0.64/1.28 s and full context, sampled per batch, so one set of weights serves every export. - MUSAN noise augmentation on the student's input only. - The release weights average the model over epochs 10 and 11. - **Language model and formatter:** the LM is seda-v0.2's. The formatter is a 2-layer BERT fine-tuned on Wikipedia, FineWeb-2 and the YODAS Whisper labels, like seda-v0.2's 4-layer one. ## Limitations - **Less accurate than seda-v0.2:** about 1.6× the errors. Noisy, reverberant and telephone audio were not measured for this model. - **Foreign names and abbreviations** are the main error source. The model often spells them by sound. - **The formatter places commas poorly** (F1 0.38 on FLEURS dev); sentence ends, casing and apostrophes are close to seda-v0.2's. - **Turkish only,** 16 kHz. ## License The model files are released under **CC BY-SA 4.0**: - The language model and the formatter were trained on Wikipedia (CC BY-SA). - The acoustic model's own training data has no share-alike source (Khan Academy, CC BY-SA 3.0, was removed), but it was distilled from seda-v0.2, whose training data includes Khan Academy. - `vad/silero_vad.onnx` is Silero VAD, MIT license (`vad/LICENSE`). - Other sources and their licenses: YODAS2 CC BY 3.0 (derived from YouTube videos by their creators); ISSAI Turkish Speech Corpus CC BY 4.0; Alania speech CC BY 4.0; Common Voice CC0; FineWeb-2 ODC-By 1.0; MUSAN CC BY 4.0 (augmentation only); Whisper MIT (labeler only); [ytu-ce-cosmos/turkish-tiny-bert-uncased](https://huggingface.co/ytu-ce-cosmos/turkish-tiny-bert-uncased) (YTU COSMOS) MIT, base of the formatter. ## Acknowledgements and citation Built with [k2](https://github.com/k2-fsa/k2), [icefall](https://github.com/k2-fsa/icefall), [lhotse](https://github.com/lhotse-speech/lhotse), [sherpa-onnx](https://github.com/k2-fsa/sherpa-onnx), [Silero VAD](https://github.com/snakers4/silero-vad) and [Whisper](https://github.com/openai/whisper). The formatter builds on the Turkish BERT models of [YTU COSMOS](https://huggingface.co/ytu-ce-cosmos). See the [seda-v0.2 card](https://huggingface.co/atasoglu/seda-v0.2) for the dataset citations (YODAS, ISSAI TSC, Common Voice, MUSAN, Zipformer).