Spaces:
Running
Running
File size: 3,776 Bytes
1f39aa6 0dc9d0c 67a163c 1f39aa6 3fdc7b6 0dc9d0c 1f39aa6 43b39f0 1f39aa6 0dc9d0c c571a45 0dc9d0c c571a45 0dc9d0c 43b39f0 1f39aa6 0dc9d0c de4ab0d 0dc9d0c 43b39f0 c571a45 0dc9d0c 3fdc7b6 1f39aa6 0dc9d0c de4ab0d 1f39aa6 e0dc6e1 0dc9d0c 1f39aa6 3fdc7b6 1f39aa6 0dc9d0c e0dc6e1 0dc9d0c 1f39aa6 43b39f0 7d583b2 0dc9d0c 613b55a 0dc9d0c dde491e 02f6bf9 67a163c 02f6bf9 67a163c 02f6bf9 0dc9d0c 613b55a dde491e 0dc9d0c | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | """
Translation interface using the MADLAD-400 3B model.
Translates English text to 22 production-ready languages from the MADLAD-400 paper.
"""
import warnings
from functools import lru_cache
import gradio as gr
import spaces
import torch
from transformers import AutoModelForSeq2SeqLM, AutoTokenizer
from langmap.langid_mapping import langid_to_language
MODEL_NAME = "google/madlad400-3b-mt"
def _get_device() -> torch.device:
if torch.cuda.is_available():
return torch.device("cuda")
warnings.warn("No GPU available. Running on CPU — translation will be slow.", stacklevel=2)
return torch.device("cpu")
@lru_cache(maxsize=1)
def _load_tokenizer() -> AutoTokenizer:
tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, use_fast=True)
if tokenizer is None:
raise RuntimeError(f"Failed to load tokenizer for {MODEL_NAME}")
return tokenizer
@lru_cache(maxsize=1)
def _load_model() -> AutoModelForSeq2SeqLM:
device = _get_device()
dtype = torch.float16 if device.type == "cuda" else torch.float32
return AutoModelForSeq2SeqLM.from_pretrained(MODEL_NAME, torch_dtype=dtype).to(device)
@lru_cache(maxsize=1)
def _build_language_mappings() -> tuple[dict[str, str], list[str]]:
tokenizer = _load_tokenizer()
vocab = tokenizer.get_vocab()
name_to_code = {v: k for k, v in langid_to_language.items() if k in vocab}
return name_to_code, sorted(name_to_code.keys())
@spaces.GPU
def translate(text: str, target_language_name: str) -> str:
tokenizer = _load_tokenizer()
model = _load_model()
device = model.device
name_to_code, _ = _build_language_mappings()
target_code = name_to_code.get(target_language_name)
if target_code is None:
raise ValueError(f"Unsupported language: {target_language_name}")
input_ids = tokenizer(target_code + " " + text, return_tensors="pt").input_ids.to(device)
outputs = model.generate(input_ids=input_ids, max_new_tokens=512)
result = tokenizer.decode(outputs[0], skip_special_tokens=True)
if not isinstance(result, str):
raise TypeError(f"Expected str from decode, got {type(result)}")
return result
def _build_demo() -> gr.Blocks:
_, language_names = _build_language_mappings()
with gr.Blocks(title="MADLAD-400 Translation") as demo:
gr.Markdown(
"# MADLAD-400 Translation\n"
"Translate English into 22 production-ready languages using Google's MADLAD-400 3B model. "
"[Paper](https://arxiv.org/pdf/2309.04662)"
)
target_language = gr.Dropdown(
choices=language_names,
value="French",
label="Target language",
)
with gr.Row():
input_text = gr.Textbox(
label="English",
placeholder="Enter English text here",
lines=4,
)
output_text = gr.Textbox(
label="Translation",
lines=4,
buttons=["copy"],
interactive=False,
)
translate_btn = gr.Button("Translate", variant="primary")
translate_btn.click(
fn=translate,
inputs=[input_text, target_language],
outputs=output_text,
)
gr.Examples(
examples=[
["Hello, how are you today?", "French"],
["The weather is beautiful.", "Spanish"],
["Thank you very much.", "German"],
["Where is the train station?", "Portuguese"],
],
inputs=[input_text, target_language],
)
return demo
demo = _build_demo()
def main() -> None:
demo.launch(theme=gr.themes.Soft())
if __name__ == "__main__":
main()
|