mlboydaisuke commited on
Commit
259820a
Β·
verified Β·
1 Parent(s): 7fb88b8

Upload README.md with huggingface_hub

Browse files
Files changed (1) hide show
  1. README.md +122 -0
README.md ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: mit
3
+ tags:
4
+ - executorch
5
+ - xnnpack
6
+ - pte
7
+ - on-device
8
+ - object-detection
9
+ base_model:
10
+ - microsoft/table-transformer-structure-recognition
11
+ ---
12
+ # Table Transformer β€” ExecuTorch (find tables, then read their structure)
13
+
14
+ Two models that pair. **`detection`** finds tables on a page; **`structure`** takes a
15
+ cropped table and returns its rows, columns, column header and spanning cells. Both are
16
+ DETR with a ResNet-18 backbone and 125 object queries, 28.8M parameters each.
17
+
18
+ ```
19
+ detect_<H>x<W> pixel_values (1, 3, H, W) fp32
20
+ -> logits (1, 125, C+1) fp32, boxes (1, 125, 4) fp32
21
+ ```
22
+
23
+ - **Files**: `table_transformer_detection_xnnpack_fp32.pte` β€” **115.8 MB**,
24
+ `table_transformer_structure_xnnpack_fp32.pte` β€” **115.9 MB**, three methods each
25
+ - **Source**: [microsoft/table-transformer-detection](https://huggingface.co/microsoft/table-transformer-detection) and [microsoft/table-transformer-structure-recognition](https://huggingface.co/microsoft/table-transformer-structure-recognition)
26
+ - **License**: MIT
27
+ - **Classes**: detection β€” `table`, `table rotated`. structure β€” `table`,
28
+ `table column`, `table row`, `table column header`, `table projected row header`,
29
+ `table spanning cell`
30
+
31
+ Boxes come out as DETR always emits them: `(cx, cy, w, h)` **normalised to the input**,
32
+ so mapping them back to your own page is two lines of arithmetic and does not depend on
33
+ which rung produced them.
34
+
35
+ ## The ladder, and why there is one
36
+
37
+ Each file carries three input sizes:
38
+
39
+ | rung | for |
40
+ |---|---|
41
+ | `detect_667x1000` | landscape β€” a wide table crop |
42
+ | `detect_1000x800` | portrait β€” a page |
43
+ | `detect_800x800` | square-ish |
44
+
45
+ **Resize to the rung nearest your aspect ratio.** Do not pad to a square, and do not
46
+ squash: both were measured against the reference running at its own size, scoring the
47
+ detections by matched IoU β€”
48
+
49
+ | what the caller does | worst matched IoU |
50
+ |---|---|
51
+ | resize to the size the processor would have chosen | **1.0000** |
52
+ | resize to 800x800 (aspect squashed) | 0.8644 |
53
+ | pad to 1000x1000 with the correct `pixel_mask` | 0.2918 |
54
+ | pad to 1000x1000 with an all-ones mask | 0.2220, and three detections invented |
55
+ | resize to 1000x1000 | 0.2095 |
56
+
57
+ The padded-canvas trick that works for this shelf's audio encoders does not work here,
58
+ which is why this is a ladder rather than one padded window. Methods in one `.pte` share
59
+ their constants, so the three rungs cost **0.3 MB** over one: a single method is 115.6 MB
60
+ and three are 115.9 MB.
61
+
62
+ ## Running it
63
+
64
+ **1. Preprocess.** ImageNet mean/std, bilinear resize to the rung, `(1, 3, H, W)`:
65
+
66
+ ```python
67
+ mean, std = processor.image_mean, processor.image_std
68
+ x = (np.asarray(image.resize((W, H))) / 255.0 - mean) / std
69
+ pixel_values = torch.from_numpy(np.ascontiguousarray(x.transpose(2, 0, 1)))[None]
70
+ ```
71
+
72
+ The copy is deliberate β€” ExecuTorch reads strides as contiguous whatever the tensor says.
73
+
74
+ **2. Post-process, outside the graph.** Softmax over the class axis, drop the last
75
+ column (the "no object" class), keep what clears your threshold:
76
+
77
+ ```python
78
+ scores = logits.softmax(-1)[0, :, :-1]
79
+ best = scores.max(-1)
80
+ keep = best.values > 0.7
81
+ ```
82
+
83
+ The threshold is your policy rather than the model's, which is why it is not baked in.
84
+
85
+ **3. Chain them** for a full page: `detection` to find the table, crop it with a small
86
+ margin, then `structure` on the crop.
87
+
88
+ ## Verification
89
+
90
+ Correlation over the raw output is not the unit this model is used in β€” 125 queries are
91
+ mostly the no-object class. The gate is the detections: both arms at the same rung, and
92
+ for every box the reference found, the best same-label box the build offers.
93
+
94
+ | model | eager finds (at 0.7) | `.pte` finds | worst matched IoU |
95
+ |---|---|---|---|
96
+ | structure | 17 β€” 9 rows, 4 columns, 1 column header, 2 spanning cells, 1 table | 17 | **1.0000** |
97
+ | detection | 1 β€” the table | 1 | **1.0000** |
98
+
99
+ The gate image is a rendered table, which is what a table in a document is. The
100
+ reference genuinely reads it: nine rows and four columns of a seven-row, four-column
101
+ table, plus the shaded header.
102
+
103
+ ## Speed
104
+
105
+ Mac arm64, median of 5, at the `667x1000` rung β€” a reference point for relative cost,
106
+ not a device number.
107
+
108
+ | model | `.pte` | torch eager fp32 |
109
+ |---|---|---|
110
+ | structure | **44.1 ms** | 66.5 ms |
111
+ | detection | **37.8 ms** | 63.4 ms |
112
+
113
+ Faster than eager, which is not the usual result on this shelf and follows from
114
+ delegation: **90.6%** of the ops run on XNNPACK, in 32 subgraphs.
115
+
116
+ ## What is not in these files
117
+
118
+ **fp32 only.** Reduced-precision builds go through this shelf's single-method harness,
119
+ which measures parity, delegation and timing per file; these are multi-method bundles
120
+ and would need that path rebuilt for the ladder. At 115 MB for 28.8M parameters there is
121
+ less to gain here than for the shelf's larger models, and an unmeasured fp16 build is not
122
+ one this shelf ships. No Core ML build for the same reason.