mlboydaisuke commited on
Commit
25daa72
·
verified ·
1 Parent(s): 2b67520

Upload README.md with huggingface_hub

Browse files
Files changed (1) hide show
  1. README.md +24 -18
README.md CHANGED
@@ -40,13 +40,16 @@ retrieves worse.
40
 
41
  | build | file | size (MB) | Mac ms* | backend takes | worst cosine vs eager | retrieval budget |
42
  |---|---|---|---|---|---|---|
43
- | fp32 | `embed_multilingual_e5_small_xnnpack_fp32.pte` | 470.2 | 89.8 | 78.5% | 1.000000 | 0% |
44
- | fp16 | `embed_multilingual_e5_small_xnnpack_fp16.pte` | 235.2 | 41.8 | 67.6% | 1.000000 | 1% |
45
- | Core ML (fp16, iOS) | `embed_multilingual_e5_small_coreml_all.pte` | 235.8 | 4.9 | 100.0% | 0.999979 | 15% |
46
 
47
- \*Mac arm64, median of 10, one 256-token sequence — a reference point for relative
48
- cost, not a device number. Torch eager fp32 on the same machine is
49
- 124.0 ms.
 
 
 
50
 
51
  Cosine is measured against the model run in eager through its own pooling, over eight
52
  sentences. The last column is the one that decides: rank those eight against each
@@ -56,18 +59,21 @@ top-1 results.
56
 
57
  ## The attention is eager, and that is the faster export
58
 
59
- On the sdpa path transformers hands `F.scaled_dot_product_attention` a **boolean**
60
- mask, PyTorch fills the masked entries with `-inf`, and the edge dialect lowers the
61
- whole thing to `_safe_softmax` — whose guard against a row of all `-inf` costs six
62
- operations XNNPACK cannot take (`scalar_tensor`, `where`, `logical_not`, `eq`,
63
- `full_like`, `any.dim`), once per attention block, each one cutting the subgraph in two.
64
-
65
- `attn_implementation="eager"` masks with `torch.finfo(dtype).min` instead — a large
66
- finite number — so there is no guard to lower. The two disagree only about rows that
67
- have no unmasked key at all: sdpa zeroes them, eager gives them a uniform row. Those
68
- are padding rows, which the pooling discards and which every real query row masks out,
69
- so the output does not move. Measured with all but eight positions masked — as
70
- adversarial as this shape gets — the two graphs agree to 1.4e-07.
 
 
 
71
 
72
  XNNPACK fp32 goes from **62.6% to 78.5%** delegated.
73
 
 
40
 
41
  | build | file | size (MB) | Mac ms* | backend takes | worst cosine vs eager | retrieval budget |
42
  |---|---|---|---|---|---|---|
43
+ | fp32 | `embed_multilingual_e5_small_xnnpack_fp32.pte` | 470.2 | 21.3 | 78.5% | 1.000000 | 0% |
44
+ | fp16 | `embed_multilingual_e5_small_xnnpack_fp16.pte` | 235.2 | 31.4 | 67.6% | 1.000000 | 1% |
45
+ | Core ML (fp16, iOS) | `embed_multilingual_e5_small_coreml_all.pte` | 235.8 | 3.9 | 100.0% | 0.999979 | 15% |
46
 
47
+ \*Mac arm64, one 256-token sequence, **fastest of five medians of ten** — a reference
48
+ point for relative cost, not a device number. The host shares its cores with other work,
49
+ and a single median does not survive that: the same eager model here measured 19.6 ms and
50
+ 182.8 ms twenty minutes apart. Contention only ever adds time, so the fastest repetition is
51
+ the one that means something. Torch eager fp32, measured the same way, is
52
+ 18.9 ms.
53
 
54
  Cosine is measured against the model run in eager through its own pooling, over eight
55
  sentences. The last column is the one that decides: rank those eight against each
 
59
 
60
  ## The attention is eager, and that is the faster export
61
 
62
+ `F.scaled_dot_product_attention` does not survive export as one operation. The edge
63
+ dialect lowers it through `_safe_softmax`, whose guard against a row with no unmasked key
64
+ at all leaves **11 operations XNNPACK cannot take, in every attention
65
+ block** — `scalar_tensor`, `where`, `mul.Scalar`, `logical_not`, `eq`, `full_like`, `any.dim`. Each one cuts the subgraph in two.
66
+
67
+ The switch is `attn_implementation="eager"`: transformers then builds the mask
68
+ itself, as `torch.finfo(dtype).min`, instead of handing `F.sdpa` a **boolean** mask
69
+ for PyTorch to fill with `-inf`.
70
+
71
+ The guard is emitted whether or not it can ever fire, and here it cannot: it triggers only
72
+ on `-inf`, and this arm never produces one. So the two differ only about rows that have no
73
+ unmasked key at all — sdpa zeroes them, this one gives them a uniform row — and those are
74
+ padding rows, which the pooling discards and which every real query row masks out anyway.
75
+ Measured with all but eight positions masked, as adversarial as this shape gets, the two
76
+ graphs agree to 1.4e-07.
77
 
78
  XNNPACK fp32 goes from **62.6% to 78.5%** delegated.
79