Mgolo commited on
Commit
8b31b10
Β·
verified Β·
1 Parent(s): 79d1580

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +90 -90
app.py CHANGED
@@ -1,9 +1,4 @@
1
- import os
2
- import os
3
- # Redirect Streamlit config/cache to a writable temp folder
4
- os.environ["STREAMLIT_HOME"] = "/tmp/.streamlit"
5
-
6
- import streamlit as st
7
  from transformers import pipeline, MarianTokenizer, AutoModelForSeq2SeqLM
8
  import torch
9
  import unicodedata
@@ -16,31 +11,47 @@ import nltk
16
  nltk.download('punkt')
17
  from nltk.tokenize import sent_tokenize
18
 
19
- import fitz # PyMuPDF for PDF
20
  import docx
21
  from bs4 import BeautifulSoup
22
  import markdown2
23
  import chardet
24
 
25
- # --- Device selection ---
26
  device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
27
 
28
- # --- Load Wolof MarianMT model from HF hub ---
29
- @st.cache_resource
 
 
30
  def load_wolof_model():
31
- model_name = "LocaleNLP/eng_wolof"
32
- model = AutoModelForSeq2SeqLM.from_pretrained(model_name).to(device)
33
- tokenizer = MarianTokenizer.from_pretrained(model_name)
34
- translator = pipeline("translation", model=model, tokenizer=tokenizer, device=0 if device.type == 'cuda' else -1)
 
 
35
  return translator
36
 
37
- @st.cache_resource
38
  def load_whisper_model():
39
- return whisper.load_model("base")
40
-
41
- def transcribe_audio(audio_path):
42
- whisper_model = load_whisper_model()
43
- return whisper_model.transcribe(audio_path)["text"]
 
 
 
 
 
 
 
 
 
 
 
 
 
44
 
45
  def translate(text):
46
  translator = load_wolof_model()
@@ -97,73 +108,62 @@ def extract_text_from_file(uploaded_file):
97
  else:
98
  raise ValueError("Unsupported file type")
99
 
100
- def main():
101
- st.set_page_config(page_title="LocaleNLP English-to-Wolof Translator", layout="wide", initial_sidebar_state="expanded")
102
-
103
- with st.sidebar:
104
- st.image("localenpl5.jpeg", use_container_width=True)
105
- st.markdown("""
106
- <h3 style='text-align: left; color: #4B8BBE;'>🌐 Wolof Translation</h3>
107
- This app translates English text to Wolof (Senegal) using a custom MarianMT model hosted on Hugging Face.
108
- """, unsafe_allow_html=True)
109
-
110
- st.markdown("<h4 style='text-align: center; color: #306998;'>Translate English to Wolof</h4>", unsafe_allow_html=True)
111
-
112
- col1, col2 = st.columns(2)
113
- with col1:
114
- input_mode = st.selectbox("Select input mode:", ("Text", "Audio", "File"))
115
- st.markdown("<hr>", unsafe_allow_html=True)
116
- with col2:
117
- target_lang = "Wolof (Senegal)"
118
- st.markdown(f"<p><b>Target language:</b> {target_lang}</p>", unsafe_allow_html=True)
119
- st.markdown("<hr>", unsafe_allow_html=True)
120
-
121
- col3, col4 = st.columns(2)
122
- with col3:
123
- input_text = ""
124
- if input_mode == "Text":
125
- input_text = st.text_area("✏️ Enter English text:", height=250)
126
- elif input_mode == "Audio":
127
- audio_file = st.file_uploader("πŸ”Š Upload audio (.wav, .mp3, .m4a)", type=["wav", "mp3", "m4a"])
128
- if audio_file:
129
- with tempfile.NamedTemporaryFile(delete=False, suffix=f".{audio_file.type.split('/')[-1]}") as tmp:
130
- tmp.write(audio_file.read())
131
- tmp_path = tmp.name
132
- with st.spinner("Transcribing..."):
133
- input_text = transcribe_audio(tmp_path)
134
- os.remove(tmp_path)
135
- st.text_area("πŸ“ Transcribed Text:", value=input_text, height=150)
136
- elif input_mode == "File":
137
- uploaded_file = st.file_uploader("πŸ“„ Upload document (PDF, Word, HTML, Markdown, SRT, TXT)",
138
- type=["pdf", "docx", "html", "htm", "md", "srt", "txt"])
139
- if uploaded_file:
140
- try:
141
- input_text = extract_text_from_file(uploaded_file)
142
- st.text_area("πŸ“ƒ Extracted Text:", value=input_text, height=200)
143
- except Exception as e:
144
- st.error(f"Error extracting text: {str(e)}")
145
-
146
- with col4:
147
- if input_text:
148
- with st.spinner("Translating..."):
149
- translated_text = translate(input_text)
150
- st.write(f"Output in {target_lang}")
151
- st.success(translated_text)
152
-
153
- st.download_button(
154
- label="πŸ’Ύ Download Translation",
155
- data=translated_text,
156
- file_name=f"translated_{target_lang.replace(' ', '_').lower()}.txt",
157
- mime="text/plain"
158
- )
159
- else:
160
- st.info("Translation will appear here.")
161
-
162
- st.markdown("""
163
- <hr>
164
- <div style='text-align: center; color: #4B8BBE; font-size: 0.9rem'>
165
- LocaleNLP Β© 2025 β€’ Empowering communities through AI and language
166
- </div>""", unsafe_allow_html=True)
167
-
168
- if __name__ == "__main__":
169
- main()
 
