--- license: apache-2.0 language: [ar] pipeline_tag: text-to-speech library_name: kokoro base_model: oddadmix/Nabra-Saudi-82M tags: [tts, arabic, saudi, dialect, kokoro, styletts2, distillation, speech-synthesis, on-device] --- # Nabra-Saudi-7M **Saudi-dialect Arabic text to speech in 7.48M parameters, 30 MB at full precision.** Distilled from [Nabra-Saudi-82M](https://huggingface.co/oddadmix/Nabra-Saudi-82M), which is 11x larger. Small enough to run on a phone, entirely offline. | | | |---|---| | parameters | 7,477,702 | | model file | `nabra_saudi_7m.pth`, 30.1 MB (fp32) | | sample rate | 24 kHz, mono | | language | Arabic, Saudi dialect | | voice | `af_msa` (single female voice, same pack as the teacher) | | training | 60k distillation steps against durations emitted by the 82M teacher (146 h corpus) | - 🎙️ **Try it:** [Nabra-Saudi-Demo](https://huggingface.co/spaces/oddadmix/Nabra-Saudi-Demo) — the 7M next to its 82M teacher on the same text. - 🧠 **Teacher:** [Nabra-Saudi-82M](https://huggingface.co/oddadmix/Nabra-Saudi-82M). ## Samples `samples/` holds three sentences synthesized with this checkpoint on CPU, no post-processing: | file | text | |---|---| | `samples/nabra_saudi_7m_hello.wav` | يا أهلاً وسهلاً، كيف حالكم؟ إن شاء الله طيبين وبأحسن حال. | | `samples/nabra_saudi_7m_weather.wav` | الطقس اليوم حلو والسما صافية مرة. | | `samples/nabra_saudi_7m_story.wav` | اليوم عندنا قصة جديدة من القصص اللي كلكم تحبونها. | ## Usage ```bash pip install torch soundfile huggingface_hub loguru attrs transformers "misaki[en]>=0.9.4" \ "phonemizer-fork>=3.3.2" camel-tools numpy sudo apt-get install -y espeak-ng ``` ```python import soundfile as sf from huggingface_hub import snapshot_download import sys; sys.path.insert(0, snapshot_download("oddadmix/Nabra-Saudi-7M")) from load_model import load model, pipeline, voice = load() # loads nabra_saudi_7m.pth + af_msa.pt audio = next(pipeline("يا أهلاً وسهلاً، كيف حالكم؟", voice=voice))[2] # 24 kHz sf.write("out.wav", audio.numpy(), 24000) ``` `load_model.py` uses the vendored `kokoro_patched/` package rather than the stock `kokoro` pip package: this config sets decoder widths that upstream Kokoro hardcodes, so the stock package raises a `TypeError`. Do not `pip install kokoro` on top of it. **Write dialect text as it is normally written, without full tashkeel.** Adding MSA diacritics makes it worse: an MSA diacritizer imposes case endings a dialect speaker does not pronounce. ## Why it was distilled rather than trained directly Training a model this size directly on dialect recordings was tried first and did not work: with durations from a forced aligner, the student inherits whatever error the aligner made, and no change of architecture, sample rate or tashkeel policy recovered it. Distillation removes the problem. The 82M teacher emits the per phoneme durations that generated its own audio, so the student trains against an alignment that is correct by construction. The same recipe produced [Nabra-7M-Distill](https://huggingface.co/oddadmix/Nabra-7M-Distill) and [Kokoro-7M-Distill](https://huggingface.co/oddadmix/Kokoro-7M-Distill). Objective: multi resolution STFT, duration L1, log mel L1, a silence term, and WavLM feature matching, with multi period and multi resolution spectrogram discriminators. The silence term stops the small decoder floating on a noise floor the teacher does not have; the WavLM term is the only thing constraining phase, and without it the output stays subtly robotic. ## Limitations Single voice, Saudi dialect. Short sentences are noticeably stronger than long spontaneous passages. Not intended for Modern Standard Arabic, which [Nabra-7M-Distill](https://huggingface.co/oddadmix/Nabra-7M-Distill) covers, nor for other dialects. No speaker cloning. ## Experiment: `nabra_saudi_7m_v1_direct.pth` (not the shipped weights) `nabra_saudi_7m_v1_direct.pth` is also in this repo. It was trained alongside the later [Nabra-Saudi-82M](https://huggingface.co/oddadmix/Nabra-Saudi-82M) checkpoint (`nabra_saudi_82m.pth`), on the same corpus (146 h real + 13.4 h synthetic phone conversations). **It is not the default and it is not recommended.** Measured on 73 reference words of conversational text it is worse than the shipped model on both axes: | | UTMOS | WER | |---|---:|---:| | `nabra_saudi_7m.pth` (shipped) | **2.363** | **0.137** | | `nabra_saudi_7m_v1_direct.pth` | 2.248 | 0.178 | Two reasons, both worth recording: 1. **It is not a distillation.** The run trained the 7M directly on the aligned index from the Arabic 7M init, rather than against the 82M teacher's emitted durations the way `training/distill_saudi.sh` does. The teacher was never involved. 2. **Synthetic data costs a small model more.** The same corpus improved the 82M's conversational word error (0.152 -> 0.091) and made the 7M worse. Capacity absorbs lower-quality data; 7M does not. The fix is to re-run it as a true distillation from that later 82M checkpoint. See `TRAINING.md`. ## Citation ```bibtex @misc{nabrasaudi7m2026, title = {Nabra-Saudi-7M: Saudi-dialect Arabic Text-to-Speech distilled to 7.48M parameters}, author = {oddadmix}, year = {2026}, howpublished = {\url{https://huggingface.co/oddadmix/Nabra-Saudi-7M}} } ``` ## License & attribution Apache-2.0, following [Kokoro-82M](https://huggingface.co/hexgrad/Kokoro-82M) (Apache-2.0) and [StyleTTS2](https://github.com/yl4579/StyleTTS2) (MIT). The training recipe builds on [kikiri-tts](https://github.com/semidark/kikiri-tts).