mlboydaisuke commited on
Commit
0583b32
Β·
verified Β·
1 Parent(s): 72b9956

Upload README.md with huggingface_hub

Browse files
Files changed (1) hide show
  1. README.md +36 -35
README.md CHANGED
@@ -39,23 +39,23 @@ was measured against.
39
 
40
  | build | encoder | decoder | encoder speed | decoder speed |
41
  |---|---|---|---|---|
42
- | **Core ML + XNNPACK int8** | `manga_ocr_encoder_coreml_all.pte` **172.1 MB** | `manga_ocr_decoder_xnnpack_int8.pte` **45.0 MB** | **4.1 ms** | 2.6 ms |
43
- | XNNPACK int8 | `manga_ocr_encoder_xnnpack_int8.pte` 88.9 MB | `manga_ocr_decoder_xnnpack_int8.pte` 45.0 MB | 33.6 ms | 2.6 ms |
44
- | XNNPACK fp32 | `manga_ocr_encoder_xnnpack_fp32.pte` 343.4 MB | `manga_ocr_decoder_xnnpack_fp32.pte` 117.4 MB | 36.0 ms | 3.0 ms |
45
- | XNNPACK fp16 | `manga_ocr_encoder_xnnpack_fp16.pte` 173.1 MB | `manga_ocr_decoder_xnnpack_fp16.pte` 58.8 MB | 69.5 ms | 4.6 ms |
46
 
47
  Host numbers, on a loaded machine, decoder timed at a 3-character prefix β€” read them as a
48
  lower bound and as ratios rather than as device latency. Eager fp32 on the same host is
49
- 29.2 ms for the encoder and 4.4 ms for the decoder.
 
50
 
51
- **fp16 is the row nothing should pick.** It is the same size as the Core ML encoder and
52
- half the speed of fp32 on the encoder, because XNNPACK inserts a cast at every boundary
53
- it cannot fuse. It is listed because it was built and measured, not because it wins
54
- anything.
55
 
56
  **int8 is the row to pick on Android**: half of fp16 on the encoder and three-quarters of
57
- it on the decoder, faster than fp32 on both, and no character different from eager
58
- anywhere it was measured. What that costs is margin, not characters β€” see below.
59
 
60
  ## Running it
61
 
@@ -118,15 +118,16 @@ the boundary per step instead of L times that.
118
  ## Greedy, not beam search
119
 
120
  The checkpoint's own generation config asks for 4 beams. Greedy is what the graph is
121
- shaped for, and it is what these files were measured with. On the shelf's gate images
122
- greedy and beam-4 read the same string. Beam search remains possible from outside β€” the
123
- decoder is a pure function of `(prefix, hidden)`, so a caller can run it once per beam per
124
- step β€” but nothing here has measured what that buys.
 
125
 
126
  ## Core ML: the encoder yes, the decoder no
127
 
128
- **The encoder is the whole speed story**: 100% delegated, 4.1 ms against 29.2 ms for eager
129
- on the same host, at 172.1 MB. Worst-output correlation against fp32 eager is 0.999985.
130
 
131
  **The decoder is not shipped for Core ML, and the reason is specific.** It converts, it
132
  delegates 100%, and β€” once eight zero-element constants that transformers' BERT attention
@@ -170,17 +171,17 @@ is a tie, below 0.0 is a changed character.
170
  | build | median | worst step | steps changed |
171
  |---|---|---|---|
172
  | XNNPACK fp32 | 1.0000 | 1.0000 | 0 / 1008 |
173
- | XNNPACK fp16 | 1.0000 | 0.9884 | 0 / 1008 |
174
- | XNNPACK int8 | 1.0000 | **0.8661** | 0 / 1008 |
175
 
176
- **int8's worst moment still kept 87% of the margin.** That is the number behind the
177
- recommendation, not the 84 identical strings.
178
 
179
- A worst-case bound over the same steps β€” the reference gap divided by twice the largest
180
- error anywhere in the 6,144 logits β€” puts int8 at 0.87, below 1.0. That bound assumes the
181
- build's largest error landed exactly on the two logits that matter, which is not what
182
- happened; it says a flip cannot be ruled out from that statistic alone, not that one
183
- nearly occurred. Both are printed by `convert/check_manga_ocr.py`.
184
 
185
  ### What a whole line costs
186
 
@@ -189,15 +190,15 @@ emitted. Measured per call, median of 20:
189
 
190
  | prefix | fp32 | fp16 | int8 |
191
  |---|---|---|---|
192
- | 1 | 2.39 ms | 3.66 ms | 2.17 ms |
193
- | 8 | 3.49 ms | 5.07 ms | 3.11 ms |
194
- | 32 | 4.91 ms | 7.70 ms | 4.98 ms |
195
- | 64 | 6.43 ms | 10.95 ms | 5.98 ms |
196
-
197
- **Sixty-four times the prefix costs 2.8 times the step**, which is what makes the missing
198
- cache a fair trade. Summed over the prefixes a real line walks through, the decoder side
199
- of a **12-character line is 35 ms on int8** (40 ms fp32, 59 ms fp16); add one encoder run β€”
200
- 4.1 ms on Core ML, 33.6 ms on XNNPACK int8 β€” for the whole read.
201
 
202
  ### What this does not say
203
 
 
39
 
40
  | build | encoder | decoder | encoder speed | decoder speed |
41
  |---|---|---|---|---|
42
+ | **Core ML + XNNPACK int8** | `manga_ocr_encoder_coreml_all.pte` **172.1 MB** | `manga_ocr_decoder_xnnpack_int8.pte` **45.0 MB** | **4.2 ms** | 2.5 ms |
43
+ | XNNPACK int8 | `manga_ocr_encoder_xnnpack_int8.pte` 88.9 MB | `manga_ocr_decoder_xnnpack_int8.pte` 45.0 MB | 25.5 ms | 2.5 ms |
44
+ | XNNPACK fp32 | `manga_ocr_encoder_xnnpack_fp32.pte` 343.3 MB | `manga_ocr_decoder_xnnpack_fp32.pte` 117.4 MB | 29.5 ms | 3.2 ms |
45
+ | XNNPACK fp16 | `manga_ocr_encoder_xnnpack_fp16.pte` 173.1 MB | `manga_ocr_decoder_xnnpack_fp16.pte` 58.8 MB | 71.2 ms | 3.1 ms |
46
 
47
  Host numbers, on a loaded machine, decoder timed at a 3-character prefix β€” read them as a
48
  lower bound and as ratios rather than as device latency. Eager fp32 on the same host is
49
+ 29.9 ms for the encoder and 4.6 ms for the decoder. XNNPACK takes 82.9% of the encoder
50
+ and 51.9% of the decoder; Core ML takes all of the encoder.
51
 
52
+ **fp16 is the row nothing should pick.** Its encoder is the size of the Core ML build and
53
+ less than half the speed of fp32, because XNNPACK inserts a cast at every boundary it
54
+ cannot fuse. It is listed because it was built and measured, not because it wins anything.
 
55
 
56
  **int8 is the row to pick on Android**: half of fp16 on the encoder and three-quarters of
57
+ it on the decoder, **faster than eager PyTorch on both**, and no character different from
58
+ eager anywhere it was measured. What that costs is margin, not characters β€” see below.
59
 
60
  ## Running it
61
 
 
118
  ## Greedy, not beam search
119
 
120
  The checkpoint's own generation config asks for 4 beams. Greedy is what the graph is
121
+ shaped for and what every number here was measured with; on the horizontal gate image
122
+ greedy and beam-4 read the same string, and the 84-line set never needed more than greedy
123
+ to match eager. Beam search remains possible from outside β€” the decoder is a pure function
124
+ of `(prefix, hidden)`, so a caller can run it once per beam per step β€” but what it buys on
125
+ harder input than this has not been measured.
126
 
127
  ## Core ML: the encoder yes, the decoder no
128
 
129
+ **The encoder is the whole speed story**: 100% delegated, 4.2 ms against 29.9 ms for eager
130
+ on the same host, at 172.1 MB. Worst-output correlation against fp32 eager is 0.999984.
131
 
132
  **The decoder is not shipped for Core ML, and the reason is specific.** It converts, it
133
  delegates 100%, and β€” once eight zero-element constants that transformers' BERT attention
 
171
  | build | median | worst step | steps changed |
172
  |---|---|---|---|
173
  | XNNPACK fp32 | 1.0000 | 1.0000 | 0 / 1008 |
174
+ | XNNPACK fp16 | 0.9999 | 0.9820 | 0 / 1008 |
175
+ | XNNPACK int8 | 0.9999 | **0.6513** | 0 / 1008 |
176
 
177
+ **int8's worst moment still kept 65% of the margin**, and it is the only step below 0.9.
178
+ That is the number behind the recommendation, not the 84 identical strings.
179
 
180
+ The same steps also carry a worst-case bound β€” the reference gap over twice the largest
181
+ error anywhere in the 6,144 logits, which assumes that error landed exactly where it would
182
+ do the most damage. Its minimum is **1.16 for int8**, above 1.0, so on this set a changed
183
+ character is not merely absent but arithmetically impossible. Both numbers are printed by
184
+ `convert/check_manga_ocr.py`.
185
 
186
  ### What a whole line costs
187
 
 
190
 
191
  | prefix | fp32 | fp16 | int8 |
192
  |---|---|---|---|
193
+ | 1 | 2.36 ms | 2.27 ms | 2.18 ms |
194
+ | 8 | 3.37 ms | 3.45 ms | 2.90 ms |
195
+ | 32 | 3.94 ms | 4.88 ms | 4.26 ms |
196
+ | 64 | 5.31 ms | 6.94 ms | 4.99 ms |
197
+
198
+ **Sixty-four times the prefix costs 2.3 times the step**, which is what makes the missing
199
+ cache a fair trade. Summed over the prefixes a real line walks through, the decoder side of
200
+ a **12-character line is 33 ms on int8** (39 ms fp32); add one encoder run β€” 4.2 ms on
201
+ Core ML, 25.5 ms on XNNPACK int8 β€” for the whole read.
202
 
203
  ### What this does not say
204