mlboydaisuke commited on
Commit
cc7b8ee
·
verified ·
1 Parent(s): 392b132

Upload README.md with huggingface_hub

Browse files
Files changed (1) hide show
  1. README.md +79 -0
README.md ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: apache-2.0
3
+ tags:
4
+ - executorch
5
+ - xnnpack
6
+ - pte
7
+ - on-device
8
+ - image-to-text
9
+ - text-recognition
10
+ ---
11
+ # docTR CRNN-MobileNetV3-Small — ExecuTorch
12
+
13
+ Text **recognition**: reads one word crop. The other half of the pair is
14
+ [DB-MobileNetV3-Large](https://huggingface.co/mlboydaisuke/docTR-DB-MobileNetV3-Large-ExecuTorch),
15
+ which finds the crops.
16
+
17
+ - **Source**: [mindee/doctr](https://github.com/mindee/doctr) `crnn_mobilenet_v3_small`,
18
+ 2.1M parameters
19
+ - **License**: Apache-2.0
20
+ - **Input**: `[1, 3, 32, 128]`, normalised with docTR's own mean (0.694, 0.695, 0.693) and
21
+ std (0.299, 0.296, 0.301)
22
+ - **Output**: `[1, 32, 127]` — 32 timesteps over a 126-symbol alphabet plus the CTC blank
23
+
24
+ Logits, not probabilities: greedy CTC only needs the argmax per timestep, so a softmax would
25
+ be thrown away. The alphabet is
26
+ `0123456789`, `a-z`, `A-Z`, punctuation, `°£€¥¢฿`, and accented Latin — read it out of
27
+ `crnn_mobilenet_v3_small().cfg["vocab"]` rather than retyping it.
28
+
29
+ ## Verification (Mac arm64, 2026-08-23)
30
+
31
+ | build | size | latency | worst corr |
32
+ |---|---|---|---|
33
+ | XNNPACK fp32 | 8.8 MB | 3.2 ms | 1.000000 |
34
+ | XNNPACK fp16 | 6.5 MB | 4.0 ms | 0.997143 |
35
+ | Core ML fp32 | 6.2 MB | **0.3 ms** | 0.999530 |
36
+
37
+ Eager fp32 for the same input is 121 ms.
38
+
39
+ **Read end to end** with the detector, on a London street photograph
40
+ (`convert/check_doctr.py`):
41
+
42
+ ```
43
+ boxes: 10
44
+ read: TIUZABXPRESS | Chrisiophers | Place | STREE! | LAG | BAR!
45
+ ```
46
+
47
+ The signs say PIZZA EXPRESS and Christopher's Place.
48
+
49
+ ## Cropping it
50
+
51
+ docTR's own `Resize` for this model is `preserve_aspect_ratio=True, symmetric_pad=False`:
52
+ the crop keeps its shape, sits at the top-left, and the rest of the strip is black. The
53
+ check does the same.
54
+
55
+ That is the principled choice rather than a measured improvement. Over four street
56
+ photographs neither it nor a plain squeeze won: one picture reads `Chrisiophers` squeezed
57
+ and `Clridabers` padded, another reads `TRAFFIC` padded and `TRAEFIC` squeezed.
58
+
59
+ ## Not shipped, and why
60
+
61
+ - **int8**: worst corr **0.883**, against a 0.95 gate, for 6.1 MB against 8.8. Recognition
62
+ is the half where a wrong character is the whole answer, so this one is not close enough.
63
+
64
+ ## Conversion
65
+
66
+ ```bash
67
+ python convert/export_doctr.py recognise
68
+ ```
69
+
70
+ docTR's `forward` runs CTC decoding in numpy whether or not it was asked to, which
71
+ `torch.export` refuses. The model carries an `exportable` flag that skips it and returns raw
72
+ logits; the wrapper sets that.
73
+
74
+ **Feed it contiguous tensors.** ExecuTorch reads a tensor in memory order rather than by its
75
+ strides, and a crop built with `np.transpose` is not contiguous. The detector half of this
76
+ pair scored 1.000000 against eager on random input and then returned a map that thresholded
77
+ to zero boxes on a real photograph, entirely because of that.
78
+
79
+ (conversion scripts: [executorch-models](https://github.com/john-rocky/executorch-models))