NeuTTS Air - Moroccan Darija

neuphonic/neutts-air fine-tuned on Moroccan Darija speech tokens from Tilas/MoulSot-Tokens-v1.

Speech is represented as NeuCodec tokens (single codebook, 65,536 codes, 50 tokens/s, 0.8 kbps). Generated tokens must be decoded with neuphonic/neucodec.

Usage

Darija text is phonemised with espeak-ng's ar voice through a custom phonemizer that maps Arabic punctuation to Latin equivalents (espeak silently drops ؟ and ،) and strips harakat. The same phonemizer must be used at inference, or the model sees a different phoneme distribution than it was trained on.

import src.darija_g2p          # registers DarijaPhonemizer as CUSTOM_PHONEMIZERS["ar"]
from neutts import NeuTTS

tts = NeuTTS(backbone_repo="Tilas/neutts-air-darija-v1", language="ar")
wav = tts.infer("شنو كتدير هنا؟", ref_codes=ref_codes, ref_text=ref_text)

language="ar" must be passed explicitly: this repo is not in BACKBONE_LANGUAGE_MAP, and _load_phonemizer raises rather than guessing.

Training

Base model neuphonic/neutts-air (747.9M trainable params)
Training samples 71,919
Eval samples 1,000
Speech ~94.8 h after filtering (101.7 h before)
Max sequence length 896 tokens
Effective batch 32
Learning rate 4e-05 (cosine, 0.03 warmup)
Epochs 2.0
Precision bf16
GPU NVIDIA GeForce RTX 4090
Final eval loss 7.1369

Supervision covers only the speech span; the phoneme prompt and padding are masked with -100. Sequences are dynamically padded with length-grouped batching.

Data

Audio and transcripts come from atlasia/MoulSot-Full, a Moroccan Darija speech corpus collected by AtlasIA from 51 YouTube channels and released under Apache-2.0. This model uses the 100-gt-2.5 config — 101.9 hours of transcribed speech.

That audio was encoded to NeuCodec tokens and published as Tilas/MoulSot-Tokens-v1, which is what this fine-tune consumes.

Data filtering

72,919 of 79,641 source rows were kept. Rejections: {"too_short": 2676, "contains_digits": 2103, "no_arabic_letters": 1797, "too_long_with_phonemes": 129, "too_long": 17}

Clips under 1.0 s were dropped to match min_new_tokens=50 at inference. Clips containing digits were dropped because espeak verbalises numerals into Modern Standard Arabic while the audio contains the Darija form.

Limitations

  • Phonemisation is a baseline, not a Darija G2P. espeak-ng's ar voice applies MSA morphophonology and reads short vowels from diacritics that undiacritised Darija does not carry, producing MSA-flavoured output and vowel-less consonant clusters (نبداو → mbdˈaːw, فالسبعة → fassbʕt). It is deterministic and collision-free on the pairs tested, so the model can learn a consistent mapping, but the IPA is frequently wrong. A dedicated Darija phonemiser is the obvious next improvement.
  • French loanwords get English-flavoured IPA under language_switch="remove-flags".
  • Transcripts are Gemini-2.5-Pro generated, not human-verified, and Darija has no standardised orthography.
  • Source audio is YouTube, so acoustic conditions vary and background noise is learnable. Voice quality at inference depends heavily on the reference clip.
  • The eval split is a random sample of training channels, so eval loss is optimistic. It is a training-health signal, not a quality benchmark.

Provenance

Tokens were produced by neuphonic/neucodec with the encode path frozen, at batch_size=1 and with no pre-padding. Both are required for token stability, since Wav2Vec2-BERT applies per-utterance feature normalisation and encode_code passes no attention mask.

Downloads last month
101
Safetensors
Model size
0.7B params
Tensor type
F32
·
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for Tilas/neutts-air-darija-v1

Finetuned
(20)
this model
Quantizations
1 model

Dataset used to train Tilas/neutts-air-darija-v1