TextLens
Local OCR for Python developers, built around modern vision-language models (VLMs).
TextLens makes local OCR reusable: initialise an OCR client, give it an image or PDF, and receive text. It also provides model discovery and caching, CUDA diagnostics, a REST API, and BatchOCR for processing document folders with exports and live progress.
Early release notice. TextLens is designed primarily for NVIDIA CUDA GPUs. Most supported engines are VLMs, so an NVIDIA RTX/CUDA-capable GPU is strongly recommended for practical local OCR. CPU fallback exists but is much slower for large documents and batches. Apple Silicon / MPS optimisation is under active investigation and is not a supported acceleration target yet.
Why TextLens?
OCR projects repeatedly need the same work: choose a capable model, download it, prepare images and PDFs, select a device, write prompts, manage batch failures, and save usable output. TextLens packages that work behind a Python-first API so the OCR code can stay small, readable, and reusable.
Supported models
The registry currently exposes four locally downloadable VLM/OCR models:
| ID | Model | Intended use | Recommended GPU memory |
|---|---|---|---|
glm-ocr |
GLM OCR (default) | General document OCR, tables, formulas | 6 GB VRAM |
lighton-ocr |
LightOnOCR | Academic and multilingual documents | 8 GB VRAM |
hunyuan-ocr |
HunyuanOCR | Complex layouts, charts, and structured extraction | 8 GB VRAM |
smolvlm |
SmolVLM-256M | Laptops, edge devices, and low-VRAM use | 2 GB VRAM |
Inspect the live catalog on your machine with textlens models or ModelManager.models().
Install
TextLens requires Python 3.9+. Current PyTorch stable releases may require Python 3.10+, so use Python 3.10+ for the smoothest GPU installation.
git clone https://github.com/Srevarshan05/textlens.git
cd textlens
python -m venv .venv
Activate the environment:
# Windows PowerShell
.\.venv\Scripts\Activate.ps1
# macOS/Linux
source .venv/bin/activate
Install the lightweight catalog/utilities package first. This is enough for
fast commands such as textlens models and for inspecting the local catalog:
python -m pip install --upgrade pip
python -m pip install -e .
Choose the features you need
TextLens keeps its large, optional stacks out of the default installation. This
makes pip install textlens-ocr and catalog-only CLI commands fast.
| Need | Install command |
|---|---|
| Browse the model catalog and basic utilities | python -m pip install textlens-ocr |
| Search live Hugging Face OCR/VLM candidates | python -m pip install "textlens-ocr[catalog]" |
| Run local VLM OCR and BatchOCR | python -m pip install "textlens-ocr[inference,ui]" |
| Run the local REST API | python -m pip install "textlens-ocr[server,inference]" |
| Install every optional feature | python -m pip install "textlens-ocr[all]" |
For NVIDIA GPU OCR, install the appropriate PyTorch CUDA wheel first, as shown
in the next section. Then install the inference extra. The following commands
are useful after a CUDA-enabled PyTorch installation:
python -m pip install "textlens-ocr[inference,ui]"
python -m pip install "textlens-ocr[inference,server]"
# Full developer installation, including the optional terminal UI/diagnostics:
python -m pip install "textlens-ocr[all]"
Fast CLI behaviour
textlens models, textlens --help, and model-catalog imports load only
TextLens metadata. They do not import PyTorch, Transformers, FastAPI, or
download models. This keeps catalog commands responsive even on a fresh
installation. OCR dependencies and model weights load only when you request an
OCR, download, server, or batch-inference feature.
Live model discovery for your hardware
The built-in catalog (textlens models) contains only TextLens-supported
backends. To research additional OCR/VLM repositories from the live Hugging
Face Hub, install the small catalog extra and run:
python -m pip install "textlens-ocr[catalog]"
textlens discover # opens an interactive search prompt
textlens discover DeepSeek-OCR --compatible
textlens discover --search "PaddleOCR-VL" --limit 10
textlens discover searches Hugging Face by model name only. Enter a full
or partial repository/model name such as DeepSeek-OCR, PaddleOCR-VL, or
GOT-OCR2_0. A blank interactive search shows popular OCR/VLM repositories.
textlens discover <model-name> and --search <model-name> are the
non-interactive forms for scripts.
--include-unknown is a discover option only. It includes repositories that
do not publish parameter metadata and labels their hardware fit as VRAM not
published; TextLens never treats that label as GPU compatibility. When it is
combined with --compatible-only, verified compatible models are shown first
and explicitly requested unverified models remain visible for research.
discover does not show a Downloads column. It shows models with published
parameter information by default, a VRAM guide, detected GPU fit, pipeline,
and use-case signals. Official TextLens models retain their catalog minimum
VRAM; other Hub repositories use a conservative fp16 estimate. These are
discovery recommendations, not a guarantee that a model will run or a
statement that TextLens already has an inference backend for it.
NVIDIA CUDA setup (Windows and Linux)
You need an NVIDIA GPU and a recent NVIDIA graphics driver. For normal TextLens use, you generally do not need to install the full CUDA Toolkit: PyTorch's CUDA wheel includes the CUDA runtime it needs. Install the toolkit only if you are compiling CUDA software yourself.
-
Check that Windows/Linux can see your GPU:
nvidia-smi
If this command is missing or errors, install or update the driver from NVIDIA Drivers, restart, and run it again.
-
In the activated virtual environment, use the command currently shown by the official PyTorch installer selector for your OS, Python, Pip, and CUDA platform. For example, the CUDA 12.8 wheel is:
python -m pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu128
Choose
cu118,cu126, orcu128only when that is what the official selector recommends for your driver/platform. Do not mix a CPU-only PyTorch package with a CUDA wheel in the same environment. -
Install TextLens:
python -m pip install -e .
-
Verify both PyTorch and TextLens:
python -c "import torch; print(torch.__version__); print('CUDA:', torch.cuda.is_available()); print('GPU:', torch.cuda.get_device_name(0) if torch.cuda.is_available() else 'not available')" textlens doctor
CUDA: True means PyTorch can accelerate TextLens. If an NVIDIA GPU is present but this prints False, run textlens doctor; it reports the detected driver and a suggested PyTorch command. The authoritative PyTorch instructions are linked above because supported CUDA wheel versions change over time.
Quick start: modern API
The OCR API is the recommended registry-based interface. It downloads a registered model the first time it is needed, then lazy-loads it on the first read() call.
Install its inference dependencies first:
python -m pip install "textlens-ocr[inference]"
from textlens import OCR
ocr = OCR(model="glm-ocr") # default model; downloads if missing
text = ocr.read("invoice.png")
print(text)
Use a different model or device:
ocr = OCR(model="smolvlm", device="cuda")
text = ocr.read("scan.jpg", prompt="Read every visible word.", max_new_tokens=1024)
OCR.read() accepts a local image/PDF path, HTTP(S) URL, Pillow image, bytes, or BytesIO. PDFs return a single string with --- Page N --- separators.
Legacy SDK: richer GLM-OCR helpers
TextLens remains supported for its GLM-OCR-specific helpers. Use auto_load=False when you want construction without immediately loading the model.
from textlens import TextLens
engine = TextLens(auto_load=False)
engine.load()
print(engine.read("invoice.png"))
print(engine.extract_table("table.png"))
print(engine.extract_formula("equation.png"))
print(engine.extract_json("receipt.jpg", schema='{"vendor": "str", "total": "float"}'))
for page in engine.read_pdf("contract.pdf", max_pages=3):
print(page["page"], page["text"])
BatchOCR
BatchOCR scans a folder (or accepts a list of files), queues supported images/PDFs, retries failures, writes one output per document, and writes a batch_manifest.json summary. Supported inputs: PDF, PNG, JPG/JPEG, WEBP, BMP, TIFF/TIF.
from textlens.batch import BatchOCR, TaskStatus
batch = BatchOCR(
model="glm-ocr",
workers=2, # start small: each worker can consume GPU memory
output_dir="./results",
output_format="json", # json | markdown | csv | txt
retries=2,
enable_dashboard=False,
)
tasks = batch.run("./documents")
for task in tasks:
if task.status is TaskStatus.COMPLETED:
print(task.source_path.name, task.output_path)
else:
print(task.source_path.name, task.error)
Set enable_dashboard=True to launch the local dashboard (default http://127.0.0.1:8765). On a GPU, do not increase workers blindly: parallel VLM inference can exhaust VRAM. Begin with one or two workers and increase only after checking textlens doctor and real memory use.
# These controls can be called from another thread or your application UI.
batch.pause()
batch.resume()
batch.cancel()
batch.retry_failed()
batch.reconfigure(workers=2, output_format="markdown", retries=3)
Model management and hardware inspection
from textlens import ModelManager
from textlens.models import HardwareDoctor
ModelManager.models()
ModelManager.download("smolvlm")
metadata = ModelManager.info("smolvlm")
report = HardwareDoctor().run()
HardwareDoctor().print_report(report)
REST API
Install the server extra before starting the API:
python -m pip install "textlens-ocr[server,inference]"
import textlens
textlens.serve(host="127.0.0.1", port=8000)
Open http://127.0.0.1:8000/docs for Swagger UI. Available endpoints include GET /api/v1/health, GET /api/v1/hardware, POST /api/v1/ocr (file upload or form path/URL), and POST /api/v1/ocr/json-payload (JSON URL/path).
CLI
textlens models
textlens discover # interactive model-name search
textlens discover DeepSeek-OCR --compatible-only
textlens discover --search "PaddleOCR-VL" --limit 10
textlens discover GOT-OCR2_0 --include-unknown
textlens discover --refresh # bypass the 15-minute cache
textlens model install smolvlm
textlens model info glm-ocr
textlens model remove smolvlm
textlens doctor
textlens read document.png --device cuda
textlens batch ./documents --model glm-ocr --workers 2 --format markdown --no-dashboard
textlens serve --host 0.0.0.0 --port 8000
textlens doctor only analyses local hardware and recommends official
TextLens catalog models. It does not search Hugging Face, so options such as
--include-unknown apply to textlens discover, not Doctor.
Test before using a model
The standard suite is offline and mocks downloads/model inference where appropriate:
python -m pytest tests -q
python scripts/run_feature_checks.py
For a real, local inference check after downloading a model, supply an image:
python scripts/run_feature_checks.py --image ./test-image-ocr.png --model glm-ocr --device cuda
See the API reference for public classes, functions, parameters, return values, and the full test checklist.
Runnable examples
The examples directory contains separate scripts for environment setup, model management, image/PDF OCR, custom prompts, table/formula/JSON extraction, device switching, BatchOCR, and the REST API. Start with:
python examples/00_environment_check.py
python examples/02_basic_ocr.py ./test-image-ocr.png --model smolvlm --device cuda
Status and roadmap
TextLens is an initial local-first release. NVIDIA CUDA is the recommended acceleration path today. CPU mode is a fallback, not the target for high-throughput OCR. Apple Silicon MPS support and strategies for optimising OCR workloads on Apple chips are planned future work; they should not yet be treated as production-ready support.
License
MIT License © TextLens Contributors.
Metadata
Release files for textlens-ocr 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| textlens_ocr-0.1.0.tar.gz | 106.4 kB | Without provenance | Details for textlens_ocr-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| textlens_ocr-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for textlens_ocr-0.1.0-py3-none-any.whl |
Total release size: 205.4 kB
Release files / textlens_ocr-0.1.0.tar.gz
| Download URL | textlens_ocr-0.1.0.tar.gz |
|---|---|
| Size | 106.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
56354d2dd5ab54e0a7d644e19270a4ac5e0cff51c5893d87f65663c7000bfd15
|
|
BLAKE2b-256 checksum How to use checksums |
28ec1e01e39f0037e01836fce618883121bc69e70ed51d612381259918fda859
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.7
|
Release files / textlens_ocr-0.1.0-py3-none-any.whl
| Download URL | textlens_ocr-0.1.0-py3-none-any.whl |
|---|---|
| Size | 98.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
11a24ca4160620cf73a03904f1fe07d3b5099d627df066cf088cc705a5a1b6bc
|
|
BLAKE2b-256 checksum How to use checksums |
51b6644f7c25d2bb6f36079c0a468f919241291dd4515366c4980b96b21dee7a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.7
|
Security for textlens-ocr 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.