Egyptian Document OCR (Gemma 4 E4B)

A LoRA adapter fine-tuned on top of unsloth/gemma-4-E4B-it-unsloth-bnb-4bit for full-page OCR of scanned Egyptian government documents (Official Gazette / الجريدة الرسمية — tax laws and Ministry of Finance decisions), in Arabic.

This is a companion model to mohamedwasef/egyptian-document-ocr (the Qwen3-VL-4B-Instruct version), fine-tuned on the exact same dataset and train/validation split, for a direct architecture comparison.

This is a LoRA adapter, not a merged standalone model - load it on top of the base model (see Usage below).

Example

Input image:

example page

Model output:

الجريدة الرسمية - العدد ٢٦ مكرر (أ) فى ٣٠ يونية سنة ٢٠١٤
٣
المادة (١٣/ الفقرة الأخيرة):
"يشترط لتطبيق الإعفاء المنصوص عليه فى البندين (٣)، (٤) ألا تزيد جملة ما يعفى للممول على (١٥/م) مصروفات الإيراد أو عشرة آلاف جنيهًا أيهما أقل، ولا يجوز تكرار إعفاء الاشتراكات والاقساط المنصوص عليها فى هذين البندين ضمن أى دخل آخر منصوص عليه فى المادة (٦) من هذا القانون".
المادة (١٧/ الفقرة الأولى):
"تحدد أرباح النشاط التجاري والصناعى على أساس الإيراد الناتج عن جميع العمليات التجارية والصناعية المحققة فى مصر، وكذلك الإيرادات المحققة من الخارج إذا كانت مصر مركزًا للنشاط التجاري والصناعى للممول، بما فى ذلك الأرباح التراكمية من باع أصول المنشأة المنصوص عليها فى البند (١)، (٢)، (٤) من المادة (٢٥) من هذا القانون، والأرباح المحققة من التعيينات التى يحصل عليها الممول نتيجة الهلاك أو الاستهلاك، على أى أصل من هذه الأصول والأوراق المالية، وكذلك أرباح التصفية التى تتحقق خلال الفترة الضريبية، وذلك كله بعد خصم جميع التكاليف واجبة الخصم".
المادة (٣٢):
"تفرض الضريبة على:
١- صافى إيرادات المهن الحرة وغيرهن من المهن غير التجارية التى يمارسها الممول بصفة مستقلة، ويكون العنصر الأساسى فيها العمل، إذا كانت ناتجة عن مزاولة المهنة أو النشاط فى مصر، وكذلك إيرادات المهن الحرة وغيرهن من المهن غير التجارية المحققة فى الخارج إذا كانت مصر مركزًا لنشاط المهنة.
٢- الدخل الذى يتلقاه أصحاب حقوق الملكية الفكرية من بيع أو استغلال حقوقهم فى مصر أو خارجها.
٣- أية إيرادات ناتجة عن أية مهنة أو نشاط غير منصوص عليه فى المادة (٦) من هذا القانون، سواء كانت هذه الإيرادات محققة فى مصر أو فى الخارج إذا كانت مصر مركزًا للمهنة أو النشاط".

Ground truth (for comparison):

الجريدة الرسمية - العدد ٢٦ مكرر (أ) فى ٣٠ يونية سنة ٢٠١٤
٣
المادة (١٣ / الفقرة الأخيرة):
"ويشترط لتطبيق الإعفاء المنصوص عليه فى البندين (٣)، (٤) ألا تزيد جملة ما يعفى للممول على (١٥٪) من صافى الإيراد أو عشرة آلاف جنيه أيهما أقل، ولا يجوز تكرار إعفاء الاشتراكات والأقساط المنصوص عليها فى هذين البندين ضمن أى دخل آخر منصوص عليه فى المادة (٦) من هذا القانون".
المادة (١٧ / الفقرة الأولى):
"تحدد أرباح النشاط التجارى والصناعى على أساس الإيراد الناتج عن جميع العمليات التجارية والصناعية المحققة فى مصر، وكذلك الإيرادات المحققة من الخارج إذا كانت مصر مركزاً للنشاط التجارى والصناعى للممول، بما فى ذلك الأرباح الناتجة عن بيع أصول المنشأة المنصوص عليها فى البنود (١)، (٢)، (٤) من المادة (٢٥) من هذا القانون، والأرباح المحققة من التعويضات التى يحصل عليها الممول نتيجة الهلاك أو الاستيلاء على أى أصل من هذه الأصول والأوراق المالية، وكذلك أرباح التصفية التى تتحقق خلال الفترة الضريبية، وذلك كله بعد خصم جميع التكاليف واجبة الخصم".
المادة (٣٢):
"تفرض الضريبة على:
١- صافى إيرادات المهن الحرة وغيرها من المهن غير التجارية التى يمارسها الممول بصفة مستقلة، ويكون العنصر الأساسى فيها هو العمل، إذا كانت ناتجة عن مزاولة المهنة أو النشاط فى مصر، وكذلك إيرادات المهن الحرة وغيرها من المهن غير التجارية المحققة فى الخارج إذا كانت مصر مركزاً لنشاطه المهنى.
٢- الدخل الذى يتلقاه أصحاب حقوق الملكية الفكرية من بيع أو استغلال حقوقهم فى مصر أو خارجها.
٣- أية إيرادات ناتجة عن أية مهنة أو نشاط غير منصوص عليه فى المادة (٦) من هذا القانون، سواء كانت هذه الإيرادات محققة فى مصر أو فى الخارج إذا كانت مصر مركزاً للمهنة أو النشاط".

