Spaces:
Paused
Paused
File size: 3,492 Bytes
384c8e8 | 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 | 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()
@spaces.GPU
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()
|