Integrating MinerU2.5 into FiftyOne as a Remote Source Zoo Model
Python
6
26 commits
updated Nov 14, 2025

A FiftyOne zoo model integration for MinerU2.5, a 1.2B-parameter vision-language model for efficient high-resolution document parsing.
MinerU2.5 achieves state-of-the-art document parsing accuracy with a two-stage strategy:
Key capabilities:
For more details, see the model card and technical report.
pip install fiftyone
pip install "mineru-vl-utils[transformers]"
For the best experience viewing extracted text, we recommend installing the Caption Viewer plugin, which provides intelligent formatting for OCR outputs and text fields:
fiftyone plugins download https://github.com/harpreetsahota204/caption_viewer
This plugin automatically:
import fiftyone.zoo as foz
foz.register_zoo_model_source(
"https://github.com/harpreetsahota204/mineru_2_5",
overwrite=True
)
# Load with default settings (fast layout detection mode)
model = foz.load_zoo_model(
"opendatalab/MinerU2.5-2509-1.2B",
operation="layout_detection", # Fast mode (default)
batch_size=8 # Process 8 images at once
)
MinerU now supports three operation modes with different speed/accuracy tradeoffs:
Get bounding boxes for all document elements with 1 inference pass per image:
import fiftyone as fo
# Load your dataset
dataset = fo.load_dataset("your-dataset")
# Apply fast layout detection (default)
model.operation = "layout_detection"
dataset.apply_model(model, label_field="layout")
Speed: ~50ms per image (1.2B model on GPU)
Returns: fo.Detections with bounding boxes and element types
Use case: Quick document analysis, element counting, layout understanding
Full extraction with bounding boxes AND OCR content:
model.operation = "ocr_detection"
dataset.apply_model(model, label_field="text_detections")
Speed: ~800ms per image (15 blocks × 50ms + overhead)
Returns: fo.Detections with bounding boxes, types, AND extracted text
Use case: Complete document extraction with precise element locations
Extract all text content as a single string:
model.operation = "ocr"
dataset.apply_model(model, label_field="text_extraction")
Speed: ~50ms per image
Returns: Plain text string
Use case: Full-text search, content indexing
All detection modes return fo.Detections with:
text, title, table, equation, image, etc.)[x, y, width, height]layout_detection mode)import fiftyone as fo
import fiftyone.zoo as foz
# Register and load model
foz.register_zoo_model_source(
"https://github.com/harpreetsahota204/mineru_2_5",
overwrite=True
)
# Load model with batching support (NEW!)
model = foz.load_zoo_model(
"opendatalab/MinerU2.5-2509-1.2B",
operation="layout_detection", # Fast mode (default)
batch_size=8 # Process 8 images at once
)
# Load your dataset
dataset = fo.Dataset.from_dir(
dataset_dir="/path/to/images",
dataset_type=fo.types.ImageDirectory,
)
# Apply FAST layout detection (with batching!)
model.operation = "layout_detection"
dataset.apply_model(model, label_field="layout")
# Optionally: Apply full OCR to specific samples
# model.operation = "ocr_detection"
# dataset.match(F("layout.detections").length() > 5).apply_model(
# model, label_field="detailed_ocr"
# )
# Launch the app
session = fo.launch_app(dataset)
| Operation | Inference Passes | Speed (per image) | Use Case |
|---|---|---|---|
layout_detection | 1 pass | ~50ms | Fast bounding boxes only ⚡ |
ocr | 1 pass | ~50ms | Fast text extraction ⚡ |
ocr_detection | N+1 passes | ~800ms | Complete extraction 🐢 |
Batching speedup: With batch_size=8, you get an additional 3-5x speedup from GPU parallelization!
layout_detection (default): Fast layout with bounding boxes → fo.Detections (1 pass)ocr_detection: Full extraction with content → fo.Detections (N+1 passes)ocr: Plain text only → str (1 pass)The model now supports efficient batching via FiftyOne's SupportsGetItem interface:
# Load model with initial batch size
model = foz.load_zoo_model(
"opendatalab/MinerU2.5-2509-1.2B",
operation="layout_detection",
batch_size=8, # Internal MinerU batch size (default: 8)
)
# Batching happens automatically with apply_model()
dataset.apply_model(
model,
label_field="results",
batch_size=8, # FiftyOne DataLoader batch size
num_workers=4 # Parallel data loading workers
)
Why set batch_size in two places?
model.batch_size: Controls MinerU's internal inference batching (how many images the VLM processes at once)apply_model(..., batch_size=...): Controls FiftyOne's DataLoader batching (how many images are loaded in parallel)For best performance, set both to the same value:
BATCH_SIZE = 32
# Update model's internal batch size
model.batch_size = BATCH_SIZE
model.operation = "layout_detection"
# Apply with matching DataLoader batch size
dataset.apply_model(
model,
label_field="layout",
batch_size=BATCH_SIZE, # Match model.batch_size
num_workers=8 # 8 workers for parallel I/O
)
Benefits:
num_workersThe model automatically:
torch.float16 on CUDA, float32 on CPU/MPSdevice_map overhead for small models)@misc{niu2025mineru25decoupledvisionlanguagemodel,
title={MinerU2.5: A Decoupled Vision-Language Model for Efficient High-Resolution Document Parsing},
author={Junbo Niu and Zheng Liu and Zhuangcheng Gu and Bin Wang and Linke Ouyang and Zhiyuan Zhao and Tao Chu and Tianyao He and Fan Wu and Qintong Zhang and Zhenjiang Jin and others},
year={2025},
eprint={2509.22186},
archivePrefix={arXiv},
primaryClass={cs.CV},
url={https://arxiv.org/abs/2509.22186}
}
AGPL-3.0 (as per the original MinerU2.5 model)
26 commits
Python
70.5%
Jupyter Notebook
29.5%
Integrating MinerU2.5 into FiftyOne as a Remote Source Zoo Model
Python
6
26 commits
updated Nov 14, 2025

A FiftyOne zoo model integration for MinerU2.5, a 1.2B-parameter vision-language model for efficient high-resolution document parsing.
MinerU2.5 achieves state-of-the-art document parsing accuracy with a two-stage strategy:
Key capabilities:
For more details, see the model card and technical report.
pip install fiftyone
pip install "mineru-vl-utils[transformers]"
For the best experience viewing extracted text, we recommend installing the Caption Viewer plugin, which provides intelligent formatting for OCR outputs and text fields:
fiftyone plugins download https://github.com/harpreetsahota204/caption_viewer
This plugin automatically:
import fiftyone.zoo as foz
foz.register_zoo_model_source(
"https://github.com/harpreetsahota204/mineru_2_5",
overwrite=True
)
# Load with default settings (fast layout detection mode)
model = foz.load_zoo_model(
"opendatalab/MinerU2.5-2509-1.2B",
operation="layout_detection", # Fast mode (default)
batch_size=8 # Process 8 images at once
)
MinerU now supports three operation modes with different speed/accuracy tradeoffs:
Get bounding boxes for all document elements with 1 inference pass per image:
import fiftyone as fo
# Load your dataset
dataset = fo.load_dataset("your-dataset")
# Apply fast layout detection (default)
model.operation = "layout_detection"
dataset.apply_model(model, label_field="layout")
Speed: ~50ms per image (1.2B model on GPU)
Returns: fo.Detections with bounding boxes and element types
Use case: Quick document analysis, element counting, layout understanding
Full extraction with bounding boxes AND OCR content:
model.operation = "ocr_detection"
dataset.apply_model(model, label_field="text_detections")
Speed: ~800ms per image (15 blocks × 50ms + overhead)
Returns: fo.Detections with bounding boxes, types, AND extracted text
Use case: Complete document extraction with precise element locations
Extract all text content as a single string:
model.operation = "ocr"
dataset.apply_model(model, label_field="text_extraction")
Speed: ~50ms per image
Returns: Plain text string
Use case: Full-text search, content indexing
All detection modes return fo.Detections with:
text, title, table, equation, image, etc.)[x, y, width, height]layout_detection mode)import fiftyone as fo
import fiftyone.zoo as foz
# Register and load model
foz.register_zoo_model_source(
"https://github.com/harpreetsahota204/mineru_2_5",
overwrite=True
)
# Load model with batching support (NEW!)
model = foz.load_zoo_model(
"opendatalab/MinerU2.5-2509-1.2B",
operation="layout_detection", # Fast mode (default)
batch_size=8 # Process 8 images at once
)
# Load your dataset
dataset = fo.Dataset.from_dir(
dataset_dir="/path/to/images",
dataset_type=fo.types.ImageDirectory,
)
# Apply FAST layout detection (with batching!)
model.operation = "layout_detection"
dataset.apply_model(model, label_field="layout")
# Optionally: Apply full OCR to specific samples
# model.operation = "ocr_detection"
# dataset.match(F("layout.detections").length() > 5).apply_model(
# model, label_field="detailed_ocr"
# )
# Launch the app
session = fo.launch_app(dataset)
| Operation | Inference Passes | Speed (per image) | Use Case |
|---|---|---|---|
layout_detection | 1 pass | ~50ms | Fast bounding boxes only ⚡ |
ocr | 1 pass | ~50ms | Fast text extraction ⚡ |
ocr_detection | N+1 passes | ~800ms | Complete extraction 🐢 |
Batching speedup: With batch_size=8, you get an additional 3-5x speedup from GPU parallelization!
layout_detection (default): Fast layout with bounding boxes → fo.Detections (1 pass)ocr_detection: Full extraction with content → fo.Detections (N+1 passes)ocr: Plain text only → str (1 pass)The model now supports efficient batching via FiftyOne's SupportsGetItem interface:
# Load model with initial batch size
model = foz.load_zoo_model(
"opendatalab/MinerU2.5-2509-1.2B",
operation="layout_detection",
batch_size=8, # Internal MinerU batch size (default: 8)
)
# Batching happens automatically with apply_model()
dataset.apply_model(
model,
label_field="results",
batch_size=8, # FiftyOne DataLoader batch size
num_workers=4 # Parallel data loading workers
)
Why set batch_size in two places?
model.batch_size: Controls MinerU's internal inference batching (how many images the VLM processes at once)apply_model(..., batch_size=...): Controls FiftyOne's DataLoader batching (how many images are loaded in parallel)For best performance, set both to the same value:
BATCH_SIZE = 32
# Update model's internal batch size
model.batch_size = BATCH_SIZE
model.operation = "layout_detection"
# Apply with matching DataLoader batch size
dataset.apply_model(
model,
label_field="layout",
batch_size=BATCH_SIZE, # Match model.batch_size
num_workers=8 # 8 workers for parallel I/O
)
Benefits:
num_workersThe model automatically:
torch.float16 on CUDA, float32 on CPU/MPSdevice_map overhead for small models)@misc{niu2025mineru25decoupledvisionlanguagemodel,
title={MinerU2.5: A Decoupled Vision-Language Model for Efficient High-Resolution Document Parsing},
author={Junbo Niu and Zheng Liu and Zhuangcheng Gu and Bin Wang and Linke Ouyang and Zhiyuan Zhao and Tao Chu and Tianyao He and Fan Wu and Qintong Zhang and Zhenjiang Jin and others},
year={2025},
eprint={2509.22186},
archivePrefix={arXiv},
primaryClass={cs.CV},
url={https://arxiv.org/abs/2509.22186}
}
AGPL-3.0 (as per the original MinerU2.5 model)
26 commits
Python
70.5%
Jupyter Notebook
29.5%