--- license: apache-2.0 language: [ar] pipeline_tag: text-to-speech tags: [tts, arabic, kokoro, styletts2, distillation, on-device, knowledge-distillation] --- # Nabra-7M-Distill **Arabic text to speech in 7.48M parameters, 28.7 MB at full precision.** Distilled from [Nabra-82M](https://huggingface.co/oddadmix/Nabra-82M-v0.1), which is 11x larger. Small enough to run on a phone, entirely offline, with no server in the loop. | | | |---|---| | parameters | 7,477,702 | | model file | 28.7 MB (fp32) | | sample rate | 24 kHz | | language | Modern Standard Arabic | | license | Apache 2.0 | ## Speed on CPU Median real time factor over 24 sentences, both models on 4 CPU threads, no GPU. A phone class thread budget rather than a workstation. Text to phoneme conversion is excluded from the timing for both, since it is the same front end either way. | model | params | RTF | synth time | |---|---:|---:|---:| | **Nabra-7M-Distill** | **7.48M** | **0.0224** | **0.081 s** | | Nabra-82M | 81.81M | 0.0947 | 0.346 s | That is **4.2x faster than the 82M** and **45x faster than realtime**: one second of speech in 22 ms. ## Usage ```python from load_model import load model, pipeline, voice = load() audio = next(pipeline("مَرْحَبًا بِكُم", voice=voice))[2] # 24 kHz ``` Use `load_model.py` rather than a bare `from kokoro import KModel`: this config sets the decoder's `hidden_channels` and `out_channels`, which upstream Kokoro hardcodes at 1024/512, so the stock package raises a TypeError on it. The patched package is vendored in `kokoro_patched/` with its defaults unchanged, so the 82M teacher still loads through it untouched. Arabic text goes through `arabic_g2p.py`: normalise, optionally add tashkeel with camel-tools, then espeak-ng to IPA and `clean_phonemes`. Text that already carries tashkeel is used as is. The voice pack is `af_msa.pt`, the one the model was conditioned on during training. ## Architecture Kokoro / StyleTTS2: a 12 layer ALBERT over phonemes, a prosody predictor for duration, pitch and energy, and an ISTFTNet decoder that ends in a 20 point inverse STFT rather than more convolution. | block | params | |---|---:| | decoder (ISTFTNet) | 4,062,450 | | prosody predictor | 2,219,572 | | plbert (12 shared layers) | 595,520 | | text encoder | 569,280 | | projection | 30,880 | Two details carry most of the size saving. The 12 ALBERT layers share one parameter block, so depth costs 596K rather than 7M. And duration is predicted by summing 50 sigmoid gates per phoneme instead of regressing a number. ## How it was distilled The teacher emits the per phoneme durations that generated its own audio, so the student trains against an alignment that is correct by construction. That is what makes this architecture distillable at all. 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 learning rate is cosine decayed to 10% of peak, which matters: at a constant rate a larger student in this family had its duration head collapse partway through while the reconstruction losses kept improving and hid it. ## Limitations Single voice, Modern Standard Arabic. Dialects are not covered. Text without tashkeel is diacritized automatically, and the model is only as good as that step, so supplying diacritized text gives better results.