Skip to content

Repository files navigation

Local OCR Studio

Local OCR Studio turns PDFs, scans, phone photos, tables, forms, receipts, invoices, and handwritten notes into searchable, reviewable results. The web application, uploaded documents, classical OCR, and default AI models all run on your computer.

No cloud API key is required. Internet access is needed during installation, package updates, and model downloads, but not during normal processing with the default configuration.

Quick links

What "local AI" means in this project

Local OCR Studio uses two kinds of processing:

  • Classical processing uses PDF text layers and RapidOCR. Many digital PDFs and clear printed scans finish without using an AI model.
  • Local AI processing uses vision models served by Ollama. It is used for handwriting, tables, complex layouts, and difficult structured extraction.

The application uses Ollama's native /api/chat, /api/tags, /api/version, and /api/ps interfaces. LM Studio, vLLM, LocalAI, and generic OpenAI-compatible servers are not currently drop-in replacements.

Supported setup paths

  • Windows 10 22H2 or newer and Windows 11: supported automated setup; recommended for new users.
  • Modern Ubuntu/Debian-style Linux: manual source setup is documented below, but Linux is not yet exercised by this repository's continuous-integration tests.
  • macOS, Alpine Linux, Docker, and direct network/shared hosting: not currently tested or supported.

The application intentionally listens only on the current computer. It is not designed to be published directly to a network or the Internet.

Requirements and realistic expectations

Software

Requirement Supported version or purpose
Windows Windows 10 22H2 or newer, or Windows 11
PowerShell Version 5 or newer
Python 3.11, 3.12, or 3.13; 64-bit Python 3.11 is the simplest choice
Ollama 0.15.5 or newer; use the current stable release
Browser A current version of Edge, Chrome, Firefox, or another modern browser
Internet Required for initial package/model downloads and later updates

Qwen3-VL requires Ollama 0.12.7 or newer, while the current glm-ocr artifact requires Ollama 0.15.5. Local OCR Studio therefore requires Ollama 0.15.5 or newer for its complete default model set. An older installation may start normally but fail while pulling or loading a default vision model.

Disk, memory, and speed

Plan for at least 15 GB of free disk space before setup, plus space for uploaded documents, generated page images, and backups. Ollama normally stores models under your user profile, while Local OCR Studio stores its working data inside the project folder; those locations may be on different drives.

The default model downloads are approximately:

Model Role Approximate download size
qwen3-vl:2b-instruct Fast extraction and clear handwriting 1.9 GB
qwen3-vl:4b-instruct Difficult-document accuracy fallback 3.3 GB
glm-ocr Tables and complex layouts 2.2 GB
Total 7.4 GB

Model sizes can change when Ollama updates an artifact. The Ollama application, Python environment, and document data require additional space. See the official Qwen3-VL tags and GLM-OCR model page for current artifacts.

A GPU is optional. CPU-only processing works, but a vision-model step can take several minutes per page. A model request may run for up to the default 15-minute timeout; a very slow machine can still time out. There is no formally benchmarked RAM or VRAM minimum yet; 16 GB of system RAM is a practical starting recommendation, not a guaranteed minimum. Run the smoke test described below to measure the actual machine.

Install on Windows from the beginning

These instructions assume no previous Python, Ollama, Git, or command-line experience.

1. Download the project

The easiest option does not require Git:

  1. Open the Local OCR Studio GitHub page.
  2. Select Code, then Download ZIP.
  3. In File Explorer, right-click the downloaded ZIP and select Extract All.
  4. Open the extracted folder. It should contain README.md, setup.ps1, and run.bat.

ZIP is simplest for a one-time trial, but it has no automated update path. Use Git instead when routine updates will matter. For sensitive documents, extract or clone into a local folder that is not synchronized by OneDrive, Dropbox, another cloud-backup tool, or a network share.

If Git is already installed, cloning is easier to update later:

