RMatar/arabic-pdf-ocr
0
1import io2import traceback3import numpy as np4import imageio.v3 as iio5from fastapi import FastAPI, File, UploadFile6from fastapi.responses import JSONResponse7from PIL import Image8import torch9from transformers import AutoProcessor, Qwen2VLForConditionalGeneration10from qwen_vl_utils import process_vision_info11 12app = FastAPI()13 14MODEL_ID = "AbdoTarek/Baseer-OCR-V1.0"15 16print("جاري تحميل نموذج بصير العربي في الذاكرة... برجاء الانتظار")17processor = AutoProcessor.from_pretrained(MODEL_ID, trust_remote_code=True)18model = Qwen2VLForConditionalGeneration.from_pretrained(19 MODEL_ID, 20 torch_dtype=torch.float32, 21 low_cpu_mem_usage=True,22 trust_remote_code=True23)24print("تم تحميل النموذج بنجاح وهو جاهز للعمل مجاناً للأبد!")25 26@app.get("/")27def home():28 return {"status": "السيرفر المجاني اللامحدود يعمل بكفاءة وأمان!"}29 30@app.post("/extract")31async def extract_text(file: UploadFile = File(...)):32 try:33 image_bytes = await file.read()34 print(f"تم استقبال ملف باسم: {file.filename} بحجم: {len(image_bytes)} بايت")35 36 if len(image_bytes) == 0:37 return JSONResponse(content={"success": False, "error": "الملف فارغ"}, status_code=400)38 39 # تحويل البايتات إلى صورة40 try:41 img_array = iio.imread(io.BytesIO(image_bytes))42 image = Image.fromarray(img_array).convert("RGB")43 except:44 image = Image.open(io.BytesIO(image_bytes)).convert("RGB")45 46 # ⚠️ التصحيح هنا: هذه الأسطر يجب أن تكون خارج الـ except47 messages = [48 {49 "role": "user",50 "content": [51 {"type": "image", "image": image},52 {"type": "text", "text": "Extract ALL visible text from the document image."},53 ],54 }55 ]56 57 text = processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)58 image_inputs, video_inputs = process_vision_info(messages)59 60 inputs = processor(61 text=[text],62 images=image_inputs,63 videos=video_inputs,64 padding=True,65 return_tensors="pt",66 )67 68 # استخدام توليد سريع لتقليل وقت الانتظار69 with torch.no_grad():70 generated_ids = model.generate(71 **inputs, 72 max_new_tokens=200, 73 do_sample=False,74 num_beams=175 )76 77 generated_ids_trimmed = [out_ids[len(in_ids):] for in_ids, out_ids in zip(inputs.input_ids, generated_ids)]78 output_text = processor.batch_decode(generated_ids_trimmed, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0]79 80 return JSONResponse(content={"success": True, "text": output_text})81 82 except Exception as e:83 traceback.print_exc()84 return JSONResponse(content={"success": False, "error": str(e)}, status_code=500)