1
+ import gradio as gr
 
 
 
 
 
2
  from transformers import pipeline, MarianTokenizer, AutoModelForSeq2SeqLM
3
  import torch
4
  import unicodedata
 
11
  nltk.download('punkt')
12
  from nltk.tokenize import sent_tokenize
13
 
14
+ import fitz # PyMuPDF
15
  import docx
16
  from bs4 import BeautifulSoup
17
  import markdown2
18
  import chardet
19
 
20
+ # Device setup
21
  device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
22
 
23
+ # Load Wolof MarianMT model from HF hub (cached manually)
24
+ translator = None
25
+ whisper_model = None
26
+
27
  def load_wolof_model():
28
+ global translator
29
+ if translator is None:
30
+ model_name = "LocaleNLP/eng_wolof"
31
+ model = AutoModelForSeq2SeqLM.from_pretrained(model_name).to(device)
32
+ tokenizer = MarianTokenizer.from_pretrained(model_name)
33
+ translator = pipeline("translation", model=model, tokenizer=tokenizer, device=0 if device.type == 'cuda' else -1)
34
  return translator
35
 
 
36
  def load_whisper_model():
37
+ global whisper_model
38
+ if whisper_model is None:
39
+ whisper_model = whisper.load_model("base")
40
+ return whisper_model
41
+
42
+ def transcribe_audio(audio_file):
43
+ model = load_whisper_model()
44
+ # Save temp file if not a path
45
+ if isinstance(audio_file, str):
46
+ audio_path = audio_file
47
+ else:
48
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as tmp:
49
+ tmp.write(audio_file.read())
50
+ audio_path = tmp.name
51
+ result = model.transcribe(audio_path)
52
+ if not isinstance(audio_file, str):
53
+ os.remove(audio_path)
54
+ return result["text"]
55
 
56
  def translate(text):
57
  translator = load_wolof_model()
 
108
  else:
109
  raise ValueError("Unsupported file type")
110
 
111
+ def process_input(input_mode, text, audio_file, file_obj):
112
+ input_text = ""
113
+ if input_mode == "Text":
114
+ input_text = text
115
+ elif input_mode == "Audio":
116
+ if audio_file is not None:
117
+ input_text = transcribe_audio(audio_file)
118
+ elif input_mode == "File":
119
+ if file_obj is not None:
120
+ input_text = extract_text_from_file(file_obj)
121
+ return input_text
122
+
123
+ def translate_and_return(text):
124
+ if not text.strip():
125
+ return "No input text to translate."
126
+ return translate(text)
127
+
128
+ # Gradio UI components
129
+ with gr.Blocks() as demo:
130
+ gr.Markdown("## LocaleNLP English-to-Wolof Translator")
131
+ gr.Markdown("Upload English text, audio, or document to translate to Wolof using a custom MarianMT model.")
132
+
133
+ with gr.Row():
134
+ input_mode = gr.Radio(choices=["Text", "Audio", "File"], label="Select input mode", value="Text")
135
+
136
+ input_text = gr.Textbox(label="Enter English text", lines=10, visible=True)
137
+ audio_input = gr.Audio(source="upload", type="file", label="Upload audio (.wav, .mp3, .m4a)", visible=False)
138
+ file_input = gr.File(file_types=['.pdf', '.docx', '.html', '.htm', '.md', '.srt', '.txt'], label="Upload document", visible=False)
139
+
140
+ extracted_text = gr.Textbox(label="Extracted / Transcribed Text", lines=10, interactive=False)
141
+ translate_button = gr.Button("Translate to Wolof")
142
+ output_text = gr.Textbox(label="Translated Wolof Text", lines=10, interactive=False)
143
+
144
+ def update_visibility(mode):
145
+ return {
146
+ input_text: gr.update(visible=(mode=="Text")),
147
+ audio_input: gr.update(visible=(mode=="Audio")),
148
+ file_input: gr.update(visible=(mode=="File")),
149
+ extracted_text: gr.update(value="", visible=True),
150
+ output_text: gr.update(value="")
151
+ }
152
+
153
+ input_mode.change(fn=update_visibility, inputs=input_mode, outputs=[input_text, audio_input, file_input, extracted_text, output_text])
154
+
155
+ def handle_process(mode, text, audio, file_obj):
156
+ try:
157
+ extracted = process_input(mode, text, audio, file_obj)
158
+ return extracted, ""
159
+ except Exception as e:
160
+ return "", f"Error: {str(e)}"
161
+
162
+ translate_button.click(fn=handle_process, inputs=[input_mode, input_text, audio_input, file_input], outputs=[extracted_text, output_text])
163
+
164
+ def handle_translate(text):
165
+ return translate_and_return(text)
166
+
167
+ translate_button.click(fn=handle_translate, inputs=extracted_text, outputs=output_text)
168
+
169
+ demo.launch()