CoolFace
Modelpublic

a-mo-yehia/Qwen3-VL-8B-Contracts-OCR

sourceHugging Faceapache-2.0updated 3mo agoView on Hugging Face
1likes34downloads
Model Card

Egyptian Company Incorporation Contract Information Extraction

This model is a fine-tuned Qwen3-VL-8B model specialized for extracting structured information from scanned Egyptian company incorporation contracts written in Arabic.

Instead of performing traditional OCR only, the model directly understands document images and generates a structured JSON representation of the contract.


GGUF Version

This repository contains the Transformers (Safetensors) version of the model.

Looking for GGUF quantizations for llama.cpp, LM Studio, or other GGUF-compatible runtimes Check : 👉[Qwen3-VL-8B-Contracts-OCR-GGUF](https://huggingface.co/a-mo-yehia/Qwen3-VL-8B-Contracts-OCR-GGUF)

Features

  • —Extracts structured information directly from scanned contract pages
  • —Designed specifically for Egyptian company incorporation contracts
  • —Supports Arabic legal documents
  • —Produces valid JSON output
  • —Preserves Arabic text exactly as it appears in the document
  • —Extracts tables as Markdown inside the JSON response
  • —Handles multi-page contracts by processing two pages simultaneously

Model Details

Base Model

  • —Qwen3-VL-8B

Fine-tuning Framework

  • —Unsloth
  • —LoRA
  • —Transformers
  • —PyTorch

Task

Vision-Language Information Extraction


Training Data

The model was fine-tuned on a private dataset consisting of Egyptian company incorporation contracts.

Dataset statistics:

  • —32 original contracts
  • —Documents converted from PDF into page images
  • —Sliding-window chunk generation
  • —Each training sample consists of:
Image(page_i)
Image(page_i+1)
Target JSON

Example:

Page1 + Page2 -> JSON
Page2 + Page3 -> JSON
Page3 + Page4 -> JSON
...

The original dataset produced approximately 480 training chunks.

Extensive image augmentation was applied including:

  • —Rotation
  • —Brightness variation
  • —Contrast variation
  • —Gaussian noise
  • —JPEG compression simulation

Final dataset size:

  • —approximately 1900 image pairs

Training Configuration

ParameterValue
LoRA Rank16
LoRA Alpha32
Dropout0
Epochs4
Learning Rate2e-4
OptimizerAdamW 8-bit
SchedulerCosine
Warmup Ratio0.05
Effective Batch Size8
Max Sequence Length4096

The model was trained using Unsloth with gradient checkpointing for efficient memory usage.


Supported Input

The model accepts document images such as:

  • —PNG
  • —JPEG
  • —PDF

PDF documents should first be converted into images.

Inference is designed to receive two consecutive pages at a time.


Output Format

The model generates structured JSON.

Characteristics:

  • —Arabic text is copied exactly as it appears.
  • —No spelling correction.
  • —Missing fields are returned as empty strings.
  • —Tables are preserved as Markdown inside the JSON.
  • —Articles spanning multiple pages are marked as partial when applicable.

Example Output

json
{
  "company_name": "",
  "company_address": "",
  "company_type": "",
  "law_reference": {
    "law_number": "",
    "law_year": ""
  },
  "company_capital": "",
  "commercial_register_number": "",
  "approval_date": "",
  "real_estate_registry_minutes_number": "",
  "company_duration": "",
  "company_activity": "",
  "articles": [
    {
      "id": "",
      "value": ""
    }
    ,...
  ]
}

Usage

python
import gc
import json
import torch
from unsloth import FastVisionModel
from qwen_vl_utils import process_vision_info
from PIL import Image

model, tokenizer = FastVisionModel.from_pretrained(
    "a-mo-yehia/contract_OCR_model",
    load_in_4bit=False,
)

FastVisionModel.for_inference(model)

img1 = Image.open("page1.jpg").convert("RGB")
img2 = Image.open("page2.jpg").convert("RGB")

SYSTEM_PROMPT = """\
أنت نظام استخراج بيانات من عقود تأسيس شركات مصرية مسحوبة ضوئياً.

الوثيقة أمامك هي صفحتان من عقد تأسيس شركة مصرية مكتوبة بالعربية.

─── بنية المستند ───
- يبدأ العقد بديباجة (تمهيد) تذكر القانون المنظِّم للشركة.
- تأتي بعدها مواد مرقّمة (مادة ١، مادة ٢، ...) تحتوي على كل التفاصيل.
- اسم الشركة ونوعها: عادةً في المواد الأولى (١–٣).
- غرض الشركة ونشاطها: في مادة الغرض (المادة ٣ أو ٤ غالباً).
- العنوان: في المادة التي تذكر "المركز الرئيسي".
- رأس المال وتوزيعه بين الشركاء: في مادة واحدة تحتوي عادةً على جدول.
- مدة الشركة: في المادة التي تذكر السنوات أو الأجل.
- رقم القانون: في التمهيد أو أوائل المواد، صيغته "القانون رقم XXX لسنة XXXX".

─── قواعد الاستخراج ───
- انسخ كل نص عربي حرفياً كما يظهر في الصورة — لا تصحّح ولا تُعيد صياغة.
- إذا كانت مادة ممتدة وانتهت الصفحة قبل اكتمالها: "partial": true.
- إذا لم يوجد حقل في الصفحتين: اتركه سلسلة فارغة "".
- إذا لم تكن هناك مواد في الصفحتين: أرجع "articles": [].
- إذا احتوت الوثيقة على أي جداول، **يجب** استخراجها كاملة وتنسيقها حصرياً بصيغة Markdown (MD).
- يمنع منعاً باتاً تجاهل أي بيانات مجدولة أو دمجها كنص عادي.
- أرجع JSON صحيح فقط — بدون markdown، بدون شرح، بدون مفاتيح إضافية.\
"""


def run_inference(img1: Image.Image, img2: Image.Image, file_id: str, page_start: int) -> str:
    gc.collect()
    torch.cuda.empty_cache()

    messages = [
        {"role": "system", "content": SYSTEM_PROMPT},
        {"role": "user", "content": [
            {"type": "image", "image": img1},
            {"type": "image", "image": img2},
            {"type": "text",  "text": (
                f"استخرج جميع البيانات من الصفحتين "
                f"من عقد {file_id} وأرجعها كـ JSON كامل."
            )},
        ]},
    ]

    input_text      = tokenizer.apply_chat_template(messages, add_generation_prompt=True)
    image_inputs, _ = process_vision_info(messages)

    inputs = tokenizer(
        image_inputs,
        input_text,
        add_special_tokens=False,
        return_tensors="pt",
    ).to("cuda")

    with torch.no_grad():
        out = model.generate(
            **inputs,
            max_new_tokens=4096,
            use_cache=True,
            do_sample=False,
            repetition_penalty=1.1,
        )

    generated = tokenizer.decode(
        out[0, inputs["input_ids"].shape[-1]:],
        skip_special_tokens=True,
    ).strip()

    return generated

raw_output = run_inference(img1, img2, FILE_ID, PAGE_START)

print("\n=== Raw Output ===")
print(raw_output)

Available Formats

This repository contains:

Full Precision

  • —FP16 merged Transformers model

GGUF

  • —F16
  • —Q8_0
  • —Q4KM

These formats allow inference using:

  • —Transformers
  • —Unsloth
  • —llama.cpp
  • —LM Studio
  • —Ollama (after creating a Modelfile)

Intended Use

The model is intended for:

  • —Company incorporation contract digitization
  • —Legal document information extraction
  • —Document automation
  • —Arabic document understanding
  • —OCR-assisted document processing

Limitations

This model was fine-tuned specifically for Egyptian company incorporation contracts.

Performance on other document types such as:

  • —invoices
  • —passports
  • —handwritten forms
  • —receipts
  • —newspapers

has not been evaluated.


Acknowledgements

This project is built upon:

  • —Qwen3-VL
  • —Unsloth
  • —Hugging Face Transformers
  • —PEFT

Special thanks to the authors of these open-source projects.


Citation

If you use this model in your research or application, please cite this repository.