Spaces:
Running on Zero
Running on Zero
| title: OvisOCR2 | |
| emoji: ๐ | |
| colorFrom: blue | |
| colorTo: gray | |
| sdk: gradio | |
| sdk_version: 6.20.0 | |
| python_version: "3.12.12" | |
| app_file: app.py | |
| pinned: false | |
| license: apache-2.0 | |
| hardware: zero-gpu | |
| startup_duration_timeout: 30m | |
| models: | |
| - ATH-MaaS/OvisOCR2 | |
| preload_from_hub: | |
| - ATH-MaaS/OvisOCR2 | |
| short_description: Stream structured Markdown from document images and PDFs. | |
| # OvisOCR2 โ document OCR demo | |
| A focused image and PDF document parsing demo for | |
| [ATH-MaaS/OvisOCR2](https://huggingface.co/ATH-MaaS/OvisOCR2). It preserves | |
| reading order and emits Markdown with LaTeX formulas, HTML tables, and rendered | |
| visual-region crops. Model tokens stream into the interface as they are generated. | |
| PDFs are rasterized locally and processed one page at a time in Base mode. Up to | |
| four pages share one streamed GPU request by default, while each page is still | |
| inferred independently and sequentially. The browser merges the results, so long | |
| documents do not have to fit inside one ZeroGPU lease. GPU duration is estimated | |
| from the number of pages that actually remain in each group, so a short second | |
| group does not reserve the same ZeroGPU quota as a four-page group. If a Gradio | |
| stream closes without an explicit backend error, the browser reconnects from the | |
| first unfinished page while retaining every completed page. This demo | |
| intentionally does not expose a separate Long mode. | |
| The five packaged examples cover two financial tables, two Chinese handwriting | |
| pages, and one formula-rich OmniDocBench research-paper page. They are selectable | |
| directly in the interface and are also covered by the local smoke-test workflow. | |
| The workspace opens empty so examples remain an explicit user choice rather than | |
| an automatic input. | |
| ## Local run | |
| The verified local model directory is `/root/models/ATH-MaaS/OvisOCR2`. | |
| ```bash | |
| conda env create -f environment.yml | |
| conda activate ovisocr2-demo | |
| npm ci | |
| npm run build | |
| CUDA_VISIBLE_DEVICES=0 \ | |
| OVISOCR_MODEL_PATH=/root/models/ATH-MaaS/OvisOCR2 \ | |
| python app.py | |
| ``` | |
| Open `http://127.0.0.1:7860`. | |
| ### DSW proxy | |
| The server already listens on `0.0.0.0`. Set a DSW id and the public proxy URL | |
| is generated from the same `PORT` automatically: | |
| ```bash | |
| CUDA_VISIBLE_DEVICES=0 \ | |
| PORT=7869 \ | |
| OVISOCR_DSW_ID=1976932 \ | |
| OVISOCR_MODEL_PATH=/root/models/ATH-MaaS/OvisOCR2 \ | |
| python app.py | |
| ``` | |
| The corresponding URL is | |
| `https://1976932-proxy-7869.dsw-gateway-cn-hangzhou.data.aliyun.com/`. | |
| For a different gateway or an explicit public URL, set `OVISOCR_ROOT_PATH` | |
| instead; it takes precedence over `OVISOCR_DSW_ID`. | |
| DSW's per-port proxy uses its own hostname and serves at `/`, so the ASGI root | |
| path stays empty. If an explicit URL contains a real subpath, such as | |
| `https://example.test/ocr/`, the app passes only `/ocr` to Gradio's `root_path`; | |
| passing the whole URL into this custom FastAPI server would break static mounts. | |
| For a UI-only smoke that does not load the model: | |
| ```bash | |
| OVISOCR_TEST_MODE=1 python app.py | |
| ``` | |
| ## Hugging Face Space | |
| The checked-in `dist/` directory is the production frontend, so the folder can | |
| be uploaded directly to a Gradio Space without a Node build step. Select | |
| ZeroGPU hardware in the Space settings. The README metadata pins Python 3.12.12 | |
| and Gradio 6.20.0 | |
| and declares `hardware: zero-gpu`; `app.py` decorates only the inference endpoint | |
| with `@spaces.GPU` and loads the model on CUDA at module scope, following the | |
| ZeroGPU loading contract. | |
| On Hugging Face, the model source automatically falls back from the local path | |
| to `ATH-MaaS/OvisOCR2`. PDFs are limited to 50 pages by default. Groups of up to | |
| four pages share a ZeroGPU reservation while the frontend preserves already | |
| completed pages. | |
| ## Runtime knobs | |
| - `OVISOCR_MODEL_PATH`: local directory or Hub model id. | |
| - `OVISOCR_MAX_NEW_TOKENS`: defaults to `16384`, matching the model README inference configuration. | |
| - `OVISOCR_MAX_PDF_PAGES`: defaults to `50`. | |
| - `OVISOCR_PAGES_PER_GPU_REQUEST`: defaults to `4` and is capped at `5`. | |
| - `OVISOCR_PDF_RENDER_SCALE`: PDF rasterization scale, defaults to `2.0`. | |
| - `OVISOCR_STREAM_MIN_CHARS`: minimum new characters between stream updates, defaults to `64`. | |
| - `OVISOCR_STREAM_MAX_INTERVAL`: maximum seconds between available stream updates, defaults to `0.25`. | |
| - `OVISOCR_GPU_SECONDS_PER_PAGE`: duration-estimation budget, defaults to `30` seconds per page. | |
| - `OVISOCR_GPU_DURATION_FLOOR`: minimum per-group ZeroGPU reservation, defaults to `45` seconds. | |
| - `OVISOCR_GPU_DURATION_CEILING`: maximum estimated per-group reservation, defaults to `120` seconds. | |
| - `OVISOCR_GPU_DURATION`: optional fixed per-group override; unset by default so dynamic duration is used. | |
| - `OVISOCR_ATTN_IMPLEMENTATION`: defaults to `sdpa`. | |
| - `OVISOCR_DSW_ID`: generates the Hangzhou DSW proxy root using the active `PORT`. | |
| - `OVISOCR_ROOT_PATH`: explicit proxy URL or ASGI path prefix; overrides `OVISOCR_DSW_ID`. | |
| - `OVISOCR_TEST_MODE=1`: deterministic mock inference for UI/integration tests. | |