Generated Computers
Locals는 Apple Silicon 엔진으로 로컬 LLM을 최대 3배 빠르게 실행하는 Generated Computers 제품
EasyOCR's accuracy in a single Rust binary: CRAFT text detection and gen2 CRNN recognition over ONNX, with no Python runtime.
개발 도구Rust · PythonGitHub @xberg-io직접 설치운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
설치형 프로젝트는 배포 도메인 없이도 확인할 수 있습니다. 개인 저장소는 GitHub 로그인으로, 조직 저장소는 위의 저장소 확인 파일로 직접 확인해 주세요.
메이커가 쓴 소개는 위의 한 줄이 전부입니다. 더 자세한 내용은 저장소 README에서 읽을 수 있습니다. 저장소 README ↗
README 전체를 불러오는 중입니다.
README 전문 보기 ↗EasyOCR's accuracy in a single Rust binary — CRAFT text detection and gen2 CRNN recognition over ONNX, with no Python runtime.
EasyOCR is accurate, but it is a PyTorch stack: a Python interpreter, a multi-gigabyte runtime, and a heavy process to keep warm. sceptre is a from-scratch Rust reimplementation of the same pipeline — CRAFT text detection then gen2 CRNN recognition with CTC decoding, over ONNX — that keeps the accuracy and drops all of that.
It agrees with EasyOCR's output across the scripts it supports, runs faster — even a cold, one-shot run beats EasyOCR's warm reader (measured figures) — and ships as one self-contained executable with no Python runtime. Models download once, cache locally, and run offline thereafter. Use it as a Rust library, a CLI, or an MCP server.
Every model call goes through one backend seam, so the deployment target is a build-time choice rather than a rewrite:
ONNX Runtime for native speed, pure-Rust ONNX for WASM and Android, and candle for GPU devices or a build that links
no ONNX Runtime at all.
| Feature | Description |
|---|---|
| Parity accuracy | Validated against real EasyOCR output across the gen2 scripts — English, Latin, Simplified Chinese, Japanese, Korean, Cyrillic, Telugu, Kannada — on text (word/char-F1) and boxes (IoU), held to a per-image floor rather than character-for-character equality |
| Faster, warm or cold | Higher throughput than EasyOCR warm on the same corpus; even a cold, one-shot CLI run beats EasyOCR's already-loaded reader (measured figures) |
| No Python, no torch | No interpreter, no multi-gigabyte runtime, no process to keep warm; peak memory is dominated by the CRAFT detector both engines share, so it scales with page size — see benchmarks |
| One binary, no Python | A single self-contained executable. Models download once, cache locally, and run offline thereafter — nothing to pip install, no interpreter to ship |
| Three surfaces | The same engine as a Rust library, a CLI (sceptre), and an MCP server for agents |
| Three backends, one seam | ONNX Runtime (ort) for native speed, pure-Rust ONNX (tract) for WASM / Android, and candle for a GPU or a build with no ONNX Runtime at all |
| Pure-Rust image decoding | PNG, JPEG, BMP, GIF, TIFF, WebP, and NetPBM |
cargo install sceptre-cli --locked
--locked uses the dependency versions tested for that release.
Every build, including the optional candle backend, supports Rust 1.99 or newer;
see Rust version requirements.
Prebuilt release archives for Linux x86_64/ARM64,
macOS ARM64, and Windows x86_64 include sceptre mcp, bundled ONNX Runtime, and model downloads.
Extract the archive and put sceptre (sceptre.exe on Windows) on PATH.
That default build is self-contained: it links a prebuilt ONNX Runtime fetched at build time (ort-bundled) and enables
model download (download), so the binary needs no ORT_DYLIB_PATH and no separately installed libonnxruntime.
The models — CRAFT plus the gen2 recognizers — are fetched from Hugging Face on first use, cached under the standard HF cache, and sha256-verified as they download. Every run after that reads the cached models with no network.
Targets with no prebuilt ONNX Runtime.
ortpublishes prebuilts for a fixed target list.x86_64-apple-darwin(Intel macOS), every*-unknown-linux-musl(Alpine),armv7-unknown-linux-gnueabihf,riscv64gc-*,*-unknown-freebsd,i686-*,s390x, andpowerpc64lehave none, so the default install fails at build time with ort-sys's ownno prebuilt binaries available for target .... Two remedies:cargo install sceptre-cli --locked --features ort-dynamic # bring your own libonnxruntime cargo install sceptre-cli --locked --no-default-features --features tract,download # pure Rust, then --backend tract
--features ort-dynamicis additive, but it still wins over the bundled default:load-dynamicimpliesort-sys/disable-linking, which the ort-sys build script checks before its download branch. So switching ONNX Runtime provisioning never needs--no-default-features— only the pure-Rust path does, because it has to droportfrom the graph entirely.
One image or many in a single warm process:
sceptre run receipt.png --lang english --format json
sceptre run page1.png page2.png page3.png # batch: models load once
sceptre run sign.jpg --lang english --lang korean # multi-language
sceptre run page.png --lang english --timings # per-stage load/detect/recognize breakdown
sceptre run huge-scan.png --canvas-size 1600 # trade some accuracy for lower peak memory
Decodes PNG, JPEG, BMP, GIF, TIFF, WebP, and NetPBM (all pure-Rust; HEIF/AVIF/JPEG-2000
are out of scope — see adrs/0022).
use sceptre::{Reader, ReadOptions};
let reader = Reader::builder().build()?;
for line in reader.readtext("receipt.png".as_ref(), &ReadOptions::default())?.lines {
println!("{} ({:.2})", line.text, line.confidence);
}
# Ok::<(), sceptre::OcrError>(())
The library ships default = [], so enable a backend and model download:
sceptre = { version = "0.8", features = ["ort-bundled", "download"] } (see Feature flags).
WASM and mobile hosts can avoid filesystem and network assumptions by calling model_descriptors,
fetching the selected artifacts, constructing a VerifiedModelProvider, and passing it to
Reader::builder().model_provider(...).build_warmed().
Android and iOS hosts that package ONNX assets as real files may instead set both
model.detector_path and model.recognizer_path; the default provider then bypasses Hugging Face.
Expose a readtext tool to an agent. Release archives include the mcp subcommand. When installing from Cargo,
enable the mcp feature explicitly:
cargo install sceptre-cli --locked --features mcp
sceptre mcp --lang english
sceptre mcp --lang english --detect-orientation # whole-page orientation pre-pass for rotated scans
| Tool | Parameter | Type | Description |
|---|---|---|---|
readtext | image_path | string (required) | Filesystem path to the image to run OCR over. |
readtext | detail | bool (optional, default true) | When false, only line text is returned (no box/confidence). |
--lang, --backend, --threads, and --detect-orientation (plus its --orientation-probe-canvas-size
/ --orientation-margin knobs) configure the Reader the server is started with — they are not
per-call readtext parameters, so every call made to one sceptre mcp process shares them.
Measured against upstream EasyOCR over a mixed corpus — documents, tables, rotated scans, scene
text and receipts, across the English, Latin, Chinese-simplified, Japanese and Korean recognizer
groups — on CPU. Both engines are measured identically: each a fresh subprocess per language
group under /usr/bin/time, at its native multi-threaded default, loading its model/reader once and
processing every image — so peak RSS is a like-for-like whole-process figure (EasyOCR's legitimately
includes the torch runtime). Numbers vary with hardware and load, and peak RSS is dominated by the
CRAFT detector both engines share, so its ratio narrows toward parity as page size grows — see the
benchmarks page for the full methodology.
The table below is generated from benchmarks/published/latest.json
by mise run python:publish; CI fails if the two drift apart. Do not edit it by hand.
| Engine | Throughput (img/s) | Peak RSS | Mean CER | Mean token-F1 |
|---|---|---|---|---|
| EasyOCR (warm/batch) | 0.12 | 4.8 GB | 0.569 | 0.337 |
| sceptre (warm/batch) | 0.23 (~1.9×) | 4.5 GB (~1.4× lower, per-image median) | 0.569 | 0.358 |
| sceptre (cold CLI run) | 0.21 (~1.8×) | 4.5 GB | 0.569 | 0.358 |
Measured with sceptre 0.6.0 (ort/cpu, ONNX Runtime 1.28.0) against EasyOCR 1.7.2 (torch 2.13.0+cu130) on
runner-medium (Linux/x86_64), over 40 of 43 corpus entries. Regenerate with mise run python:benchmark then
mise run python:publish.
The accuracy columns are the parity check — sceptre and EasyOCR land on the same reading of the corpus; the speedup is the win. Even a cold, one-shot CLI run, which pays model load on every invocation, still beats EasyOCR's already-warm reader. Peak memory is dominated by the CRAFT detector both engines share, so it tracks page size rather than the runtime; sceptre's memory advantage is having no Python/torch process at all, which shows up on smaller pages and in process count rather than as a fixed ratio.
Runtime scope. Every figure above — speed, memory, and the parity claim — was produced on the
ort backend running the CPU execution provider, which is what model.accelerator defaults to.
The same ONNX graph produces different numeric output on a different provider, so an accelerated run
is a different measurement, not a faster one. Select one with --accelerator or
model.accelerator; which values a backend accepts differs, because ort reaches hardware through
ONNX Runtime execution providers while candle addresses devices directly:
| Backend | Accelerators | Cargo feature |
|---|---|---|
ort | coreml, directml, cuda | ort-coreml, ort-directml, ort-cuda |
tract | — (CPU only) | — |
candle | metal, cuda | candle-metal, candle-cuda |
For ort the linked ONNX Runtime build must also carry the provider. An explicitly requested
accelerator that cannot be used is a hard error, not a silent fall back to CPU — only auto is
allowed to settle for whatever it finds. The parity figures above cover only the ort backend's CPU
execution provider, validated against the golden fixtures under
crates/sceptre/tests/data/golden/: every accelerator is
unvalidated in CI, which has no GPU runner, so none of the numbers above should be assumed to
transfer. candle is a compatibility and deployment option, not a fast one — on a GPU it is still
several times slower than ort on the CPU (see ADR 0031).
Re-run the parity harness on your own target before relying on them.
cargo bench covers the internal hot paths; the head-to-head harness (mise run python:benchmark)
re-measures and writes the gitignored benchmark-results/comparison.{json,md}. Use
--group labeled --limit 3 --repeats 1 for a fast inner-loop run, --baseline <prior.json> to see
per-image deltas, and --assert for the regression gate (see
ADR 0021). mise run python:publish then distils that
report into the committed artifact and regenerates the table above; mise run python:publish:check is
the drift gate CI runs (see ADR 0030).
Parity fixtures live under
crates/sceptre/tests/data/golden/.
Three stages behind one Reader, mirroring EasyOCR's latest pipeline:
ort (native ONNX Runtime),
tract (pure Rust), or candle (hand-written networks over the same ONNX weights, able to run
on Metal or CUDA). config, types, and geometry stay backend-agnostic.Design decisions live as MADR records under adrs/, indexed on the
Decision records page; conventions
live in .ai-rulez/.
Targets EasyOCR's current models — the CRAFT detector and all eight gen2 (*_g2) recognizers
(English, Latin, Simplified Chinese, Japanese, Korean, Cyrillic, Telugu, Kannada).
Legacy gen1 models, DBNet, and beam-search decoding are out of scope
(see adrs/0002 and
adrs/0026). ONNX artifacts are first-party exports,
built from EasyOCR's weights and hosted on the xberg-io
Hugging Face org (Apache-2.0; see adrs/0025).
| Feature | Enables | Library | CLI |
|---|---|---|---|
ort | Native ONNX Runtime backend (desktop / server), provisioning-agnostic | ✓ | — |
ort-bundled | ort with a prebuilt runtime fetched at build time (zero-config) | ✓ | default |
ort-dynamic | ort loading libonnxruntime at runtime via ORT_DYLIB_PATH (no build-time download) | ✓ | ✓ |
tract | Pure-Rust ONNX backend (WASM / Android), selected at runtime with --backend tract | ✓ | ✓ |
download | Runtime model download + cache from Hugging Face | ✓ | default |
mcp | MCP (rmcp) server surface | ✓ | ✓ |
ort-coreml / ort-directml / ort-cuda | Compile in the matching ONNX Runtime execution provider for model.accelerator | ✓ | ✓ |
candle | Native-tensor backend needing no ONNX Runtime, selected at runtime with --backend candle (see ADR 0031) | ✓ | ✓ |
candle-metal / candle-cuda | Compile in the matching GPU device for model.accelerator on the candle backend | ✓ | ✓ |
bench | Exposes the crate's internal hot paths through a bench seam for criterion benchmarking (see ADR 0015) | ✓ | — |
The library ships default = []. The CLI ships default = ["ort-bundled", "download"], so
cargo install sceptre-cli --locked produces a self-contained binary; --features ort-dynamic overrides the
provisioning strategy without --no-default-features (see Install).
Configuration (OcrConfig) is backend-agnostic. The CLI builds it from OcrConfig::default() plus
flags — there is no config-file loader and no SCEPTRE_* environment variable. The CLI does read one
env var, EASYOCR_LOG (sets --log-level), a name kept from the project's EasyOCR lineage.
cache_dir, registry_owner, detector_path, and recognizer_path are library-only fields with no
CLI flag.
The Sceptre plugin provides local image OCR instructions and MCP tools for Claude Code, Codex, Cursor, Gemini CLI, Kimi, OpenCode, Factory Droid, Hermes, Agent Plugins and GitHub Copilot CLI. Pi loads the packaged skills and prompts and uses the CLI directly.
Install an MCP-enabled binary before using the server or Hermes bridge:
cargo install sceptre-cli --locked --features mcp
Models download on first use. Set the image language through the MCP configuration; the default is English. Install the Claude marketplace plugin with:
/plugin marketplace add xberg-io/sceptre
/plugin install sceptre@sceptre
For other runtimes, follow the plugin installation guide. Install public skills independently with the skills CLI:
npx skills add xberg-io/sceptre --list
npx skills add xberg-io/sceptre
Select skills and target agents interactively. This installs instructions; the binary and model cache remain separate requirements.
mise run setup # fetch deps, install git hooks
mise run check # cargo fmt + clippy -D warnings + test + poly lint
cargo bench -p sceptre --features bench # criterion microbenchmarks
Run mise run python:typecheck to check all Python tooling with Pyrefly. This synchronizes
the locked optional export and corpus dependencies, including PyTorch and EasyOCR.
Coding conventions are generated from .ai-rulez/ into CLAUDE.md / AGENTS.md — edit the source,
then run ai-rulez generate.
Full guides, the configuration reference, backend and accelerator selection, and the benchmark methodology live at docs.sceptre.xberg.io. The Rust API reference is on docs.rs.
Contributions welcome! See CONTRIBUTING.md for setup instructions and guidelines.
MIT License. Model weights are distributed under their own licenses — the gen2 EasyOCR
models and the first-party xberg-io/sceptre-* ONNX exports derived
from them are Apache-2.0.