Nabra-Saudi-7M
Saudi-dialect Arabic text to speech in 7.48M parameters, 30 MB at full precision. Distilled from 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 โ the 7M next to its 82M teacher on the same text.
- ๐ง Teacher: 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
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
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 and 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 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 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:
- 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.shdoes. The teacher was never involved. - 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
@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 (Apache-2.0) and StyleTTS2 (MIT). The training recipe builds on kikiri-tts.
- Downloads last month
- 26
Model tree for oddadmix/Nabra-Saudi-7M
Base model
yl4579/StyleTTS2-LJSpeech