Docling Preprocessing Pipeline
PROOF uses IBM Docling as the first-stage preprocessor for structured documents (PDF, DOCX, PPTX, XLSX, HTML). Docling extracts native text, tables, and images into a structured markdown representation, reducing the load on the downstream vision LLM.
Supported Input Types
pdf— processed by the Docling PDF pipeline (CPU + VNNI/OneDNN on Intel Xeon).docx,doc,dotx,docm— Word documents via the Docling MS Word backend.pptx,ppt,potx,ppsx,pptm,potm,ppsm— PowerPoint presentations.xlsx,xls,xlsm— Excel spreadsheets.html,htm,xhtml— HTML documents.
HWP/HWPX files are handled by a separate converter (see HWP Support).
Architecture
- The user uploads one or more files to the a1 backend.
- The backend detects file types and routes Docling-compatible files to the Docling service.
- The Docling service converts each file to a
DoclingDocument, exports markdown with image placeholders, and extracts embedded images. - The backend receives the markdown and image paths.
- If Docling refinement is enabled, the backend downloads the images and sends the markdown + images to the media LLM for layout-aware cleanup.
- The final structured output is converted to CSV, XLSX, Markdown, or DOCX/PPTX.
Docling Service (CPU/VNNI)
The Docling service runs as a standalone FastAPI container on the document-preprocessing server. On the Xeon Scalable 6230 dual-socket host, the service is tuned for Intel VNNI/AVX-512 inference using the CPU PyTorch wheel and Intel Extension for PyTorch (IPEX).
Base image and dependencies
ubuntu:22.04base image.torch==2.3.1+cpuandtorchvision==0.18.1+cpuinstalled from the PyTorch CPU wheel index.intel-extension-for-pytorch==2.3.1+cpufor OneDNN graph optimization.numactlinstalled in the container for NUMA binding.
Runtime environment variables
| Variable | Default | Description |
|---|---|---|
DOCLING_NUM_THREADS | 20 | Number of CPU threads per pipeline. Set to one socket's physical core count. |
DOCLING_LAYOUT_BATCH_SIZE | 16 | Layout model batch size. Can be increased on VNNI-enabled CPUs. |
DOCLING_TABLE_BATCH_SIZE | 4 | Table structure model batch size. |
DOCLING_OCR_BATCH_SIZE | 4 | OCR batch size (currently disabled with do_ocr=false). |
DOCLING_SERVICE_PORT | 28182 | FastAPI listening port. |
NUMA / numactl binding
The Xeon 6230 dual-socket setup has two NUMA nodes. To avoid UPI latency between sockets, bind each Docling worker to a single NUMA node and run two independent workers in parallel for maximum throughput.
# Worker 1: socket 0
export OMP_NUM_THREADS=20
export MKL_NUM_THREADS=20
numactl --cpunodebind=0 --membind=0 \
docker compose -f docker-compose.docling.yml up -d
# Worker 2: socket 1 (change host port and compose project name)
export DOCLING_SERVICE_PORT=28183
export COMPOSE_PROJECT_NAME=docling_socket1
numactl --cpunodebind=1 --membind=1 \
docker compose -f docker-compose.docling.yml up -d
For a single worker on a single socket, use:
numactl --cpunodebind=0 --membind=0 \
docker compose -f docker-compose.docling.yml up -d
VNNI verification
Inside the container, verify VNNI is available through PyTorch OneDNN:
import torch
print(torch.__config__.show())
# Look for AVX512_VNNI and oneDNN entries.
Backend Integration
The a1 backend connects to the Docling service via core/docling_client.py:
docling_client.convert_file(path)uploads a file and returns markdown, image paths, and estimated page count.docling_client.download_image(path)fetches extracted image bytes.docling_client.health_check()verifies service availability.
The DOCLING_SERVICE_URL and DOCLING_ENABLED settings are managed in settings_store (or via .env).
Docling Refinement (LLM Post-processing)
When a user enables refinement, the backend downloads the extracted images and calls the media LLM endpoint with the markdown and a layout-cleanup prompt. This costs an additional cost_per_docling_refinement_page_krw per page.
Refinement is controlled by:
use_docling_refinementper-job flag.docling_refinement_enabledglobal setting.docling_max_images_per_doc— max images sent to the LLM per document.docling_image_max_size— max long-edge dimension for extracted images.
Deployment Checklist
- Build the CPU image on the preprocessing server:
cd appdocker compose -f docker-compose.docling.yml build
- Apply the DB migration:
psql $DATABASE_URL -f app/backend/db/migrations/006_add_docling_refinement.sql
- Start the service with NUMA binding.
- Verify health:
curl http://<docling-host>:28182/health
- Run
test_docling_service.pyandtest_backend_docling.py.