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,59 @@
|
||||
import click
|
||||
import copy
|
||||
import json
|
||||
import time
|
||||
from collections import defaultdict
|
||||
|
||||
from surya.detection import DetectionPredictor
|
||||
from surya.debug.draw import draw_polys_on_image
|
||||
from surya.logging import configure_logging, get_logger
|
||||
from surya.scripts.config import CLILoader
|
||||
import os
|
||||
|
||||
configure_logging()
|
||||
logger = get_logger()
|
||||
|
||||
|
||||
@click.command(help="Detect bboxes in an input file or folder (PDFs or image).")
|
||||
@CLILoader.common_options
|
||||
def detect_text_cli(input_path: str, **kwargs):
|
||||
loader = CLILoader(input_path, kwargs)
|
||||
|
||||
det_predictor = DetectionPredictor()
|
||||
|
||||
start = time.time()
|
||||
predictions = det_predictor(loader.images, include_maps=loader.debug)
|
||||
end = time.time()
|
||||
if loader.debug:
|
||||
logger.debug(f"Detection took {end - start} seconds")
|
||||
|
||||
if loader.save_images:
|
||||
for idx, (image, pred, name) in enumerate(
|
||||
zip(loader.images, predictions, loader.names)
|
||||
):
|
||||
polygons = [p.polygon for p in pred.bboxes]
|
||||
bbox_image = draw_polys_on_image(polygons, copy.deepcopy(image))
|
||||
bbox_image.save(os.path.join(loader.result_path, f"{name}_{idx}_bbox.png"))
|
||||
|
||||
if loader.debug:
|
||||
heatmap = pred.heatmap
|
||||
heatmap.save(os.path.join(loader.result_path, f"{name}_{idx}_heat.png"))
|
||||
|
||||
predictions_by_page = defaultdict(list)
|
||||
for idx, (pred, name, image) in enumerate(
|
||||
zip(predictions, loader.names, loader.images)
|
||||
):
|
||||
out_pred = pred.model_dump(exclude=["heatmap", "affinity_map"])
|
||||
out_pred["page"] = len(predictions_by_page[name]) + 1
|
||||
predictions_by_page[name].append(out_pred)
|
||||
|
||||
with open(
|
||||
os.path.join(loader.result_path, "results.json"), "w+", encoding="utf-8"
|
||||
) as f:
|
||||
json.dump(predictions_by_page, f, ensure_ascii=False)
|
||||
|
||||
logger.info(f"Wrote results to {loader.result_path}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
detect_text_cli()
|
||||
Reference in New Issue
Block a user