| --- |
| language: |
| - ar |
| license: apache-2.0 |
| base_model: Qwen/Qwen3-TTS-12Hz-1.7B-Base |
| pipeline_tag: text-to-speech |
| tags: |
| - tts |
| - text-to-speech |
| - arabic |
| - saudi |
| - ksa |
| - fine-tuned |
| - qwen3 |
| datasets: |
| - vadimbelsky/KSA_Arabic_English_Dataset_13k |
| --- |
| |
| # Qwen3-TTS โ KSA Arabic Fine-tune |
|
|
| A fine-tuned version of [`Qwen/Qwen3-TTS-12Hz-1.7B-Base`](https://huggingface.co/Qwen/Qwen3-TTS-12Hz-1.7B-Base) for **Saudi Arabian (Khaleeji/KSA) Arabic** speech synthesis. |
|
|
| Training data: [`vadimbelsky/KSA_Arabic_English_Dataset_13k`](https://huggingface.co/datasets/vadimbelsky/KSA_Arabic_English_Dataset_13k) โ ~13 k Arabic utterances in the KSA dialect, filtered to 1โ20 s duration. |
|
|
| --- |
|
|
| ## How Arabic support was added |
|
|
| The base model ships with a fixed set of languages in its codec token vocabulary; Arabic was not among them. Adding it required changes at three levels: |
|
|
| ### 1. Arabic language embedding โ warm-start initialisation |
|
|
| Arabic was assigned codec token ID `2072`. Rather than initialising this embedding randomly, it was set to the **mean of all existing language embeddings** before training: |
|
|
| ```python |
| ARABIC_LANG_ID = 2072 |
| codec_emb = qwen3tts.model.talker.model.codec_embedding |
| existing_ids = [v for k, v in config.talker_config.codec_language_id.items() if k != 'arabic'] |
| avg = codec_emb.weight[existing_ids].float().mean(0) |
| codec_emb.weight[ARABIC_LANG_ID] = avg |
| ``` |
|
|
| ### 2. Language-conditioned codec prefix (4-token think block) |
|
|
| A 4-token block injects the explicit language ID through the codec channel: |
|
|
| ``` |
| pos 3: codec_think_id |
| pos 4: codec_think_bos_id |
| pos 5: lang_id โ Arabic token 2072 |
| pos 6: codec_think_eos_id |
| pos 7: speaker embedding slot โ shifted +1 vs. base model |
| ``` |
|
|
| The sequence offset in the collator was adjusted from `+8` to `+9`, and `codec_embedding_mask[7] = False` so the speaker embedding is injected directly from the speaker encoder. |
|
|
| ### 3. Language auto-detection |
|
|
| `dataset.py` detects Arabic automatically from Unicode range `\u0600`โ`\u06FF`, so no explicit language field is needed per sample. |
|
|
| ### 4. KSA speaker registration |
|
|
| Speaker ID `3000` (`ksa_speaker`) was registered. The embedding is extracted from a reference KSA audio clip by the frozen speaker encoder and written directly into the safetensors weights โ the saved model is fully self-contained. |
|
|
| --- |
|
|
| ## Training setup |
|
|
| | Setting | Value | |
| |---|---| |
| | Base model | `Qwen/Qwen3-TTS-12Hz-1.7B-Base` | |
| | Training data | `vadimbelsky/KSA_Arabic_English_Dataset_13k` (Arabic subset) | |
| | Optimizer | AdamW, lr=2e-6, weight decay=0.01 | |
| | Precision | bf16 mixed precision | |
| | Gradient accumulation | 4 steps (effective batch ~32) | |
| | Gradient clipping | 1.0 | |
| | Epochs | 5 (this checkpoint: epoch 4) | |
| | Loss | `talker_loss + 0.3 ร sub_talker_loss` | |
|
|
| All model parameters were fine-tuned (no LoRA). The speaker encoder was kept frozen during training. |
|
|
| --- |
|
|
| ## Inference |
|
|
| **Install dependencies:** |
| ```bash |
| pip install qwen-tts soundfile torch |
| ``` |
|
|
| **Single utterance:** |
| ```python |
| import torch |
| import soundfile as sf |
| from qwen_tts.inference.qwen3_tts_model import Qwen3TTSModel |
| |
| tts = Qwen3TTSModel.from_pretrained( |
| "vadimbelsky/qwen3-TTS-KSA", |
| dtype=torch.bfloat16, |
| device_map="cuda:0", |
| attn_implementation="sdpa", |
| ) |
| |
| wavs, sr = tts.generate_custom_voice( |
| text="ุงูุญูู ุณููุช ููุฌุงู ูููุฉุ ุชููู ุตุญูุช ู
ู ุงูููู
", |
| speaker="ksa_speaker", |
| language="arabic", |
| ) |
| sf.write("output.wav", wavs[0], sr) |
| ``` |
|
|
| **CLI with `infer_ksa.py`:** |
| ```bash |
| python infer_ksa.py \ |
| --checkpoint vadimbelsky/qwen3-TTS-KSA \ |
| --text "ููู ุชุจู ุชูุชูู ุงูุญููุ" \ |
| --output out_ksa.wav |
| ``` |
| |
| Output is 24 kHz mono WAV. |
| |
| --- |
| |
| ## Supported speakers & languages |
| |
| | Speaker name | Language | |
| |---|---| |
| | `ksa_speaker` | `arabic` | |
| |
| --- |
| |
| ## License |
| |
| Apache 2.0 โ same as the base model. |
| |