Short answer: run Xinference 3.2.0 on a loopback-only Docker port, launch the built-in DeepDoc image model, then upload a PDF to /v1/images/ocr with model=DeepDoc and kwargs={"task":"parse"}. The response contains ordered document elements rather than only a flat OCR string.
Xinference 3.2.0 added PDF input to its OCR API and a built-in DeepDoc model. The full parse task can combine OCR, layout, reading order, paragraph merging, tables and figures across an ordinary multi-page PDF. It is a useful local document-processing route when you do not want to send each file to a hosted OCR API, provided the model and server remain on infrastructure you control.
What arrived in Xinference 3.2.0
| Item | Verified detail |
|---|---|
| Release | Xinference 3.2.0, published 15 August 2026 |
| PDF route | PDF uploads accepted by the OCR API |
| Built-in model | DeepDoc, launched as an image model |
| Full document task | task="parse" |
| Response | Elements with type, text, optional base64 image crop and metadata such as page number |
| Licence | Xinference code: Apache-2.0. Review the separate terms supplied with downloaded model assets. |
| Maturity | Xinference is established; this integrated DeepDoc PDF parse path is new in 3.2.0 |
Unlike a retrieval framework, this first stage extracts structure from the document. You could later feed reviewed text into a system such as the site’s LlamaIndex document-chat workflow or compare it with the Quivr installation guide. Keep extraction and question answering as separate, testable steps.
Prerequisites and hardware choices
- A supported Docker installation with enough free disk space for the image, model files and temporary document data.
- A non-sensitive test PDF you are allowed to process.
- For the official GPU image, a compatible NVIDIA stack. Xinference’s 3.x Docker documentation specifies CUDA 13 and an NVIDIA driver of 580 or newer.
- For a simpler compatibility test, use the official CPU-suffixed image shown below and expect lower throughput.
- On Windows, run the multipart request with
curl.exe, not PowerShell’s legacycurlalias.
Do not choose a GPU image solely from the graphics card marketing name. Check the installed driver, container GPU access and Xinference’s current image notes. The instructions make no promise that a particular PDF size will fit your RAM or VRAM.
1. Start Xinference on loopback
docker run -d --name xinference-deepdoc -p 127.0.0.1:9997:9997 -e XINFERENCE_HOME=/data -v xinference-deepdoc-data:/data xprobe/xinference:v3.2.0-cpu xinference-local -H 0.0.0.0
The service listens on all interfaces inside the container, while Docker publishes it only to 127.0.0.1 on the host. The named volume keeps downloaded model data when the container is replaced. The official GPU route uses --gpus all with xprobe/xinference:v3.2.0 after the documented NVIDIA prerequisites are met.
docker ps --filter name=xinference-deepdoc docker logs --tail 100 xinference-deepdoc
Open http://127.0.0.1:9997 for the web interface or http://127.0.0.1:9997/docs for the local API documentation. Do not expose port 9997 to a LAN or the internet without configuring Xinference authentication, TLS and network access controls.
2. Launch DeepDoc
In the web interface, choose the image-model section, select DeepDoc and launch it. The equivalent standard Xinference CLI form is:
docker exec xinference-deepdoc xinference launch --model-name DeepDoc --model-type image
Run xinference launch --help inside your pinned image if a later build changes CLI flags. First launch can download model weights and create a model-specific environment, so it is not an offline step. Wait for the launch to finish and list running models:
docker exec xinference-deepdoc xinference list
Confirm the actual model UID displayed by Xinference. The examples below use DeepDoc, matching the documented request, but a customised launch can assign a different UID.
3. Parse a PDF through the verified API
Use a small, non-sensitive sample.pdf for the first request. In the same folder, create a plain UTF-8 file named deepdoc-options.json containing only:
{"task":"parse"}Reading the JSON field from a file avoids nested-quote differences between Windows PowerShell and newer PowerShell. From that folder, run this single-line Windows command. It writes or replaces deepdoc-result.json and prints the HTTP status:
curl.exe -sS -X POST http://127.0.0.1:9997/v1/images/ocr -F "model=DeepDoc" -F "kwargs=<deepdoc-options.json" -F "image=@sample.pdf;type=application/pdf" -o deepdoc-result.json -w "%{http_code}"On macOS or Linux, use curl instead of curl.exe; the same quoted file-reading form works. The < tells curl to read the field’s content from the JSON file, while @ uploads the PDF as a file. If authentication is configured, add the real bearer token using the syntax of your shell, for example, -H "Authorization: Bearer $env:XINFERENCE_TOKEN" in PowerShell. Do not add a fake Authorization header to an unauthenticated loopback test.
The exact field names matter:
model=DeepDocselects the launched model.kwargs={"task":"parse"}requests whole-document parsing.image=@sample.pdfuploads the file even though it is a PDF./v1/images/ocris the OCR endpoint used by the merged 3.2 implementation.
Do not pass pages or dpi with task=parse. The implementation rejects those options for full parsing because it consumes the whole document and uses cross-page coordinates. The documented PDF limit is 200 pages, with additional resource and pixel budgets that can reject problematic input earlier.
4. Validate the result before using it
Check the printed HTTP status before interpreting the output: a non-2xx status means the file may contain an error response, even if curl wrote it successfully. Open deepdoc-result.json in an editor that does not execute embedded HTML. The verified response shape includes a top-level task and an elements array similar to this abbreviated example:
{
"task": "parse",
"elements": [
{
"type": "table",
"text": "<table>...</table>",
"image_base64": "...",
"metadata": { "page_number": 2 }
}
]
}The default image scope can include crops for tables and figures. Treat text as untrusted extracted content: table HTML should be sanitised before rendering in a browser, and base64 images should not be logged unnecessarily. A useful acceptance test checks all of the following:
- the HTTP request completes without an error object;
taskequalsparseandelementsis a non-empty array;- page numbers map to the correct source pages;
- headings and paragraphs are in usable reading order;
- table cells match the visible table rather than merely looking plausible;
- critical names, dates and numbers are manually compared with the PDF.
OCR is an extraction aid, not evidence. Scans, rotated pages, handwriting, faint text and complex tables can fail silently. Keep the original document and a traceable review step before search indexing, automation or publication.
Network, credential and document safety
| Stage | Network or data flow | Control |
|---|---|---|
| Docker and model setup | Images, Python dependencies and model assets can be downloaded from Docker Hub, package indexes and model hosting used by Xinference. | Pin version 3.2.0, use approved registries and review downloaded licences and hashes where supplied. |
| PDF request | The entire PDF is sent to the Xinference endpoint in the URL. | Use 127.0.0.1 for local processing. A remote URL means the document leaves the workstation. |
| Authentication | An optional bearer token travels in the HTTP header. | Use TLS for any non-loopback endpoint and inject the token from a secret store. |
| Results | JSON can contain extracted document text and base64 crops. | Protect output files like the source PDF; avoid public logs and delete test artifacts according to policy. |
| Broader Xinference server | The same server can host models with different backends and data paths. | Do not assume every model on an existing shared instance is local just because DeepDoc is. |
After the model and container assets are cached, the specific loopback DeepDoc request does not require a hosted OCR provider. That statement does not cover operating-system telemetry, container registries, later updates or other models configured in the same Xinference instance.
Troubleshooting
| Symptom | What to check |
|---|---|
| Connection refused on port 9997 | Check docker ps and container logs. Confirm the host mapping is 127.0.0.1:9997:9997. |
| Model not found | Run xinference list in the container and use the displayed model UID. Wait for first-launch downloads to finish. |
| HTTP 400 for a valid PDF | Confirm the request uses task=parse, does not include pages or dpi, is within the 200-page and resource limits, and is genuinely a PDF. |
| PowerShell mangles the multipart form | Call curl.exe explicitly, keep the complete kwargs=<deepdoc-options.json argument quoted, and check that the options file contains valid JSON. |
| Out-of-memory or container exit | Try a smaller non-sensitive document, inspect Docker memory limits and start with conservative concurrency. Do not increase limits beyond safe host capacity. |
| Tables look correct but values are wrong | Compare every critical row with the rendered source. Store confidence or review status in downstream systems rather than treating HTML as authoritative. |
Stop or remove the service
Terminate the model using the UID shown by xinference list:
docker exec xinference-deepdoc xinference terminate --model-uid DeepDoc docker stop xinference-deepdoc docker rm xinference-deepdoc
The named volume remains after the container is removed. That is useful for a rollback, but it can retain model files and service data. Inspect and back up what you need before intentionally deleting it with docker volume rm xinference-deepdoc-data. Volume deletion is destructive and is not part of a routine stop.
Frequently asked questions
Can DeepDoc parse only selected pages?
Not through the 3.2 full parse task using pages or dpi; those options are rejected. Split a permitted copy of the PDF first if you need a selected-page workflow, while preserving the original and page mapping.
Does it need an NVIDIA GPU?
No for the documented CPU image route, but CPU processing can be slower. The official 3.x GPU image has specific CUDA and driver requirements; verify them before downloading the larger image.
Is a local PDF automatically private?
No. Privacy depends on the endpoint, bind address, host security, logs and output handling. The loopback example keeps the request on one host, but a remote endpoint uploads the entire file to that server.
Can I send the output straight to an LLM?
Technically yes, but first validate reading order and critical values, remove unnecessary personal data, and understand the LLM provider’s data path. Chunking unreviewed OCR can preserve extraction errors while making them harder to trace.
Official sources
Sources reviewed: 10 September 2026. Reviewed against the official Xinference 3.2.0 release, DeepDoc request contract and Docker documentation. The pinned release includes the full parse task and follow-up multi-page PDF fix. Record the versions and validate the workflow in your own environment.
Documentation links
- Xinference 3.2.0 release notes
- Merged DeepDoc PDF parsing API implementation and request contract
- Official Xinference installation guide
- Using Xinference, listing and terminating models
- Official Docker image and GPU requirements
- Xinference repository and Apache-2.0 licence
- curl manual: form fields, file input and HTTP status output
Bottom line: Xinference 3.2 makes DeepDoc’s structured PDF parsing available through one local API call, but the path is new and OCR can be confidently wrong. Keep the endpoint on loopback, use the exact task=parse multipart contract, review every critical field and preserve the source document.