yasuogg commited on
Commit
9528c5e
·
verified ·
1 Parent(s): 21e8a45

Add KasbahTTS V0 Algerian Dardja demo

Browse files
Files changed (5) hide show
  1. .gitattributes +1 -0
  2. README.md +39 -7
  3. app.py +201 -0
  4. examples/ALG.wav +3 -0
  5. requirements.txt +3 -0
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ examples/ALG.wav filter=lfs diff=lfs merge=lfs -text
README.md CHANGED
@@ -1,13 +1,45 @@
1
  ---
2
- title: KasbahTTS Demo
3
- emoji: 🐨
4
- colorFrom: purple
5
- colorTo: indigo
6
  sdk: gradio
7
- sdk_version: 6.12.0
8
- python_version: '3.12'
9
  app_file: app.py
10
  pinned: false
 
 
 
 
 
 
 
 
 
 
 
11
  ---
12
 
13
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ title: KasbahTTS V0 — Algerian Dardja TTS
3
+ emoji: 🎙️
4
+ colorFrom: red
5
+ colorTo: green
6
  sdk: gradio
7
+ sdk_version: 5.50.0
 
8
  app_file: app.py
9
  pinned: false
10
+ license: mit
11
+ short_description: Zero-shot Algerian Dardja (الدارجة) text-to-speech
12
+ models:
13
+ - MenaVoice/KasbahTTS-V0
14
+ tags:
15
+ - text-to-speech
16
+ - arabic
17
+ - algerian-arabic
18
+ - dardja
19
+ - f5-tts
20
+ - voice-cloning
21
  ---
22
 
