qari-ocr-batch / app.py
Pythonista993's picture
Update app.py
f5dcfe4 verified
Raw
History Blame Contribute Delete
2.28 kB
import spaces
import torch
import gradio as gr
from transformers import Qwen2VLForConditionalGeneration, AutoProcessor
MODEL_ID = "NAMAA-Space/Qari-OCR-v0.3-VL-2B-Instruct"
# High max_pixels keeps small Arabic glyphs + tashkeel legible (OCR needs detail).
# 28 is Qwen2-VL's patch factor; 4096*28*28 β‰ˆ 3.2M px β‰ˆ a 300-DPI textbook page.
processor = AutoProcessor.from_pretrained(
MODEL_ID, min_pixels=256 * 28 * 28, max_pixels=4096 * 28 * 28
)
# Loaded on CPU at startup β€” ZeroGPU only attaches a GPU inside @spaces.GPU functions.
model = Qwen2VLForConditionalGeneration.from_pretrained(MODEL_ID, torch_dtype=torch.bfloat16)
PROMPT = (
"Below is an image of one page of an Arabic school textbook. "
"Transcribe ALL the Arabic text exactly as printed, preserving line breaks, "
"headings, and right-to-left reading order. Keep diacritics (tashkeel) if present. "
"Ignore any faint diagonal draft watermark. Output only the transcribed text."
)
@spaces.GPU(duration=120)
def ocr(image):
if image is None:
return ""
model.to("cuda")
messages = [{"role": "user", "content": [
{"type": "image", "image": image},
{"type": "text", "text": PROMPT},
]}]
text = processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
# Feed the PIL image straight to the processor β€” avoids qwen-vl-utils/torchvision.
inputs = processor(
text=[text], images=[image], padding=True, return_tensors="pt",
).to("cuda")
with torch.no_grad():
generated = model.generate(**inputs, max_new_tokens=4096, do_sample=False)
trimmed = [g[len(i):] for i, g in zip(inputs.input_ids, generated)]
return processor.batch_decode(
trimmed, skip_special_tokens=True, clean_up_tokenization_spaces=False
)[0]
with gr.Blocks(title="Qari-OCR β€” Arabic page OCR") as demo:
gr.Markdown("## Qari-OCR β€” Arabic textbook page OCR\nUpload a page image, or call the `/ocr` API.")
with gr.Row():
inp = gr.Image(type="pil", label="Page image")
out = gr.Textbox(label="Transcribed Arabic", lines=25, rtl=True)
gr.Button("Run OCR", variant="primary").click(ocr, inp, out, api_name="ocr")
if __name__ == "__main__":
demo.queue(max_size=16).launch()