# How to Set Up a Development Environment for allenai/olmocr: Complete Guide

> Set up your allenai/olmocr development environment easily. Install system deps, create a conda env, and pip install extras like gpu or dev versions. Get started fast.

- Repository: [Ai2/olmocr](https://github.com/allenai/olmocr)
- Tags: how-to-guide
- Published: 2026-07-07

---

**Install system dependencies (poppler-utils, fonts, and optionally CUDA), create a Python 3.11 conda environment, run `pip install -e .`, then install extras like `[gpu]` or `[dev]` based on your use case.**

Setting up a development environment for allenai/olmocr requires configuring system-level PDF dependencies, creating an isolated Python environment, and installing optional extras for GPU inference or distributed processing. This guide walks you through the exact steps needed to build the olmOCR toolkit from source, whether you plan to run local inference, submit Beaker jobs, or extend the benchmark suite.

## Install System Dependencies

olmOCR requires several system-level packages for PDF rendering and text recognition. These are used by the rendering code in [`olmocr/data/renderpdf.py`](https://github.com/allenai/olmocr/blob/main/olmocr/data/renderpdf.py) to extract raster images from PDFs.

On Ubuntu or Debian, run:

```bash
sudo apt-get update
sudo apt-get install poppler-utils ttf-mscorefonts-installer msttcorefonts fonts-crosextra-caladea fonts-crosextra-carlito gsfonts lcdf-typetools

```

**For GPU inference**, install NVIDIA drivers and **CUDA ≥12.0**. The `[gpu]` optional dependency pulls in `torch` and `vllm`, which require compatible CUDA drivers to utilize the vision-language model (VLM) locally.

## Create a Python Environment

olmOCR requires **Python 3.11**. Create an isolated conda environment to avoid dependency conflicts:

```bash
conda create -n olmocr python=3.11
conda activate olmocr

```

Install the base package in editable mode from the repository root:

```bash
pip install -e .

```

This installs the required runtime dependencies declared in [`pyproject.toml`](https://github.com/allenai/olmocr/blob/main/pyproject.toml) (e.g., `pypdf`, `Pillow`, `boto3`), but excludes heavy extras like GPU libraries or testing frameworks.

## Install Optional Extras

The repository defines four optional dependency groups in [`pyproject.toml`](https://github.com/allenai/olmocr/blob/main/pyproject.toml) under `[project.optional-dependencies]`. Install only what you need:

- **GPU inference**: `pip install "olmocr[gpu]"` — Adds `torch`, `vllm`, and `transformers` for local GPU processing.
- **Beaker cluster**: `pip install "olmocr[beaker]"` — Adds `beaker-py` for submitting jobs to AI2's Beaker cluster.
- **Benchmark suite**: `pip install "olmocr[bench]"` — Adds `tinyhost`, `playwright`, and `openai` for running the olmOCR-Bench evaluation suite.
- **Development**: `pip install "olmocr[dev]"` — Adds `ruff`, `pytest`, `mypy`, and `sphinx` for contributors.

## Verify Your Installation

Run the built-in sanity check to confirm poppler and torch GPU status:

```bash
python -c "from olmocr.check import check_poppler_version, check_torch_gpu_available; check_poppler_version(); check_torch_gpu_available()"

```

If both return `OK`, your environment is ready for processing.

## Run the Pipeline Locally

Once installed, process PDFs to Markdown using local GPU inference:

```bash
mkdir -p my_workspace

olmocr my_workspace \
    --pdfs tests/gnarly_pdfs/olmo-page-1.pdf \
    --markdown \
    --gpu-memory-utilization 0.9

```

**What happens under the hood:**
1. **WorkQueue** ([`olmocr/work_queue.py`](https://github.com/allenai/olmocr/blob/main/olmocr/work_queue.py)) creates a local work queue for the specified PDFs.
2. **Worker coroutines** in [`olmocr/pipeline.py`](https://github.com/allenai/olmocr/blob/main/olmocr/pipeline.py) render each page to base64 PNG using `render_pdf_to_base64png` from [`olmocr/data/renderpdf.py`](https://github.com/allenai/olmocr/blob/main/olmocr/data/renderpdf.py).
3. The **vLLM server** (`vllm_server_task` in [`pipeline.py`](https://github.com/allenai/olmocr/blob/main/pipeline.py)) processes vision-language requests.
4. **PageResponse** parsing (defined in [`olmocr/prompts.py`](https://github.com/allenai/olmocr/blob/main/olmocr/prompts.py)) extracts natural text and builds Dolma documents via `build_dolma_document`.

## Remote Inference and S3 Scaling

To skip local GPU setup and use an external vLLM endpoint:

```bash
olmocr my_workspace \
    --pdfs tests/gnarly_pdfs/olmo-page-1.pdf \
    --server https://my-vllm-instance:8000/v1 \
    --api_key $MY_API_KEY \
    --markdown

```

For large-scale processing, use S3-backed work queues:

```bash
olmocr s3://my-bucket/workspace \
    --pdfs s3://my-bucket/pdfs/*.pdf \
    --beaker \
    --workers 40

```

The `S3Backend` in [`olmocr/work_queue.py`](https://github.com/allenai/olmocr/blob/main/olmocr/work_queue.py) handles S3 I/O via `boto3`, while `submit_beaker_job` (in [`pipeline.py`](https://github.com/allenai/olmocr/blob/main/pipeline.py)) constructs Beaker experiment specs when the `--beaker` flag is present.

## Development Workflow

Run the test suite to ensure your changes do not break existing functionality:

```bash
pytest -m "not nonci"

```

Lint and type-check your code:

```bash
ruff check .
mypy .

```

Tests are located in `tests/` (e.g., [`tests/test_pipeline.py`](https://github.com/allenai/olmocr/blob/main/tests/test_pipeline.py), [`tests/test_table_parsing.py`](https://github.com/allenai/olmocr/blob/main/tests/test_table_parsing.py)) and use PDF fixtures stored in `tests/gnarly_pdfs/`.

## Code Examples

### Direct VLM Invocation

Bypass the pipeline and call the VLM directly using internal functions from [`olmocr/pipeline.py`](https://github.com/allenai/olmocr/blob/main/olmocr/pipeline.py):

```python
import asyncio
from olmocr.pipeline import build_page_query, try_single_page

async def demo():
    query = await build_page_query(
        local_pdf_path="tests/gnarly_pdfs/olmo-page-1.pdf",
        page=1,
        target_longest_image_dim=1024,
        model_name="allenai/olmOCR-2-7B-1025-FP8",
    )
    
    args = type("Args", (), {
        "server": "http://localhost:8000/v1",
        "model": "allenai/olmOCR-2-7B-1025-FP8",
        "target_longest_image_dim": 1024,
        "max_page_retries": 0,
        "guided_decoding": False,
        "api_key": None,
    })
    
    result = await try_single_page(args, "dummy.pdf", "tests/gnarly_pdfs/olmo-page-1.pdf", 1, 0, 0)
    print(result.response.natural_text)

asyncio.run(demo())

```

### Programmatic Batch Processing

Convert multiple PDFs to Dolma documents programmatically:

```python
from olmocr.pipeline import process_single_pdf
import asyncio
from json import dumps

async def batch_convert(pdf_paths, workspace):
    docs = []
    for pdf in pdf_paths:
        doc = await process_single_pdf(
            args=type("Args", (), {
                "apply_filter": False,
                "max_page_error_rate": 0.004,
                "max_page_retries": 8,
                "target_longest_image_dim": 1024,
                "markdown": False,
                "server": None,
                "model": "allenai/olmOCR-2-7B-1025-FP8",
                "api_key": None,
                "guided_decoding": False,
            }),
            worker_id=0,
            pdf_orig_path=pdf,
            local_pdf_path=pdf,
        )
        if doc:
            docs.append(doc)
    
    with open(f"{workspace}/output.jsonl", "w") as f:
        for d in docs:
            f.write(dumps(d) + "\n")

asyncio.run(batch_convert(
    ["tests/gnarly_pdfs/olmo-page-1.pdf"],
    workspace="my_workspace"
))

```

## Summary

- **System dependencies** include `poppler-utils` and font packages for PDF rendering, plus CUDA ≥12.0 for GPU inference.
- **Python 3.11** is required; install the base package with `pip install -e .` and add extras like `[gpu]` or `[beaker]` as needed.
- **Verify** your setup using `check_poppler_version()` and `check_torch_gpu_available()` from `olmocr.check`.
- **Local processing** uses [`olmocr/pipeline.py`](https://github.com/allenai/olmocr/blob/main/olmocr/pipeline.py) to orchestrate workers that render PDFs via [`olmocr/data/renderpdf.py`](https://github.com/allenai/olmocr/blob/main/olmocr/data/renderpdf.py) and query a local vLLM server.
- **Remote processing** supports external vLLM endpoints and S3-backed distributed queues via [`olmocr/work_queue.py`](https://github.com/allenai/olmocr/blob/main/olmocr/work_queue.py).

## Frequently Asked Questions

### What Python version is required for allenai/olmocr?

The repository requires **Python 3.11**, as specified in the development documentation. Using a different version may result in dependency conflicts with `torch` and `vllm`.

### Can I run olmocr without a GPU?

Yes, you can run olmocr using a remote vLLM server by specifying `--server https://your-endpoint/v1` and optionally `--api_key`. However, local CPU inference is not supported for the vision-language model; the `[gpu]` extra is required for local processing.

### How do I run the benchmark suite?

Install the benchmark dependencies with `pip install "olmocr[bench]"`, then execute `python -m olmocr.bench.run --model allenai/olmOCR-2-7B-1025-FP8`. This runs approximately 7,000 test cases covering tables, equations, and handwriting extraction.

### What is the difference between the [beaker] and [dev] extras?

The `[beaker]` extra installs `beaker-py` for submitting jobs to AI2's Beaker cluster, enabling distributed processing via the `--beaker` CLI flag. The `[dev]` extra installs linting and testing tools (`ruff`, `pytest`, `mypy`) for code quality and unit testing during development.