Tharshan commited on
Commit
94cc0a6
·
verified ·
1 Parent(s): 23c2909

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +59 -47
app.py CHANGED
@@ -1,35 +1,47 @@
1
- import os
 
 
 
 
 
 
 
 
 
2
 
3
  import gradio as gr
4
- import spaces
5
  import torch
6
  from transformers import AutoModel
7
 
8
  REPO = "Tharshan/indicf5_hindi-english_code_switch"
 
9
 
10
  print("loading model ...")
11
  model = AutoModel.from_pretrained(REPO, trust_remote_code=True)
12
  model.eval()
 
13
 
14
  VOICES = model.voices()
15
  CHOICES = [(v.get("name", k), k) for k, v in VOICES.items()]
16
  DEFAULT = list(VOICES)[0]
17
-
18
- # same sentence in every language, so switching is directly comparable
19
- EXAMPLES = [
20
- ["मैं आज office जा रहा हूँ, morning में एक important meeting है।", "ritu_hinglish"],
21
- ["நான் இன்னைக்கு office போறேன், morning ல ஒரு important meeting இருக்கு.", "ta_hinglish"],
22
- ["আমি আজ office যাচ্ছি, morning এ একটা important meeting আছে।", "bn"],
23
- ["నేను ఈరోజు office కి వెళ్తున్నాను, morning లో ఒక important meeting ఉంది.", "te"],
24
- ["ನಾನು ಇವತ್ತು office ಗೆ ಹೋಗುತ್ತಿದ್ದೇನೆ, morning ನಲ್ಲಿ ಒಂದು important meeting ಇದೆ.", "kn"],
25
- ["ഞാൻ ഇന്ന് office ലേക്ക് പോകുന്നു, morning ൽ ഒരു important meeting ഉണ്ട്.", "ml"],
26
- ["मी आज office ला जातोय, morning मध्ये एक important meeting आहे.", "mr"],
27
- ["હું આજે office જઈ રહ્યો છું, morning માં એક important meeting છે.", "gu"],
28
- ["ਮੈਂ ਅੱਜ office ਜਾ ਰਿਹਾ ਹਾਂ, morning ਵਿੱਚ ਇੱਕ important meeting ਹੈ।", "pa"],
29
- ["ମୁଁ ଆଜି office ଯାଉଛି, morning ରେ ଗୋଟିଏ important meeting ଅଛି।", "or"],
 
 
30
  ]
31
-
32
- MAX_CHARS = 300
33
 
34
 
35
  def synth(text, voice_key, nfe, speed):
@@ -37,69 +49,69 @@ def synth(text, voice_key, nfe, speed):
37
  if not text:
38
  raise gr.Error("Enter some text first.")
39
  if len(text) > MAX_CHARS:
40
- raise gr.Error(f"Keep it under {MAX_CHARS} characters. This build "
41
- "generates in a single pass with no text chunking, so "
42
- "longer input degrades noticeably.")
 
43
 
44
  ref_audio, ref_text = model.voice(voice_key)
45
- model.to("cuda" if torch.cuda.is_available() else "cpu")
46
-
47
  audio, sr = model.generate(text, ref_audio=ref_audio, ref_text=ref_text,
48
  nfe_step=int(nfe), speed=float(speed))
49
  return sr, audio
50
 
51
 
52
  with gr.Blocks(title="Indic code-switched TTS") as demo:
53
- gr.Markdown("""
54
  # Indic code-switched TTS
55
 
56
- Text-to-speech for Indian languages with **English words mixed in** — the way
57
- people actually speak. Fine-tuned from
 
 
58
  [ai4bharat/IndicF5](https://huggingface.co/ai4bharat/IndicF5) on Hindi-English
59
- code-switched speech.
60
 
61
- Pick a language, write a sentence with some English in it, and listen to how the
62
- English is pronounced inside the Indic sentence.
63
  """)
64
 
65
  with gr.Row():
66
  with gr.Column(scale=3):
67
  text = gr.Textbox(
68
- label="Text",
69
- lines=3,
70
- placeholder="Write an Indic sentence with English words mixed in…",
71
- )
72
  voice = gr.Dropdown(choices=CHOICES, value=DEFAULT,
73
  label="Language / voice")
74
  with gr.Accordion("Advanced", open=False):
75
  nfe = gr.Slider(8, 32, value=16, step=4,
76
- label="Denoising steps (lower = faster)")
 
77
  speed = gr.Slider(0.7, 1.3, value=1.0, step=0.05, label="Speed")
78
  btn = gr.Button("Generate", variant="primary")
79
 
80
  with gr.Column(scale=2):
81
  out = gr.Audio(label="Output", show_download_button=True)
82
- gr.Markdown("""
83
- **Tip:** match the voice to your text's language. The reference voice drives
84
- prosody and accent, and a mismatched one degrades output substantially — more
85
- than any other setting here.
86
- """)
87
 
88
- gr.Examples(examples=EXAMPLES, inputs=[text, voice],
89
- label="The same sentence in ten languages")
 
90
 
91
  gr.Markdown(f"""
92
  ---
93
- **Model:** [{REPO}](https://huggingface.co/{REPO}) ·
94
- fine-tuned from [ai4bharat/IndicF5](https://huggingface.co/ai4bharat/IndicF5) (MIT),
95
- trained on OpenSLR-104 Hindi-English.
96
 
97
- **Limitations.** Single-pass generation, no text chunking — keep to a sentence or
98
- two. Heavy code-switching can drop words. Training audio came from an ASR corpus
99
- upsampled to 24 kHz, so timbre is duller than the base model.
100
  """)
101
 
102
  btn.click(synth, inputs=[text, voice, nfe, speed], outputs=out)
103
  text.submit(synth, inputs=[text, voice, nfe, speed], outputs=out)
104
 
105
- demo.queue(max_size=20).launch()
 
1
+ """
2
+ Gradio demo for Tharshan/indicf5_hindi-english_code_switch.
3
+
4
+ Tuned for HF Spaces CPU basic (2 vCPU / 16 GB):
5
+ - no `spaces` / ZeroGPU decorator (nothing to allocate on CPU)
6
+ - torch pinned to 2 threads (container over-reports core count)
7
+ - default 16 denoising steps instead of 32 (~halves inference time)
8
+ - 150-char cap, validated before any model work
9
+ - requests queued so each gets the full CPU instead of contending
10
+ """
11
 
12
  import gradio as gr
 
13
  import torch
14
  from transformers import AutoModel
15
 
16
  REPO = "Tharshan/indicf5_hindi-english_code_switch"
17
+ MAX_CHARS = 150
18
 
19
  print("loading model ...")
20
  model = AutoModel.from_pretrained(REPO, trust_remote_code=True)
21
  model.eval()
22
+ torch.set_num_threads(2)
23
 
24
  VOICES = model.voices()
25
  CHOICES = [(v.get("name", k), k) for k, v in VOICES.items()]
26
  DEFAULT = list(VOICES)[0]
27
+ print(f"ready — voices: {list(VOICES)}")
28
+
29
+ # Same sentence across languages, so switching the dropdown is directly
30
+ # comparable. Keys must exist in voices.json or the buttons raise KeyError.
31
+ _CANDIDATES = [
32
+ ("ritu_hinglish", "मैं आज office जा रहा हूँ, morning में meeting है।"),
33
+ ("ta_hinglish", "நான் இன்னைக்கு office போறேன், morning ல meeting இருக்கு."),
34
+ ("bn", "আমি আজ office যাচ্ছি, morning এ একটা meeting আছে।"),
35
+ ("te", "నేను ఈరోజు office కి వెళ్తున్నాను, morning లో meeting ఉంది."),
36
+ ("kn", "ನಾನು ಇವತ್ತು office ಗೆ ಹೋಗುತ್ತಿದ್ದೇನೆ, morning ನಲ್ಲಿ meeting ಇದೆ."),
37
+ ("ml", "ഞാൻ ഇന്ന് office ലേക്ക് പോകുന്നു, morning ൽ ഒരു meeting ഉണ്ട്."),
38
+ ("mr", "मी आज office ला जातोय, morning मध्ये एक meeting आहे."),
39
+ ("gu", "હું આજે office જઈ રહ્યો છું, morning માં એક meeting છે."),
40
+ ("pa", "ਮੈਂ ਅੱਜ office ਜਾ ਰਿਹਾ ਹਾਂ, morning ਵਿੱਚ ਇੱਕ meeting ਹੈ।"),
41
+ ("or", "ମୁଁ ଆଜି office ଯାଉଛି, morning ରେ ଗୋଟିଏ meeting ଅଛି।"),
42
  ]
43
+ # drop any example whose voice isn't actually bundled
44
+ EXAMPLES = [[text, key] for key, text in _CANDIDATES if key in VOICES]
45
 
46
 
47
  def synth(text, voice_key, nfe, speed):
 
49
  if not text:
50
  raise gr.Error("Enter some text first.")
51
  if len(text) > MAX_CHARS:
52
+ raise gr.Error(f"Keep it under {MAX_CHARS} characters — this runs on "
53
+ f"free CPU hardware. You entered {len(text)}.")
54
+ if voice_key not in VOICES:
55
+ raise gr.Error("Pick a voice from the dropdown.")
56
 
57
  ref_audio, ref_text = model.voice(voice_key)
 
 
58
  audio, sr = model.generate(text, ref_audio=ref_audio, ref_text=ref_text,
59
  nfe_step=int(nfe), speed=float(speed))
60
  return sr, audio
61
 
62
 
63
  with gr.Blocks(title="Indic code-switched TTS") as demo:
64
+ gr.Markdown(f"""
65
  # Indic code-switched TTS
66
 
67
+ Because nobody says "कार्यालय" when they mean office.
68
+
69
+ Most Indic text-to-speech mangles English words embedded in an Indic sentence.
70
+ This one doesn't. Fine-tuned from
71
  [ai4bharat/IndicF5](https://huggingface.co/ai4bharat/IndicF5) on Hindi-English
72
+ code-switched speech — the English gain carries across to the other scripts too.
73
 
74
+ > ⏳ Running on free CPU hardware: **30–60 seconds per sentence**, and the first
75
+ > request after idle is slower while the model wakes up. Keep it short.
76
  """)
77
 
78
  with gr.Row():
79
  with gr.Column(scale=3):
80
  text = gr.Textbox(
81
+ label="Text", lines=2,
82
+ placeholder="An Indic sentence with English words mixed in…")
 
 
83
  voice = gr.Dropdown(choices=CHOICES, value=DEFAULT,
84
  label="Language / voice")
85
  with gr.Accordion("Advanced", open=False):
86
  nfe = gr.Slider(8, 32, value=16, step=4,
87
+ label="Denoising steps — lower is faster, "
88
+ "quality difference is small")
89
  speed = gr.Slider(0.7, 1.3, value=1.0, step=0.05, label="Speed")
90
  btn = gr.Button("Generate", variant="primary")
91
 
92
  with gr.Column(scale=2):
93
  out = gr.Audio(label="Output", show_download_button=True)
94
+ gr.Markdown(
95
+ "**Tip:** match the voice to your text's language. The reference "
96
+ "voice sets accent and prosody, and a mismatched one degrades "
97
+ "output more than any other setting here.")
 
98
 
99
+ if EXAMPLES:
100
+ gr.Examples(examples=EXAMPLES, inputs=[text, voice],
101
+ label="The same sentence across languages")
102
 
103
  gr.Markdown(f"""
104
  ---
105
+ **Model:** [{REPO}](https://huggingface.co/{REPO}) · fine-tuned from
106
+ [ai4bharat/IndicF5](https://huggingface.co/ai4bharat/IndicF5) (MIT) on
107
+ OpenSLR-104 Hindi-English.
108
 
109
+ **Limitations.** Single-pass generation with no text chunking — one or two
110
+ sentences at a time. Heavy code-switching can drop words. Training audio came
111
+ from an ASR corpus upsampled to 24 kHz, so timbre is duller than the base model.
112
  """)
113
 
114
  btn.click(synth, inputs=[text, voice, nfe, speed], outputs=out)
115
  text.submit(synth, inputs=[text, voice, nfe, speed], outputs=out)
116
 
117
+ demo.queue(max_size=10).launch()