git clone https://github.com/iamsaurabhsaha/local-ocr-studio.git
Set-Location .\local-ocr-studio

2. Install Python

Open PowerShell from the Start menu and install 64-bit Python 3.11:

winget install --id Python.Python.3.11 --exact

If winget is unavailable, use the official Python downloads for Windows. Select a supported 64-bit Python 3.11, 3.12, or 3.13 installation. Accept the option to install the Python launcher or add Python to PATH when the installer offers it.

Close and reopen PowerShell after installation, then verify:

py -3.11 --version

The output should begin with Python 3.11. If another supported version is installed, use py -3.12 --version, py -3.13 --version, or python --version instead.

Python 3.10 or 3.14 may remain installed for other software, but Local OCR Studio must use Python 3.11, 3.12, or 3.13.

3. Install or update Ollama

Install Ollama with one of these methods:

winget install --id Ollama.Ollama --exact

Or download the official Ollama Windows installer.

Open Ollama once from the Windows Start menu. It normally stays running in the notification area and serves its local API at http://127.0.0.1:11434.

Close and reopen PowerShell, then check the version:

ollama --version

Use Ollama 0.15.5 or newer. If the command shows an older version, update Ollama, restart the Ollama application, and check again. If ollama is not recognized immediately after installation, reopen PowerShell or restart Windows.

If the Ollama desktop application cannot be used, start its service in a separate PowerShell window and leave that window open:

ollama serve

Only one Ollama service should use port 11434 at a time.

4. Open PowerShell in the project folder

In File Explorer, open the folder containing setup.ps1. Select the address bar, type powershell, and press Enter. The new PowerShell window should open in that folder.

Confirm the location by running:

Get-ChildItem .\setup.ps1

If PowerShell says the file does not exist, navigate to the extracted or cloned project folder before continuing.

5. Run the one-time setup

Run:

powershell -NoProfile -ExecutionPolicy Bypass -File .\setup.ps1

The ExecutionPolicy option applies only to this command. It does not permanently weaken the computer's PowerShell policy.

Setup performs the following work:

  1. Finds Python 3.11, 3.12, or 3.13.
  2. Creates an isolated .venv Python environment inside the project.
  3. Installs and checks the pinned application packages.
  4. Creates the machine-local config.json and synthetic sample documents.
  5. Checks or starts the local Ollama service.
  6. Downloads the three configured models.
  7. Runs local readiness diagnostics.
  8. Offers an optional real OCR/model smoke test.

Model downloads can take a while. Keep the window open while Ollama displays download progress. When setup asks whether to run the real smoke test, answering y is recommended for a first installation. A CPU-only smoke test can take 5–10 minutes or longer depending on the machine.

If Ollama was deliberately omitted and only printed OCR is wanted, use:

powershell -NoProfile -ExecutionPolicy Bypass -File .\setup.ps1 -SkipOllama

That mode cannot process handwriting, complex tables, or other routes that require a local vision model.

6. Verify that local AI is ready

Run both checks:

ollama list
powershell -NoProfile -ExecutionPolicy Bypass -File .\doctor.ps1 -RequireAI

ollama list should contain these names:

qwen3-vl:2b-instruct
qwen3-vl:4b-instruct
glm-ocr

The strict diagnostic should report successful checks for the Python environment, packages, database, privacy boundary, Ollama version, model locality, local AI models, and disk space. A failed or warning model check means the web application may open, but its AI-dependent routes are not ready.

To exercise representative real OCR and AI paths and measure this machine, run:

.\.venv\Scripts\python.exe .\scripts\smoke_test.py

The smoke test invokes GLM-OCR and the primary 2B Qwen model, and confirms that the configured 4B fallback tag is installed; it does not deliberately force a 4B fallback inference. The report is written to benchmark_results.md inside the configured data directory (data\benchmark_results.md by default). No real document is used; the repository's synthetic samples are used instead.

7. Start the application

