# Repository Instructions ## Project Context This repo serves a FastAPI OCR API from `api.py`. The API keeps the legacy request/response shape: ```json {"data": ..., "message": "success", "code": 200} ``` Input validation is handled with Pydantic in `Info`. Keep external payload fields stable unless the user explicitly asks for a breaking API change. Primary endpoints: - `POST /v1/api/ai/suya_ocr/`: legacy OCR route. - `POST /v1/api/ai/suya_ocr_vllm/`: vLLM-backed OCR route. - `GET /v1/api/ai/suya_ocr_vllm/health`: reports vLLM backend attachment. - `POST /v1/api/ai/suya_text_det/`, `/suya_layout_det/`, `/suya_table_rec/`. ## Local Run Use the conda Python on this host; Homebrew `python3` may not have the API dependencies installed. For local direct `api.py` runs, start a vLLM OpenAI server separately and point the API at it. ```bash PYTHONDONTWRITEBYTECODE=1 \ PYTHONPATH=/path/to/suya-ocr-api \ SURYA_INFERENCE_BACKEND=vllm \ SURYA_INFERENCE_URL=http://127.0.0.1:8000/v1 \ SURYA_INFERENCE_AUTOSTART=false \ SURYA_INFERENCE_PARALLEL=8 \ SURYA_MAX_TOKENS_FULL_PAGE=6144 \ /opt/conda/bin/python api.py ``` The API listens on `http://127.0.0.1:5002`. For Kubernetes/container deployment, use `Dockerfile`. It is based on `vllm/vllm-openai:v0.20.1` and runs vLLM in the background, then `api.py` in the foreground through `scripts/start_single_container.sh`. ## vLLM Backend Notes The repo vendors the Surya source under `surya/`; runtime must not depend on `/path/to/surya`. `vllm_tools.py` must set Surya/vLLM environment defaults before importing `surya.settings` or Surya predictor classes. Important defaults: - `SURYA_INFERENCE_BACKEND=vllm` - `SURYA_INFERENCE_URL=http://127.0.0.1:8000/v1` - `SURYA_INFERENCE_AUTOSTART=false` - `SURYA_INFERENCE_LOGPROBS=false` - `SURYA_INFERENCE_MAX_RETRIES=1` - `SURYA_MAX_TOKENS_FULL_PAGE=6144` - `SURYA_MAX_BLOCKS_PER_PAGE=80` - `SUYA_OCR_MODE=block` The Dockerfile is tuned conservatively for a T4 machine: - `VLLM_GPU_TYPE=t4` - `VLLM_DTYPE=float16` - `SURYA_INFERENCE_PARALLEL=8` - `VLLM_MAX_NUM_SEQS=16` - `VLLM_MAX_BATCHED_TOKENS=4096` - `VLLM_GPU_MEMORY_UTILIZATION=0.85` If running on A100 hardware, do not silently change the Dockerfile T4 defaults; ask or document the deployment target first. ## Docker/NVIDIA The production container must not run nested Docker. Kubernetes should provide GPU access to the single container. The old Surya Docker auto-spawn path is disabled unless `SUYA_ALLOW_NESTED_DOCKER=true` is explicitly set. For host-level debugging only, Docker GPU runtime can be checked with: ```bash docker info --format '{{json .Runtimes}}' docker run --rm --runtime nvidia --gpus all --entrypoint nvidia-smi vllm/vllm-openai:v0.20.1 -L ``` If the named runtime is missing, use: ```bash sudo nvidia-ctk runtime configure --runtime=docker --config=/etc/docker/daemon.json sudo systemctl restart docker ``` `scripts/docker_nvidia_runtime_compat.sh` is legacy support for local debugging, not the Kubernetes deployment path. ## Concurrency Benchmark Run the comparison benchmark with the same image and settings when updating results: ```bash /opt/conda/bin/python concurrency_test.py \ --image /path/to/surya/static/images/excerpt.png \ --requests 16 \ --concurrency 16 \ --timeout 900 \ --output concurrency_test_results.json ``` After a successful run, update: - `concurrency_test_results.json` - `IMPLEMENTATION_PLAN_AND_TEST_RESULTS.md` Report latency columns as seconds. Mean latency is the average elapsed time per request, not wall-clock time for the whole benchmark. ## Editing Guidance - Use `rg`/`rg --files` for search. - Use `apply_patch` for manual edits. - Do not revert user changes or generated benchmark artifacts unless requested. - Keep logging structured and include request IDs for API paths. - Avoid import-time OCR work; model or backend attachment should happen only as needed by predictor setup and requests.