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,52 @@
|
||||
import math
|
||||
from typing import List, Optional
|
||||
|
||||
from tqdm import tqdm
|
||||
|
||||
from surya.common.predictor import BasePredictor
|
||||
from surya.ocr_error.loader import OCRErrorModelLoader
|
||||
from surya.ocr_error.model.config import ID2LABEL
|
||||
from surya.ocr_error.schema import OCRErrorDetectionResult
|
||||
from surya.settings import settings
|
||||
|
||||
|
||||
class OCRErrorPredictor(BasePredictor):
|
||||
model_loader_cls = OCRErrorModelLoader
|
||||
batch_size = settings.OCR_ERROR_BATCH_SIZE
|
||||
default_batch_sizes = {"cpu": 8, "mps": 8, "cuda": 64}
|
||||
|
||||
def __call__(self, texts: List[str], batch_size: Optional[int] = None):
|
||||
return self.batch_ocr_error_detection(texts, batch_size)
|
||||
|
||||
def batch_ocr_error_detection(
|
||||
self, texts: List[str], batch_size: Optional[int] = None
|
||||
):
|
||||
if batch_size is None:
|
||||
batch_size = self.get_batch_size()
|
||||
|
||||
num_batches = math.ceil(len(texts) / batch_size)
|
||||
texts_processed = self.processor(
|
||||
texts, padding="longest", truncation=True, return_tensors="pt"
|
||||
)
|
||||
predictions = []
|
||||
for batch_idx in tqdm(
|
||||
range(num_batches),
|
||||
desc="Running OCR Error Detection",
|
||||
disable=self.disable_tqdm,
|
||||
):
|
||||
start_idx, end_idx = batch_idx * batch_size, (batch_idx + 1) * batch_size
|
||||
batch_input_ids = texts_processed.input_ids[start_idx:end_idx].to(
|
||||
self.model.device
|
||||
)
|
||||
batch_attention_mask = texts_processed.attention_mask[start_idx:end_idx].to(
|
||||
self.model.device
|
||||
)
|
||||
|
||||
with settings.INFERENCE_MODE():
|
||||
pred = self.model(batch_input_ids, attention_mask=batch_attention_mask)
|
||||
logits = pred.logits.argmax(dim=1).cpu().tolist()
|
||||
predictions.extend(logits)
|
||||
|
||||
return OCRErrorDetectionResult(
|
||||
texts=texts, labels=[ID2LABEL[p] for p in predictions]
|
||||
)
|
||||
Reference in New Issue
Block a user