{
  "@context": "https://schema.org",
  "@id": "https://aggr.aymericbeaumet.com/items/huggingface-co/2025-10-21-supercharge-your-ocr-pipelines-with-open-models/#webpage",
  "@type": [
    "WebPage",
    "ArchiveComponent"
  ],
  "articleBody": "> We have added [Chandra](https://huggingface.co/datalab-to/chandra) and [OlmOCR-2](https://huggingface.co/allenai/olmOCR-2-7B-1025) to this blog, as well as OlmOCR Scores of the models 🫡\n\nTL;DR: The rise of powerful vision-language models has transformed document AI. Each model comes with unique strengths, making it tricky to choose the right one. Open-weight models offer better cost efficiency and privacy. To help you get started with them, we’ve put together this guide.\n\nIn this guide, you’ll learn:\n\n- The landscape of current models and their capabilities\n- When to fine-tune models vs. use models out-of-the-box\n- Key factors to consider when selecting a model for your use case\n- How to move beyond OCR with multimodal retrieval and document QA\n\nBy the end, you’ll know how to choose the right OCR model, start building with it, and gain deeper insights into document AI. Let’s go!\n\n## Table-of-Contents\n\n- [Supercharge your OCR Pipelines with Open Models](https://huggingface.co/blog/ocr-open-models#supercharge-your-ocr-pipelines-with-open-models)\n  - [Brief Introduction to Modern OCR](https://huggingface.co/blog/ocr-open-models#brief-introduction-to-modern-ocr)\n    - [Model Capabilities](https://huggingface.co/blog/ocr-open-models#model-capabilities)\n      - [Transcription](https://huggingface.co/blog/ocr-open-models#transcription)\n      - [Handling complex components in documents](https://huggingface.co/blog/ocr-open-models#handling-complex-components-in-documents)\n      - [Output formats](https://huggingface.co/blog/ocr-open-models#output-formats)\n      - [Locality Awareness in OCR](https://huggingface.co/blog/ocr-open-models#locality-awareness-in-ocr)\n      - [Model Prompting](https://huggingface.co/blog/ocr-open-models#model-prompting)\n  - [Cutting-edge Open OCR Models](https://huggingface.co/blog/ocr-open-models#cutting-edge-open-ocr-models)\n    - [Comparing Latest Models](https://huggingface.co/blog/ocr-open-models#comparing-latest-models)\n    - [Evaluating Models](https://huggingface.co/blog/ocr-open-models#evaluating-models)\n      - [Benchmarks](https://huggingface.co/blog/ocr-open-models#benchmarks)\n      - [Cost-efficiency](https://huggingface.co/blog/ocr-open-models#cost-efficiency)\n      - [Open OCR Datasets](https://huggingface.co/blog/ocr-open-models#open-ocr-datasets)\n  - [Tools to Run Models](https://huggingface.co/blog/ocr-open-models#tools-to-run-models)\n    - [Locally](https://huggingface.co/blog/ocr-open-models#locally)\n    - [Remotely](https://huggingface.co/blog/ocr-open-models#remotely)\n  - [Going Beyond OCR](https://huggingface.co/blog/ocr-open-models#going-beyond-ocr)\n    - [Visual Document Retrievers](https://huggingface.co/blog/ocr-open-models#visual-document-retrievers)\n    - [Using Vision Language Models for Document Question Answering](https://huggingface.co/blog/ocr-open-models#using-vision-language-models-for-document-question-answering)\n  - [Wrapping up](https://huggingface.co/blog/ocr-open-models#wrapping-up)\n\n## Brief Introduction to Modern OCR\n\nOptical Character Recognition (OCR) is one of the earliest and longest running challenges in computer vision. Many of AI’s first practical applications focused on turning printed text into digital form.\n\nWith the surge of [vision-language models](https://huggingface.co/blog/vlms) (VLMs), OCR has advanced significantly. Recently, many OCR models have been developed by fine-tuning existing VLMs. But today’s capabilities extend far beyond OCR: you can retrieve documents by query or answer questions about them directly. Thanks to stronger vision features, these models can also handle low-quality scans, interpret complex elements like tables, charts, and images, and fuse text with visuals to answer open-ended questions across documents.\n\n### Model Capabilities\n\n#### Transcription\n\nRecent models transcribe texts into a machine-readable format.\\\nThe input can include:\n\n- Handwritten text\n- Various scripts like Latin, Arabic, and Japanese characters\n- Mathematical expressions\n- Chemical formulas\n- Image/Layout/Page number tags\n\nOCR models convert them into machine-readable text that comes in many different formats like HTML, Markdown and more.\n\n#### Handling complex components in documents\n\nOn top of text, some models can also recognize:\n\n- Images\n- Charts\n- Tables\n\nSome models know where images are inside the document, extract their coordinates, and insert them appropriately between texts. Other models generate captions for images and insert them where they appear. This is especially useful if you are feeding the machine-readable output into an LLM. Example models are [OlmOCR by AllenAI](https://huggingface.co/allenai/olmOCR-7B-0825), or [PaddleOCR-VL by PaddlePaddle](https://huggingface.co/PaddlePaddle/PaddleOCR-VL).\n\nModels use different machine-readable output formats, such as **DocTags**, **HTML** or **Markdown** (explained in the next section *Output Formats*). The way a model handles tables and charts often depends on the output format they are using. Some models treat charts like images: they are kept as is. Other models convert charts into markdown tables or JSON, e.g., a bar chart can be converted as follows.\n\n[![Chart Rendering](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/ocr/chart-rendering.png)](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/ocr/chart-rendering.png)\n\nSimilarly for tables, cells are converted into a machine-readable format while retaining context from headings and columns.\n\n[![Table Rendering](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/ocr/table-rendering.png)](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/ocr/table-rendering.png)\n\n#### Output formats\n\nDifferent OCR models have different output formats. Briefly, here are the common output formats used by modern models.\\\n**DocTag:** DocTag is an XML-like format for documents that expresses location, text format, component-level information, and more. Below is an illustration of a paper parsed into DocTags. This format is employed by the open Docling models.\n\n[![DocTags](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/ocr/doctags_v2.png)](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/ocr/doctags_v2.png)\n\n- **HTML:** HTML is one of the most popular output formats used for document parsing as it properly encodes structure and hierarchical information.\n- **Markdown:** Markdown is the most human-readable format. It’s simpler than HTML but not as expressive. For example, it can’t represent split-column tables.\n- **JSON:** JSON is not a format that models use for the entire output, but it can be used to represent information in tables or charts.\n\nThe right model depends on how you plan to use its outputs:\n\n- **Digital reconstruction**: To reconstruct documents digitally, choose a model with a layout-preserving format (e.g., DocTags or HTML).\n- **LLM input or Q&A**: If the use case involves passing outputs to LLM, pick a model that outputs Markdown and image captions, since they’re closer to natural language.\n- **Programmatic use**: If you want to pass your outputs to a program (like data analysis), opt for a model that generates structured outputs like JSON.\n\n#### Locality Awareness\n\nDocuments can have complex structures, like multi-column text blocks and floating figures. Older OCR models handled these documents by detecting words and then the layout of pages manually in post-processing to have the text rendered in reading order, which is brittle. Modern OCR models, on the other hand, incorporate layout metadata to help preserve reading order and accuracy. This metadata is called “anchor”, it can come in bounding boxes. This process is also called as “grounding/anchoring” because it helps with reducing hallucination.\n\n#### Model Prompting\n\nOCR models can either take in images and an optional text prompt, this depends on the model architecture and the pre-training setup.\\\nSome OCR models support prompt-based task switching, e.g. [granite-docling](https://huggingface.co/ibm-granite/granite-docling-258M) can parse an entire page with the prompt “Convert this page to Docling” while it can also take prompts like “Convert this formula to LaTeX” along with a page full of formulas.\\\nOther models, however, are trained only for parsing entire pages, and they are conditioned to do this through a system prompt.\\\nFor instance, [OlmOCR by AllenAI](https://huggingface.co/collections/allenai/olmocr-67af8630b0062a25bf1b54a1) takes a long conditioning prompt. Like many others, OlmOCR is technically an OCR fine-tuned version of a VLM (Qwen2.5VL in this case), so you can prompt for other tasks, but its performance will not be on par with the OCR capabilities.\n\n## Cutting-edge Open OCR Models\n\nWe’ve seen an incredible wave of new models this past year. Because so much work is happening in the open, these players build on and benefit from each other’s work. A great example is AllenAI’s release of OlmOCR, which not only released a model but also the dataset used to train it. With these, others can build upon them in new directions. The field is incredibly active, but it’s not always obvious which model to use.\n\n### Comparing Latest Models\n\nTo make things a bit easier, we’re putting together a non-exhaustive comparison of some of our current favorite models. All of the models below are layout-aware and can parse tables, charts, and math equations. The full list of languages each model supports are detailed in their model cards, so make sure to check them if you’re interested. All models below have open-source license except for Chandra having OpenRAIL license and Nanonets license being unclear. The average scores are taken from model cards of Chandra, OlmOCR, evaluated on OlmOCR Benchmark, which is English-only. Many of the models in this collection have been fine-tuned from Qwen2.5-VL or Qwen3-VL, so we also provide Qwen3-VL model below as well.\n\n| Model Name                                                                                              | Output formats                                                     | Features                                                                                                                                                             | Model Size | Multilingual?                                        | Average Score on OlmOCR Benchmark |\n| ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | ---------------------------------------------------- | --------------------------------- |\n| [Nanonets-OCR2-3B](https://huggingface.co/collections/nanonets/nanonets-ocr2-68ed207f17ee6c31d226319e) | structured Markdown with semantic tagging (plus HTML tables, etc.) | Captions images in the documents Signature & watermark extraction Handles checkboxes, flowcharts, and handwriting                                                    | 4B         | ✅Supports English, Chinese, French, Arabic and more. | N/A                               |\n| [PaddleOCR-VL](https://huggingface.co/collections/PaddlePaddle/paddleocr-vl-68f0db852483c7af0bc86849)  | Markdown, JSON, HTML tables and charts                             | Handles handwriting, old documents Allows prompting Converts tables & charts to HTML Extracts and inserts images directly                                            | 0.9B       | ✅Supports 109 languages                              | N/A                               |\n| [dots.ocr](https://huggingface.co/rednote-hilab/dots.ocr)                                              | Markdown, JSON                                                     | Grounding Extracts and inserts images Handles handwriting                                                                                                            | 3B         | ✅Multilingual with language info not available       | 79.1 ± 1.0                        |\n| [OlmOCR-2](https://huggingface.co/allenai/olmOCR-2-7B-1025)                                            | Markdown, HTML, LaTeX                                              | Grounding Optimized for large-scale batch processing                                                                                                                 | 8B         | ❎English-only                                        | 82.3 ± 1.1                        |\n| [Granite-Docling-258M](https://huggingface.co/ibm-granite/granite-docling-258M)                        | DocTags                                                            | Prompt-based task switching Ability to prompt element locations with location tokens Rich output                                                                     | 258M       | ✅Supports English, Japanese, Arabic and Chinese.     | N/A                               |\n| [DeepSeek-OCR](https://huggingface.co/deepseek-ai/DeepSeek-OCR)                                        | Markdown, HTML                                                     | Supports general visual understanding Can parse and re-render all charts, tables, and more into HTML Handles handwriting Memory-efficient, solves text through image | 3B         | ✅Supports nearly 100 languages                       | 75.4 ± 1.0                        |\n| [Chandra](https://huggingface.co/datalab-to/chandra)                                                   | Markdown, HTML, JSON                                               | Grounding Extracts and inserts images as is                                                                                                                          | 9B         | ✅Supports 40+ languages                              | 83.1 ± 0.9                        |\n| [Qwen3-VL](https://huggingface.co/collections/Qwen/qwen3-vl)                                           | Vision Language Model can output in all formats                    | Can recognize ancient text Handles handwriting Extracts and inserts images as is                                                                                     | 9B         | ✅Supports 32 languages                               | N/A                               |\n\nWhile Qwen3-VL itself is a powerful and versatile vision-language model post-trained for document understanding and other tasks, it isn’t optimized for a single, universal OCR prompt. In contrast, the other models were fine-tuned using one or a few fixed prompts specifically designed for OCR tasks. So to use Qwen3-VL, we recommend experimenting with prompts.\n\nHere’s a [small demo](https://prithivMLmods-Multimodal-OCR3.hf.space) for you to try some of the latest models and compare their outputs.\n\n### Evaluating Models\n\n#### Benchmarks\n\nThere’s no single best model, as every problem has different needs. Should tables be rendered in Markdown or HTML? Which elements should we extract? How should we quantify text accuracy and error rates? 👀\\\nWhile there are many evaluation datasets and tools, many don’t answer these questions. So we suggest using the following benchmarks:\n\n1. [**OmniDocBenchmark**](https://huggingface.co/datasets/opendatalab/OmniDocBench)**:** This widely used benchmark stands out for its diverse document types: books, magazines, and textbooks. Its evaluation criteria are well designed, accepting tables in both HTML and Markdown formats. A novel matching algorithm evaluates the reading order, and formulas are normalized before evaluation. Most metrics rely on edit distance or tree edit distance (tables). Notably, the annotations used for evaluation are not solely human-generated but are acquired through SoTA VLMs or conventional OCR methods.\n2. [**OlmOCR-Bench**](https://huggingface.co/datasets/allenai/olmOCR-bench): OlmOCR-Bench takes a different approach: they treat the evaluation as a set of unit tests. For example, table evaluation is done by checking the relation between selected cells of a given table. They use PDFs from public sources, and annotations are done using a wide range of closed-source VLMs. This benchmark is quite successful to evaluate on the English language.\n3. [**CC-OCR (Multilingual)**:](https://huggingface.co/datasets/wulipc/CC-OCR) Compared to the previous benchmarks, CC-OCR is less preferred when picking models, due to lower document quality and diversity. However, it’s the only benchmark that contains evaluation beyond English and Chinese! While the evaluation is far from perfect (images are photos with few words), it’s still the best you can do for multilingual evaluation.\n\nWhen testing different OCR models, we've found that the performance across different document types, languages, etc., varies a lot. Your domain may not be well represented in existing benchmarks! To make effective use of this new generation of VLM-based OCR models we suggest aiming to collect a dataset of representative examples of your task domain and testing a few different models to compare their performance.\n\n#### Cost-efficiency\n\nMost OCR models are small, having between 3B and 7B parameters; you can even find models with fewer than 1B parameters, like PaddleOCR-VL. However, the cost also depends on the availability of optimized implementations for specialized inference frameworks. For example, OlmOCR-2 comes with vLLM and SGLang implementations, and the cost per million pages is 178 dollars (assuming on H100 for $2.69/hour). DeepSeek-OCR can process 200k+ pages per day on a single A100 with 40GB VRAM. With napkin math, we see that the cost per million pages is more or less similar to OlmOCR (although it depends on your A100 provider). If your use case remains unaffected, you can also opt for quantized versions of the models. The cost of running open-source models heavily depends on the hourly cost of the instance and the optimizations the model includes, but it’s guaranteed to be cheaper than many closed-source models out there on a larger scale.\n\n#### Open OCR Datasets\n\nWhile the past year has seen a surge in open OCR models, this hasn't been matched by as many open training and evaluation datasets. An exception is AllenAI's [olmOCR-mix-0225](https://huggingface.co/datasets/allenai/olmOCR-mix-0225), which has been used to train at least [72 models on the Hub](https://huggingface.co/models?dataset=dataset:allenai/olmOCR-mix-0225) – likely more, since not all models document their training data.\n\nSharing more datasets could unlock even greater advances in open OCR models. There are several promising approaches for creating these datasets:\n\n- **Synthetic data generation** (e.g., [isl\\_synthetic\\_ocr](https://huggingface.co/datasets/Sigurdur/isl_synthetic_ocr))\n- **VLM-generated transcriptions** filtered manually or through heuristics\n- **Using existing OCR models** to generate training data for new, potentially more efficient models in specific domains\n- **Leveraging existing corrected datasets** like the [Medical History of British India Dataset](https://huggingface.co/NationalLibraryOfScotland), which contains extensively human-corrected OCR for historic documents\n\nIt's worth noting that many such datasets exist but remain unused. Making them more readily available as 'training-ready' datasets carries a considerable potential for the open-source community.\n\n## Tools to Run Models\n\nWe have received many questions about getting started with OCR models, so here are a few ways you can use local inference tools and host remotely with Hugging Face.\n\n### Locally\n\nMost cutting-edge models come with vLLM support and transformers implementation. You can get more info about how to serve each from the models’ own cards. For convenience, we show how to infer locally using vLLM here. The code below can differ from model to model, but for most models it looks like the following.\n\n```shell\nvllm serve nanonets/Nanonets-OCR2-3B\n```\n\nAnd then you can query as follows using e.g. OpenAI client.\n\n```py\nfrom openai import OpenAI\nimport base64\n\nclient = OpenAI(base_url=\"http://localhost:8000/v1\")\n\nmodel = \"nanonets/Nanonets-OCR2-3B\"\n\ndef encode_image(image_path):\n    with open(image_path, \"rb\") as image_file:\n        return base64.b64encode(image_file.read()).decode(\"utf-8\")\n\ndef infer(img_base64):\n    response = client.chat.completions.create(\n        model=model,\n        messages=[\n            {\n                \"role\": \"user\",\n                \"content\": [\n                    {\n                        \"type\": \"image_url\",\n                        \"image_url\": {\"url\": f\"data:image/png;base64,{img_base64}\"},\n                    },\n                    {\n                        \"type\": \"text\",\n                        \"text\": \"Extract the text from the above document as if you were reading it naturally.\",\n                    },\n                ],\n            }\n        ],\n        temperature=0.0,\n        max_tokens=15000\n    )\n    return response.choices[0].message.content\n\nimg_base64 = encode_image(your_img_path)\nprint(infer(img_base64))\n```\n\n**Transformers**\n\nTransformers provides standard model definitions for easy inference and fine-tuning. Models available in transformers come with either official transformers implementation (model definitions within the library) or “remote code” implementations. Latter is defined by the model owners to enable easy loading of models into transformers interface, so you don’t have to go through the model implementation. Below is an example loading Nanonets model using transformers implementation.\n\n```py\n# make sure to install flash-attn and transformers\nfrom transformers import AutoProcessor, AutoModelForImageTextToText\n\nmodel = AutoModelForImageTextToText.from_pretrained(\n    \"nanonets/Nanonets-OCR2-3B\", \n    torch_dtype=\"auto\", \n    device_map=\"auto\", \n    attn_implementation=\"flash_attention_2\"\n)\nmodel.eval()\nprocessor = AutoProcessor.from_pretrained(\"nanonets/Nanonets-OCR2-3B\")\n\ndef infer(image_url, model, processor, max_new_tokens=4096):\n    prompt = \"\"\"Extract the text from the above document as if you were reading it naturally. Return the tables in html format. Return the equations in LaTeX representation. If there is an image in the document and image caption is not present, add a small description of the image inside the <img></img> tag; otherwise, add the image caption inside <img></img>. Watermarks should be wrapped in brackets. Ex: <watermark>OFFICIAL COPY</watermark>. Page numbers should be wrapped in brackets. Ex: <page_number>14</page_number> or <page_number>9/22</page_number>. Prefer using ☐ and ☑ for check boxes.\"\"\"\n    image = Image.open(image_path)\n    messages = [\n        {\"role\": \"system\", \"content\": \"You are a helpful assistant.\"},\n        {\"role\": \"user\", \"content\": [\n            {\"type\": \"image\", \"image\": image_url},\n            {\"type\": \"text\", \"text\": prompt},\n        ]},\n    ]\n    text = processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)\n    inputs = processor(text=[text], images=[image], padding=True, return_tensors=\"pt\").to(model.device)\n    \n    output_ids = model.generate(**inputs, max_new_tokens=max_new_tokens, do_sample=False)\n    generated_ids = [output_ids[len(input_ids):] for input_ids, output_ids in zip(inputs.input_ids, output_ids)]\n    \n    output_text = processor.batch_decode(generated_ids, skip_special_tokens=True, clean_up_tokenization_spaces=True)\n    return output_text[0]\n\nresult = infer(image_path, model, processor, max_new_tokens=15000)\nprint(result)\n```\n\n**MLX**\\\nMLX is an open-source machine learning framework for Apple Silicon. [MLX-VLM](https://github.com/Blaizzy/mlx-vlm) is built on top of MLX to serve vision language models easily. You can explore all the OCR models available in MLX format [here](https://huggingface.co/models?sort=trending&search=ocr). They also come in quantized versions.\\\nYou can install MLX-VLM as follows.\n\n```\npip install -U mlx-vlm\n```\n\n```\nwget https://huggingface.co/datasets/merve/vlm_test_images/resolve/main/throughput_smolvlm.png\n\npython -m mlx_vlm.generate --model ibm-granite/granite-docling-258M-mlx --max-tokens 4096 --temperature 0.0 --prompt \"Convert this chart to JSON.\" --image throughput_smolvlm.png \n```\n\n### Remotely\n\n**Inference Endpoints for Managed Deployment**\\\nYou can deploy OCR models compatible with vLLM or SGLang on Hugging Face Inference Endpoints, either from a model repository “Deploy” option or directly through [Inference Endpoints interface](https://endpoints.huggingface.co/). Inference Endpoints serve the cutting-edge models in a fully managed environment with GPU acceleration, auto-scaling, and monitoring without manually managing the infrastructure.\n\nHere is a simple method of deploying `nanonets` using vLLM as the inference engine.\n\n1. Navigate to the model repository [`nanonets/Nanonets-OCR2-3B`](https://huggingface.co/nanonets/Nanonets-OCR2-3B)\n2. Click on the “Deploy” button and select the “HF Inference Endpoints”\n\n[![Inference Endpoints](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/ocr/IE.png)](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/ocr/IE.png)\n\n3. Configure the deployment setup within seconds\n\n[![Inference Endpoints](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/ocr/IE2.png)](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/ocr/IE2.png)\n\n4. After the endpoint is created, you can consume it using the OpenAI client snippet we provided in the previous section.\n\nYou can learn more about it [here](https://huggingface.co/docs/inference-endpoints/engines/vllm).\n\n**Hugging Face Jobs for Batch Inference**\n\nFor many OCR applications, you want to do efficient batch inference, i.e., running a model across thousands of images as cheaply and efficiently as possible. A good approach is to use vLLM's offline inference mode. As discussed above, many recent VLM-based OCR models are supported by vLLM, which efficiently batches images and generates OCR outputs at scale.\n\nTo make this even easier, we've created [uv-scripts/ocr](https://huggingface.co/datasets/uv-scripts/ocr), a collection of ready-to-run OCR scripts that work with Hugging Face Jobs. These scripts let you run OCR on any dataset without needing your own GPU. Simply point the script at your input dataset, and it will:\n\n- Process all images in a dataset column using many different open OCR models\n- Add OCR results as a new markdown column to the dataset\n- Push the updated dataset with OCR results to the Hub\n\nFor example, to run OCR on 100 images:\n\n```bash\nhf jobs uv run --flavor l4x1 \\\n  https://huggingface.co/datasets/uv-scripts/ocr/raw/main/nanonets-ocr.py \\\n  your-input-dataset your-output-dataset \\\n  --max-samples 100\n```\n\nThe scripts handle all the vLLM configuration and batching automatically, making batch OCR accessible without infrastructure setup.\n\n### Going Beyond OCR\n\nIf you are interested in document AI, not just OCR, here are some of our recommendations.\n\n#### Visual Document Retrievers\n\nVisual document retrieval is to retrieve the most relevant top-k documents when given a text query. If you have previously worked with retriever models, the difference is that you search directly on a stack of PDFs. Aside from using them standalone, you can also build multimodal RAG pipelines by combining them with a vision language model (find how to do so [here](https://huggingface.co/merve/smol-vision/blob/main/ColPali_%2B_Qwen2_VL.ipynb)). You can find [all of them on Hugging Face Hub](https://huggingface.co/models?pipeline_tag=visual-document-retrieval&sort=trending).\n\nThere are two types of visual document retrievers, single-vector and multi-vector models. Single-vector models are more memory efficient and less performant; meanwhile, multi-vector models are more memory hungry and more performant. Most of these models often come with vLLM and transformers integrations, so you can index documents using them and then do a search easily using a vector DB.\n\n#### Using Vision Language Models for Document Question Answering\n\nIf you have a task at hand that only requires answering questions based on documents, you can use some of the vision language models that had document tasks in their training tasks. We’ve observed users trying to convert documents into text and passing the output to LLMs, but if your document has a complex layout, and your converted document outputs charts and so on in HTML, or images are captioned incorrectly, the LLM will miss out. Instead, feed your document and query to one of the advanced vision language models like [Qwen3-VL](https://huggingface.co/collections/Qwen/qwen3-vl-68d2a7c1b8a8afce4ebd2dbe) not to miss out on any context.\n\n## Wrapping up\n\nIn this blog post, we wanted to give you an overview of how to pick your OCR model, existing cutting-edge models and capabilities, and the tools to get you started with OCR.\\\nIf you want to learn more about OCR and vision language models, we encourage you to read the resources below.\n\n- [Vision Language Models Explained](https://huggingface.co/blog/vlms)\n- [Vision Language Models 2025 Update](https://huggingface.co/blog/vlms-2025)\n- [Blog on PP-OCR-v5](https://huggingface.co/blog/baidu/ppocrv5)\n- [Tutorial: Fine-tuning Kosmos2.5 on Grounded OCR](https://huggingface.co/merve/smol-vision/blob/main/Grounded_Fine_tuning.ipynb)\n- [Tutorial: Fine-tuning Florence-2 on DocVQA](https://huggingface.co/merve/smol-vision/blob/main/Fine_tune_Florence_2.ipynb)\n- [SOTA OCR on-device with Core ML and dots.ocr](https://huggingface.co/blog/dots-ocr-ne)\n",
  "authors": [],
  "captured_at": "2026-10-04T12:50:30.804479567+00:00",
  "category": "ai",
  "content_html": "<blockquote>\n<p>We have added <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/datalab-to/chandra\">Chandra</a> and <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/allenai/olmOCR-2-7B-1025\">OlmOCR-2</a> to this blog, as well as OlmOCR Scores of the models 🫡</p>\n</blockquote>\n<p>TL;DR: The rise of powerful vision-language models has transformed document AI. Each model comes with unique strengths, making it tricky to choose the right one. Open-weight models offer better cost efficiency and privacy. To help you get started with them, we’ve put together this guide.</p>\n<p>In this guide, you’ll learn:</p>\n<ul>\n<li>The landscape of current models and their capabilities</li>\n<li>When to fine-tune models vs. use models out-of-the-box</li>\n<li>Key factors to consider when selecting a model for your use case</li>\n<li>How to move beyond OCR with multimodal retrieval and document QA</li>\n</ul>\n<p>By the end, you’ll know how to choose the right OCR model, start building with it, and gain deeper insights into document AI. Let’s go!</p>\n<h2>Table-of-Contents</h2>\n<ul>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/ocr-open-models#supercharge-your-ocr-pipelines-with-open-models\">Supercharge your OCR Pipelines with Open Models</a>\n<ul>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/ocr-open-models#brief-introduction-to-modern-ocr\">Brief Introduction to Modern OCR</a>\n<ul>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/ocr-open-models#model-capabilities\">Model Capabilities</a>\n<ul>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/ocr-open-models#transcription\">Transcription</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/ocr-open-models#handling-complex-components-in-documents\">Handling complex components in documents</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/ocr-open-models#output-formats\">Output formats</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/ocr-open-models#locality-awareness-in-ocr\">Locality Awareness in OCR</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/ocr-open-models#model-prompting\">Model Prompting</a></li>\n</ul>\n</li>\n</ul>\n</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/ocr-open-models#cutting-edge-open-ocr-models\">Cutting-edge Open OCR Models</a>\n<ul>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/ocr-open-models#comparing-latest-models\">Comparing Latest Models</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/ocr-open-models#evaluating-models\">Evaluating Models</a>\n<ul>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/ocr-open-models#benchmarks\">Benchmarks</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/ocr-open-models#cost-efficiency\">Cost-efficiency</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/ocr-open-models#open-ocr-datasets\">Open OCR Datasets</a></li>\n</ul>\n</li>\n</ul>\n</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/ocr-open-models#tools-to-run-models\">Tools to Run Models</a>\n<ul>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/ocr-open-models#locally\">Locally</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/ocr-open-models#remotely\">Remotely</a></li>\n</ul>\n</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/ocr-open-models#going-beyond-ocr\">Going Beyond OCR</a>\n<ul>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/ocr-open-models#visual-document-retrievers\">Visual Document Retrievers</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/ocr-open-models#using-vision-language-models-for-document-question-answering\">Using Vision Language Models for Document Question Answering</a></li>\n</ul>\n</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/ocr-open-models#wrapping-up\">Wrapping up</a></li>\n</ul>\n</li>\n</ul>\n<h2>Brief Introduction to Modern OCR</h2>\n<p>Optical Character Recognition (OCR) is one of the earliest and longest running challenges in computer vision. Many of AI’s first practical applications focused on turning printed text into digital form.</p>\n<p>With the surge of <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/vlms\">vision-language models</a> (VLMs), OCR has advanced significantly. Recently, many OCR models have been developed by fine-tuning existing VLMs. But today’s capabilities extend far beyond OCR: you can retrieve documents by query or answer questions about them directly. Thanks to stronger vision features, these models can also handle low-quality scans, interpret complex elements like tables, charts, and images, and fuse text with visuals to answer open-ended questions across documents.</p>\n<h3>Model Capabilities</h3>\n<h4>Transcription</h4>\n<p>Recent models transcribe texts into a machine-readable format.<br />\nThe input can include:</p>\n<ul>\n<li>Handwritten text</li>\n<li>Various scripts like Latin, Arabic, and Japanese characters</li>\n<li>Mathematical expressions</li>\n<li>Chemical formulas</li>\n<li>Image/Layout/Page number tags</li>\n</ul>\n<p>OCR models convert them into machine-readable text that comes in many different formats like HTML, Markdown and more.</p>\n<h4>Handling complex components in documents</h4>\n<p>On top of text, some models can also recognize:</p>\n<ul>\n<li>Images</li>\n<li>Charts</li>\n<li>Tables</li>\n</ul>\n<p>Some models know where images are inside the document, extract their coordinates, and insert them appropriately between texts. Other models generate captions for images and insert them where they appear. This is especially useful if you are feeding the machine-readable output into an LLM. Example models are <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/allenai/olmOCR-7B-0825\">OlmOCR by AllenAI</a>, or <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/PaddlePaddle/PaddleOCR-VL\">PaddleOCR-VL by PaddlePaddle</a>.</p>\n<p>Models use different machine-readable output formats, such as <strong>DocTags</strong>, <strong>HTML</strong> or <strong>Markdown</strong> (explained in the next section <em>Output Formats</em>). The way a model handles tables and charts often depends on the output format they are using. Some models treat charts like images: they are kept as is. Other models convert charts into markdown tables or JSON, e.g., a bar chart can be converted as follows.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/ocr/chart-rendering.png\"><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/ocr/chart-rendering.png\" alt=\"Chart Rendering\" loading=\"eager\" decoding=\"async\" fetchpriority=\"high\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></a></p>\n<p>Similarly for tables, cells are converted into a machine-readable format while retaining context from headings and columns.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/ocr/table-rendering.png\"><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/ocr/table-rendering.png\" alt=\"Table Rendering\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></a></p>\n<h4>Output formats</h4>\n<p>Different OCR models have different output formats. Briefly, here are the common output formats used by modern models.<br />\n<strong>DocTag:</strong> DocTag is an XML-like format for documents that expresses location, text format, component-level information, and more. Below is an illustration of a paper parsed into DocTags. This format is employed by the open Docling models.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/ocr/doctags_v2.png\"><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/ocr/doctags_v2.png\" alt=\"DocTags\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></a></p>\n<ul>\n<li><strong>HTML:</strong> HTML is one of the most popular output formats used for document parsing as it properly encodes structure and hierarchical information.</li>\n<li><strong>Markdown:</strong> Markdown is the most human-readable format. It’s simpler than HTML but not as expressive. For example, it can’t represent split-column tables.</li>\n<li><strong>JSON:</strong> JSON is not a format that models use for the entire output, but it can be used to represent information in tables or charts.</li>\n</ul>\n<p>The right model depends on how you plan to use its outputs:</p>\n<ul>\n<li><strong>Digital reconstruction</strong>: To reconstruct documents digitally, choose a model with a layout-preserving format (e.g., DocTags or HTML).</li>\n<li><strong>LLM input or Q&amp;A</strong>: If the use case involves passing outputs to LLM, pick a model that outputs Markdown and image captions, since they’re closer to natural language.</li>\n<li><strong>Programmatic use</strong>: If you want to pass your outputs to a program (like data analysis), opt for a model that generates structured outputs like JSON.</li>\n</ul>\n<h4>Locality Awareness</h4>\n<p>Documents can have complex structures, like multi-column text blocks and floating figures. Older OCR models handled these documents by detecting words and then the layout of pages manually in post-processing to have the text rendered in reading order, which is brittle. Modern OCR models, on the other hand, incorporate layout metadata to help preserve reading order and accuracy. This metadata is called “anchor”, it can come in bounding boxes. This process is also called as “grounding/anchoring” because it helps with reducing hallucination.</p>\n<h4>Model Prompting</h4>\n<p>OCR models can either take in images and an optional text prompt, this depends on the model architecture and the pre-training setup.<br />\nSome OCR models support prompt-based task switching, e.g. <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/ibm-granite/granite-docling-258M\">granite-docling</a> can parse an entire page with the prompt “Convert this page to Docling” while it can also take prompts like “Convert this formula to LaTeX” along with a page full of formulas.<br />\nOther models, however, are trained only for parsing entire pages, and they are conditioned to do this through a system prompt.<br />\nFor instance, <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/collections/allenai/olmocr-67af8630b0062a25bf1b54a1\">OlmOCR by AllenAI</a> takes a long conditioning prompt. Like many others, OlmOCR is technically an OCR fine-tuned version of a VLM (Qwen2.5VL in this case), so you can prompt for other tasks, but its performance will not be on par with the OCR capabilities.</p>\n<h2>Cutting-edge Open OCR Models</h2>\n<p>We’ve seen an incredible wave of new models this past year. Because so much work is happening in the open, these players build on and benefit from each other’s work. A great example is AllenAI’s release of OlmOCR, which not only released a model but also the dataset used to train it. With these, others can build upon them in new directions. The field is incredibly active, but it’s not always obvious which model to use.</p>\n<h3>Comparing Latest Models</h3>\n<p>To make things a bit easier, we’re putting together a non-exhaustive comparison of some of our current favorite models. All of the models below are layout-aware and can parse tables, charts, and math equations. The full list of languages each model supports are detailed in their model cards, so make sure to check them if you’re interested. All models below have open-source license except for Chandra having OpenRAIL license and Nanonets license being unclear. The average scores are taken from model cards of Chandra, OlmOCR, evaluated on OlmOCR Benchmark, which is English-only. Many of the models in this collection have been fine-tuned from Qwen2.5-VL or Qwen3-VL, so we also provide Qwen3-VL model below as well.</p>\n<table>\n<thead>\n<tr>\n<th>Model Name</th>\n<th>Output formats</th>\n<th>Features</th>\n<th>Model Size</th>\n<th>Multilingual?</th>\n<th>Average Score on OlmOCR Benchmark</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/collections/nanonets/nanonets-ocr2-68ed207f17ee6c31d226319e\">Nanonets-OCR2-3B</a></td>\n<td>structured Markdown with semantic tagging (plus HTML tables, etc.)</td>\n<td>Captions images in the documents Signature &amp; watermark extraction Handles checkboxes, flowcharts, and handwriting</td>\n<td>4B</td>\n<td>✅Supports English, Chinese, French, Arabic and more.</td>\n<td>N/A</td>\n</tr>\n<tr>\n<td><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/collections/PaddlePaddle/paddleocr-vl-68f0db852483c7af0bc86849\">PaddleOCR-VL</a></td>\n<td>Markdown, JSON, HTML tables and charts</td>\n<td>Handles handwriting, old documents Allows prompting Converts tables &amp; charts to HTML Extracts and inserts images directly</td>\n<td>0.9B</td>\n<td>✅Supports 109 languages</td>\n<td>N/A</td>\n</tr>\n<tr>\n<td><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/rednote-hilab/dots.ocr\">dots.ocr</a></td>\n<td>Markdown, JSON</td>\n<td>Grounding Extracts and inserts images Handles handwriting</td>\n<td>3B</td>\n<td>✅Multilingual with language info not available</td>\n<td>79.1 ± 1.0</td>\n</tr>\n<tr>\n<td><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/allenai/olmOCR-2-7B-1025\">OlmOCR-2</a></td>\n<td>Markdown, HTML, LaTeX</td>\n<td>Grounding Optimized for large-scale batch processing</td>\n<td>8B</td>\n<td>❎English-only</td>\n<td>82.3 ± 1.1</td>\n</tr>\n<tr>\n<td><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/ibm-granite/granite-docling-258M\">Granite-Docling-258M</a></td>\n<td>DocTags</td>\n<td>Prompt-based task switching Ability to prompt element locations with location tokens Rich output</td>\n<td>258M</td>\n<td>✅Supports English, Japanese, Arabic and Chinese.</td>\n<td>N/A</td>\n</tr>\n<tr>\n<td><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/deepseek-ai/DeepSeek-OCR\">DeepSeek-OCR</a></td>\n<td>Markdown, HTML</td>\n<td>Supports general visual understanding Can parse and re-render all charts, tables, and more into HTML Handles handwriting Memory-efficient, solves text through image</td>\n<td>3B</td>\n<td>✅Supports nearly 100 languages</td>\n<td>75.4 ± 1.0</td>\n</tr>\n<tr>\n<td><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/datalab-to/chandra\">Chandra</a></td>\n<td>Markdown, HTML, JSON</td>\n<td>Grounding Extracts and inserts images as is</td>\n<td>9B</td>\n<td>✅Supports 40+ languages</td>\n<td>83.1 ± 0.9</td>\n</tr>\n<tr>\n<td><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/collections/Qwen/qwen3-vl\">Qwen3-VL</a></td>\n<td>Vision Language Model can output in all formats</td>\n<td>Can recognize ancient text Handles handwriting Extracts and inserts images as is</td>\n<td>9B</td>\n<td>✅Supports 32 languages</td>\n<td>N/A</td>\n</tr>\n</tbody>\n</table>\n<p>While Qwen3-VL itself is a powerful and versatile vision-language model post-trained for document understanding and other tasks, it isn’t optimized for a single, universal OCR prompt. In contrast, the other models were fine-tuned using one or a few fixed prompts specifically designed for OCR tasks. So to use Qwen3-VL, we recommend experimenting with prompts.</p>\n<p>Here’s a <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://prithivMLmods-Multimodal-OCR3.hf.space\">small demo</a> for you to try some of the latest models and compare their outputs.</p>\n<h3>Evaluating Models</h3>\n<h4>Benchmarks</h4>\n<p>There’s no single best model, as every problem has different needs. Should tables be rendered in Markdown or HTML? Which elements should we extract? How should we quantify text accuracy and error rates? 👀<br />\nWhile there are many evaluation datasets and tools, many don’t answer these questions. So we suggest using the following benchmarks:</p>\n<ol>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/datasets/opendatalab/OmniDocBench\"><strong>OmniDocBenchmark</strong></a><strong>:</strong> This widely used benchmark stands out for its diverse document types: books, magazines, and textbooks. Its evaluation criteria are well designed, accepting tables in both HTML and Markdown formats. A novel matching algorithm evaluates the reading order, and formulas are normalized before evaluation. Most metrics rely on edit distance or tree edit distance (tables). Notably, the annotations used for evaluation are not solely human-generated but are acquired through SoTA VLMs or conventional OCR methods.</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/datasets/allenai/olmOCR-bench\"><strong>OlmOCR-Bench</strong></a>: OlmOCR-Bench takes a different approach: they treat the evaluation as a set of unit tests. For example, table evaluation is done by checking the relation between selected cells of a given table. They use PDFs from public sources, and annotations are done using a wide range of closed-source VLMs. This benchmark is quite successful to evaluate on the English language.</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/datasets/wulipc/CC-OCR\"><strong>CC-OCR (Multilingual)</strong>:</a> Compared to the previous benchmarks, CC-OCR is less preferred when picking models, due to lower document quality and diversity. However, it’s the only benchmark that contains evaluation beyond English and Chinese! While the evaluation is far from perfect (images are photos with few words), it’s still the best you can do for multilingual evaluation.</li>\n</ol>\n<p>When testing different OCR models, we've found that the performance across different document types, languages, etc., varies a lot. Your domain may not be well represented in existing benchmarks! To make effective use of this new generation of VLM-based OCR models we suggest aiming to collect a dataset of representative examples of your task domain and testing a few different models to compare their performance.</p>\n<h4>Cost-efficiency</h4>\n<p>Most OCR models are small, having between 3B and 7B parameters; you can even find models with fewer than 1B parameters, like PaddleOCR-VL. However, the cost also depends on the availability of optimized implementations for specialized inference frameworks. For example, OlmOCR-2 comes with vLLM and SGLang implementations, and the cost per million pages is 178 dollars (assuming on H100 for $2.69/hour). DeepSeek-OCR can process 200k+ pages per day on a single A100 with 40GB VRAM. With napkin math, we see that the cost per million pages is more or less similar to OlmOCR (although it depends on your A100 provider). If your use case remains unaffected, you can also opt for quantized versions of the models. The cost of running open-source models heavily depends on the hourly cost of the instance and the optimizations the model includes, but it’s guaranteed to be cheaper than many closed-source models out there on a larger scale.</p>\n<h4>Open OCR Datasets</h4>\n<p>While the past year has seen a surge in open OCR models, this hasn't been matched by as many open training and evaluation datasets. An exception is AllenAI's <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/datasets/allenai/olmOCR-mix-0225\">olmOCR-mix-0225</a>, which has been used to train at least <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/models?dataset=dataset:allenai/olmOCR-mix-0225\">72 models on the Hub</a> – likely more, since not all models document their training data.</p>\n<p>Sharing more datasets could unlock even greater advances in open OCR models. There are several promising approaches for creating these datasets:</p>\n<ul>\n<li><strong>Synthetic data generation</strong> (e.g., <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/datasets/Sigurdur/isl_synthetic_ocr\">isl_synthetic_ocr</a>)</li>\n<li><strong>VLM-generated transcriptions</strong> filtered manually or through heuristics</li>\n<li><strong>Using existing OCR models</strong> to generate training data for new, potentially more efficient models in specific domains</li>\n<li><strong>Leveraging existing corrected datasets</strong> like the <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/NationalLibraryOfScotland\">Medical History of British India Dataset</a>, which contains extensively human-corrected OCR for historic documents</li>\n</ul>\n<p>It's worth noting that many such datasets exist but remain unused. Making them more readily available as 'training-ready' datasets carries a considerable potential for the open-source community.</p>\n<h2>Tools to Run Models</h2>\n<p>We have received many questions about getting started with OCR models, so here are a few ways you can use local inference tools and host remotely with Hugging Face.</p>\n<h3>Locally</h3>\n<p>Most cutting-edge models come with vLLM support and transformers implementation. You can get more info about how to serve each from the models’ own cards. For convenience, we show how to infer locally using vLLM here. The code below can differ from model to model, but for most models it looks like the following.</p>\n<pre><code class=\"language-shell\"><span class=\"code-snippet\" data-language=\"Shell\"><span class=\"syntax-source syntax-shell syntax-bash\"><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">vllm</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> serve nanonets/Nanonets-OCR2-3B</span>\n</span></span></code></pre>\n<p>And then you can query as follows using e.g. OpenAI client.</p>\n<pre><code class=\"language-py\"><span class=\"code-snippet\" data-language=\"Python\"><span class=\"syntax-source syntax-python\"><span class=\"syntax-meta syntax-statement syntax-import syntax-python\"><span class=\"syntax-keyword syntax-control syntax-import syntax-from syntax-python\">from</span></span><span class=\"syntax-meta syntax-statement syntax-import syntax-python\"><span class=\"syntax-meta syntax-import-source syntax-python\"> <span class=\"syntax-meta syntax-import-path syntax-python\"><span class=\"syntax-meta syntax-import-name syntax-python\">openai</span></span> <span class=\"syntax-meta syntax-statement syntax-import syntax-python\"><span class=\"syntax-keyword syntax-control syntax-import syntax-python\">import</span></span></span></span><span class=\"syntax-meta syntax-statement syntax-import syntax-python\"></span><span class=\"syntax-meta syntax-statement syntax-import syntax-python\"> <span class=\"syntax-meta syntax-generic-name syntax-python\">OpenAI</span></span>\n<span class=\"syntax-meta syntax-statement syntax-import syntax-python\"><span class=\"syntax-keyword syntax-control syntax-import syntax-python\">import</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">base64</span></span></span>\n\n<span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">client</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">OpenAI</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-variable syntax-parameter syntax-python\">base_url</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">http://localhost:8000/v1<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n\n<span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">model</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">nanonets/Nanonets-OCR2-3B<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span>\n\n<span class=\"syntax-meta syntax-function syntax-python\"><span class=\"syntax-storage syntax-type syntax-function syntax-python\">def</span> <span class=\"syntax-entity syntax-name syntax-function syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">encode_image</span></span></span><span class=\"syntax-meta syntax-function syntax-parameters syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-parameters syntax-begin syntax-python\">(</span></span><span class=\"syntax-meta syntax-function syntax-parameters syntax-python\"><span class=\"syntax-variable syntax-parameter syntax-python\">image_path</span><span class=\"syntax-punctuation syntax-section syntax-parameters syntax-end syntax-python\">)</span></span><span class=\"syntax-meta syntax-function syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-function syntax-begin syntax-python\">:</span></span>\n    <span class=\"syntax-meta syntax-statement syntax-with syntax-python\"><span class=\"syntax-keyword syntax-control syntax-flow syntax-with syntax-python\">with</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-support syntax-function syntax-builtin syntax-python\">open</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">image_path</span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">rb<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span> <span class=\"syntax-meta syntax-statement syntax-with syntax-python\"><span class=\"syntax-keyword syntax-control syntax-flow syntax-with syntax-as syntax-python\">as</span></span></span><span class=\"syntax-meta syntax-statement syntax-with syntax-python\"> <span class=\"syntax-meta syntax-generic-name syntax-python\">image_file</span><span class=\"syntax-punctuation syntax-section syntax-block syntax-with syntax-python\">:</span></span>\n        <span class=\"syntax-keyword syntax-control syntax-flow syntax-return syntax-python\">return</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">base64</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">b64encode</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">image_file</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">read</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span><span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">decode</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">utf-8<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n\n<span class=\"syntax-meta syntax-function syntax-python\"><span class=\"syntax-storage syntax-type syntax-function syntax-python\">def</span> <span class=\"syntax-entity syntax-name syntax-function syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">infer</span></span></span><span class=\"syntax-meta syntax-function syntax-parameters syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-parameters syntax-begin syntax-python\">(</span></span><span class=\"syntax-meta syntax-function syntax-parameters syntax-python\"><span class=\"syntax-variable syntax-parameter syntax-python\">img_base64</span><span class=\"syntax-punctuation syntax-section syntax-parameters syntax-end syntax-python\">)</span></span><span class=\"syntax-meta syntax-function syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-function syntax-begin syntax-python\">:</span></span>\n    <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">response</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">client</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">chat</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">completions</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">create</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\">\n        <span class=\"syntax-variable syntax-parameter syntax-python\">model</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">model</span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span>\n        <span class=\"syntax-variable syntax-parameter syntax-python\">messages</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-structure syntax-list syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-list syntax-begin syntax-python\">[</span>\n            <span class=\"syntax-meta syntax-structure syntax-dictionary-or-set syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-begin syntax-python\">{</span>\n                <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">role<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-python\">:</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">user<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-dictionary-or-set syntax-python\">,</span>\n                <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">content<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-python\">:</span> <span class=\"syntax-meta syntax-structure syntax-list syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-list syntax-begin syntax-python\">[</span>\n                    <span class=\"syntax-meta syntax-structure syntax-dictionary-or-set syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-begin syntax-python\">{</span>\n                        <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">type<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-python\">:</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">image_url<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-dictionary-or-set syntax-python\">,</span>\n                        <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">image_url<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-python\">:</span> <span class=\"syntax-meta syntax-structure syntax-dictionary-or-set syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-begin syntax-python\">{</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">url<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-python\">:</span> <span class=\"syntax-storage syntax-type syntax-string syntax-python\">f</span><span class=\"syntax-meta syntax-string syntax-interpolated syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-interpolated syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">data:image/png;base64,</span><span class=\"syntax-meta syntax-interpolation syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-interpolation syntax-begin syntax-python\">{</span><span class=\"syntax-source syntax-python syntax-embedded\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">img_base64</span></span></span></span><span class=\"syntax-meta syntax-interpolation syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-interpolation syntax-end syntax-python\">}</span></span><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-end syntax-python\">}</span></span><span class=\"syntax-punctuation syntax-separator syntax-dictionary-or-set syntax-python\">,</span>\n                    <span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-end syntax-python\">}</span></span><span class=\"syntax-punctuation syntax-separator syntax-list syntax-python\">,</span>\n                    <span class=\"syntax-meta syntax-structure syntax-dictionary-or-set syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-begin syntax-python\">{</span>\n                        <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">type<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-python\">:</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">text<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-dictionary-or-set syntax-python\">,</span>\n                        <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">text<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-python\">:</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">Extract the text from the above document as if you were reading it naturally.<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-dictionary-or-set syntax-python\">,</span>\n                    <span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-end syntax-python\">}</span></span><span class=\"syntax-punctuation syntax-separator syntax-list syntax-python\">,</span>\n                <span class=\"syntax-punctuation syntax-section syntax-list syntax-end syntax-python\">]</span></span><span class=\"syntax-punctuation syntax-separator syntax-dictionary-or-set syntax-python\">,</span>\n            <span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-end syntax-python\">}</span></span>\n        <span class=\"syntax-punctuation syntax-section syntax-list syntax-end syntax-python\">]</span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span>\n        <span class=\"syntax-variable syntax-parameter syntax-python\">temperature</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-constant syntax-numeric syntax-float syntax-python\">0<span class=\"syntax-punctuation syntax-separator syntax-decimal syntax-python\">.</span>0</span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span>\n        <span class=\"syntax-variable syntax-parameter syntax-python\">max_tokens</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">15000</span>\n    </span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n    <span class=\"syntax-keyword syntax-control syntax-flow syntax-return syntax-python\">return</span> <span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">response</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">choices</span></span></span><span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-brackets syntax-begin syntax-python\">[</span></span><span class=\"syntax-meta syntax-item-access syntax-arguments syntax-python\"><span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">0</span></span><span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-brackets syntax-end syntax-python\">]</span></span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">message</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">content</span>\n\n<span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">img_base64</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">encode_image</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">your_img_path</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n<span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-support syntax-function syntax-builtin syntax-python\">print</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">infer</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">img_base64</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n</span></span></code></pre>\n<p><strong>Transformers</strong></p>\n<p>Transformers provides standard model definitions for easy inference and fine-tuning. Models available in transformers come with either official transformers implementation (model definitions within the library) or “remote code” implementations. Latter is defined by the model owners to enable easy loading of models into transformers interface, so you don’t have to go through the model implementation. Below is an example loading Nanonets model using transformers implementation.</p>\n<pre><code class=\"language-py\"><span class=\"code-snippet\" data-language=\"Python\"><span class=\"syntax-source syntax-python\"><span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> make sure to install flash-attn and transformers\n</span><span class=\"syntax-meta syntax-statement syntax-import syntax-python\"><span class=\"syntax-keyword syntax-control syntax-import syntax-from syntax-python\">from</span></span><span class=\"syntax-meta syntax-statement syntax-import syntax-python\"><span class=\"syntax-meta syntax-import-source syntax-python\"> <span class=\"syntax-meta syntax-import-path syntax-python\"><span class=\"syntax-meta syntax-import-name syntax-python\">transformers</span></span> <span class=\"syntax-meta syntax-statement syntax-import syntax-python\"><span class=\"syntax-keyword syntax-control syntax-import syntax-python\">import</span></span></span></span><span class=\"syntax-meta syntax-statement syntax-import syntax-python\"></span><span class=\"syntax-meta syntax-statement syntax-import syntax-python\"> <span class=\"syntax-meta syntax-generic-name syntax-python\">AutoProcessor</span><span class=\"syntax-punctuation syntax-separator syntax-import-list syntax-python\">,</span> <span class=\"syntax-meta syntax-generic-name syntax-python\">AutoModelForImageTextToText</span></span>\n\n<span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">model</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">AutoModelForImageTextToText</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">from_pretrained</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\">\n    <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">nanonets/Nanonets-OCR2-3B<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> \n    <span class=\"syntax-variable syntax-parameter syntax-python\">torch_dtype</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">auto<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> \n    <span class=\"syntax-variable syntax-parameter syntax-python\">device_map</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">auto<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> \n    <span class=\"syntax-variable syntax-parameter syntax-python\">attn_implementation</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">flash_attention_2<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span>\n</span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n<span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">model</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">eval</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n<span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">processor</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">AutoProcessor</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">from_pretrained</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">nanonets/Nanonets-OCR2-3B<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n\n<span class=\"syntax-meta syntax-function syntax-python\"><span class=\"syntax-storage syntax-type syntax-function syntax-python\">def</span> <span class=\"syntax-entity syntax-name syntax-function syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">infer</span></span></span><span class=\"syntax-meta syntax-function syntax-parameters syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-parameters syntax-begin syntax-python\">(</span></span><span class=\"syntax-meta syntax-function syntax-parameters syntax-python\"><span class=\"syntax-variable syntax-parameter syntax-python\">image_url</span><span class=\"syntax-punctuation syntax-separator syntax-parameters syntax-python\">,</span> <span class=\"syntax-variable syntax-parameter syntax-python\">model</span><span class=\"syntax-punctuation syntax-separator syntax-parameters syntax-python\">,</span> <span class=\"syntax-variable syntax-parameter syntax-python\">processor</span><span class=\"syntax-punctuation syntax-separator syntax-parameters syntax-python\">,</span> <span class=\"syntax-variable syntax-parameter syntax-python\">max_new_tokens</span></span><span class=\"syntax-meta syntax-function syntax-parameters syntax-default-value syntax-python\"><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">4096</span></span><span class=\"syntax-meta syntax-function syntax-parameters syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-parameters syntax-end syntax-python\">)</span></span><span class=\"syntax-meta syntax-function syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-function syntax-begin syntax-python\">:</span></span>\n    <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">prompt</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-block syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;&quot;&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-block syntax-python\"><span class=\"syntax-meta syntax-string syntax-python\"></span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-block syntax-python\">Extract the text from the above document as if you were reading it naturally. Return the tables in html format. Return the equations in LaTeX representation. If there is an image in the document and image caption is not present, add a small description of the image inside the &lt;img&gt;&lt;/img&gt; tag; otherwise, add the image caption inside &lt;img&gt;&lt;/img&gt;. Watermarks should be wrapped in brackets. Ex: &lt;watermark&gt;OFFICIAL COPY&lt;/watermark&gt;. Page numbers should be wrapped in brackets. Ex: &lt;page_number&gt;14&lt;/page_number&gt; or &lt;page_number&gt;9/22&lt;/page_number&gt;. Prefer using ☐ and ☑ for check boxes.<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;&quot;&quot;</span></span></span>\n    <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">image</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">Image</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">open</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">image_path</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n    <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">messages</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-structure syntax-list syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-list syntax-begin syntax-python\">[</span>\n        <span class=\"syntax-meta syntax-structure syntax-dictionary-or-set syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-begin syntax-python\">{</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">role<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-python\">:</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">system<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-dictionary-or-set syntax-python\">,</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">content<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-python\">:</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">You are a helpful assistant.<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-end syntax-python\">}</span></span><span class=\"syntax-punctuation syntax-separator syntax-list syntax-python\">,</span>\n        <span class=\"syntax-meta syntax-structure syntax-dictionary-or-set syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-begin syntax-python\">{</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">role<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-python\">:</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">user<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-dictionary-or-set syntax-python\">,</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">content<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-python\">:</span> <span class=\"syntax-meta syntax-structure syntax-list syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-list syntax-begin syntax-python\">[</span>\n            <span class=\"syntax-meta syntax-structure syntax-dictionary-or-set syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-begin syntax-python\">{</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">type<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-python\">:</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">image<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-dictionary-or-set syntax-python\">,</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">image<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-python\">:</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">image_url</span></span><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-end syntax-python\">}</span></span><span class=\"syntax-punctuation syntax-separator syntax-list syntax-python\">,</span>\n            <span class=\"syntax-meta syntax-structure syntax-dictionary-or-set syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-begin syntax-python\">{</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">type<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-python\">:</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">text<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-dictionary-or-set syntax-python\">,</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">text<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-python\">:</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">prompt</span></span><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-end syntax-python\">}</span></span><span class=\"syntax-punctuation syntax-separator syntax-list syntax-python\">,</span>\n        <span class=\"syntax-punctuation syntax-section syntax-list syntax-end syntax-python\">]</span></span><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-end syntax-python\">}</span></span><span class=\"syntax-punctuation syntax-separator syntax-list syntax-python\">,</span>\n    <span class=\"syntax-punctuation syntax-section syntax-list syntax-end syntax-python\">]</span></span>\n    <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">text</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">processor</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">apply_chat_template</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">messages</span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-variable syntax-parameter syntax-python\">tokenize</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-constant syntax-language syntax-python\">False</span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-variable syntax-parameter syntax-python\">add_generation_prompt</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-constant syntax-language syntax-python\">True</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n    <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">inputs</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">processor</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-variable syntax-parameter syntax-python\">text</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-structure syntax-list syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-list syntax-begin syntax-python\">[</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">text</span></span><span class=\"syntax-punctuation syntax-section syntax-list syntax-end syntax-python\">]</span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-variable syntax-parameter syntax-python\">images</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-structure syntax-list syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-list syntax-begin syntax-python\">[</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">image</span></span><span class=\"syntax-punctuation syntax-section syntax-list syntax-end syntax-python\">]</span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-variable syntax-parameter syntax-python\">padding</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-constant syntax-language syntax-python\">True</span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-variable syntax-parameter syntax-python\">return_tensors</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">pt<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span><span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">to</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">model</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">device</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n    \n    <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">output_ids</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">model</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">generate</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">*</span><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">*</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">inputs</span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-variable syntax-parameter syntax-python\">max_new_tokens</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">max_new_tokens</span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-variable syntax-parameter syntax-python\">do_sample</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-constant syntax-language syntax-python\">False</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n    <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">generated_ids</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-structure syntax-list syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-list syntax-begin syntax-python\">[</span><span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">output_ids</span></span></span><span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-brackets syntax-begin syntax-python\">[</span></span><span class=\"syntax-meta syntax-item-access syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-support syntax-function syntax-builtin syntax-python\">len</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">input_ids</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span><span class=\"syntax-punctuation syntax-separator syntax-slice syntax-python\">:</span></span><span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-brackets syntax-end syntax-python\">]</span></span> <span class=\"syntax-meta syntax-expression syntax-generator syntax-python\"><span class=\"syntax-keyword syntax-control syntax-flow syntax-for syntax-generator syntax-python\">for</span> <span class=\"syntax-meta syntax-generic-name syntax-python\">input_ids</span><span class=\"syntax-punctuation syntax-separator syntax-target-list syntax-python\">,</span> <span class=\"syntax-meta syntax-generic-name syntax-python\">output_ids</span> <span class=\"syntax-keyword syntax-control syntax-flow syntax-for syntax-in syntax-python\">in</span></span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-support syntax-function syntax-builtin syntax-python\">zip</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">inputs</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">input_ids</span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">output_ids</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span><span class=\"syntax-punctuation syntax-section syntax-list syntax-end syntax-python\">]</span></span>\n    \n    <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">output_text</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">processor</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">batch_decode</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">generated_ids</span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-variable syntax-parameter syntax-python\">skip_special_tokens</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-constant syntax-language syntax-python\">True</span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-variable syntax-parameter syntax-python\">clean_up_tokenization_spaces</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-constant syntax-language syntax-python\">True</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n    <span class=\"syntax-keyword syntax-control syntax-flow syntax-return syntax-python\">return</span> <span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">output_text</span></span></span><span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-brackets syntax-begin syntax-python\">[</span></span><span class=\"syntax-meta syntax-item-access syntax-arguments syntax-python\"><span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">0</span></span><span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-brackets syntax-end syntax-python\">]</span></span>\n\n<span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">result</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">infer</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">image_path</span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">model</span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">processor</span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-variable syntax-parameter syntax-python\">max_new_tokens</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">15000</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n<span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-support syntax-function syntax-builtin syntax-python\">print</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">result</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n</span></span></code></pre>\n<p><strong>MLX</strong><br />\nMLX is an open-source machine learning framework for Apple Silicon. <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/Blaizzy/mlx-vlm\">MLX-VLM</a> is built on top of MLX to serve vision language models easily. You can explore all the OCR models available in MLX format <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/models?sort=trending&amp;search=ocr\">here</a>. They also come in quantized versions.<br />\nYou can install MLX-VLM as follows.</p>\n<pre><code><span class=\"code-snippet\">pip install -U mlx-vlm\n</span></code></pre>\n<pre><code><span class=\"code-snippet\">wget https://huggingface.co/datasets/merve/vlm_test_images/resolve/main/throughput_smolvlm.png\n\npython -m mlx_vlm.generate --model ibm-granite/granite-docling-258M-mlx --max-tokens 4096 --temperature 0.0 --prompt &quot;Convert this chart to JSON.&quot; --image throughput_smolvlm.png \n</span></code></pre>\n<h3>Remotely</h3>\n<p><strong>Inference Endpoints for Managed Deployment</strong><br />\nYou can deploy OCR models compatible with vLLM or SGLang on Hugging Face Inference Endpoints, either from a model repository “Deploy” option or directly through <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://endpoints.huggingface.co/\">Inference Endpoints interface</a>. Inference Endpoints serve the cutting-edge models in a fully managed environment with GPU acceleration, auto-scaling, and monitoring without manually managing the infrastructure.</p>\n<p>Here is a simple method of deploying <code>nanonets</code> using vLLM as the inference engine.</p>\n<ol>\n<li>Navigate to the model repository <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/nanonets/Nanonets-OCR2-3B\"><code>nanonets/Nanonets-OCR2-3B</code></a></li>\n<li>Click on the “Deploy” button and select the “HF Inference Endpoints”</li>\n</ol>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/ocr/IE.png\"><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/ocr/IE.png\" alt=\"Inference Endpoints\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></a></p>\n<ol start=\"3\">\n<li>Configure the deployment setup within seconds</li>\n</ol>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/ocr/IE2.png\"><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/ocr/IE2.png\" alt=\"Inference Endpoints\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></a></p>\n<ol start=\"4\">\n<li>After the endpoint is created, you can consume it using the OpenAI client snippet we provided in the previous section.</li>\n</ol>\n<p>You can learn more about it <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/docs/inference-endpoints/engines/vllm\">here</a>.</p>\n<p><strong>Hugging Face Jobs for Batch Inference</strong></p>\n<p>For many OCR applications, you want to do efficient batch inference, i.e., running a model across thousands of images as cheaply and efficiently as possible. A good approach is to use vLLM's offline inference mode. As discussed above, many recent VLM-based OCR models are supported by vLLM, which efficiently batches images and generates OCR outputs at scale.</p>\n<p>To make this even easier, we've created <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/datasets/uv-scripts/ocr\">uv-scripts/ocr</a>, a collection of ready-to-run OCR scripts that work with Hugging Face Jobs. These scripts let you run OCR on any dataset without needing your own GPU. Simply point the script at your input dataset, and it will:</p>\n<ul>\n<li>Process all images in a dataset column using many different open OCR models</li>\n<li>Add OCR results as a new markdown column to the dataset</li>\n<li>Push the updated dataset with OCR results to the Hub</li>\n</ul>\n<p>For example, to run OCR on 100 images:</p>\n<pre><code class=\"language-bash\"><span class=\"code-snippet\" data-language=\"Shell\"><span class=\"syntax-source syntax-shell syntax-bash\"><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">hf</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> jobs uv run<span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\"> --</span>flavor</span> l4x1 <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span>  https://huggingface.co/datasets/uv-scripts/ocr/raw/main/nanonets-ocr.py <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span>  your-input-dataset your-output-dataset <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">  --</span>max-samples</span> 100</span>\n</span></span></code></pre>\n<p>The scripts handle all the vLLM configuration and batching automatically, making batch OCR accessible without infrastructure setup.</p>\n<h3>Going Beyond OCR</h3>\n<p>If you are interested in document AI, not just OCR, here are some of our recommendations.</p>\n<h4>Visual Document Retrievers</h4>\n<p>Visual document retrieval is to retrieve the most relevant top-k documents when given a text query. If you have previously worked with retriever models, the difference is that you search directly on a stack of PDFs. Aside from using them standalone, you can also build multimodal RAG pipelines by combining them with a vision language model (find how to do so <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/merve/smol-vision/blob/main/ColPali_%2B_Qwen2_VL.ipynb\">here</a>). You can find <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/models?pipeline_tag=visual-document-retrieval&amp;sort=trending\">all of them on Hugging Face Hub</a>.</p>\n<p>There are two types of visual document retrievers, single-vector and multi-vector models. Single-vector models are more memory efficient and less performant; meanwhile, multi-vector models are more memory hungry and more performant. Most of these models often come with vLLM and transformers integrations, so you can index documents using them and then do a search easily using a vector DB.</p>\n<h4>Using Vision Language Models for Document Question Answering</h4>\n<p>If you have a task at hand that only requires answering questions based on documents, you can use some of the vision language models that had document tasks in their training tasks. We’ve observed users trying to convert documents into text and passing the output to LLMs, but if your document has a complex layout, and your converted document outputs charts and so on in HTML, or images are captioned incorrectly, the LLM will miss out. Instead, feed your document and query to one of the advanced vision language models like <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/collections/Qwen/qwen3-vl-68d2a7c1b8a8afce4ebd2dbe\">Qwen3-VL</a> not to miss out on any context.</p>\n<h2>Wrapping up</h2>\n<p>In this blog post, we wanted to give you an overview of how to pick your OCR model, existing cutting-edge models and capabilities, and the tools to get you started with OCR.<br />\nIf you want to learn more about OCR and vision language models, we encourage you to read the resources below.</p>\n<ul>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/vlms\">Vision Language Models Explained</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/vlms-2025\">Vision Language Models 2025 Update</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/baidu/ppocrv5\">Blog on PP-OCR-v5</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/merve/smol-vision/blob/main/Grounded_Fine_tuning.ipynb\">Tutorial: Fine-tuning Kosmos2.5 on Grounded OCR</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/merve/smol-vision/blob/main/Fine_tune_Florence_2.ipynb\">Tutorial: Fine-tuning Florence-2 on DocVQA</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/dots-ocr-ne\">SOTA OCR on-device with Core ML and dots.ocr</a></li>\n</ul>\n",
  "content_markdown": "> We have added [Chandra](https://huggingface.co/datalab-to/chandra) and [OlmOCR-2](https://huggingface.co/allenai/olmOCR-2-7B-1025) to this blog, as well as OlmOCR Scores of the models 🫡\n\nTL;DR: The rise of powerful vision-language models has transformed document AI. Each model comes with unique strengths, making it tricky to choose the right one. Open-weight models offer better cost efficiency and privacy. To help you get started with them, we’ve put together this guide.\n\nIn this guide, you’ll learn:\n\n- The landscape of current models and their capabilities\n- When to fine-tune models vs. use models out-of-the-box\n- Key factors to consider when selecting a model for your use case\n- How to move beyond OCR with multimodal retrieval and document QA\n\nBy the end, you’ll know how to choose the right OCR model, start building with it, and gain deeper insights into document AI. Let’s go!\n\n## Table-of-Contents\n\n- [Supercharge your OCR Pipelines with Open Models](https://huggingface.co/blog/ocr-open-models#supercharge-your-ocr-pipelines-with-open-models)\n  - [Brief Introduction to Modern OCR](https://huggingface.co/blog/ocr-open-models#brief-introduction-to-modern-ocr)\n    - [Model Capabilities](https://huggingface.co/blog/ocr-open-models#model-capabilities)\n      - [Transcription](https://huggingface.co/blog/ocr-open-models#transcription)\n      - [Handling complex components in documents](https://huggingface.co/blog/ocr-open-models#handling-complex-components-in-documents)\n      - [Output formats](https://huggingface.co/blog/ocr-open-models#output-formats)\n      - [Locality Awareness in OCR](https://huggingface.co/blog/ocr-open-models#locality-awareness-in-ocr)\n      - [Model Prompting](https://huggingface.co/blog/ocr-open-models#model-prompting)\n  - [Cutting-edge Open OCR Models](https://huggingface.co/blog/ocr-open-models#cutting-edge-open-ocr-models)\n    - [Comparing Latest Models](https://huggingface.co/blog/ocr-open-models#comparing-latest-models)\n    - [Evaluating Models](https://huggingface.co/blog/ocr-open-models#evaluating-models)\n      - [Benchmarks](https://huggingface.co/blog/ocr-open-models#benchmarks)\n      - [Cost-efficiency](https://huggingface.co/blog/ocr-open-models#cost-efficiency)\n      - [Open OCR Datasets](https://huggingface.co/blog/ocr-open-models#open-ocr-datasets)\n  - [Tools to Run Models](https://huggingface.co/blog/ocr-open-models#tools-to-run-models)\n    - [Locally](https://huggingface.co/blog/ocr-open-models#locally)\n    - [Remotely](https://huggingface.co/blog/ocr-open-models#remotely)\n  - [Going Beyond OCR](https://huggingface.co/blog/ocr-open-models#going-beyond-ocr)\n    - [Visual Document Retrievers](https://huggingface.co/blog/ocr-open-models#visual-document-retrievers)\n    - [Using Vision Language Models for Document Question Answering](https://huggingface.co/blog/ocr-open-models#using-vision-language-models-for-document-question-answering)\n  - [Wrapping up](https://huggingface.co/blog/ocr-open-models#wrapping-up)\n\n## Brief Introduction to Modern OCR\n\nOptical Character Recognition (OCR) is one of the earliest and longest running challenges in computer vision. Many of AI’s first practical applications focused on turning printed text into digital form.\n\nWith the surge of [vision-language models](https://huggingface.co/blog/vlms) (VLMs), OCR has advanced significantly. Recently, many OCR models have been developed by fine-tuning existing VLMs. But today’s capabilities extend far beyond OCR: you can retrieve documents by query or answer questions about them directly. Thanks to stronger vision features, these models can also handle low-quality scans, interpret complex elements like tables, charts, and images, and fuse text with visuals to answer open-ended questions across documents.\n\n### Model Capabilities\n\n#### Transcription\n\nRecent models transcribe texts into a machine-readable format.\\\nThe input can include:\n\n- Handwritten text\n- Various scripts like Latin, Arabic, and Japanese characters\n- Mathematical expressions\n- Chemical formulas\n- Image/Layout/Page number tags\n\nOCR models convert them into machine-readable text that comes in many different formats like HTML, Markdown and more.\n\n#### Handling complex components in documents\n\nOn top of text, some models can also recognize:\n\n- Images\n- Charts\n- Tables\n\nSome models know where images are inside the document, extract their coordinates, and insert them appropriately between texts. Other models generate captions for images and insert them where they appear. This is especially useful if you are feeding the machine-readable output into an LLM. Example models are [OlmOCR by AllenAI](https://huggingface.co/allenai/olmOCR-7B-0825), or [PaddleOCR-VL by PaddlePaddle](https://huggingface.co/PaddlePaddle/PaddleOCR-VL).\n\nModels use different machine-readable output formats, such as **DocTags**, **HTML** or **Markdown** (explained in the next section *Output Formats*). The way a model handles tables and charts often depends on the output format they are using. Some models treat charts like images: they are kept as is. Other models convert charts into markdown tables or JSON, e.g., a bar chart can be converted as follows.\n\n[![Chart Rendering](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/ocr/chart-rendering.png)](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/ocr/chart-rendering.png)\n\nSimilarly for tables, cells are converted into a machine-readable format while retaining context from headings and columns.\n\n[![Table Rendering](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/ocr/table-rendering.png)](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/ocr/table-rendering.png)\n\n#### Output formats\n\nDifferent OCR models have different output formats. Briefly, here are the common output formats used by modern models.\\\n**DocTag:** DocTag is an XML-like format for documents that expresses location, text format, component-level information, and more. Below is an illustration of a paper parsed into DocTags. This format is employed by the open Docling models.\n\n[![DocTags](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/ocr/doctags_v2.png)](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/ocr/doctags_v2.png)\n\n- **HTML:** HTML is one of the most popular output formats used for document parsing as it properly encodes structure and hierarchical information.\n- **Markdown:** Markdown is the most human-readable format. It’s simpler than HTML but not as expressive. For example, it can’t represent split-column tables.\n- **JSON:** JSON is not a format that models use for the entire output, but it can be used to represent information in tables or charts.\n\nThe right model depends on how you plan to use its outputs:\n\n- **Digital reconstruction**: To reconstruct documents digitally, choose a model with a layout-preserving format (e.g., DocTags or HTML).\n- **LLM input or Q&A**: If the use case involves passing outputs to LLM, pick a model that outputs Markdown and image captions, since they’re closer to natural language.\n- **Programmatic use**: If you want to pass your outputs to a program (like data analysis), opt for a model that generates structured outputs like JSON.\n\n#### Locality Awareness\n\nDocuments can have complex structures, like multi-column text blocks and floating figures. Older OCR models handled these documents by detecting words and then the layout of pages manually in post-processing to have the text rendered in reading order, which is brittle. Modern OCR models, on the other hand, incorporate layout metadata to help preserve reading order and accuracy. This metadata is called “anchor”, it can come in bounding boxes. This process is also called as “grounding/anchoring” because it helps with reducing hallucination.\n\n#### Model Prompting\n\nOCR models can either take in images and an optional text prompt, this depends on the model architecture and the pre-training setup.\\\nSome OCR models support prompt-based task switching, e.g. [granite-docling](https://huggingface.co/ibm-granite/granite-docling-258M) can parse an entire page with the prompt “Convert this page to Docling” while it can also take prompts like “Convert this formula to LaTeX” along with a page full of formulas.\\\nOther models, however, are trained only for parsing entire pages, and they are conditioned to do this through a system prompt.\\\nFor instance, [OlmOCR by AllenAI](https://huggingface.co/collections/allenai/olmocr-67af8630b0062a25bf1b54a1) takes a long conditioning prompt. Like many others, OlmOCR is technically an OCR fine-tuned version of a VLM (Qwen2.5VL in this case), so you can prompt for other tasks, but its performance will not be on par with the OCR capabilities.\n\n## Cutting-edge Open OCR Models\n\nWe’ve seen an incredible wave of new models this past year. Because so much work is happening in the open, these players build on and benefit from each other’s work. A great example is AllenAI’s release of OlmOCR, which not only released a model but also the dataset used to train it. With these, others can build upon them in new directions. The field is incredibly active, but it’s not always obvious which model to use.\n\n### Comparing Latest Models\n\nTo make things a bit easier, we’re putting together a non-exhaustive comparison of some of our current favorite models. All of the models below are layout-aware and can parse tables, charts, and math equations. The full list of languages each model supports are detailed in their model cards, so make sure to check them if you’re interested. All models below have open-source license except for Chandra having OpenRAIL license and Nanonets license being unclear. The average scores are taken from model cards of Chandra, OlmOCR, evaluated on OlmOCR Benchmark, which is English-only. Many of the models in this collection have been fine-tuned from Qwen2.5-VL or Qwen3-VL, so we also provide Qwen3-VL model below as well.\n\n| Model Name                                                                                              | Output formats                                                     | Features                                                                                                                                                             | Model Size | Multilingual?                                        | Average Score on OlmOCR Benchmark |\n| ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | ---------------------------------------------------- | --------------------------------- |\n| [Nanonets-OCR2-3B](https://huggingface.co/collections/nanonets/nanonets-ocr2-68ed207f17ee6c31d226319e) | structured Markdown with semantic tagging (plus HTML tables, etc.) | Captions images in the documents Signature & watermark extraction Handles checkboxes, flowcharts, and handwriting                                                    | 4B         | ✅Supports English, Chinese, French, Arabic and more. | N/A                               |\n| [PaddleOCR-VL](https://huggingface.co/collections/PaddlePaddle/paddleocr-vl-68f0db852483c7af0bc86849)  | Markdown, JSON, HTML tables and charts                             | Handles handwriting, old documents Allows prompting Converts tables & charts to HTML Extracts and inserts images directly                                            | 0.9B       | ✅Supports 109 languages                              | N/A                               |\n| [dots.ocr](https://huggingface.co/rednote-hilab/dots.ocr)                                              | Markdown, JSON                                                     | Grounding Extracts and inserts images Handles handwriting                                                                                                            | 3B         | ✅Multilingual with language info not available       | 79.1 ± 1.0                        |\n| [OlmOCR-2](https://huggingface.co/allenai/olmOCR-2-7B-1025)                                            | Markdown, HTML, LaTeX                                              | Grounding Optimized for large-scale batch processing                                                                                                                 | 8B         | ❎English-only                                        | 82.3 ± 1.1                        |\n| [Granite-Docling-258M](https://huggingface.co/ibm-granite/granite-docling-258M)                        | DocTags                                                            | Prompt-based task switching Ability to prompt element locations with location tokens Rich output                                                                     | 258M       | ✅Supports English, Japanese, Arabic and Chinese.     | N/A                               |\n| [DeepSeek-OCR](https://huggingface.co/deepseek-ai/DeepSeek-OCR)                                        | Markdown, HTML                                                     | Supports general visual understanding Can parse and re-render all charts, tables, and more into HTML Handles handwriting Memory-efficient, solves text through image | 3B         | ✅Supports nearly 100 languages                       | 75.4 ± 1.0                        |\n| [Chandra](https://huggingface.co/datalab-to/chandra)                                                   | Markdown, HTML, JSON                                               | Grounding Extracts and inserts images as is                                                                                                                          | 9B         | ✅Supports 40+ languages                              | 83.1 ± 0.9                        |\n| [Qwen3-VL](https://huggingface.co/collections/Qwen/qwen3-vl)                                           | Vision Language Model can output in all formats                    | Can recognize ancient text Handles handwriting Extracts and inserts images as is                                                                                     | 9B         | ✅Supports 32 languages                               | N/A                               |\n\nWhile Qwen3-VL itself is a powerful and versatile vision-language model post-trained for document understanding and other tasks, it isn’t optimized for a single, universal OCR prompt. In contrast, the other models were fine-tuned using one or a few fixed prompts specifically designed for OCR tasks. So to use Qwen3-VL, we recommend experimenting with prompts.\n\nHere’s a [small demo](https://prithivMLmods-Multimodal-OCR3.hf.space) for you to try some of the latest models and compare their outputs.\n\n### Evaluating Models\n\n#### Benchmarks\n\nThere’s no single best model, as every problem has different needs. Should tables be rendered in Markdown or HTML? Which elements should we extract? How should we quantify text accuracy and error rates? 👀\\\nWhile there are many evaluation datasets and tools, many don’t answer these questions. So we suggest using the following benchmarks:\n\n1. [**OmniDocBenchmark**](https://huggingface.co/datasets/opendatalab/OmniDocBench)**:** This widely used benchmark stands out for its diverse document types: books, magazines, and textbooks. Its evaluation criteria are well designed, accepting tables in both HTML and Markdown formats. A novel matching algorithm evaluates the reading order, and formulas are normalized before evaluation. Most metrics rely on edit distance or tree edit distance (tables). Notably, the annotations used for evaluation are not solely human-generated but are acquired through SoTA VLMs or conventional OCR methods.\n2. [**OlmOCR-Bench**](https://huggingface.co/datasets/allenai/olmOCR-bench): OlmOCR-Bench takes a different approach: they treat the evaluation as a set of unit tests. For example, table evaluation is done by checking the relation between selected cells of a given table. They use PDFs from public sources, and annotations are done using a wide range of closed-source VLMs. This benchmark is quite successful to evaluate on the English language.\n3. [**CC-OCR (Multilingual)**:](https://huggingface.co/datasets/wulipc/CC-OCR) Compared to the previous benchmarks, CC-OCR is less preferred when picking models, due to lower document quality and diversity. However, it’s the only benchmark that contains evaluation beyond English and Chinese! While the evaluation is far from perfect (images are photos with few words), it’s still the best you can do for multilingual evaluation.\n\nWhen testing different OCR models, we've found that the performance across different document types, languages, etc., varies a lot. Your domain may not be well represented in existing benchmarks! To make effective use of this new generation of VLM-based OCR models we suggest aiming to collect a dataset of representative examples of your task domain and testing a few different models to compare their performance.\n\n#### Cost-efficiency\n\nMost OCR models are small, having between 3B and 7B parameters; you can even find models with fewer than 1B parameters, like PaddleOCR-VL. However, the cost also depends on the availability of optimized implementations for specialized inference frameworks. For example, OlmOCR-2 comes with vLLM and SGLang implementations, and the cost per million pages is 178 dollars (assuming on H100 for $2.69/hour). DeepSeek-OCR can process 200k+ pages per day on a single A100 with 40GB VRAM. With napkin math, we see that the cost per million pages is more or less similar to OlmOCR (although it depends on your A100 provider). If your use case remains unaffected, you can also opt for quantized versions of the models. The cost of running open-source models heavily depends on the hourly cost of the instance and the optimizations the model includes, but it’s guaranteed to be cheaper than many closed-source models out there on a larger scale.\n\n#### Open OCR Datasets\n\nWhile the past year has seen a surge in open OCR models, this hasn't been matched by as many open training and evaluation datasets. An exception is AllenAI's [olmOCR-mix-0225](https://huggingface.co/datasets/allenai/olmOCR-mix-0225), which has been used to train at least [72 models on the Hub](https://huggingface.co/models?dataset=dataset:allenai/olmOCR-mix-0225) – likely more, since not all models document their training data.\n\nSharing more datasets could unlock even greater advances in open OCR models. There are several promising approaches for creating these datasets:\n\n- **Synthetic data generation** (e.g., [isl\\_synthetic\\_ocr](https://huggingface.co/datasets/Sigurdur/isl_synthetic_ocr))\n- **VLM-generated transcriptions** filtered manually or through heuristics\n- **Using existing OCR models** to generate training data for new, potentially more efficient models in specific domains\n- **Leveraging existing corrected datasets** like the [Medical History of British India Dataset](https://huggingface.co/NationalLibraryOfScotland), which contains extensively human-corrected OCR for historic documents\n\nIt's worth noting that many such datasets exist but remain unused. Making them more readily available as 'training-ready' datasets carries a considerable potential for the open-source community.\n\n## Tools to Run Models\n\nWe have received many questions about getting started with OCR models, so here are a few ways you can use local inference tools and host remotely with Hugging Face.\n\n### Locally\n\nMost cutting-edge models come with vLLM support and transformers implementation. You can get more info about how to serve each from the models’ own cards. For convenience, we show how to infer locally using vLLM here. The code below can differ from model to model, but for most models it looks like the following.\n\n```shell\nvllm serve nanonets/Nanonets-OCR2-3B\n```\n\nAnd then you can query as follows using e.g. OpenAI client.\n\n```py\nfrom openai import OpenAI\nimport base64\n\nclient = OpenAI(base_url=\"http://localhost:8000/v1\")\n\nmodel = \"nanonets/Nanonets-OCR2-3B\"\n\ndef encode_image(image_path):\n    with open(image_path, \"rb\") as image_file:\n        return base64.b64encode(image_file.read()).decode(\"utf-8\")\n\ndef infer(img_base64):\n    response = client.chat.completions.create(\n        model=model,\n        messages=[\n            {\n                \"role\": \"user\",\n                \"content\": [\n                    {\n                        \"type\": \"image_url\",\n                        \"image_url\": {\"url\": f\"data:image/png;base64,{img_base64}\"},\n                    },\n                    {\n                        \"type\": \"text\",\n                        \"text\": \"Extract the text from the above document as if you were reading it naturally.\",\n                    },\n                ],\n            }\n        ],\n        temperature=0.0,\n        max_tokens=15000\n    )\n    return response.choices[0].message.content\n\nimg_base64 = encode_image(your_img_path)\nprint(infer(img_base64))\n```\n\n**Transformers**\n\nTransformers provides standard model definitions for easy inference and fine-tuning. Models available in transformers come with either official transformers implementation (model definitions within the library) or “remote code” implementations. Latter is defined by the model owners to enable easy loading of models into transformers interface, so you don’t have to go through the model implementation. Below is an example loading Nanonets model using transformers implementation.\n\n```py\n# make sure to install flash-attn and transformers\nfrom transformers import AutoProcessor, AutoModelForImageTextToText\n\nmodel = AutoModelForImageTextToText.from_pretrained(\n    \"nanonets/Nanonets-OCR2-3B\", \n    torch_dtype=\"auto\", \n    device_map=\"auto\", \n    attn_implementation=\"flash_attention_2\"\n)\nmodel.eval()\nprocessor = AutoProcessor.from_pretrained(\"nanonets/Nanonets-OCR2-3B\")\n\ndef infer(image_url, model, processor, max_new_tokens=4096):\n    prompt = \"\"\"Extract the text from the above document as if you were reading it naturally. Return the tables in html format. Return the equations in LaTeX representation. If there is an image in the document and image caption is not present, add a small description of the image inside the <img></img> tag; otherwise, add the image caption inside <img></img>. Watermarks should be wrapped in brackets. Ex: <watermark>OFFICIAL COPY</watermark>. Page numbers should be wrapped in brackets. Ex: <page_number>14</page_number> or <page_number>9/22</page_number>. Prefer using ☐ and ☑ for check boxes.\"\"\"\n    image = Image.open(image_path)\n    messages = [\n        {\"role\": \"system\", \"content\": \"You are a helpful assistant.\"},\n        {\"role\": \"user\", \"content\": [\n            {\"type\": \"image\", \"image\": image_url},\n            {\"type\": \"text\", \"text\": prompt},\n        ]},\n    ]\n    text = processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)\n    inputs = processor(text=[text], images=[image], padding=True, return_tensors=\"pt\").to(model.device)\n    \n    output_ids = model.generate(**inputs, max_new_tokens=max_new_tokens, do_sample=False)\n    generated_ids = [output_ids[len(input_ids):] for input_ids, output_ids in zip(inputs.input_ids, output_ids)]\n    \n    output_text = processor.batch_decode(generated_ids, skip_special_tokens=True, clean_up_tokenization_spaces=True)\n    return output_text[0]\n\nresult = infer(image_path, model, processor, max_new_tokens=15000)\nprint(result)\n```\n\n**MLX**\\\nMLX is an open-source machine learning framework for Apple Silicon. [MLX-VLM](https://github.com/Blaizzy/mlx-vlm) is built on top of MLX to serve vision language models easily. You can explore all the OCR models available in MLX format [here](https://huggingface.co/models?sort=trending&search=ocr). They also come in quantized versions.\\\nYou can install MLX-VLM as follows.\n\n```\npip install -U mlx-vlm\n```\n\n```\nwget https://huggingface.co/datasets/merve/vlm_test_images/resolve/main/throughput_smolvlm.png\n\npython -m mlx_vlm.generate --model ibm-granite/granite-docling-258M-mlx --max-tokens 4096 --temperature 0.0 --prompt \"Convert this chart to JSON.\" --image throughput_smolvlm.png \n```\n\n### Remotely\n\n**Inference Endpoints for Managed Deployment**\\\nYou can deploy OCR models compatible with vLLM or SGLang on Hugging Face Inference Endpoints, either from a model repository “Deploy” option or directly through [Inference Endpoints interface](https://endpoints.huggingface.co/). Inference Endpoints serve the cutting-edge models in a fully managed environment with GPU acceleration, auto-scaling, and monitoring without manually managing the infrastructure.\n\nHere is a simple method of deploying `nanonets` using vLLM as the inference engine.\n\n1. Navigate to the model repository [`nanonets/Nanonets-OCR2-3B`](https://huggingface.co/nanonets/Nanonets-OCR2-3B)\n2. Click on the “Deploy” button and select the “HF Inference Endpoints”\n\n[![Inference Endpoints](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/ocr/IE.png)](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/ocr/IE.png)\n\n3. Configure the deployment setup within seconds\n\n[![Inference Endpoints](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/ocr/IE2.png)](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/ocr/IE2.png)\n\n4. After the endpoint is created, you can consume it using the OpenAI client snippet we provided in the previous section.\n\nYou can learn more about it [here](https://huggingface.co/docs/inference-endpoints/engines/vllm).\n\n**Hugging Face Jobs for Batch Inference**\n\nFor many OCR applications, you want to do efficient batch inference, i.e., running a model across thousands of images as cheaply and efficiently as possible. A good approach is to use vLLM's offline inference mode. As discussed above, many recent VLM-based OCR models are supported by vLLM, which efficiently batches images and generates OCR outputs at scale.\n\nTo make this even easier, we've created [uv-scripts/ocr](https://huggingface.co/datasets/uv-scripts/ocr), a collection of ready-to-run OCR scripts that work with Hugging Face Jobs. These scripts let you run OCR on any dataset without needing your own GPU. Simply point the script at your input dataset, and it will:\n\n- Process all images in a dataset column using many different open OCR models\n- Add OCR results as a new markdown column to the dataset\n- Push the updated dataset with OCR results to the Hub\n\nFor example, to run OCR on 100 images:\n\n```bash\nhf jobs uv run --flavor l4x1 \\\n  https://huggingface.co/datasets/uv-scripts/ocr/raw/main/nanonets-ocr.py \\\n  your-input-dataset your-output-dataset \\\n  --max-samples 100\n```\n\nThe scripts handle all the vLLM configuration and batching automatically, making batch OCR accessible without infrastructure setup.\n\n### Going Beyond OCR\n\nIf you are interested in document AI, not just OCR, here are some of our recommendations.\n\n#### Visual Document Retrievers\n\nVisual document retrieval is to retrieve the most relevant top-k documents when given a text query. If you have previously worked with retriever models, the difference is that you search directly on a stack of PDFs. Aside from using them standalone, you can also build multimodal RAG pipelines by combining them with a vision language model (find how to do so [here](https://huggingface.co/merve/smol-vision/blob/main/ColPali_%2B_Qwen2_VL.ipynb)). You can find [all of them on Hugging Face Hub](https://huggingface.co/models?pipeline_tag=visual-document-retrieval&sort=trending).\n\nThere are two types of visual document retrievers, single-vector and multi-vector models. Single-vector models are more memory efficient and less performant; meanwhile, multi-vector models are more memory hungry and more performant. Most of these models often come with vLLM and transformers integrations, so you can index documents using them and then do a search easily using a vector DB.\n\n#### Using Vision Language Models for Document Question Answering\n\nIf you have a task at hand that only requires answering questions based on documents, you can use some of the vision language models that had document tasks in their training tasks. We’ve observed users trying to convert documents into text and passing the output to LLMs, but if your document has a complex layout, and your converted document outputs charts and so on in HTML, or images are captioned incorrectly, the LLM will miss out. Instead, feed your document and query to one of the advanced vision language models like [Qwen3-VL](https://huggingface.co/collections/Qwen/qwen3-vl-68d2a7c1b8a8afce4ebd2dbe) not to miss out on any context.\n\n## Wrapping up\n\nIn this blog post, we wanted to give you an overview of how to pick your OCR model, existing cutting-edge models and capabilities, and the tools to get you started with OCR.\\\nIf you want to learn more about OCR and vision language models, we encourage you to read the resources below.\n\n- [Vision Language Models Explained](https://huggingface.co/blog/vlms)\n- [Vision Language Models 2025 Update](https://huggingface.co/blog/vlms-2025)\n- [Blog on PP-OCR-v5](https://huggingface.co/blog/baidu/ppocrv5)\n- [Tutorial: Fine-tuning Kosmos2.5 on Grounded OCR](https://huggingface.co/merve/smol-vision/blob/main/Grounded_Fine_tuning.ipynb)\n- [Tutorial: Fine-tuning Florence-2 on DocVQA](https://huggingface.co/merve/smol-vision/blob/main/Fine_tune_Florence_2.ipynb)\n- [SOTA OCR on-device with Core ML and dots.ocr](https://huggingface.co/blog/dots-ocr-ne)\n",
  "dateCreated": "2026-10-04T12:50:30.804479567+00:00",
  "date_created": "2025-10-21T00:00:00+00:00",
  "date_modified": "2025-10-21T00:00:00+00:00",
  "date_published": "2025-10-21T00:00:00+00:00",
  "description": "We have added Chandra and OlmOCR-2 to this blog, as well as OlmOCR Scores of the models 🫡 TL;DR: The rise of powerful vision-language models has transformed document AI. Each model comes with unique strengths, making it tricky to choose…",
  "external_url": "https://huggingface.co/blog/ocr-open-models",
  "git": {
    "commit": "ebb0941c5c06a2ab2377342d607535262a3e969e",
    "path": "items/huggingface-co/2025/10/2025-10-21-supercharge-your-ocr-pipelines-with-open-models.md",
    "permalink": "https://github.com/aymericbeaumet/aggr-instance/blob/ebb0941c5c06a2ab2377342d607535262a3e969e/items/huggingface-co/2025/10/2025-10-21-supercharge-your-ocr-pipelines-with-open-models.md"
  },
  "id": "urn:aggr:item:d37d5f8c15f3370e9691140a9b1be599a97c1dc6",
  "isBasedOn": {
    "@id": "https://huggingface.co/blog/ocr-open-models"
  },
  "mainEntity": {
    "@id": "https://huggingface.co/blog/ocr-open-models",
    "@type": "CreativeWork",
    "archivedAt": {
      "@id": "https://aggr.aymericbeaumet.com/items/huggingface-co/2025-10-21-supercharge-your-ocr-pipelines-with-open-models/#webpage"
    },
    "dateModified": "2025-10-21T00:00:00+00:00",
    "datePublished": "2025-10-21T00:00:00+00:00",
    "headline": "Supercharge your OCR Pipelines with Open Models",
    "timeRequired": "PT15M",
    "url": "https://huggingface.co/blog/ocr-open-models",
    "wordCount": 3347
  },
  "name": "Archived snapshot: Supercharge your OCR Pipelines with Open Models",
  "preview": null,
  "reading_minutes": 15,
  "replicated_at": null,
  "source": "huggingface-co",
  "source_name": "Hugging Face - Blog",
  "summary": null,
  "tags": [],
  "temporalCoverage": "2026-10-04T12:50:30.804479567+00:00",
  "title": "Supercharge your OCR Pipelines with Open Models",
  "url": "https://aggr.aymericbeaumet.com/items/huggingface-co/2025-10-21-supercharge-your-ocr-pipelines-with-open-models/",
  "word_count": 3347
}