Double-click run.bat, or run it from PowerShell:

.\run.bat

Keep the launcher window open. The browser should open at:

http://127.0.0.1:8765

If the browser does not open automatically, enter that address manually. Do not replace 127.0.0.1 with a public or network address.

Open System in the application and confirm that Ollama and all three model rows are ready.

Process a first sample document

  1. On the Documents page, select Choose files.
  2. Open the project's samples folder.
  3. Select handwriting_note.png to exercise a Qwen vision model, or table_report.png to exercise GLM-OCR.
  4. Leave the type as Auto-detect, or explicitly choose the matching type.
  5. Select Upload & process.
  6. Wait for local processing to finish. CPU inference may take several minutes.
  7. Compare the source page with the extracted result, correct anything necessary, and save the review.
  8. Approve the document only after the displayed checks and source content have been verified.

Some samples intentionally finish through PDF text extraction or RapidOCR without an AI call. That is expected: the application avoids a slower model call when deterministic processing is adequate.

Start, stop, and restart later

  1. Make sure Ollama is running.
  2. Double-click run.bat.
  3. Leave the launcher window open while using the application.

To stop Local OCR Studio, return to its launcher window and press Ctrl+C. Press a key if the window asks you to do so. Ollama may continue running in the Windows notification area; that is normal. Exit Ollama separately if desired.

After changing config.json, stop and restart Local OCR Studio so the new settings are loaded.

Manual Linux setup

This path is suitable for a modern glibc-based desktop distribution such as Ubuntu 24.04 or Debian 12. It is not currently covered by the project's CI tests. Alpine/musl Linux and minimal headless images are untested and may not work with the current OCR dependency stack.

Install Python 3.11, 3.12, or 3.13 with your distribution's venv support, then install Ollama by following the official Ollama Linux instructions. Confirm that ollama --version reports 0.15.5 or newer and that ollama serve or the Ollama system service is running.

From a terminal:

git clone https://github.com/iamsaurabhsaha/local-ocr-studio.git
cd local-ocr-studio

python3 -m venv .venv
.venv/bin/python -m pip install --upgrade pip
.venv/bin/python -m pip install -r requirements.txt
.venv/bin/python -m pip check
.venv/bin/python -c "from app.config import ensure_config_file; ensure_config_file()"
.venv/bin/python scripts/make_samples.py

ollama pull qwen3-vl:2b-instruct
ollama pull qwen3-vl:4b-instruct
ollama pull glm-ocr

.venv/bin/python scripts/smoke_test.py
.venv/bin/python -m uvicorn app.main:app --host 127.0.0.1 --port 8765

Leave the final command running and manually open http://127.0.0.1:8765. Stop it with Ctrl+C. Run all commands from the repository root, which must be writable.

For a remote Linux computer, keep the application bound to loopback and use an SSH tunnel instead of exposing port 8765:

ssh -L 8765:127.0.0.1:8765 user@remote-computer

Then open http://127.0.0.1:8765 on the local computer. Do not use multiple Uvicorn worker processes; configure the application's job_workers and vlm_parallel_requests settings instead.

Product flow

  1. Add documents. Drag in as many as 100 files per batch. Each file can be auto-detected or assigned a type before upload.
  2. Intake checks. The app verifies the file signature, openability, page count, image size, file size, and duplicate hash before creating a document. Oversized files are rejected; pages are never silently discarded.
  3. Page-aware processing. Digital PDF pages use their text layer. Printed pages use RapidOCR. Table-heavy pages, handwriting, and structured documents use the configured local Ollama models only when needed.
  4. Review. Source pages sit beside editable results. OCR confidence, source matches, scan-quality warnings, failed arithmetic, missing values, and incomplete model coverage explain why a document needs attention.
  5. Approve. Normal approval is allowed only when checks pass. A reviewer can approve a known exception only with a reason. Editing an approved result revokes that approval and returns it to review.
  6. Find and deliver. Search uses the latest corrected text and fields. Approved structured records export to Excel or CSV. Individual documents provide text, Markdown, JSON, and a searchable PDF.

