Downloads · 30 days
64
18% of all-time downloads
lgtk/qwen25vl-3b-modi-synth-lora
qwen25vl-3b-modi-synth-lora is a machine learning model from lgtk. Use it for the machine learning task on the model card, and read the license before you ship it in a product. It is set up for peft. The card lists the license as apache-2.0.
A QLoRA adapter for Modi script → Devanagari (Marathi) transliteration, fine-tuned on MoDeTrans (real handwritten Modi documents) plus SynthMoDe (synthetic Modi images rendered from the same Devanagari text using Modi…
Downloads · 30 days
64
18% of all-time downloads
All-time downloads
349
Public
Repo size
309 MB
Likes
0
Public
Click a slice to open those files.
.safetensors297 MB · 96%
From the Hugging Face model README
A QLoRA adapter for Modi script → Devanagari (Marathi) transliteration, fine-tuned on MoDeTrans (real handwritten Modi documents) plus SynthMoDe (synthetic Modi images rendered from the same Devanagari text using Modi fonts).
This is the recommended adapter — it achieves the best test CER (0.328) and is the default in the project's Gradio demo and CLI inference script.
Project: modi-to-Marathi on GitHub
| Base model | Qwen/Qwen2.5-VL-3B-Instruct |
| Fine-tuning method | QLoRA — LoRA rank 32, alpha 64, 4-bit NF4 quantization |
| LoRA target modules | q_proj, k_proj, v_proj, o_proj, gate_proj, up_proj, down_proj |
| Trainable parameters | 74M (1.94% of 3.8B total) |
| Training data | MoDeTrans (1,635 real) + SynthMoDe (4,086 synthetic) = 5,721 total |
| Training epochs | 2 |
| Training time | ~9.75 hours on RTX 5060 (8.5 GB VRAM) |
| Test CER | 0.328 (on 204 held-out MoDeTrans examples; real images only) |
| Zero-shot baseline CER | 0.930 |
A 65% reduction in character error rate vs zero-shot. CER 0.328 means roughly 33% of characters require expert correction — designed for human-in-the-loop use.
| Quality tier | CER range | Count |
|---|---|---|
| Perfect | 0.0 | 3 |
| Excellent | < 0.10 | 5 |
| Good | 0.10–0.20 | 38 |
| Fair | 0.20–0.40 | 109 |
| Poor | 0.40–0.70 | 44 |
| Very poor | 0.70–1.0 | 3 |
| Hallucination loops | > 1.0 | 2 |
The majority of examples fall in the "fair" tier — usable as a first draft for expert review.
| Model | Test CER | Poor + worse |
|---|---|---|
Real data only (lgtk/qwen25vl-3b-modi-lora) | 0.332 | 59 examples |
| Real + synthetic (this adapter) | 0.328 | 47 examples |
Synthetic data gave a small but consistent improvement, mainly reducing poor-tier examples. Vowel-length confusion was unchanged (font rendering does not capture that ambiguity).
Input: photograph or scan of a handwritten Modi-script Marathi document Output: Devanagari transliteration of that text
This is transliteration, not translation — the language (Marathi) does not change, only the script. Modi was the administrative script of Maharashtra from roughly the 13th to the mid-20th century; most surviving documents are from the Shivakalin (17th c.), Peshwekalin (18th–early 19th c.), and Anglakalin (1818–1952) eras.
Install dependencies:
pip install transformers peft bitsandbytes accelerate pillow torch
from transformers import Qwen2_5_VLForConditionalGeneration, AutoProcessor, BitsAndBytesConfig
from peft import PeftModel
from PIL import Image
import torch
MODEL_ID = "Qwen/Qwen2.5-VL-3B-Instruct"
ADAPTER_ID = "lgtk/qwen25vl-3b-modi-synth-lora" # ← this repo
bnb = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.bfloat16,
)
base = Qwen2_5_VLForConditionalGeneration.from_pretrained(
MODEL_ID, quantization_config=bnb, device_map="auto")
model = PeftModel.from_pretrained(base, ADAPTER_ID)
model.eval()
processor = AutoProcessor.from_pretrained(MODEL_ID, max_pixels=512 * 28 * 28)
PROMPT = (
"This image contains handwritten text in Modi script, a historical cursive "
"script used to write the Marathi language. "
"Transliterate the text in this image into Devanagari script. "
"Output only the Devanagari text, with no explanation."
)
image = Image.open("your_modi_image.jpg").convert("RGB")
messages = [{
"role": "user",
"content": [
{{"type": "image", "image": image}},
{{"type": "text", "text": PROMPT}},
],
}]
text_in = processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
inputs = processor(text=[text_in], images=[image], return_tensors="pt").to(model.device)
with torch.no_grad():
out = model.generate(**inputs, max_new_tokens=256, do_sample=False)
result = processor.batch_decode(
out[:, inputs["input_ids"].shape[1]:], skip_special_tokens=True
)[0].strip()
print(result)
Developed and tested on a desktop with an NVIDIA RTX 5060 GPU (8.5 GB VRAM) running WSL2 on Windows. At 4-bit NF4 quantization, the adapter uses approximately 3–4 GB of VRAM during inference. A 5060 or better is recommended; the pipeline should also fit on any GPU with ≥6 GB VRAM.
historyHulk/MoDeTrans on HuggingFacehistoryHulk/SynthMoDe on HuggingFace