Model reference · open weights
LightOnOCR-2 is an open-weight language model from lightonai. LightOnOCR-2-1B (BF16) weighs 2.0 GB; the smallest configuration that runs it is RTX 3060 12 GB.
Summary of the lightonai/LightOnOCR-2-1B model card, 2026-10-01
What it is
| Released by | lightonai |
|---|---|
| Released | 2026-01-16 |
| Parameters | 1.0B |
| VRAM | 2.0 GB for the weights |
What it runs on
| Card | Requests at once | Context max | Memory |
|---|---|---|---|
| 8K each | |||
| RTX 3060 12 GB | 8 | all 16K | 11.6 GB |
| RTX 4060 Ti 16 GB | 12 | all 16K | 15.4 GB |
| RTX 3090 24 GB | 20 | all 16K | 23.4 GB |
| RTX 4090 24 GB | 20 | all 16K | 23.4 GB |
| RTX 5090 32 GB | 28 | all 16K | 31.0 GB |
| L40S 48 GB | 42 | all 16K | 44.0 GB |
| A100 80 GB | 79 | all 16K | 78.2 GB |
| H100 80 GB | 74 | all 16K | 78.1 GB |
| RTX PRO 6000 Blackwell 96 GB | 91 | all 16K | 93.8 GB |
| DGX Spark (GB10) 128 GB unified | 105 | all 16K | 107 GB |
| H200 141 GB | 138 | all 16K | 138 GB |
| B200 180 GB | 178 | all 16K | 176 GB |
| Requests at once | 8K tokens each |
|---|---|
| 1 | 4.9 GB |
| 5 | 8.6 GB |
| 8 | 11.4 GB |
| 16 | 19.0 GB |
| 32 | 34.0 GB |
| 64 | 64.1 GB |
One card, with vLLM's small-card settings.
From the model card
Best OCR model . LightOnOCR-2-1B is LightOn's flagship OCR model, refined with RLVR training for maximum accuracy. We recommend this variant for most OCR tasks.
LightOnOCR-2 is an efficient end-to-end 1B-parameter vision-language model for converting documents (PDFs, scans, images) into clean, naturally ordered text without relying on brittle pipelines. This second version is trained on a larger and higher-quality corpus with stronger French, arXiv, and scan coverage, improved LaTeX handling, and cleaner normalization. LightOnOCR-2 achieves state-of-the-art performance on OlmOCR-Bench while being ~9× smaller and significantly faster than competing approaches.
| Variant | Description |
|---|---|
| LightOnOCR-2-1B | Best OCR model |
| LightOnOCR-2-1B-base | Base model, ideal for fine-tuning |
| LightOnOCR-2-1B-bbox | Best model with image bounding boxes |
| LightOnOCR-2-1B-bbox-base | Base bbox model, ideal for fine-tuning |
| LightOnOCR-2-1B-ocr-soup | Merged variant for extra robustness |
| LightOnOCR-2-1B-bbox-soup | Merged variant: OCR + bbox combined |
See the paper for full benchmark details and methodology.
Note: LightOnOCR-2 is avaible in latest transformers release starting from v5.
uv pip install transformers # => 5.0.0
uv pip install pillow pypdfium2
import torch
from transformers import LightOnOcrForConditionalGeneration, LightOnOcrProcessor
device = "mps" if torch.backends.mps.is_available() else "cuda" if torch.cuda.is_available() else "cpu"
dtype = torch.float32 if device == "mps" else torch.bfloat16
model = LightOnOcrForConditionalGeneration.from_pretrained("lightonai/LightOnOCR-2-1B", torch_dtype=dtype).to(device)
processor = LightOnOcrProcessor.from_pretrained("lightonai/LightOnOCR-2-1B")
url = "https://huggingface.co/datasets/hf-internal-testing/fixtures_ocr/resolve/main/SROIE-receipt.jpeg"
conversation = [{"role": "user", "content": [{"type": "image", "url": url}]}]
inputs = processor.apply_chat_template(
conversation,
add_generation_prompt=True,
tokenize=True,
return_dict=True,
return_tensors="pt",
)
inputs = {k: v.to(device=device, dtype=dtype) if v.is_floating_point() else v.to(device) for k, v in inputs.items()}
output_ids = model.generate(**inputs, max_new_tokens=1024)
generated_ids = output_ids[0, inputs["input_ids"].shape[1]:]
output_text = processor.decode(generated_ids, skip_special_tokens=True)
print(output_text)
vllm serve lightonai/LightOnOCR-2-1B \
--limit-mm-per-prompt '{"image": 1}' --mm-processor-cache-gb 0 --no-enable-prefix-caching
import base64
import requests
import pypdfium2 as pdfium
import io
ENDPOINT = "http://localhost:8000/v1/chat/completions"
MODEL = "lightonai/LightOnOCR-2-1B"
# Download PDF from arXiv
pdf_url = "https://arxiv.org/pdf/2412.13663"
pdf_data = requests.get(pdf_url).content
# Open PDF and convert first page to image
pdf = pdfium.PdfDocument(pdf_data)
page = pdf[0]
# Render at 200 DPI (scale factor = 200/72 ≈ 2.77)
pil_image = page.render(scale=2.77).to_pil()
# Convert to base64
buffer = io.BytesIO()
pil_image.save(buffer, format="PNG")
image_base64 = base64.b64encode(buffer.getvalue()).decode('utf-8')
# Make request
payload = {
"model": MODEL,
"messages": [{
"role": "user",
"content": [{
"type": "image_url",
"image_url": {"url": f"data:image/png;base64,{image_base64}"}
}]
}],
"max_tokens": 4096,
"temperature": 0.2,
"top_p": 0.9,
}
response = requests.post(ENDPOINT, json=payload)
text = response.json()['choices'][0]['message']['content']
print(text)
Quoted from the model card on Hugging Face. The full card is behind the Hugging Face link above.