If auto-detection is wrong, open the document, choose Change type, and reprocess the original without uploading it again.

Processing routes

Source Route Typical output
Digital PDF page Embedded text layer Searchable text and fields
Printed scan or photo RapidOCR on CPU Text, line boxes, confidence
Table or complex layout RapidOCR + GLM-OCR Markdown tables/layout
Invoice, receipt, form Fast OCR checks → 2B model → validated 4B fallback Validated structured fields
Handwriting 2B on clear pages · 4B on difficult pages · human review Transcription draft

Independent documents and page OCR can run concurrently. Local-model requests are separately bounded to one at a time by default, keeping GPU/RAM usage predictable while other CPU and file work continues. Atomic job leases prevent duplicate work; jobs can be cancelled and interrupted jobs are recovered on restart.

For structured documents, clean high-confidence OCR can pass deterministic field and math checks without an AI call. Otherwise, qwen3-vl:2b-instruct handles the fast first pass. When field grounding, arithmetic, schema, OCR confidence, scan quality, or coverage remains uncertain, the pipeline makes one qwen3-vl:4b-instruct accuracy pass, using the source image when available. The hard path stays bounded to two extraction calls. Every run records the chosen model, fallback use, route, and timing as local processing metrics without storing prompts or document content in external telemetry.

Configuration

setup.ps1 creates a machine-local config.json. The file is intentionally not source controlled because it can contain local paths. config.example.json is the portable reference containing every supported setting.

To change a setting:

  1. Stop Local OCR Studio.
  2. Make a backup copy of config.json.
  3. Edit the original with a text editor such as Notepad.
  4. Keep valid JSON syntax: double quotes, commas between entries, and no trailing comma on the last entry.
  5. Start Local OCR Studio again and inspect the System page for configuration warnings.

Important settings include:

  • model_extract, model_extract_fallback, model_cascade_enabled, and model_parse
  • ollama_url and enforce_local_ollama
  • max_upload_mb, max_batch_files, max_pages, and max_image_megapixels
  • max_vlm_image_pages and extraction_context_chars
  • classical_conf_review_threshold
  • ocr_first_enabled, vision_fallback_enabled, and vlm_think
  • job_workers, ocr_page_workers, and vlm_parallel_requests
  • data_dir and backup_dir

Invalid values are replaced with safe defaults and shown on the System page.

Using different local models

The default models are the tested configuration. A replacement must:

  • be installed in Ollama, not merely downloaded as an arbitrary GGUF file;
  • support image input for extraction, handwriting, or parsing roles;
  • support Ollama's chat behavior used by the application; and
  • fit in the machine's available memory.

Pull the model first, update the appropriate name in config.json, restart the application, and run the smoke test. If only one extraction model is wanted, set model_cascade_enabled to false.

Keep enforce_local_ollama set to true. Do not select an Ollama model whose tag ends in -cloud when documents must remain on the computer: a cloud-tagged model can send work through Ollama's hosted service even though the application connects to a loopback address. Local-only enforcement rejects recognized cloud tags as well as non-loopback server addresses.

Automatic Windows setup can check and pull models from the configured Ollama endpoint, but it can start Ollama automatically only at the standard http://127.0.0.1:11434 endpoint. Advanced users choosing another loopback port must start that service themselves, update ollama_url, and rerun strict diagnostics. Generic OpenAI-compatible endpoints will not work.

Environment-variable overrides

Environment variables override config.json for the process being launched. The supported names are:

