Spaces:
Paused
Paused
| import spaces | |
| import torch | |
| import gradio as gr | |
| from PIL import Image | |
| from transformers import AutoProcessor, AutoModelForImageTextToText | |
| from peft import PeftModel | |
| BASE_MODEL_ID = "google/gemma-3-12b-it" | |
| ADAPTER_ID = "historyHulk/ModiTrans-12B-Gemma-Teacher" | |
| PROMPT = "Translitrate the following Modi script to Devnagri script." | |
| MAX_NEW_TOKENS = 350 | |
| # Model + processor are loaded once at startup and kept on CPU. | |
| # They are moved to GPU inside the @spaces.GPU-decorated function, | |
| # which is how ZeroGPU spaces work (GPU only attached per-call). | |
| print("Loading processor...") | |
| processor = AutoProcessor.from_pretrained(BASE_MODEL_ID) | |
| print("Loading base model...") | |
| base_model = AutoModelForImageTextToText.from_pretrained( | |
| BASE_MODEL_ID, | |
| torch_dtype=torch.bfloat16, | |
| ) | |
| print("Loading LoRA adapter...") | |
| model = PeftModel.from_pretrained( | |
| base_model, | |
| ADAPTER_ID, | |
| torch_dtype=torch.bfloat16, | |
| ) | |
| model.eval() | |
| def transliterate(image: Image.Image) -> str: | |
| if image is None: | |
| return "Please upload an image of Modi script." | |
| device = "cuda" | |
| model.to(device) | |
| image = image.convert("RGB").resize((1024, 512)) | |
| messages = [ | |
| { | |
| "role": "user", | |
| "content": [ | |
| {"type": "image", "image": image}, | |
| {"type": "text", "text": PROMPT}, | |
| ], | |
| }, | |
| ] | |
| inputs = processor.apply_chat_template( | |
| messages, | |
| add_generation_prompt=True, | |
| tokenize=True, | |
| return_dict=True, | |
| return_tensors="pt", | |
| ).to(device, dtype=torch.bfloat16) | |
| input_len = inputs["input_ids"].shape[-1] | |
| with torch.no_grad(): | |
| output_ids = model.generate( | |
| **inputs, | |
| max_new_tokens=MAX_NEW_TOKENS, | |
| do_sample=False, | |
| ) | |
| generated = output_ids[0][input_len:] | |
| text = processor.decode(generated, skip_special_tokens=True) | |
| return text.strip() | |
| with gr.Blocks(title="ModiTrans: Modi Script to Devanagari") as demo: | |
| gr.Markdown( | |
| """ | |
| # ModiTrans — Modi Script to Devanagari Transliteration | |
| Upload a scanned image of historic **Modi script** text and this model | |
| will transliterate it into modern **Devanagari** script. | |
| Uses [`historyHulk/ModiTrans-12B-Gemma-Teacher`](https://huggingface.co/historyHulk/ModiTrans-12B-Gemma-Teacher), | |
| a LoRA adapter on `google/gemma-3-12b-it`, from the paper | |
| *"Historic Scripts to Modern Vision: A Novel Dataset and A VLM Framework | |
| for Transliteration of Modi Script to Devanagari"* (ICDAR 2025). | |
| > This is a gated model — the Space owner's `HF_TOKEN` must have accepted | |
| > access on the model page for inference to work. | |
| """ | |
| ) | |
| with gr.Row(): | |
| with gr.Column(): | |
| image_input = gr.Image(type="pil", label="Modi Script Image") | |
| run_btn = gr.Button("Transliterate", variant="primary") | |
| with gr.Column(): | |
| output_text = gr.Textbox( | |
| label="Devanagari Transliteration", lines=8 | |
| ) | |
| run_btn.click(fn=transliterate, inputs=image_input, outputs=output_text) | |
| image_input.change(fn=transliterate, inputs=image_input, outputs=output_text) | |
| gr.Markdown( | |
| """ | |
| --- | |
| **Citation:** Kausadikar, H., Kale, T., Susladkar, O., Mittal, S. | |
| *Historic Scripts to Modern Vision.* ICDAR 2025 (Springer LNCS). | |
| """ | |
| ) | |
| if __name__ == "__main__": | |
| demo.launch() | |