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)

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:

  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

@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
Inference Providers NEW
This model isn't deployed by any Inference Provider. ๐Ÿ™‹ Ask for provider support

Model tree for oddadmix/Nabra-Saudi-7M

Finetuned
(1)
this model

Space using oddadmix/Nabra-Saudi-7M 1