OCRSTUDIO_DATA_DIR
OCRSTUDIO_BACKUP_DIR
OCRSTUDIO_OLLAMA_URL
OCRSTUDIO_MODEL_EXTRACT
OCRSTUDIO_MODEL_EXTRACT_FALLBACK
OCRSTUDIO_MODEL_CASCADE
OCRSTUDIO_MODEL_PARSE
OCRSTUDIO_MOCK
OCRSTUDIO_VLM_TIMEOUT_S
OCRSTUDIO_VLM_THINK
OCRSTUDIO_VLM_PARALLEL_REQUESTS
OCRSTUDIO_OCR_PAGE_WORKERS
OCRSTUDIO_JOB_WORKERS
OCRSTUDIO_MAX_PAGES
OCRSTUDIO_MAX_UPLOAD_MB
OCRSTUDIO_MAX_BATCH_FILES
OCRSTUDIO_ENFORCE_LOCAL_OLLAMA

The application does not automatically load a .env file. Set variables in the shell or service that launches the application.

Privacy, security, and local data

With the default configuration:

  • The web server binds to 127.0.0.1, rejects untrusted Host headers, checks request origins, and protects every state-changing form with a CSRF token.
  • enforce_local_ollama=true blocks model endpoints that are not loopback addresses on this computer.
  • No cloud OCR service or external application telemetry is used.
  • Uploaded originals are immutable. The first machine output is retained for evaluation; retries archive prior structured extractions and create a new processing run.
  • Search indexes canonical corrected content, not stale OCR text.
  • Normal bulk exports include approved and approved-with-exception records only.
  • Spreadsheet cells beginning with formula operators are neutralized.
  • Deletion first moves a document to recoverable Trash. Permanent deletion verifies derived files are removed before deleting the database record.

The local-only check protects the configured server address and rejects recognized Ollama cloud model tags. Keep the default local model tags and local enforcement enabled; disabling that policy removes both safeguards.

Local OCR Studio does not encrypt the project directory, SQLite database, uploads, exports, or backup archives. Protect the operating-system account and store sensitive projects and backups on encrypted storage.

Do not keep a sensitive installation in a OneDrive-, Dropbox-, or other cloud-synchronized folder, including a Desktop or Documents folder redirected by an organization. Because data/ and backups/ live inside the project by default, a separate sync application can upload documents even though Local OCR Studio itself makes only local processing requests.

Runtime locations are:

Data Default location
Configuration config.json in the project folder
Originals, generated pages, search index, database data/
Verified backups backups/
Ollama models Ollama's model directory, normally under the user profile

Back up, restore, and update

Stop Local OCR Studio before restoring or updating it.

Task Windows command
Create a verified backup .\.venv\Scripts\python.exe .\scripts\backup_restore.py
Restore with rollback protection .\.venv\Scripts\python.exe .\scripts\backup_restore.py --restore .\backups\FILE.zip --confirm RESTORE
Build the review-derived accuracy report .\.venv\Scripts\python.exe .\scripts\eval_accuracy.py
Run the real-machine smoke test .\.venv\Scripts\python.exe .\scripts\smoke_test.py
Run all offline tests .\.venv\Scripts\python.exe -m pytest

Backups use SQLite's online backup API, include originals and generated page images, verify database integrity, and preserve a pre-restore safety backup. The configuration is included as a reference but is not automatically restored. See docs/OPERATIONS.md for the recovery playbook.

Restore onto the same operating system and preferably the same project path. Some derived-file locations are stored as absolute paths; moving a restored installation to a different folder can require a deliberate migration.

Keep at least one verified backup on a separate encrypted disk.

Update a Git installation

Stop the application, create a backup, and run:

.\.venv\Scripts\python.exe .\scripts\backup_restore.py
git pull --ff-only
powershell -NoProfile -ExecutionPolicy Bypass -File .\setup.ps1
powershell -NoProfile -ExecutionPolicy Bypass -File .\doctor.ps1 -RequireAI

setup.ps1 preserves the existing config.json and data directory.

ZIP installations do not currently have a one-command update path. Create a verified backup and keep the entire old folder. Do not simply delete it or restore into a differently named folder: uploaded documents, the database, configuration, backups, and some absolute paths belong to that installation. Git installation is recommended when routine updates are important.