23
+ # KasbahTTS V0 Algerian Dardja TTS
24
+
25
+ Interactive demo for [`MenaVoice/KasbahTTS-V0`](https://huggingface.co/MenaVoice/KasbahTTS-V0),
26
+ the first open-source text-to-speech model built for **Algerian Dardja** (الدارجة الجزائرية).
27
+
28
+ Give it a few seconds of any voice and some Dardja text, and it speaks that text in that voice.
29
+
30
+ ## How it works
31
+
32
+ Built on **F5-TTS** (DiT-based flow matching), fine-tuned from **Habibi-TTS** on real Algerian
33
+ conversational speech. Weights are pulled at runtime from the model repo, so this Space does not
34
+ carry its own copy.
35
+
36
+ ## Limitations
37
+
38
+ - Arabic script only — no French code-switching
39
+ - No digits — spell numbers out (`ثلاثة`, not `3`)
40
+ - No diacritics (تشكيل)
41
+ - May occasionally repeat words; try `nfe_step=64` or shorter segments
42
+
43
+ ---
44
+
45
+ *من القصبة للعالم — From the Kasbah to the world*
app.py ADDED
@@ -0,0 +1,201 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ KasbahTTS V0 — Algerian Dardja text-to-speech.
3
+
4
+ Zero-shot voice cloning demo for MenaVoice/KasbahTTS-V0, an F5-TTS (DiT flow
5
+ matching) model fine-tuned on Algerian Dardja.
6
+
7
+ `spaces` must be imported before torch so ZeroGPU can patch CUDA init.
8
+ """
9
+
10
+ import os
11
+ import random
12
+ import re
13
+ import tempfile
14
+
15
+ try:
16
+ import spaces
17
+
18
+ USING_ZEROGPU = True
19
+ except ImportError:
20
+ USING_ZEROGPU = False
21
+
22
+ import gradio as gr
23
+ import soundfile as sf
24
+ import torch
25
+ from f5_tts.infer.utils_infer import (
26
+ load_model,
27
+ load_vocoder,
28
+ preprocess_ref_audio_text,
29
+ remove_silence_for_generated_wav,
30
+ )
31
+ from f5_tts.model import DiT
32
+ from huggingface_hub import hf_hub_download
33
+
34
+ from habibi_tts.infer.utils_infer import infer_process
35
+
36
+
37
+ def gpu_decorator(func):
38
+ # Only wrap with the ZeroGPU allocator when actually running on ZeroGPU
39
+ # hardware (env var set by HF). On CPU/paid-GPU spaces this is a no-op.
40
+ if USING_ZEROGPU and os.environ.get("SPACES_ZERO_GPU"):
41
+ return spaces.GPU(duration=120)(func)
42
+ return func
43
+
44
+
45
+ MODEL_REPO = "MenaVoice/KasbahTTS-V0"
46
+ CKPT_FILE = "ALGERIA.safetensors"
47
+ V1_CFG = dict(dim=1024, depth=22, heads=16, ff_mult=2, text_dim=512, conv_layers=4)
48
+
49
+ DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
50
+
51
+ ckpt_path = hf_hub_download(MODEL_REPO, CKPT_FILE)
52
+ vocab_path = hf_hub_download(MODEL_REPO, "vocab.txt")
53
+
54
+ vocoder = load_vocoder(vocoder_name="vocos", is_local=False, device=DEVICE)
55
+ model = load_model(DiT, V1_CFG, ckpt_path, vocab_file=vocab_path, device=DEVICE)
56
+
57
+ EXAMPLE_REF = os.path.join(os.path.dirname(__file__), "examples", "ALG.wav")
58
+ EXAMPLE_REF_TEXT = "أنيا هكا باغية ناكل هكا أني ن نشوف فيها الحاجة هذيكا."
59
+
60
+ # The model was trained on unvocalized Arabic script only: Latin letters and
61
+ # digits fall outside its vocabulary and produce unpredictable audio.
62
+ UNSUPPORTED = re.compile(r"[A-Za-z0-9٠-٩]")
63
+
64
+
65
+ @gpu_decorator
66
+ def generate(
67
+ ref_audio_orig,
68
+ ref_text,
69
+ gen_text,
70
+ speed,
71
+ nfe_step,
72
+ cfg_strength,
73
+ cross_fade,
74
+ remove_sil,
75
+ seed,
76
+ progress=gr.Progress(),
77
+ ):
78
+ if not ref_audio_orig:
79
+ raise gr.Error("Please provide a reference audio clip (5-15 seconds works best).")
80
+ if not gen_text.strip():
81
+ raise gr.Error("Please enter some Algerian Dardja text to synthesize.")
82
+
83
+ if UNSUPPORTED.search(gen_text):
84
+ gr.Warning(
85
+ "Latin letters and digits are outside the model's vocabulary. "
86
+ "Spell numbers out in Arabic words (ثلاثة, not 3)."
87
+ )
88
+
89
+ if seed is None or int(seed) < 0:
90
+ seed = random.randint(0, 2**31 - 1)
91
+ seed = int(seed)
92
+ torch.manual_seed(seed)
93
+
94
+ # Leaving ref_text blank triggers Whisper auto-transcription inside f5-tts.
95
+ ref_audio, ref_text = preprocess_ref_audio_text(ref_audio_orig, ref_text or "", show_info=gr.Info)
96
+
97
+ # KasbahTTS is a *specialized* single-dialect checkpoint, so no dialect token
98
+ # is prepended — infer_process defaults dialect_id to None.
99
+ wave, sample_rate, _ = infer_process(
100
+ ref_audio,
101
+ ref_text,
102
+ gen_text,
103
+ model,
104
+ vocoder,
105
+ cross_fade_duration=cross_fade,
106
+ nfe_step=int(nfe_step),
107
+ cfg_strength=cfg_strength,
108
+ speed=speed,
109
+ show_info=gr.Info,
110
+ progress=progress,
111
+ )
112
+
113
+ if remove_sil:
114
+ with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as f:
115
+ tmp_path = f.name
116
+ try:
117
+ sf.write(tmp_path, wave, sample_rate)
118
+ remove_silence_for_generated_wav(tmp_path)
119
+ wave, sample_rate = sf.read(tmp_path)
120
+ finally:
121
+ os.unlink(tmp_path)
122
+
123
+ return (sample_rate, wave), ref_text, seed
124
+
125
+
126
+ with gr.Blocks(title="KasbahTTS V0", theme=gr.themes.Soft()) as demo:
127
+ gr.Markdown(
128
+ """
129
+ # 🇩🇿 KasbahTTS V0 — Algerian Dardja TTS
130
+
131
+ Zero-shot voice cloning for **Algerian Dardja** (الدارجة الجزائرية).
132
+ Upload a few seconds of any voice, type Dardja text, and hear it spoken back in that voice.
133
+
134
+ Model: [`MenaVoice/KasbahTTS-V0`](https://huggingface.co/MenaVoice/KasbahTTS-V0) ·
135
+ F5-TTS architecture, fine-tuned from Habibi-TTS · MIT licensed.
136
+ """
137
+ )
138
+
139
+ with gr.Row():
140
+ with gr.Column():
141
+ ref_audio = gr.Audio(label="Reference voice", type="filepath")
142
+ ref_text = gr.Textbox(
143
+ label="Reference transcript (optional)",
144
+ lines=2,
145
+ placeholder="Leave blank to auto-transcribe with Whisper…",
146
+ )
147
+ gen_text = gr.Textbox(
148
+ label="Text to generate (Arabic script only)",
149
+ lines=4,
150
+ placeholder="واش راك خويا، لاباس عليك؟",
151
+ rtl=True,
152
+ )
153
+ run = gr.Button("🎤 Generate", variant="primary", size="lg")
154
+
155
+ with gr.Column():
156
+ audio_out = gr.Audio(label="Generated speech", interactive=False)
157
+ ref_text_out = gr.Textbox(label="Reference transcript used", interactive=False, lines=2)
158
+ seed_out = gr.Number(label="Seed used", interactive=False, precision=0)
159
+
160
+ with gr.Accordion("Advanced settings", open=False):
161
+ speed = gr.Slider(0.5, 1.5, value=1.0, step=0.05, label="Speed")
162
+ nfe_step = gr.Slider(
163
+ 8, 64, value=32, step=8, label="NFE steps",
164
+ info="More steps = higher quality, slower.",
165
+ )
166
+ cfg_strength = gr.Slider(0.5, 5.0, value=2.0, step=0.1, label="CFG strength")
167
+ cross_fade = gr.Slider(0.0, 0.5, value=0.15, step=0.05, label="Cross-fade (s)")
168
+ remove_sil = gr.Checkbox(label="Trim long silences", value=False)
169
+ seed = gr.Number(label="Seed (-1 = random)", value=-1, precision=0)
170
+
171
+ inputs = [ref_audio, ref_text, gen_text, speed, nfe_step, cfg_strength, cross_fade, remove_sil, seed]
172
+ outputs = [audio_out, ref_text_out, seed_out]
173
+
174
+ run.click(generate, inputs=inputs, outputs=outputs)
175
+
176
+ if os.path.exists(EXAMPLE_REF):
177
+ gr.Examples(
178
+ examples=[
179
+ [EXAMPLE_REF, EXAMPLE_REF_TEXT, "واش راك خويا، لاباس عليك؟ صباح الخير."],
180
+ [EXAMPLE_REF, EXAMPLE_REF_TEXT, "من القصبة للعالم، هذا أول موديل يهدر بالدارجة الجزائرية."],
181
+ ],
182
+ inputs=[ref_audio, ref_text, gen_text],
183
+ )
184
+
185
+ gr.Markdown(
186
+ """
187
+ ---
188
+ ### Known limitations
189
+
190
+ - **Arabic script only.** No French code-switching — `ça va` will not work.
191
+ - **No digits.** Write `ثلاثة`, not `3`.
192
+ - **No diacritics (تشكيل).** Use plain, unvocalized Arabic.
193
+ - **Occasional repetition.** Try `nfe_step` 64, adjust `cfg_strength`, or split long text.
194
+
195
+ Built with ❤️ for Algeria by MenaVoice — *من القصبة للعالم*
196
+ """
197
+ )
198
+
199
+
200
+ if __name__ == "__main__":
201
+ demo.queue().launch()
examples/ALG.wav ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:187b5992f7b068371f2769860a8b776e50abcc4168d9d24811ebb97ec0b8664f
3
+ size 294174
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ habibi-tts==0.1.1
2
+ soundfile
3
+ spaces