This example scores CER 2.35% / WER 7.89% (the median result among non-table test pages).

Training data

Fine-tuned on mohamedwasef/egyptian-official-documents-ocr, 280 pages for training, 56 held out for validation (same split used for the Qwen3-VL companion model).

Training details

  • Base model: unsloth/gemma-4-E4B-it-unsloth-bnb-4bit
  • Method: LoRA (r=16, alpha=16), language-model layers only, vision encoder frozen
  • Trainable parameters: 36,700,160 (0.46% of 8.03B total)
  • Hardware: single NVIDIA T4 (Kaggle, free tier)
  • Precision: float32 - Gemma 4's architecture is not numerically stable in fp16, and this T4 has no native bf16 support
  • Epochs: 2, ~27 minutes total training time (an earlier 3-epoch run showed eval loss plateauing after epoch ~1.7, so this run stops before that point)
  • Learning rate: 1e-4 (lowered from an initial 2e-4 run to reduce large parameter updates that were producing near-miss substitutions on numbers and semantically-close-but-wrong words)

Evaluation

Evaluated on the dataset's official 30-page test set (never seen during training or validation), CER/WER computed after normalizing diacritics and unifying ى/ي; digits evaluated separately and exactly.

Subset Pages CER WER
All test pages 30 6.56% 15.85%
Pages without a table 28 2.89% 7.87%
Pages with a table 2 57.93% 127.60%

Digit-run error rate on non-table pages: 9.98%.

For reference, a Qwen3-VL-4B-Instruct LoRA fine-tuned on the identical data and split scores CER 2.33% / WER 8.09% on non-table pages - the two models perform within a comparable range of each other on plain text, with each ahead on a different metric (Qwen slightly better on CER, this model slightly better on WER and digit accuracy).

Known limitations

  • Dataset size. The training set is 280 pages from 19 documents. Several of the errors below (near-miss word substitutions, occasional digit errors) are consistent with a fine-tune that hasn't fully converged on a small dataset rather than a fundamental model weakness - a larger training set would likely narrow these further.
  • Tables. Only 18 of 336 training pages (5.4%) contained a table. CER on the 2 table pages in the test set rises to 57.9%, noticeably worse than this model's non-table performance and worse than the Qwen3-VL companion model's table performance too. Table output should not be trusted without manual review.
  • Occasional instruction-text leakage. On 1 of the 30 test pages, generation did not stop cleanly at the end of the transcription and continued by reproducing the training instruction text verbatim. This is a known generation/EOS-handling quirk in this specific Unsloth + Gemma 4 LoRA setup, not a content-understanding failure - the actual transcription up to that point was correct. Downstream use should detect and strip any trailing recurrence of the instruction text, or cap max_new_tokens more tightly for short pages.
  • Near-miss word/number substitutions. On some pages the model produces a semantically close but incorrect word (e.g. a synonym or a visually/ phonetically similar term) rather than the exact printed word, and occasionally a digit or digit-grouping error. As with tables, numeric values should be spot-checked rather than trusted blindly, same as recommended for the Qwen3-VL companion model.
  • Labels in the training dataset are LLM-generated with spot checks, not fully human-verified - see the dataset card for details.

Usage

import torch
from unsloth import FastVisionModel
from PIL import Image

BASE_MODEL = "unsloth/gemma-4-E4B-it-unsloth-bnb-4bit"
ADAPTER = "mohamedwasef/egyptian-document-ocr-gemma4"

model, processor = FastVisionModel.from_pretrained(
    ADAPTER,
    load_in_4bit=True,
    max_seq_length=2048,
    dtype=None,
)
FastVisionModel.for_inference(model)

image = Image.open("your_page.png").convert("RGB")

instruction = (
    "اقرأ هذه الصفحة وانسخ النص الموجود فيها بالكامل كما هو مكتوب، "
    "مع الحفاظ على ترتيب القراءة وتنسيق الأسطر قدر الإمكان، "
    "ودون إضافة أو حذف أو تلخيص أو تصحيح للنص. "
    "لا تستخدم أي وسوم HTML أو Markdown إلا داخل الجداول فقط كما وردت في النص الأصلي."
)

messages = [
    {"role": "user", "content": [
        {"type": "image", "image": image},
        {"type": "text", "text": instruction},
    ]}
]

input_text = processor.apply_chat_template(messages, add_generation_prompt=True)
inputs = processor(
    image, input_text, add_special_tokens=False, return_tensors="pt"
).to("cuda")

with torch.inference_mode():
    output_ids = model.generate(
        **inputs,
        max_new_tokens=1024,
        use_cache=True,
        temperature=0.0,
        do_sample=False,
    )

generated_ids = output_ids[:, inputs["input_ids"].shape[1]:]
prediction = processor.batch_decode(generated_ids, skip_special_tokens=True)[0].strip()

# strip a trailing instruction-text repeat, if the known EOS quirk occurs
INSTRUCTION_SNIPPET = "اقرأ هذه الصفحة وانسخ النص الموجود فيها"
leak_idx = prediction.find(INSTRUCTION_SNIPPET)
if leak_idx != -1:
    prediction = prediction[:leak_idx].rstrip()

print(prediction)

Note: this model requires float32 on GPUs without native bf16 support (Unsloth handles this automatically - a console message will say "Using float16 precision for gemma4 won't work! Using float32."). On a T4, peak VRAM usage during inference is comparable to the ~10GB seen during training.

License

Apache 2.0, matching the base model. The training data annotations are CC BY 4.0 (see the dataset card); source documents are official Egyptian government publications.

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for mohamedwasef/Docora-gemma

Adapter
(24)
this model