Mock mode and development checks

Set OCRSTUDIO_MOCK=1 to exercise the complete product without Ollama. RapidOCR remains real; vision/model responses are deterministic. Mock mode is for demonstrations and tests, not real OCR quality evaluation.

In PowerShell:

$env:OCRSTUDIO_MOCK = "1"
.\run.bat

Remove it from the current shell with:

Remove-Item Env:OCRSTUDIO_MOCK

For development, install the quality tools and run both checks:

.\.venv\Scripts\python.exe -m pip install -r requirements-dev.txt
.\.venv\Scripts\python.exe -m ruff check app scripts tests
.\.venv\Scripts\python.exe -m pytest

The test suite uses a new temporary data store for every test and never touches the production data folder. See CONTRIBUTING.md for the contribution workflow and SECURITY.md for private vulnerability reporting guidance.

Troubleshooting

Python or PowerShell setup problems

  • py or python is not recognized: install a supported 64-bit Python, close all PowerShell windows, reopen one, and run the version check again.
  • Python 3.10 or 3.14 is selected: install Python 3.11 and rerun setup. The project intentionally rejects unsupported versions.
  • Script execution is blocked: use the complete setup command shown above. Its bypass applies only to that invocation.
  • .venv is missing or damaged: rerun setup.ps1. A damaged environment is preserved under a timestamped name before setup rebuilds it.
  • Packages are missing even though .venv starts: run setup.ps1 manually. run.bat repairs a missing or non-starting interpreter; it does not fully diagnose every package or model.

Ollama and model problems

  • ollama is not recognized: reopen PowerShell, launch Ollama from the Start menu, or reinstall it from the official installer.

  • Ollama is too old: update it, restart the tray application/service, and verify version 0.15.5 or newer.

  • Ollama is offline: launch Ollama or run ollama serve in another window.

  • A model is missing: run:

    ollama pull qwen3-vl:2b-instruct
    ollama pull qwen3-vl:4b-instruct
    ollama pull glm-ocr
  • The app opens but handwriting/tables fail: run powershell -NoProfile -ExecutionPolicy Bypass -File .\doctor.ps1 -RequireAI and inspect the System page. The web UI and printed OCR can work even when local AI is unavailable.

  • A pull fails for Qwen3-VL: confirm the Ollama version, Internet connection, and free space in Ollama's model directory.

Application problems

  • The browser does not open: keep run.bat running and browse manually to http://127.0.0.1:8765.
  • Port 8765 is already in use: stop the other Local OCR Studio launcher or other service using that port, then retry.
  • Processing appears stuck: model loading and CPU vision inference can take minutes. Check the document status and System page before stopping the process.
  • Processing is very slow: CPU-only vision inference is expected to be slower. Keep vlm_parallel_requests at 1 unless available memory has been measured. A supported GPU managed by Ollama can improve speed.
  • The wrong document type was selected: open the document, choose Change type, and reprocess it without uploading again.
  • Normal approval is blocked: resolve the failed check, or use a documented exception only after verifying the source.
  • Configuration changes seem ignored: validate the JSON, stop the launcher, start it again, and inspect System for warnings. Remember that shell environment variables override the file.

Project layout

app/               web product, storage, worker, OCR engines, validation, exports, UI
scripts/           backup/restore, evaluation, samples, smoke test
tests/             unit, safety, recovery, and end-to-end tests
samples/           synthetic documents for local verification
data/              runtime originals, derived pages, reports, SQLite database (not source controlled)
backups/           verified backup archives (not source controlled)
docs/               decisions, operations, and improvement impact

License

Local OCR Studio is available under the MIT License. See LICENSE. Bundled font assets retain their original OFL-1.1 terms; see THIRD_PARTY_NOTICES.md.

About

No description or website provided.

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages