SaraZahran212's picture
Update app.py
812ef22 verified
Raw
History Blame Contribute Delete
8.01 kB
import gradio as gr
import torch
from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
from langdetect import detect, LangDetectException
import logging
# Logging setup
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Model and device configuration
MODEL_NAME = "facebook/nllb-200-distilled-600M"
device = "cuda" if torch.cuda.is_available() else "cpu"
# Load the model
try:
logger.info(f"Loading model on device: {device}")
model = AutoModelForSeq2SeqLM.from_pretrained(
MODEL_NAME,
cache_dir=".cache",
trust_remote_code=True
).to(device)
model.eval()
logger.info("Model loaded successfully")
except Exception as e:
logger.error(f"Failed to load model: {str(e)}")
raise
# Supported languages (50 languages)
LANGUAGES = {
"Arabic": "arb_Arab",
"English": "eng_Latn",
"French": "fra_Latn",
"Spanish": "spa_Latn",
"German": "deu_Latn",
"Italian": "ita_Latn",
"Portuguese": "por_Latn",
"Russian": "rus_Cyrl",
"Chinese (Simplified)": "zho_Hans",
"Chinese (Traditional)": "zho_Hant",
"Japanese": "jpn_Jpan",
"Korean": "kor_Hang",
"Hindi": "hin_Deva",
"Bengali": "ben_Beng",
"Pashto": "pes_Arab",
"Persian": "pes_Arab",
"Urdu": "urd_Arab",
"Punjabi": "pan_Guru",
"Thai": "tha_Thai",
"Vietnamese": "vie_Latn",
"Indonesian": "ind_Latn",
"Malay": "zsm_Latn",
"Swahili": "swh_Latn",
"Hebrew": "heb_Hebr",
"Greek": "ell_Grek",
"Polish": "pol_Latn",
"Ukrainian": "ukr_Cyrl",
"Romanian": "ron_Latn",
"Dutch": "nld_Latn",
"Swedish": "swe_Latn",
"Danish": "dan_Latn",
"Norwegian": "nob_Latn",
"Finnish": "fin_Latn",
"Turkish": "tur_Latn",
"Czech": "ces_Latn",
"Hungarian": "hun_Latn",
"Bulgarian": "bul_Cyrl",
"Croatian": "hrv_Latn",
"Serbian": "srp_Cyrl",
"Slovak": "slk_Latn",
"Slovenian": "slv_Latn",
"Lithuanian": "lit_Latn",
"Latvian": "lav_Latn",
"Estonian": "est_Latn",
"Macedonian": "mkd_Cyrl",
"Albanian": "als_Latn",
"Catalan": "cat_Latn",
"Basque": "eus_Latn",
"Galician": "glg_Latn",
"Icelandic": "isl_Latn",
"Maltese": "mlt_Latn"
}
# Default source language for auto-detection
DEFAULT_SRC_LANG = "eng_Latn"
def detect_language(text: str) -> str:
"""Detect text language with error handling"""
try:
lang = detect(text)
# Special handling for Chinese variants
if lang.lower() in ("zh-cn", "zh", "zh-tw"):
lang = lang.lower()
# Map to NLLB language codes
lang_map = {
"ar": "arb_Arab", "en": "eng_Latn", "fr": "fra_Latn",
"es": "spa_Latn", "de": "deu_Latn", "it": "ita_Latn",
"pt": "por_Latn", "ru": "rus_Cyrl", "zh-cn": "zho_Hans",
"zh-tw": "zho_Hant", "ja": "jpn_Jpan", "ko": "kor_Hang",
"hi": "hin_Deva", "fa": "pes_Arab", "ur": "urd_Arab",
"th": "tha_Thai", "vi": "vie_Latn", "id": "ind_Latn",
"tr": "tur_Latn", "nl": "nld_Latn", "pl": "pol_Latn",
"uk": "ukr_Cyrl", "el": "ell_Grek", "he": "heb_Hebr",
"sv": "swe_Latn", "da": "dan_Latn", "fi": "fin_Latn",
"no": "nob_Latn", "cs": "ces_Latn", "hu": "hun_Latn",
"ro": "ron_Latn", "bg": "bul_Cyrl", "sr": "srp_Cyrl",
"hr": "hrv_Latn", "sk": "slk_Latn", "sl": "slv_Latn",
"lt": "lit_Latn", "lv": "lav_Latn", "et": "est_Latn",
"mk": "mkd_Cyrl", "sq": "als_Latn", "ca": "cat_Latn",
"eu": "eus_Latn", "gl": "glg_Latn", "is": "isl_Latn",
"mt": "mlt_Latn"
}
return lang_map.get(lang, DEFAULT_SRC_LANG)
except LangDetectException:
logger.warning("Language detection failed, using default")
return DEFAULT_SRC_LANG
except Exception as e:
logger.error(f"Unexpected error in language detection: {str(e)}")
return DEFAULT_SRC_LANG
def translate_text(
text: str,
src_lang: str,
tgt_lang: str,
max_length: int = 512,
num_beams: int = 4
) -> str:
"""Translate text with comprehensive error handling"""
try:
if not text.strip():
return ""
logger.info(f"Translating from {src_lang} to {tgt_lang}")
# Determine source language
src_code = detect_language(text) if src_lang == "Auto-detect" else LANGUAGES.get(src_lang, DEFAULT_SRC_LANG)
tgt_code = LANGUAGES.get(tgt_lang, "eng_Latn")
logger.info(f"Language codes: Source={src_code}, Target={tgt_code}")
# Load tokenizer with source language
tokenizer = AutoTokenizer.from_pretrained(
MODEL_NAME,
src_lang=src_code,
cache_dir=".cache"
)
# Get target language ID
if hasattr(tokenizer, 'lang_code_to_id'):
forced_bos = tokenizer.lang_code_to_id[tgt_code]
else:
forced_bos = tokenizer.convert_tokens_to_ids(tgt_code)
# Encode input text
inputs = tokenizer(text, return_tensors="pt", truncation=True).to(device)
# Generate translation
with torch.no_grad():
outputs = model.generate(
**inputs,
forced_bos_token_id=forced_bos,
max_length=max_length,
num_beams=num_beams,
no_repeat_ngram_size=3,
early_stopping=True
)
# Decode output
translated_text = tokenizer.decode(outputs[0], skip_special_tokens=True)
return translated_text
except Exception as e:
logger.error(f"Translation error: {str(e)}")
return f"⚠ Translation error: {str(e)}"
# Gradio interface
with gr.Blocks(title="Multilingual Translator") as app:
gr.Markdown("""
# 🌍 Multilingual Translator (50 Languages)
### Use auto-detection or manually select source language
""")
with gr.Row():
with gr.Column():
src_lang = gr.Dropdown(
choices=["Auto-detect"] + list(LANGUAGES.keys()),
value="Auto-detect",
label="Source Language"
)
input_text = gr.Textbox(
lines=5,
placeholder="Enter text here...",
label="Original Text"
)
with gr.Accordion("Advanced Settings", open=False):
max_length = gr.Slider(
minimum=50,
maximum=1024,
value=512,
step=10,
label="Max Text Length"
)
num_beams = gr.Slider(
minimum=1,
maximum=8,
value=4,
step=1,
label="Number of Beams"
)
translate_btn = gr.Button("Translate", variant="primary")
with gr.Column():
tgt_lang = gr.Dropdown(
choices=list(LANGUAGES.keys()),
value="English",
label="Target Language"
)
output_text = gr.Textbox(
lines=5,
placeholder="Translation will appear here...",
label="Translation"
)
# Event binding
translate_btn.click(
fn=translate_text,
inputs=[input_text, src_lang, tgt_lang, max_length, num_beams],
outputs=output_text
)
# Quick examples
examples = [
["Hello, how are you?", "Auto-detect", "Arabic"],
["مرحبا، كيف حالك؟", "Auto-detect", "English"],
["Bonjour, comment ça va?", "Auto-detect", "Arabic"]
]
gr.Examples(examples=examples, inputs=[input_text, src_lang, tgt_lang])
# Launch the app
if __name__ == "__main__":
app.launch(server_name="0.0.0.0", server_port=7860)