Skip to content

Unlimited-OCR: multi-page document OCR (MLX decoder + Core ML encoder) + PDF reader demo - #38

Merged
Alex-Wengg merged 7 commits into
mainfrom
feat/unlimited-ocr
Oct 12, 2026
Merged

Alex-Wengg merged 7 commits into
mainfrom
feat/unlimited-ocr

Conversation

@Alex-Wengg

@Alex-Wengg Alex-Wengg commented Oct 12, 2026 •

Copy link
Copy Markdown
Member

Baidu's Unlimited-OCR (DeepSeek-OCR architecture, 3B MoE / ~0.5B active, MIT) on Apple silicon, including its multi-page mode: up to 16 pages in one prompt, the whole document out of one generation as markdown with layout boxes. Model: FluidInference/unlimited-ocr-mlx-coreml @ 9d5f274c.

  • UnlimitedOcrFastManager (new UnlimitedOcrMLX target): Core ML page encoder + MLX text decoder (8-bit, SwitchGLU experts) with upstream's R-SWA cache (prefix + 128-token ring), pipelined decode. ~3.5 ms/token on M5 Pro; turbo: true loads 4-bit routed experts (~3.1 ms/token, text within ~1 pt).
  • UnlimitedOcrManager: all-Core-ML path (stateful 8-bit decoder, ~20 ms/token), kept for macOS 15 without MLX.
  • UnlimitedOcrModelStore: pinned, checksummed download per runtime (.mlx ~3.9 GB, .mlxTurbo ~2.9 GB, .coreML ~3.8 GB).
  • UnlimitedOcrDemo: open/drop a PDF, Start/Restart (Return), Pause (Space), Turbo switch; thumbnails highlight the block being written; demo.sh adds a Ghostty window with usage bars + block log. Baidu's 14-page paper: 70 s (8-bit) / 55 s (turbo).
  • UnlimitedOcrCheck: CLI parity tool (--mlx, hub, --npy).

Notes:

  • With upstream's preprocessed pixels both decoders reproduce upstream fp32 generate on page 4 token for token (865/865); 3 pages in one pass: MLX 99.95% of the text, Core ML 2,461/2,461 tokens.
  • MLX builds need Xcode's Metal toolchain (xcodebuild -downloadComponent MetalToolchain on Xcode 26+). Unit tests pass locally (DEVELOPER_DIR=…/Xcode-27.0.0.app/Contents/Developer swift test --filter UnlimitedOcrTests); swift-format lint clean.

🤖 Generated with Claude Code

UnlimitedOcrManager runs Baidu Unlimited-OCR (3B MoE) on Core ML: page encoder (fp16) + 8-bit
stateful decoder bundle (prefill/decode functions per prefix-capacity bucket, 128-slot ring
for generated tokens), upstream's multi-page prompt and 35-gram no-repeat ban on the host.

- UnlimitedOcrCheck: CLI parity tool; with the reference pixels it reproduces upstream's fp32
  output token for token (paper page 4, 865 tokens).
- UnlimitedOcrDemo: drop a PDF, every page is read in one generation; the page thumbnails
  highlight the layout block being written while the markdown streams in.
- UnlimitedOcrModelStore: pinned, checksummed download of FluidInference/unlimited-ocr-coreml.
- Demo: opening a PDF only loads its pages; Start (Return) reads them, Pause/Resume (Space)
  holds generation between tokens. The pause flag is a lock, not actor state: the decode loop
  holds the actor without suspending, so an actor-isolated pause() only ran after the read.
- Warm-up zeroes its inputs and keeps each state alive for the call (the app intermittently
  hit an MPSGraph `shape.count = 0 != strides.count = 2` assert with uninitialized inputs).
- UnlimitedOcrCheck: `hub` bundle argument, --warm-all, --out.
- Unit tests: output/box parsing, page fit, capacity buckets, pinned assets.
…olchain

CI's compiler rejects sending the non-Sendable MLModel returned by the
nonisolated compiledModel(...) into the actor (UnlimitedOcrManager.swift:125, 128).
Same import as the other managers (Laya, GLiClass, Kev, Verdict, GLiNER2).
@Alex-Wengg
Alex-Wengg merged commit d278e17 into main Oct 12, 2026
1 check passed
@Alex-Wengg Alex-Wengg changed the title Unlimited-OCR: multi-page document OCR on Core ML + PDF reader demo Unlimited-OCR: multi-page document OCR (MLX decoder + Core ML encoder) + PDF reader demo Oct 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant