Suya OCR API — vLLM-backed, OpenAI-compatible OCR service
FastAPI service wrapping the Surya-OCR-2 model (datalab-to) served through vLLM: legacy /v1/api/ai/* endpoints, an OpenAI-compatible /v1/chat/completions endpoint, a coalescing request batcher, a local OCR CLI, Docker packaging, multilingual example outputs, and quantization/concurrency benchmarks. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
"""Post one or more images to an OCR endpoint and save text_lines per image.
|
||||
|
||||
Used to freeze the accuracy baseline and to capture candidate outputs for CER.
|
||||
|
||||
Usage:
|
||||
python scripts/capture_ocr_text.py \
|
||||
--url http://127.0.0.1:5002/v1/api/ai/suya_ocr_vllm/ \
|
||||
--out-dir baseline_outputs \
|
||||
temp_image_c3c56948-282e-453b-8fac-6c482243d1e5.jpg
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import base64
|
||||
from pathlib import Path
|
||||
|
||||
import requests
|
||||
|
||||
|
||||
def _payload(image_path: Path) -> dict:
|
||||
suffix = image_path.suffix.lstrip(".").lower() or "png"
|
||||
return {
|
||||
"file": base64.b64encode(image_path.read_bytes()).decode("utf-8"),
|
||||
"type": "jpg" if suffix == "jpeg" else suffix,
|
||||
"skip_text_detection": False,
|
||||
"skip_table_detection": False,
|
||||
"recognize_math": False,
|
||||
"ocr_with_boxes": True,
|
||||
}
|
||||
|
||||
|
||||
def capture(url: str, image_path: Path, out_dir: Path, timeout: float) -> str:
|
||||
resp = requests.post(url, json=_payload(image_path), timeout=timeout)
|
||||
body = resp.json()
|
||||
text = (body.get("data") or {}).get("text_lines", "") if isinstance(body.get("data"), dict) else ""
|
||||
out_dir.mkdir(parents=True, exist_ok=True)
|
||||
(out_dir / (image_path.stem + ".txt")).write_text(text, encoding="utf-8")
|
||||
return text
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(description="Capture OCR text_lines per image.")
|
||||
parser.add_argument("images", nargs="+", type=Path)
|
||||
parser.add_argument("--url", required=True)
|
||||
parser.add_argument("--out-dir", type=Path, required=True)
|
||||
parser.add_argument("--timeout", type=float, default=900)
|
||||
args = parser.parse_args()
|
||||
for image in args.images:
|
||||
capture(args.url, image, args.out_dir, args.timeout)
|
||||
print(f"captured {image.name} -> {args.out_dir}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user