10. Interview Prep Guide¶
2-minute architecture script¶
Universal OCR is an async microservice that turns PDFs and images into Markdown and HTML. The browser or any HTTP client posts a file to FastAPI and gets a job id. Celery workers do the heavy lifting while Redis stores progress. The default path runs PaddleX layout detection, then sends each text block to a vision-language model — either a local Paddle VL server or any LiteLLM-compatible model. We also support whole-page VLM, NVIDIA NeMo Retriever Parse, and Sarvam behind the same job API. Results are files on disk; the React dashboard polls every two seconds and shows HTML and Markdown previews. There is no agent loop and no SQL database — it is a focused OCR utility with pluggable inference backends.
5-minute architecture script¶
Expand the 2-minute version with:
- Why async: multi-page PDFs and VLM latency exceed HTTP request budgets (ADR 1).
- Layout path detail: PP-DocLayoutV3 labels → skip VLM for figures → parallel block OCR → stitch MD/HTML with page markers.
- Model routing: blank/
paddleocr-vl*→ Paddle client; else LiteLLM; singletons + prewarm avoid cold start. - Third-party branches: nvidia/sarvam/vlm short-circuit before layout; Sarvam metadata normalized into shared schema.
- Storage: Redis DB 0 job hashes (24h TTL), Celery on DB 1,
jobs/{uuid}/artifacts. - Frontend: single-page Vite app, mode select, history sheet, iframe HTML preview.
- Ops:
make startor amd64 Docker full stack; Apple Silicon needs Rosetta for Paddle images. - Honest limits: no auth, ephemeral storage, provider-dependent quality.
Likely system design questions¶
| Question | Answer sketch |
|---|---|
| Sync vs async OCR? | Async — long GPU/API work; scale workers independently |
| Why not WebSockets? | Polling sufficient; simpler failure modes (ADR 6) |
| How to scale? | More Celery workers + shared volume + Redis; watch GPU memory with solo pool |
| How to add a provider? | New extractor + branch in run_ocr_job + frontend mode entry |
| Consistency of Redis vs disk? | Best-effort; TTL can leave orphans — call out as gap |
Likely backend questions¶
- Explain
get_modelscache invalidation on model name change - Difference between
vlm_async_concurrencyandvlm_max_workers - How ZIP download is built and cleaned up
- Why Celery uses Redis DB 1
- How custom OCR prompts apply only on LiteLLM path
Likely frontend questions¶
- Polling interval and cleanup on unmount/reset
- Why both md and html are fetched on done
- XSS implications of
srcDoc - No router / no global store rationale
Likely infra / security questions¶
- Compose password mismatch
- amd64 platform pin
- Missing auth and upload limits
- Where secrets live
Likely data / OCR questions¶
- What
IMAGE_LABELSdo - How PDF pages are rasterized (PyMuPDF DPI)
- NVIDIA JPEG backoff and Gemma fallback
- Sarvam coordinate normalization
STAR stories¶
Parallel block OCR¶
- Situation: Page-level sequential VLM was too slow
- Task: Cut turnaround without losing layout fidelity
- Action: Parallelize blocks with semaphore/thread pool; stream progress to Redis
- Result: Interactive progress UX; tunable concurrency per provider
Provider abstraction¶
- Situation: Stakeholders wanted NVIDIA and Sarvam trials without forking the API
- Task: Keep one job contract
- Action: Mode branch in Celery + shared download/metadata endpoints
- Result: Dashboard mode switch for A/B comparison
Cold start mitigation¶
- Situation: First job after worker boot was painfully slow
- Task: Remove model load from the critical path
- Action: Process singletons + optional prewarm on API and worker start
- Result: Steady-state latency dominated by inference, not init
Weak spots to acknowledge¶
- No authentication or multi-tenancy
- Upload size not enforced server-side
- Redis TTL vs disk retention drift
- Limited live-provider automated tests
- Prefetch multiplier comment vs value mismatch
- HTML preview sanitization
Short answers¶
What was hard?
Coordinating layout detection, heterogeneous VLM APIs, and progress UX without turning the service into a full document platform.
What would you improve?
Auth + upload limits, disk GC, provider contract tests, sanitize HTML preview, fix compose Redis auth consistency.
What are you proud of?
The hybrid layout+VLM design and the ability to swap inference backends behind one async job API.