indic-ocr-mlx-8bit / README.md
hari31416's picture
docs: clarify PyTorch MPS layout and MLX recognition backends
93af357 verified
|
Raw History Blame Contribute Delete
8.06 kB
metadata
base_model: bodhan-ai/indic-ocr
language:
  - en
  - as
  - bn
  - brx
  - doi
  - gu
  - hi
  - kn
  - ks
  - kok
  - mai
  - ml
  - mni
  - mr
  - ne
  - or
  - pa
  - sa
  - sat
  - sd
  - ta
  - te
  - ur
tags:
  - mlx
  - mlx-vlm
  - ocr
  - document-ai
  - vision
  - 8-bit
  - quantized
  - qwen3.5
  - sarvam
pipeline_tag: image-to-text
license: other
license_name: indic-open-model-license-v1.0
license_link: >-
  https://github.com/Bodhan-AI/bodhan-model-info/blob/main/licenses/indic-open-model-license/v1/Indic_Open_Model_License.md
extra_gated_prompt: >-
  Please provide your details and agree to the
  [LICENSE](https://github.com/Bodhan-AI/bodhan-model-info/blob/main/licenses/indic-open-model-license/v1/Indic_Open_Model_License.md)
  [[simpler
  version](https://github.com/Bodhan-AI/bodhan-model-info/blob/main/licenses/indic-open-model-license/v1/Indic_Open_Model_License_Deed.md)]
  to request access.
extra_gated_fields:
  Company / Organization: text
  Country: country
  Intended Use Case:
    type: select
    options:
      - Research
      - Commercial
      - Education
      - label: Other
        value: other
  I agree to the license terms: checkbox

IndicOCR MLX 8-bit (IndicBlockOCR)

This repository provides an optimized 8-bit quantized MLX export of IndicBlockOCR (Stage 2 of bodhan-ai/indic-ocr), delivering near-full-precision accuracy with a 20x latency speedup on Apple Silicon Metal GPUs (M1/M2/M3/M4).

The recognizer architecture is based on Qwen3.5-0.8B with a 151k-token Sarvam-30B vocabulary covering 22 official Indic scripts, English, numbers, and mathematical notation.

Precision Variants

Empirical Parity and Accuracy Benchmarks

Evaluated against the PyTorch reference baseline on 50 real-world Indic document crops from ai4bharat/indicdlp.

Stage 2 Recognition Parity (8-bit vs PyTorch Baseline)

Metric PyTorch Baseline (CPU) IndicOCR MLX 8-bit (Metal GPU) Parity Delta / Speedup
Character Error Rate (CER) Reference (0.0) 0.0156 (1.56%) Near-lossless accuracy
Word Error Rate (WER) Reference (0.0) 0.0343 (3.43%) Near-lossless readability
Exact Match Rate 100.0% 74.0% See analysis below
Crops with CER <= 5% 100.0% 94.0% High fidelity
Crops with CER <= 10% 100.0% 96.0% Production-ready
Crops with CER <= 20% 100.0% 98.0% Production-ready
Latency per Crop 9,768.58 ms 486.25 ms 20.09x Speedup
Throughput 15.3 chars/sec 307.5 chars/sec 20.1x Throughput
Memory Footprint ~1.7 GB ~1.0 GB 41.2% Reduction

Stage 1 Layout Detection (PP-DocLayoutV3 on PyTorch MPS)

Stage 1 runs with PyTorch on Apple's MPS backend. The recognizer uses MLX, but the layout detector does not: this project has no MLX PP-DocLayoutV3 runtime, and converting the layout tensors alone does not improve inference.

Metric Score Note
Mean IoU 0.9983 Near-perfect bounding box alignment
Label Match Rate 100.0% 37 document class categories identical
Reading Order Match Rate 100.0% Pairwise reading order identical
Detection Latency 156.61 ms 3.85x Speedup vs PyTorch CPU (603 ms)

Understanding Exact Match vs Character Error Rate

While the Exact Match rate is 74.0%, the mean Character Error Rate is only 1.56% and 94.0% of crops have less than 5% CER. Exact Match is an all-or-nothing metric: on long paragraph crops (e.g. 600+ characters), a single whitespace difference or character substitution drops the entire crop score to 0.

Autoregressive vision-language decoding on Apple Silicon Metal GPU uses different matrix multiplication tiling, reduction order, and floating-point accumulation compared to NVIDIA CUDA kernels, causing tiny logit variations (~1e-4) that can flip argmax selections at near-tie probability boundaries.

Quickstart

1. Installation

pip install -r requirements.txt

2. Interactive Gradio Web Studio

Launch the visual interface with interactive bounding box hover tooltips, reading-ordered Markdown preview, and JSON inspection:

python app.py

Then open http://127.0.0.1:7860 in your browser.

3. End-to-End Python Pipeline

Run the full two-stage document pipeline (Stage 1 Layout Detection + Stage 2 Text Transcription):

from pipeline import IndicOCRPipeline

# Initialize end-to-end pipeline (auto-loads Stage 1 and Stage 2 on Apple Silicon)
ocr = IndicOCRPipeline()

# Process full document page
result = ocr.process("path/to/document.png")

# Reading-ordered Markdown
print(result.markdown)

# Access individual detected blocks
for block in result.blocks:
    print(f"#{block.order} [{block.label}] {block.bbox_xyxy}: {block.text}")

4. Single Crop CLI Transcription

Quickly transcribe a specific cropped text line or region:

python transcribe.py --image path/to/crop.png

5. Direct mlx_vlm Usage

Load the recognizer directly using standard MLX VLM:

from mlx_vlm import generate, load
from PIL import Image

model, processor = load("hari31416/indic-ocr-mlx-8bit")
prompt = processor.apply_chat_template(
    [
        {
            "role": "user",
            "content": [
                {"type": "image"},
                {"type": "text", "text": "Transcribe the text in this image."},
            ],
        }
    ],
    add_generation_prompt=True,
    tokenize=False,
)

image = Image.open("crop.png").convert("RGB")
output = generate(model, processor, prompt=prompt, image=[image], max_tokens=256)
print(output.text.strip())

Repository Structure

β”œβ”€β”€ README.md                      # Model card and parity benchmarks
β”œβ”€β”€ app.py                         # Interactive Gradio web application
β”œβ”€β”€ pipeline.py                    # Importable end-to-end Python pipeline
β”œβ”€β”€ transcribe.py                  # Single-crop CLI transcription script
β”œβ”€β”€ config.json                    # Recognizer model configuration
β”œβ”€β”€ generation_config.json         # Generation hyperparameter defaults
β”œβ”€β”€ model.safetensors              # 8-bit recognizer weights (~1.0 GB)
β”œβ”€β”€ model.safetensors.index.json   # Weight index mapping
β”œβ”€β”€ processor_config.json          # Vision & image processor configuration
β”œβ”€β”€ tokenizer.json                 # Sarvam-30B tokenizer
β”œβ”€β”€ tokenizer_config.json
β”œβ”€β”€ chat_template.jinja            # Multimodal chat template
β”œβ”€β”€ requirements.txt               # Minimal dependencies
β”œβ”€β”€ .gitattributes                 # Git LFS tracking configuration
└── layout/                        # Legacy experimental tensor export, not used at runtime
    β”œβ”€β”€ config.json
    └── model.safetensors          # PP-DocLayoutV3 tensors; requires an MLX model implementation

License and Citations

This model is distributed under the Indic Open Model License v1.0. See the Indic Open Model License and the Plain-Language License Deed for complete terms.

If using this export, please cite the original Bodhan AI project:

@misc{bodhan2026indicocr,
  author = {Bodhan AI},
  title = {IndicOCR: High-Performance Document OCR for Indic Languages},
  year = {2026},
  url = {https://huggingface.co/bodhan-ai/indic-ocr}
}