import torch
from PIL import Image
from peft import PeftModel
from qwen_vl_utils import process_vision_info
from transformers import AutoProcessor, Qwen2_5_VLForConditionalGeneration
BASE_MODEL = "Qwen/Qwen2.5-VL-3B-Instruct"
ADAPTER_ID = "zidanmubarak/jawi-qwen25-vl-qlora"
base = Qwen2_5_VLForConditionalGeneration.from_pretrained(
BASE_MODEL,
device_map="auto",
torch_dtype=torch.bfloat16,
)
model = PeftModel.from_pretrained(base, ADAPTER_ID)
model.eval()
processor = AutoProcessor.from_pretrained(ADAPTER_ID)
SYSTEM_PROMPT = (
"Anda adalah sistem multimodal untuk ekstraksi dan transliterasi aksara Jawi cetak. "
"Tugas Anda terdiri dari dua langkah yang harus dilakukan secara berurutan:\\n"
"1. Ekstraksi: Baca gambar dan ekstrak teks aksara Jawi (huruf Arab) yang tertulis "
"pada gambar secara akurat, persis seperti yang tertulis.\\n"
"2. Transliterasi: Konversi teks Jawi yang telah diekstrak ke huruf Latin (Rumi) "
"sesuai pedoman Ejaan Jawi Yang Disempurnakan (PEJYD) oleh Dewan Bahasa dan Pustaka Malaysia.\\n\\n"
"ATURAN OUTPUT:\\n"
"- Keluarkan hasil dalam format berikut secara tepat:\\n"
" Jawi: [teks aksara Arab hasil ekstraksi]\\n"
" Rumi: [teks Latin hasil transliterasi]\\n"
"- Jangan menambahkan penjelasan, komentar, atau teks lain di luar format tersebut.\\n"
"- Transliterasi bersifat karakter ke karakter, bukan penerjemahan makna."
)
image = Image.open("contoh_jawi.jpg").convert("RGB")
messages = [
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": [
{"type": "image", "image": image},
{"type": "text", "text": "Ekstrak teks aksara Jawi dari gambar ini, kemudian transliterasikan ke huruf Latin (Rumi)."},
]},
]
text = processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
image_inputs, _ = process_vision_info(messages)
inputs = processor(text=[text], images=image_inputs, padding=True, return_tensors="pt").to("cuda")
with torch.no_grad():
generated = model.generate(**inputs, max_new_tokens=1024, do_sample=False)
trimmed = [out[len(inp):] for inp, out in zip(inputs.input_ids, generated)]
output_text = processor.batch_decode(trimmed, skip_special_tokens=True)[0].strip()
print(output_text)