phungpx commited on
Commit
d7270b2
·
verified ·
1 Parent(s): 73d9684

Upload ONNX export

Browse files
Files changed (1) hide show
  1. README.md +149 -0
README.md ADDED
@@ -0,0 +1,149 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: apache-2.0
3
+ base_model: PaddlePaddle/PP-DocLayoutV3_safetensors
4
+ tags:
5
+ - onnx
6
+ - onnxruntime
7
+ - document-layout-analysis
8
+ - document-ai
9
+ - layout-detection
10
+ - object-detection
11
+ pipeline_tag: object-detection
12
+ library_name: onnxruntime
13
+ ---
14
+
15
+ # PP-DocLayoutV3 (ONNX)
16
+
17
+ ONNX export of [`PaddlePaddle/PP-DocLayoutV3_safetensors`](https://huggingface.co/PaddlePaddle/PP-DocLayoutV3_safetensors),
18
+ a DETR-style document layout detection model. Given a document page image, it
19
+ predicts per-region bounding boxes, layout class, reading order, and
20
+ (optionally) segmentation polygons for 25 layout element types
21
+ (title, text, table, figure, formula, header/footer, reference, seal, ...).
22
+
23
+ This repo ships the traced ONNX graph only — inference needs **ONNX Runtime +
24
+ NumPy + OpenCV**, no PyTorch or `transformers` required at serve time. The
25
+ export script and reference pre/post-processing code (`pp_doclayout_v3_onnx.py`)
26
+ are included in this repo for convenience — see below.
27
+
28
+ ## Files
29
+
30
+ | File | Description |
31
+ |---|---|
32
+ | `pp_doclayoutv3.onnx` | Full graph, includes the mask head (`out_masks`) for polygon output |
33
+ | `pp_doclayoutv3_nomask.onnx` | Same graph without `out_masks` — smaller, no ~48 MB/image mask tensor; polygons degrade to axis-aligned boxes |
34
+ | `pp_doclayoutv3_fp16.onnx` | Half-precision copy of the graph above it (normalization/mask ops kept in fp32) |
35
+ | `labels.json` | `id2label` mapping used to decode `logits` |
36
+
37
+ Only the variants actually present in this repo were exported — see the
38
+ file list on the repo page for what's available.
39
+
40
+ ## Model I/O
41
+
42
+ **Input**
43
+
44
+ | Name | Shape | Notes |
45
+ |---|---|---|
46
+ | `pixel_values` | `(B, 3, 800, 800)` float32 | RGB, resized to a fixed 800×800 square (bicubic), scaled to `[0, 1]`. No mean/std normalization (`mean=0`, `std=1`). Batch dim is dynamic. |
47
+
48
+ **Output**
49
+
50
+ | Name | Shape | Notes |
51
+ |---|---|---|
52
+ | `logits` | `(B, 300, 25)` | Per-query class scores (sigmoid, not softmax) |
53
+ | `pred_boxes` | `(B, 300, 4)` | `cxcywh`, normalized to `[0, 1]` |
54
+ | `order_logits` | `(B, 300, 300)` | Reading-order pointer matrix |
55
+ | `out_masks` *(optional)* | `(B, 300, 200, 200)` | Mask logits at stride 4 (input_size / 4) |
56
+
57
+ 300 object queries, no NMS — box selection is done by top-`k` over the
58
+ flattened `(query, class)` score grid and thresholding, matching the
59
+ original PaddlePaddle/HF post-processing.
60
+
61
+ ## Usage
62
+
63
+ ```python
64
+ import numpy as np
65
+ import onnxruntime as ort
66
+
67
+ session = ort.InferenceSession("pp_doclayoutv3.onnx", providers=["CPUExecutionProvider"])
68
+ pixel_values = np.random.rand(1, 3, 800, 800).astype(np.float32) # preprocess your image to this
69
+ logits, pred_boxes, order_logits, out_masks = session.run(None, {"pixel_values": pixel_values})
70
+ ```
71
+
72
+ Decoding raw outputs into boxes/labels/reading-order/polygons requires the
73
+ post-processing logic ported from `PPDocLayoutV3ImageProcessor` (sigmoid
74
+ scoring, top-k selection, cxcywh→xyxy rescaling, reading-order pointer
75
+ resolution, mask→polygon extraction). The reference implementation is
76
+ `pp_doclayout_v3_onnx.py` in the source repo — a self-contained
77
+ `PPDocLayoutV3ONNX` class with no torch/transformers dependency:
78
+
79
+ ```python
80
+ from pp_doclayout_v3_onnx import PPDocLayoutV3ONNX
81
+
82
+ det = PPDocLayoutV3ONNX("pp_doclayoutv3.onnx", device="cpu") # or "cuda" / "tensorrt"
83
+ for r in det.predict("page.jpg"):
84
+ print(r["order"], r["label"], r["score"], r["box"])
85
+ ```
86
+
87
+ ## Examples
88
+
89
+ Served with `serve_pp_doclayout_v3.py` (TensorRT/CUDA EP, `threshold=0.4`, masks on)
90
+ against dense scientific-article pages from the CDLA-Permissive-1.0-licensed
91
+ [`creative-graphic-design/PubLayNet`](https://huggingface.co/datasets/creative-graphic-design/PubLayNet)
92
+ dataset (PubMed Central open-access articles), selected for high layout-element
93
+ count out of a scan of the train split — see `fetch_example_images.py`. Boxes
94
+ below are colored by predicted label, tagged `{reading_order}:{label} {score}`.
95
+ Full detections (all 25 classes, boxes, polygons, reading order) are in the
96
+ linked JSON.
97
+
98
+ | Input → detections | Elements | Labels detected | JSON |
99
+ |---|---|---|---|
100
+ | ![PMC5883225_00001](examples/outputs/PMC5883225_00001_annotated.jpg) | 38 | chart, figure_title, formula, header, number, paragraph_title, text | [PMC5883225_00001.json](examples/outputs/PMC5883225_00001.json) |
101
+ | ![PMC5883194_00003](examples/outputs/PMC5883194_00003_annotated.jpg) | 30 | chart, figure_title, header, number, paragraph_title, table, text, vision_footnote | [PMC5883194_00003.json](examples/outputs/PMC5883194_00003.json) |
102
+ | ![PMC4413546_00014](examples/outputs/PMC4413546_00014_annotated.jpg) | 29 | chart, figure_title, header, number, paragraph_title, text | [PMC4413546_00014.json](examples/outputs/PMC4413546_00014.json) |
103
+ | ![PMC5942346_00002](examples/outputs/PMC5942346_00002_annotated.jpg) | 25 | figure_title, footer, header, image, number, paragraph_title, table, text, vision_footnote | [PMC5942346_00002.json](examples/outputs/PMC5942346_00002.json) |
104
+
105
+ Source page images and their provenance are in `examples/inputs/SOURCE.json`.
106
+ Reproduce with:
107
+
108
+ ```bash
109
+ python fetch_example_images.py --count 4 --out-dir examples/inputs
110
+ python visualize_layout.py --images "examples/inputs/*.jpg" --out-dir examples/outputs --threshold 0.4
111
+ ```
112
+
113
+ ## Export details
114
+
115
+ - Traced with `torch.onnx.export`, opset 17 (`GridSample` requires ≥16), dynamic batch axis.
116
+ - `disable_custom_kernels=True` — the custom CUDA deformable-attention kernel
117
+ has no ONNX symbolic, so export uses the pure-PyTorch (`grid_sample`) path instead.
118
+ - The upstream 2D sin/cos position embedding is computed in float64 upstream;
119
+ ONNX Runtime's CPU EP has no double kernel for `Cos`, so it's patched to
120
+ float32 during tracing (diff ~1e-6, otherwise the exported graph fails to load).
121
+ - Verified against the PyTorch reference with a parity check
122
+ (`max|diff| < 1e-3` per output tensor) using the real pretrained weights.
123
+ - Export script: `export_pp_doclayout_v3.py` (`torch==2.13.0`, `transformers==5.15.0`).
124
+
125
+ ## Intended use & limitations
126
+
127
+ - Intended for document layout analysis in document-AI / IDP pipelines
128
+ (reading-order extraction, region cropping, downstream OCR routing).
129
+ - Inherits the training data, biases, and limitations of the base
130
+ `PaddlePaddle/PP-DocLayoutV3_safetensors` checkpoint — this repo changes
131
+ only the runtime format, not the weights or decision boundary.
132
+ - Fixed 800×800 input: very small text regions or extreme aspect-ratio pages
133
+ may lose detail relative to their original resolution.
134
+ - Not evaluated here beyond output-tensor parity with the PyTorch model —
135
+ refer to the base model card for accuracy/benchmark numbers.
136
+
137
+ ## License
138
+
139
+ Apache 2.0, inherited from the base model. Verify current license terms on
140
+ the [base model card](https://huggingface.co/PaddlePaddle/PP-DocLayoutV3_safetensors)
141
+ before redistribution.
142
+
143
+ ## Citation
144
+
145
+ Please cite the original PP-DocLayoutV3 / PaddleOCR work if you use this model:
146
+
147
+ ```
148
+ https://huggingface.co/PaddlePaddle/PP-DocLayoutV3_safetensors
149
+ ```