mlboydaisuke commited on
Commit
bfc9b0e
ยท
verified ยท
1 Parent(s): 4623bd9

Upload README.md with huggingface_hub

Browse files
Files changed (1) hide show
  1. README.md +59 -71
README.md CHANGED
@@ -12,83 +12,71 @@ base_model:
12
  ---
13
  # all-MiniLM-L12-v2 โ€” ExecuTorch
14
 
15
- Sentence embeddings: text in, one vector out. For search, clustering and retrieval that
16
- never leaves the device. The deeper sibling of
17
- [all-MiniLM-L6-v2](https://huggingface.co/mlboydaisuke/all-MiniLM-L6-v2-ExecuTorch) โ€”
18
- twelve layers instead of six, the same 384-dimensional output and the same recipe.
19
-
20
- - **Source**: sentence-transformers/all-MiniLM-L12-v2 โ€” 33.4M parameters, 12 BERT layers,
21
- 384-dimensional output
22
- - **License**: Apache-2.0
23
- - **Input**: `input_ids` and `attention_mask`, both `[1, 256]` int64
24
- - **Output**: `[1, 384]`, mean-pooled over the mask and L2-normalised inside the graph
25
-
26
- ## The pooling is in the graph, on purpose
27
 
28
- sentence-transformers keeps the recipe per model in `1_Pooling/config.json` and
29
- `modules.json`, and the six embedding models on this shelf do not agree:
 
 
30
 
31
- | | pooling | normalised |
32
- |---|---|---|
33
- | all-MiniLM-L6-v2 | mean | yes |
34
- | **all-MiniLM-L12-v2** | **mean** | **yes** |
35
- | bge-small-en-v1.5 | **CLS** | yes |
36
- | multilingual-e5-base | mean | yes |
37
- | multilingual-e5-large | mean | yes |
38
- | paraphrase-multilingual-L12 | mean | **no** |
39
 
40
- This one was read off the repo rather than assumed from the family name: `modules.json`
41
- lists `Transformer, Pooling, Normalize` and the pooling config sets
42
- `pooling_mode_mean_tokens`. Getting it wrong does not throw โ€” mean-pooling BGE, or
43
- normalising the multilingual one, gives vectors that look fine and rank wrong โ€” so it is
44
- baked in rather than left to the caller.
45
 
46
  ## Verification
47
 
48
- | build | file | size | latency | worst cosine vs eager |
49
- |---|---|---|---|---|
50
- | XNNPACK fp32 | `embed_all_minilm_l12_xnnpack_fp32.pte` | 133.0 MB | 29.2 ms | 1.000000 |
51
- | XNNPACK fp16 | `embed_all_minilm_l12_xnnpack_fp16.pte` | 66.7 MB | 51.0 ms | 0.999998 |
52
- | Core ML fp32 | `embed_all_minilm_l12_coreml_all.pte` | 66.9 MB | **3.6 ms** | 0.999955 |
53
-
54
- Mac arm64, median of 10, one 256-token sequence โ€” a reference point for relative cost, not
55
- a device number. Eager fp32 on the same input is 17.4 ms. Cosine is measured against the
56
- model run in eager through its own documented pooling, over eight sentences including one
57
- in Japanese โ€” not against random token ids, which would tell you nothing.
58
-
59
- **And that the vectors are useful**, which agreement alone cannot show. A paraphrase
60
- against an unrelated sentence:
61
-
62
- ```
63
- 0.606 same meaning vs -0.110 unrelated
64
- ```
65
-
66
- Across languages โ€” "ๆฉŸๆขฐๅญฆ็ฟ’ใฎใƒขใƒ‡ใƒซใ‚’็ซฏๆœซใฎไธŠใงๅ‹•ใ‹ใ™" against "On-device inference keeps
67
- the data on the phone" โ€” it scores **-0.089**, below its score for an unrelated English
68
- sentence. That is the right answer for an English-only model, and the reason
69
- paraphrase-multilingual is on the shelf next to it.
70
-
71
- ```bash
72
- python convert/check_embed.py all_minilm_l12 fp32 # or fp16, int8, coreml
73
- ```
74
-
75
- ## Not shipped
76
-
77
- **int8** converts and holds โ€” worst cosine 0.998275 against eager over the same eight
78
- sentences โ€” but it comes out at **69.5 MB against fp16's 66.7 MB**, so nothing would pick
79
- it. The arithmetic is the same as on L6: dynamic int8 quantises the linear weights and
80
- leaves the token embedding table alone, and that table is 46.9 MB of the 133.0 MB model.
81
- fp16 halves the table too. On a model whose weights are substantially a vocabulary, fp16
82
- is the smaller build โ€” the depth doubled from L6 and the table did not, which is why the
83
- gap here (69.5 against 66.7) is narrower than L6's (58.6 against 45.3).
84
-
85
- ## Worth knowing about the speed
86
-
87
- XNNPACK fp32 is **slower than PyTorch eager** here (29.2 ms against 17.4), and fp16 is
88
- slower again while halving the file โ€” XNNPACK has no fp16 kernels for this graph and
89
- inserts casts instead. Core ML is the one that pays: **3.6 ms**, roughly five times eager,
90
- 100% delegated in a single subgraph. On iOS take the Core ML build; on Android the
91
- portable file is fp32 unless the size matters more than the latency.
 
 
92
 
93
  torch.export -> to_edge_transform_and_lower(partitioner) -> .pte
94
  (conversion scripts: [executorch-models](https://github.com/john-rocky/executorch-models))
 
12
  ---
13
  # all-MiniLM-L12-v2 โ€” ExecuTorch
14
 
15
+ all-MiniLM at twice the depth, on the same recipe. Text in, one
16
+ 384-dimensional vector out, for search and retrieval that never leaves the
17
+ device.
 
 
 
 
 
 
 
 
 
18
 
19
+ - **Source**: sentence-transformers/all-MiniLM-L12-v2 โ€” 12 layers, 384 dimensions, 30,522 vocabulary
20
+ - **License**: apache-2.0
21
+ - **Input**: `input_ids` and `attention_mask`, both `[1, 256]` int64
22
+ - **Output**: `[1, 384]`, mean-pooled and L2-normalised inside the graph
23
 
24
+ ## The recipe is in the graph, and it was read off this repo
 
 
 
 
 
 
 
25
 
26
+ sentence-transformers stores it per model, and the shelf's seven embedding models do
27
+ not agree. This one pools **mean** and
28
+ **normalises**, read from
29
+ `1_Pooling/config.json` and `modules.json` rather than inferred from the family name.
30
+ Getting it wrong does not throw; it returns vectors that look fine and rank wrong.
31
 
32
  ## Verification
33
 
34
+ | build | file | size (MB) | Mac ms* | backend takes | worst cosine vs eager | retrieval budget |
35
+ |---|---|---|---|---|---|---|
36
+ | fp32 | `embed_all_minilm_l12_xnnpack_fp32.pte` | 133.0 | 22.2 | 78.5% | 1.000000 | 0% |
37
+ | fp16 | `embed_all_minilm_l12_xnnpack_fp16.pte` | 66.7 | 33.5 | 67.6% | 0.999999 | 4% |
38
+ | Core ML (fp16, iOS) | `embed_all_minilm_l12_coreml_all.pte` | 67.2 | 3.6 | 100.0% | 0.999969 | 23% |
39
+
40
+ \*Mac arm64, median of 10, one 256-token sequence โ€” a reference point for relative
41
+ cost, not a device number. Torch eager fp32 on the same machine is
42
+ 19.6 ms.
43
+
44
+ Cosine is measured against the model run in eager through its own pooling, over eight
45
+ sentences. The last column is the one that decides: rank those eight against each
46
+ other, and ask whether this build's score error is smaller than the gap between the
47
+ document a query retrieves and the runner-up. Every shipped build keeps all eight
48
+ top-1 results.
49
+
50
+ ## The attention is eager, and that is the faster export
51
+
52
+ `F.scaled_dot_product_attention` decomposes in the edge dialect to `_safe_softmax`,
53
+ whose guard against a fully-masked row costs six operations XNNPACK cannot take โ€”
54
+ `scalar_tensor`, `where`, `logical_not`, `eq`, `full_like`, `any.dim` โ€” once per
55
+ attention block, and each one cuts the subgraph in two. The guard can only ever fire
56
+ when some query row loses **every** key, which needs left padding or an empty
57
+ sequence. This model is right-padded, so even a row that is all padding still sees the
58
+ real tokens and the guard protects nothing.
59
+
60
+ Exporting with `attn_implementation="eager"` removes it. Measured with 251 of 256
61
+ positions masked โ€” as adversarial as this shape gets โ€” the two graphs agree to 1.4e-07,
62
+ and XNNPACK fp32 goes from **62.6% to 78.5%** delegated.
63
+
64
+ ## Not shipped: int8
65
+
66
+ `embed_all_minilm_l12_xnnpack_int8.pte` is **69.5 MB** against fp16's 66.7 MB. Dynamic int8 quantises the
67
+ linear weights and leaves the token embedding table in fp32, and here that table is
68
+ 47 MB of the 133.0 MB model โ€” **35%**. The size a build comes out at is
69
+ `0.5 + 1.5 x (table share)` times the fp16 build; at 35% that is
70
+ 1.03, so there was never a smaller file to be had.
71
+
72
+ It is withheld on the number that decides. Ranking the eight test sentences against
73
+ each other, this build moves a pair score by at most **0.0107** while the
74
+ closest fp32 decision โ€” the gap between the document a query retrieves and the
75
+ runner-up โ€” is **0.0078**. That is **138%** of
76
+ the room available, against a bar of 50%.
77
+
78
+ Correlation reads 0.998465 for this build, which no correlation gate
79
+ would stop.
80
 
81
  torch.export -> to_edge_transform_and_lower(partitioner) -> .pte
82
  (conversion scripts: [executorch-models](https://github.com/john-rocky/executorch-models))