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.
- Install on Windows from the beginning
- Verify that local AI is ready
- Process a first sample document
- Manual Linux setup
- Configuration and different models
- Back up, restore, and update
- Troubleshooting
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.
- 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.
| 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.
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.
These instructions assume no previous Python, Ollama, Git, or command-line experience.
The easiest option does not require Git:
- Open the Local OCR Studio GitHub page.
- Select Code, then Download ZIP.
- In File Explorer, right-click the downloaded ZIP and select Extract All.
- Open the extracted folder. It should contain
README.md,setup.ps1, andrun.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-studioOpen PowerShell from the Start menu and install 64-bit Python 3.11:
winget install --id Python.Python.3.11 --exactIf 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 --versionThe 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.
Install Ollama with one of these methods:
winget install --id Ollama.Ollama --exactOr 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 --versionUse 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 serveOnly one Ollama service should use port 11434 at a time.
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.ps1If PowerShell says the file does not exist, navigate to the extracted or cloned project folder before continuing.
Run:
powershell -NoProfile -ExecutionPolicy Bypass -File .\setup.ps1The ExecutionPolicy option applies only to this command. It does not permanently weaken the
computer's PowerShell policy.
Setup performs the following work:
- Finds Python 3.11, 3.12, or 3.13.
- Creates an isolated
.venvPython environment inside the project. - Installs and checks the pinned application packages.
- Creates the machine-local
config.jsonand synthetic sample documents. - Checks or starts the local Ollama service.
- Downloads the three configured models.
- Runs local readiness diagnostics.
- 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 -SkipOllamaThat mode cannot process handwriting, complex tables, or other routes that require a local vision model.
Run both checks:
ollama list
powershell -NoProfile -ExecutionPolicy Bypass -File .\doctor.ps1 -RequireAIollama 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.pyThe 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.
Double-click run.bat, or run it from PowerShell:
.\run.batKeep 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.
- On the Documents page, select Choose files.
- Open the project's
samplesfolder. - Select
handwriting_note.pngto exercise a Qwen vision model, ortable_report.pngto exercise GLM-OCR. - Leave the type as Auto-detect, or explicitly choose the matching type.
- Select Upload & process.
- Wait for local processing to finish. CPU inference may take several minutes.
- Compare the source page with the extracted result, correct anything necessary, and save the review.
- 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.
- Make sure Ollama is running.
- Double-click
run.bat. - 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.
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 8765Leave 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-computerThen 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.
- Add documents. Drag in as many as 100 files per batch. Each file can be auto-detected or assigned a type before upload.
- 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.
- 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.
- 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.
- 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.
- 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.
| 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.
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:
- Stop Local OCR Studio.
- Make a backup copy of
config.json. - Edit the original with a text editor such as Notepad.
- Keep valid JSON syntax: double quotes, commas between entries, and no trailing comma on the last entry.
- Start Local OCR Studio again and inspect the System page for configuration warnings.
Important settings include:
model_extract,model_extract_fallback,model_cascade_enabled, andmodel_parseollama_urlandenforce_local_ollamamax_upload_mb,max_batch_files,max_pages, andmax_image_megapixelsmax_vlm_image_pagesandextraction_context_charsclassical_conf_review_thresholdocr_first_enabled,vision_fallback_enabled, andvlm_thinkjob_workers,ocr_page_workers, andvlm_parallel_requestsdata_dirandbackup_dir
Invalid values are replaced with safe defaults and shown on the System page.
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 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.
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=trueblocks 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 |
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.
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 -RequireAIsetup.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.
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.batRemove it from the current shell with:
Remove-Item Env:OCRSTUDIO_MOCKFor 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 pytestThe 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.
pyorpythonis 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.
.venvis missing or damaged: rerunsetup.ps1. A damaged environment is preserved under a timestamped name before setup rebuilds it.- Packages are missing even though
.venvstarts: runsetup.ps1manually.run.batrepairs a missing or non-starting interpreter; it does not fully diagnose every package or model.
-
ollamais 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 servein 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 -RequireAIand 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.
- The browser does not open: keep
run.batrunning and browse manually tohttp://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_requestsat1unless 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.
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
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.