BurhaanZargar commited on
Commit
7f95fc6
Β·
1 Parent(s): c0c2e82

Added English audio feature

Browse files
Files changed (3) hide show
  1. app.py +73 -50
  2. postBuild +7 -1
  3. requirements.txt +2 -1
app.py CHANGED
@@ -1,31 +1,35 @@
1
  import torch
2
- from transformers import AutoModelForSeq2SeqLM, AutoTokenizer
3
  from IndicTransToolkit.processor import IndicProcessor
4
  import gradio as gr
5
  import requests
6
  from datetime import datetime
 
7
 
8
  # Supabase configuration
9
  SUPABASE_URL = "https://gptmdbhzblfybdnohqnh.supabase.co"
10
- SUPABASE_API_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImdwdG1kYmh6YmxmeWJkbm9ocW5oIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NDc0NjY1NDgsImV4cCI6MjA2MzA0MjU0OH0.CfWArts6Kd_x7Wj0a_nAyGJfrFt8F7Wdy_MdYDj9e7U" # ← Replace with your anon/public API key
11
  SUPABASE_TABLE = "translations"
12
 
13
  # Device configuration
14
  DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
15
 
16
- # Load both models ahead of time
17
  model_en_to_indic = AutoModelForSeq2SeqLM.from_pretrained("ai4bharat/indictrans2-en-indic-1B", trust_remote_code=True).to(DEVICE)
18
  tokenizer_en_to_indic = AutoTokenizer.from_pretrained("ai4bharat/indictrans2-en-indic-1B", trust_remote_code=True)
19
  model_indic_to_en = AutoModelForSeq2SeqLM.from_pretrained("ai4bharat/indictrans2-indic-en-1B", trust_remote_code=True).to(DEVICE)
20
  tokenizer_indic_to_en = AutoTokenizer.from_pretrained("ai4bharat/indictrans2-indic-en-1B", trust_remote_code=True)
21
  ip = IndicProcessor(inference=True)
22
 
23
- # Separate save function (only called if user clicks Save button)
 
 
 
 
24
  def save_to_supabase(input_text, output_text, direction):
25
  if not input_text.strip() or not output_text.strip():
26
  return "Nothing to save."
27
 
28
- # Choose table name based on direction
29
  table_name = "translations" if direction == "en_to_ks" else "ks_to_en_translations"
30
 
31
  payload = {
@@ -47,19 +51,12 @@ def save_to_supabase(input_text, output_text, direction):
47
  json=payload,
48
  timeout=10
49
  )
50
-
51
- if response.status_code == 201:
52
- return "βœ… Saved successfully!"
53
- else:
54
- print("SAVE ERROR:", response.status_code, response.text)
55
- return "❌ Failed to save."
56
  except Exception as e:
57
  print("SAVE EXCEPTION:", e)
58
  return "❌ Save request error."
59
 
60
-
61
-
62
- # Function to retrieve recent translation history from Supabase
63
  def get_translation_history(direction="en_to_ks"):
64
  table_name = "translations" if direction == "en_to_ks" else "ks_to_en_translations"
65
 
@@ -74,19 +71,16 @@ def get_translation_history(direction="en_to_ks"):
74
  headers=headers,
75
  timeout=10
76
  )
77
-
78
  if response.status_code == 200:
79
  records = response.json()
80
  return "\n\n".join(
81
  [f"Input: {r['input_text']} β†’ Output: {r['output_text']}" for r in records]
82
  )
83
- else:
84
- return "Failed to load history."
85
  except Exception as e:
86
  print("HISTORY FETCH ERROR:", e)
87
  return "Error loading history."
88
 
89
-
90
  # Translation function
91
  def translate(text, direction):
92
  if not text.strip():
@@ -123,34 +117,47 @@ def translate(text, direction):
123
  print("Translation Error:", e)
124
  return "⚠️ Translation failed.", gr.update(), gr.update()
125
 
126
-
127
-
128
- # Toggle function to switch direction and update labels
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
  def switch_direction(direction, input_text_val, output_text_val):
130
  new_direction = "ks_to_en" if direction == "en_to_ks" else "en_to_ks"
131
  input_label = "Kashmiri Text" if new_direction == "ks_to_en" else "English Text"
132
  output_label = "English Translation" if new_direction == "ks_to_en" else "Kashmiri Translation"
133
-
134
- # Swap input/output text too
135
  return (
136
  new_direction,
137
  gr.update(value=output_text_val, label=input_label),
138
  gr.update(value=input_text_val, label=output_label)
139
  )
140
 
141
-
142
- # Update your Gradio interface block
143
  with gr.Blocks() as interface:
144
  gr.HTML("""
145
- <div style="display: flex; justify-content: space-between; align-items: center; padding: 10px;">
146
- <img src="https://raw.githubusercontent.com/BurhaanRasheedZargar/Images/211321a234613a9c3dd944fe9367cf13d1386239/assets/left_logo.png" style="height:150px; width:auto;">
147
- <h2 style="margin: 0; text-align: center;">English ↔ Kashmiri Translator</h2>
148
- <img src="https://raw.githubusercontent.com/BurhaanRasheedZargar/Images/77797f7f7cbee328fa0f9d31cf3e290441e04cd3/assets/right_logo.png">
149
- </div>
150
- """)
151
 
152
-
153
- translation_direction = gr.State(value="en_to_ks")
154
 
155
  with gr.Row():
156
  input_text = gr.Textbox(lines=2, label="English Text", placeholder="Enter text....")
@@ -159,12 +166,17 @@ with gr.Blocks() as interface:
159
  with gr.Row():
160
  translate_button = gr.Button("Translate")
161
  save_button = gr.Button("Save Translation")
162
- switch_button = gr.Button("Switch") # ← New button
163
 
164
  save_status = gr.Textbox(label="Save Status", interactive=False)
165
  history_box = gr.Textbox(lines=10, label="Translation History", interactive=False)
166
 
167
- # Actions
 
 
 
 
 
168
  translate_button.click(
169
  fn=translate,
170
  inputs=[input_text, translation_direction],
@@ -172,23 +184,34 @@ with gr.Blocks() as interface:
172
  )
173
 
174
  save_button.click(
175
- fn=save_to_supabase,
176
- inputs=[input_text, output_text, translation_direction],
177
- outputs=save_status
178
- ).then(
179
- fn=get_translation_history,
180
- inputs=translation_direction,
181
- outputs=history_box
182
- )
183
-
184
-
185
 
186
  switch_button.click(
187
- fn=switch_direction,
188
- inputs=[translation_direction, input_text, output_text],
189
- outputs=[translation_direction, input_text, output_text]
190
- )
191
 
 
 
 
 
 
 
 
 
 
 
 
 
 
192
 
193
  if __name__ == "__main__":
194
- interface.launch(share=True, inbrowser=True)
 
1
  import torch
2
+ from transformers import AutoModelForSeq2SeqLM, AutoTokenizer, pipeline
3
  from IndicTransToolkit.processor import IndicProcessor
4
  import gradio as gr
5
  import requests
6
  from datetime import datetime
7
+ import tempfile
8
 
9
  # Supabase configuration
10
  SUPABASE_URL = "https://gptmdbhzblfybdnohqnh.supabase.co"
11
+ SUPABASE_API_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImdwdG1kYmh6YmxmeWJkbm9ocW5oIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NDc0NjY1NDgsImV4cCI6MjA2MzA0MjU0OH0.CfWArts6Kd_x7Wj0a_nAyGJfrFt8F7Wdy_MdYDj9e7U"
12
  SUPABASE_TABLE = "translations"
13
 
14
  # Device configuration
15
  DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
16
 
17
+ # Load translation models
18
  model_en_to_indic = AutoModelForSeq2SeqLM.from_pretrained("ai4bharat/indictrans2-en-indic-1B", trust_remote_code=True).to(DEVICE)
19
  tokenizer_en_to_indic = AutoTokenizer.from_pretrained("ai4bharat/indictrans2-en-indic-1B", trust_remote_code=True)
