Text recognition with no limit on document length —
and an installer that sets itself up.
A Windows desktop program built on baidu/Unlimited-OCR that installs and configures everything it needs by itself. The user needs no Python, no CUDA toolkit and no command line: launch it, pick a drive, wait for the install, and work.
The model parses whole documents in a single pass: a constant-size KV cache lets it read dozens of pages inside a 32K context instead of cutting the document into chunks and stitching the pieces back together.
The first screen is not a list of checkboxes but a reading of this particular machine. Here it found a GTX 1060, worked out that PyTorch had dropped that architecture from current builds, and chose the CPU profile — labelling it honestly as reference quality. It also spotted the Microsoft Store Python placeholder and dimmed the system drive: 22 GB there is formally more than the install needs, but it would leave Windows with no room.
- PDFs and images → Markdown. Multi-page documents go through in one pass.
- Read and correct. Fix the result in the window and save it.
- Batch queue. Point it at a folder of a hundred files; progress, pause, and resume after a restart.
- Export to Markdown, DOCX, HTML and TXT, with the
<|det|>grounding markers stripped. - English and Russian interface. It follows the system language and can be switched by hand.
On first launch the program:
- reads the hardware — graphics card model, compute capability, VRAM, driver version, memory, free space per drive;
- chooses an execution profile and explains the choice honestly;
- installs its own Python through
uv, leaving the system one alone; - installs PyTorch from the wheel index that matches this card and this driver;
- downloads the weights (6.67 GB), resumable, with a mirror;
- patches the model code, removing its hardcoded CUDA binding;
- runs a test recognition and measures the real speed.
All of that happens once. After it, the program simply starts.
The model ships in bfloat16 and weighs 6.67 GB. Every constraint follows from that.
| Profile | Condition | What you get |
|---|---|---|
| Full | sm_80+, VRAM ≥ 12 GB | Native bf16, 32K context. Reference quality |
| Reduced | sm_80+, VRAM 8–12 GB | Native bf16, reference quality, shorter context |
| Economy | sm_75+, VRAM < 8 GB | fp16 and NF4 quantisation. Fast, below reference quality |
| CPU | no suitable card, RAM ≥ 16 GB | The original bf16 weights, reference quality, but slow — about a minute per page on an i5-8400 |
The profile is shown in the interface with a badge saying whether it is reference quality. The program does not pass an approximate result off as an exact one.
- bfloat16 needs Ampere (sm_80+). Turing and Pascal can store bf16 but not compute on it. On those cards you have to drop to fp16, which is not an equivalent swap — fp16 has a narrower exponent range.
- 6.67 GB of weights do not fit in 6 GB of VRAM. No amount of newness changes that. Quantisation is the only way in.
- PyTorch dropped Maxwell and Pascal from CUDA 12.8 and later builds; Turing (7.5) is the floor. Older cards only have cu126. The installer accounts for that and for the CUDA ceiling imposed by the driver version.
- Windows 10 or 11 (x64)
- ~16 GB of free disk space
- 16 GB of RAM for the CPU profile
- An NVIDIA card with compute capability 7.5+ for the GPU profiles
Prefer a drive other than the system one: the installer suggests another partition by default and demands an extra 20 GB of headroom from the system drive.
Version 0.1.0. What has been verified on real hardware, and what has not:
Verified: a complete install from nothing, and document recognition. The run was done on
an Intel i5-8400 / 16 GB / GTX 1060 6 GB — a machine this program puts on the CPU profile by
itself, because Pascal is gone from current PyTorch builds. Everything was exercised: uv, an
isolated Python 3.12, PyTorch, 6.67 GB of weights, the patch, and a test recognition. An A4
page with a heading, a paragraph and a table came back in 55 seconds, table cells included.
Also verified: hardware detection and profile choice, the device patch (a functional test
against a fixture of real model calls), DOCX export as a valid zip, queue logic, and MSI and
NSIS bundling.
Driven through the finished window rather than through tests: a screenshot, an English A4
page, a Russian document and a two-page PDF. PDFs render and go through the multi-page
infer_multi pass: two pages in 1 min 21 s, both present and separated in the text.
Not verified on hardware yet: the GPU profiles (no suitable card here) and NF4 quantisation in the Economy profile.
Only Sapphire Rapids and later can compute in bfloat16 on the processor. On everything else PyTorch falls back to a reference implementation roughly 9–20 times slower than fp32 — the vision encoder took 114 seconds per page on an i5-8400 instead of 10. So on the CPU profile the program keeps the vision encoders (400M parameters, +0.8 GB of memory) in float32, and for the 3B decoder it widens the multiplications themselves to float32.
This costs no quality: the weights are the same, the output dtype is the same, only the accumulation is more precise. It is not a quality-for-speed trade, which is why the profile stays labelled as reference.
English by default, Russian when the system asks for it, and either can be chosen from the window at any time. The language covers the whole program, not just the front end: the probe's explanation of your hardware, the installer's stage names and the queue labels are composed in Rust, and the Python worker's progress messages come from a third catalogue — all three switch together.
You need Rust, Node.js 18+, and on Windows the Visual Studio Build Tools and the WebView2 Runtime.
npm install
npm run tauri dev # development run
npm run tauri build # build the installerscd src-tauri && cargo test # 54 tests: profiles, queue, export, protocol, i18n
python python/tests/test_device_patch.py # functional test of the device patchThe hardware probe runs on its own, without the GUI:
cd src-tauri
cargo run --bin probe-cli # readable report
cargo run --bin probe-cli -- --json # what the interface receivessrc-tauri/src/
probe.rs hardware detection and profile choice
paths.rs where files live on disk
download.rs resumable download with a mirror
setup.rs the installer: uv → Python → PyTorch → weights → patch → self-test
engine.rs supervises the Python worker, JSON-lines protocol
queue.rs batch queue, persisted across restarts
export.rs Markdown, DOCX, HTML, TXT, and marker stripping
i18n.rs the two languages of everything this side composes
python/
worker.py loads the model once and serves requests
device_patch.py removes the model code's hardcoded CUDA binding
src/
components/SetupWizard.tsx first-run wizard
components/Workspace.tsx queue, editor, export
i18n.tsx the interface string catalogues
assets/
generate_icon.py the icon is drawn by script, not stored as art
The icon is an infinity sign over lines of text. To rebuild it:
python assets/generate_icon.py # needs Pillow
npm run tauri icon assets/icon.png # expand into every formatThe Tauri shell (Rust) talks to the Python worker over JSON-lines on stdin/stdout: no ports, no server, no Docker. The model is loaded once and stays in memory.
The model's infer() is nailed to CUDA — .cuda() on tensors and
torch.autocast("cuda", dtype=torch.bfloat16) — and the method takes no device argument.
python/device_patch.py rewrites those sites to read environment variables instead.
The weights, the architecture, the prompts and the arithmetic are unchanged; only the address
the tensors travel to. The patch is idempotent, keeps .orig backups, and refuses to run
if it cannot find the bindings it expects: that would mean the upstream code changed and the
patch is stale.
MIT — the same as the model.
baidu/Unlimited-OCR is released under MIT by its authors and is downloaded from Hugging Face
during installation. This program neither contains nor redistributes it.