20
  model_indic_to_en = AutoModelForSeq2SeqLM.from_pretrained("ai4bharat/indictrans2-indic-en-1B", trust_remote_code=True).to(DEVICE)
21
  tokenizer_indic_to_en = AutoTokenizer.from_pretrained("ai4bharat/indictrans2-indic-en-1B", trust_remote_code=True)
22
  ip = IndicProcessor(inference=True)
23
 
24
+ # Whisper STT and English TTS pipelines
25
+ asr = pipeline("automatic-speech-recognition", model="openai/whisper-small")
26
+ tts_en = pipeline("text-to-speech", model="espnet/kan-bayashi_ljspeech_vits")
27
+
28
+ # Save to Supabase
29
  def save_to_supabase(input_text, output_text, direction):
30
  if not input_text.strip() or not output_text.strip():
31
  return "Nothing to save."
32
 
 
33
  table_name = "translations" if direction == "en_to_ks" else "ks_to_en_translations"
34
 
35
  payload = {
 
51
  json=payload,
52
  timeout=10
53
  )
54
+ return "βœ… Saved successfully!" if response.status_code == 201 else "❌ Failed to save."
 
 
 
 
 
55
  except Exception as e:
56
  print("SAVE EXCEPTION:", e)
57
  return "❌ Save request error."
58
 
59
+ # Fetch translation history
 
 
60
  def get_translation_history(direction="en_to_ks"):
61
  table_name = "translations" if direction == "en_to_ks" else "ks_to_en_translations"
62
 
 
71
  headers=headers,
72
  timeout=10
73
  )
 
74
  if response.status_code == 200:
75
  records = response.json()
76
  return "\n\n".join(
77
  [f"Input: {r['input_text']} β†’ Output: {r['output_text']}" for r in records]
78
  )
79
+ return "Failed to load history."
 
80
  except Exception as e:
81
  print("HISTORY FETCH ERROR:", e)
82
  return "Error loading history."
83
 
 
84
  # Translation function
85
  def translate(text, direction):
86
  if not text.strip():
 
117
  print("Translation Error:", e)
118
  return "⚠️ Translation failed.", gr.update(), gr.update()
119
 
120
+ # Transcribe English audio
121
+ def transcribe_audio(audio_path):
122
+ try:
123
+ result = asr(audio_path)
124
+ return result["text"]
125
+ except Exception as e:
126
+ print("STT Error:", e)
127
+ return "⚠️ Transcription failed."
128
+
129
+ # Synthesize English audio if direction is ks_to_en
130
+ def synthesize_tts(text, direction):
131
+ if direction == "ks_to_en":
132
+ try:
133
+ result = tts_en(text)
134
+ return (result["sampling_rate"], result["audio"])
135
+ except Exception as e:
136
+ print("TTS Error:", e)
137
+ return None
138
+
139
+ # Direction switch
140
  def switch_direction(direction, input_text_val, output_text_val):
141
  new_direction = "ks_to_en" if direction == "en_to_ks" else "en_to_ks"
142
  input_label = "Kashmiri Text" if new_direction == "ks_to_en" else "English Text"
143
  output_label = "English Translation" if new_direction == "ks_to_en" else "Kashmiri Translation"
 
 
144
  return (
145
  new_direction,
146
  gr.update(value=output_text_val, label=input_label),
147
  gr.update(value=input_text_val, label=output_label)
148
  )
149
 
150
+ # Gradio interface
 
151
  with gr.Blocks() as interface:
152
  gr.HTML("""
153
+ <div style="display: flex; justify-content: space-between; align-items: center; padding: 10px;">
154
+ <img src="https://raw.githubusercontent.com/BurhaanRasheedZargar/Images/211321a234613a9c3dd944fe9367cf13d1386239/assets/left_logo.png" style="height:150px; width:auto;">
155
+ <h2 style="margin: 0; text-align: center;">English ↔ Kashmiri Translator</h2>
156
+ <img src="https://raw.githubusercontent.com/BurhaanRasheedZargar/Images/77797f7f7cbee328fa0f9d31cf3e290441e04cd3/assets/right_logo.png">
157
+ </div>
158
+ """)
159
 
160
+ translation_direction = gr.State(value="en_to_ks")
 
161
 
162
  with gr.Row():
163
  input_text = gr.Textbox(lines=2, label="English Text", placeholder="Enter text....")
 
166
  with gr.Row():
167
  translate_button = gr.Button("Translate")
168
  save_button = gr.Button("Save Translation")
169
+ switch_button = gr.Button("Switch")
170
 
171
  save_status = gr.Textbox(label="Save Status", interactive=False)
172
  history_box = gr.Textbox(lines=10, label="Translation History", interactive=False)
173
 
174
+ with gr.Row():
175
+ audio_input = gr.Audio(source="microphone", type="filepath", label="πŸŽ™οΈ Speak in English")
176
+ audio_output = gr.Audio(label="πŸ”Š English Output Audio")
177
+ stt_translate_button = gr.Button("🎀 Transcribe & Translate")
178
+
179
+ # Click events
180
  translate_button.click(
181
  fn=translate,
182
  inputs=[input_text, translation_direction],
 
184
  )
185
 
186
  save_button.click(
187
+ fn=save_to_supabase,
188
+ inputs=[input_text, output_text, translation_direction],
189
+ outputs=save_status
190
+ ).then(
191
+ fn=get_translation_history,
192
+ inputs=translation_direction,
193
+ outputs=history_box
194
+ )
 
 
195
 
196
  switch_button.click(
197
+ fn=switch_direction,
198
+ inputs=[translation_direction, input_text, output_text],
199
+ outputs=[translation_direction, input_text, output_text]
200
+ )
201
 
202
+ stt_translate_button.click(
203
+ fn=transcribe_audio,
204
+ inputs=audio_input,
205
+ outputs=input_text
206
+ ).then(
207
+ fn=translate,
208
+ inputs=[input_text, translation_direction],
209
+ outputs=[output_text, input_text, output_text]
210
+ ).then(
211
+ fn=synthesize_tts,
212
+ inputs=[output_text, translation_direction],
213
+ outputs=audio_output
214
+ )
215
 
216
  if __name__ == "__main__":
217
+ interface.queue().launch()
postBuild CHANGED
@@ -1 +1,7 @@
1
- python -c "from transformers import AutoModelForSeq2SeqLM, AutoTokenizer; AutoModelForSeq2SeqLM.from_pretrained('ai4bharat/indictrans2-en-indic-1B'); AutoTokenizer.from_pretrained('ai4bharat/indictrans2-en-indic-1B'); AutoModelForSeq2SeqLM.from_pretrained('ai4bharat/indictrans2-indic-en-1B'); AutoTokenizer.from_pretrained('ai4bharat/indictrans2-indic-en-1B')"
 
 
 
 
 
 
 
1
+ python -c "from transformers import AutoModelForSeq2SeqLM, AutoTokenizer, pipeline; \
2
+ AutoModelForSeq2SeqLM.from_pretrained('ai4bharat/indictrans2-en-indic-1B'); \
3
+ AutoTokenizer.from_pretrained('ai4bharat/indictrans2-en-indic-1B'); \
4
+ AutoModelForSeq2SeqLM.from_pretrained('ai4bharat/indictrans2-indic-en-1B'); \
5
+ AutoTokenizer.from_pretrained('ai4bharat/indictrans2-indic-en-1B'); \
6
+ pipeline('automatic-speech-recognition', model='openai/whisper-small'); \
7
+ pipeline('text-to-speech', model='espnet/kan-bayashi_ljspeech_vits')"
requirements.txt CHANGED
@@ -1,6 +1,7 @@
1
  torch>=1.12
2
  transformers>=4.30.0
 
 
3
  gradio
4
  requests
5
- sentencepiece # Optional, may still be needed by transformers
6
  git+https://github.com/VarunGumma/IndicTransToolkit.git
 
1
  torch>=1.12
2
  transformers>=4.30.0
3
+ sentencepiece # Required for tokenizer in IndicTrans2
4
+ torchaudio # Required by Whisper and ESPnet TTS
5
  gradio
6
  requests
 
7
  git+https://github.com/VarunGumma/IndicTransToolkit.git