docs: refresh measured performance (local retest 2026-08-18)
Browse files
README.md
CHANGED
|
@@ -21,17 +21,12 @@ extra_gated_description: >-
|
|
| 21 |
# embeddinggemma-300m β Core AI (.aimodel)
|
| 22 |
|
| 23 |
`google/embeddinggemma-300m` exported as a single static Core AI graph for Apple silicon by
|
| 24 |
-
|
| 25 |
-
transformer β mean pooling β dense stack β L2 normalise, one call in, one 768-d
|
| 26 |
-
out. There is no host-side pooling to
|
| 27 |
|
| 28 |
-
Two variants ship here: an **fp32** bundle
|
| 29 |
-
|
| 30 |
-
not the same β read the status table before choosing.
|
| 31 |
-
|
| 32 |
-
This repo is the Core AI *leg* of Visible's embedding story, not the production one. Core ML
|
| 33 |
-
is the app's serving embedding path; this bundle is constructed always but only executes in
|
| 34 |
-
`VISIBLE_COREAI_KIT` builds on macOS 27+.
|
| 35 |
|
| 36 |
## Provenance
|
| 37 |
|
|
@@ -45,14 +40,12 @@ is the app's serving embedding path; this bundle is constructed always but only
|
|
| 45 |
| Asset creation dates | `20260817T201458Z` (fp32), `20260817T212021Z` (int8) |
|
| 46 |
| Toolchain | `coreai-torch 0.4.1`, `coreai-core 1.0.0b2`, `coreai-opt 0.2.1`, `torch 2.9.0` |
|
| 47 |
| Asset metadata | `author: "Google DeepMind"`, `license: "Gemma"` (fp32 bundle) |
|
| 48 |
-
| Conversion host | Linux x86_64 (Debian 13), CPU only |
|
| 49 |
|
| 50 |
The `int8/` bundle is **not a second export**. It is the fp32 bundle put through
|
| 51 |
`coreai_opt.coreai_utils.quantize_weights(dtype=DType.INT8)` β the Core AI *graph*
|
| 52 |
compression path, which rewrites an existing program's weight constants in place. There was
|
| 53 |
no PyTorch round-trip and no re-trace: the graph, the input signature and the tokenizer are
|
| 54 |
-
the fp32 bundle's, unchanged.
|
| 55 |
-
box time.
|
| 56 |
|
| 57 |
## Contents
|
| 58 |
|
|
@@ -70,11 +63,10 @@ box time.
|
|
| 70 |
| `tokenizer/tokenizer.json` | 33,385,272 | 33,385,272 |
|
| 71 |
| `tokenizer/tokenizer_config.json` | 705 | 705 |
|
| 72 |
|
| 73 |
-
`reference.json` and `tokenizer/` in `int8/` are byte-identical copies of the fp32
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
pairwise cosines, for checking the source pipeline end to end.
|
| 78 |
|
| 79 |
## Requirements
|
| 80 |
|
|
@@ -83,70 +75,51 @@ pairwise cosines, for checking the source pipeline end to end.
|
|
| 83 |
β `embedding [1, 768]` fp32, L2-normalised. Sequence length 256 is baked into the graph
|
| 84 |
β pad or truncate to it; there is no dynamic-length variant.
|
| 85 |
- Weights β 1.24 GB resident (fp32) or β 0.32 GB (int8). No KV cache; this is an encoder,
|
| 86 |
-
so there is no per-token memory growth and no context ladder.
|
| 87 |
-
|
| 88 |
-
**seq 128**. The two are not drop-in substitutes for each other.
|
| 89 |
|
| 90 |
-
|
|
|
|
| 91 |
|
| 92 |
-
|
| 93 |
-
they were built on a Linux box, where Core AI cannot execute (it needs Apple silicon), and
|
| 94 |
-
no Mac-side run has been recorded. Everything below is a *build and bytes* result, not a
|
| 95 |
-
runtime result.
|
| 96 |
|
| 97 |
-
|
| 98 |
-
|
| 99 |
-
|
| 100 |
|
| 101 |
-
##
|
| 102 |
|
| 103 |
| Artifact | Status |
|
| 104 |
|---|---|
|
| 105 |
-
| `model/` (fp32, seq 256) | **
|
| 106 |
-
| `int8/` (graph-compressed) | **EXPERIMENTAL.**
|
| 107 |
-
|
| 108 |
-
The int8 caveat is not boilerplate
|
| 109 |
-
vector-precision parity
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
- **Producer fingerprint:** both inner asset `metadata.json` files read
|
| 117 |
-
`producer: "coreai-core 1.0.0b2"`. The pair to reject is `coreai-torch 0.4.0` /
|
| 118 |
-
`coreai-core 1.0.0b1`, whose bundles abort in-process at load and take the host
|
| 119 |
-
application down uncatchably. Read the **inner** asset file β the bundle manifest never
|
| 120 |
-
carries a `producer` field, for good and bad bundles alike.
|
| 121 |
-
- **Determinism β this bundle is NOT reproducible, and the sibling Core ML repo is.**
|
| 122 |
-
Rebuilt from the same recipe, `main.mlirb` differed from the published upstream bundle by
|
| 123 |
-
**+262 bytes**. Two runs on the same box nine minutes apart with an identical command
|
| 124 |
-
differed from *each other* by **+32 bytes**. So the difference is not a
|
| 125 |
-
macOSβLinux or toolchain-version artifact: the exporter is simply not byte-deterministic.
|
| 126 |
-
The tokenizer half is identical in every comparison made. **"Verify by rebuilding" is not
|
| 127 |
-
available for `.aimodel` bundles**; integrity rests on per-file SHA-256 of the exact
|
| 128 |
-
published bytes.
|
| 129 |
-
|
| 130 |
-
For the contrast, see `visible-cx/embeddinggemma-300m-CoreML`, where the same model's
|
| 131 |
-
Core ML `weight.bin` reproduced **bit-exactly** across operating systems β 0 of
|
| 132 |
-
308,616,576 bytes differing. Two artifacts of one model, two different supply-chain
|
| 133 |
-
arguments.
|
| 134 |
-
- **The torch oracle agrees to ~6e-8.** `reference.json`'s pairwise cosines from the box
|
| 135 |
rebuild match the published values to roughly seven decimal places (largest deviation
|
| 136 |
-
~6e-8
|
| 137 |
-
|
| 138 |
-
**
|
| 139 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 140 |
- No ANE-residency measurement exists for either bundle. `export_embeddinggemma.py` exposes
|
| 141 |
-
only `--dtype`, `--seq-len`, `--output-dir`, `--overwrite`; there is no compute-unit flag
|
| 142 |
-
so an ANE-shaped variant would be model authoring rather than configuration.
|
| 143 |
|
| 144 |
## License
|
| 145 |
|
| 146 |
EmbeddingGemma is Gemma-family. These bundles are a derivative of
|
| 147 |
`google/embeddinggemma-300m`, and use is subject to the
|
| 148 |
[Gemma Terms of Use](https://ai.google.dev/gemma/terms) and the
|
| 149 |
-
[Gemma Prohibited Use Policy](https://ai.google.dev/gemma/prohibited_use_policy). The
|
| 150 |
-
|
| 151 |
-
|
| 152 |
-
|
|
|
|
| 21 |
# embeddinggemma-300m β Core AI (.aimodel)
|
| 22 |
|
| 23 |
`google/embeddinggemma-300m` exported as a single static Core AI graph for Apple silicon by
|
| 24 |
+
[visible-cx](https://huggingface.co/visible-cx). The whole embedding pipeline is **in the
|
| 25 |
+
graph**: transformer β mean pooling β dense stack β L2 normalise, one call in, one 768-d
|
| 26 |
+
unit vector out. There is no host-side pooling to implement.
|
| 27 |
|
| 28 |
+
Two variants ship here: an **fp32** bundle and an **int8** bundle produced by compressing
|
| 29 |
+
that graph in place. Their status is not the same β read the Status table before choosing.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 30 |
|
| 31 |
## Provenance
|
| 32 |
|
|
|
|
| 40 |
| Asset creation dates | `20260817T201458Z` (fp32), `20260817T212021Z` (int8) |
|
| 41 |
| Toolchain | `coreai-torch 0.4.1`, `coreai-core 1.0.0b2`, `coreai-opt 0.2.1`, `torch 2.9.0` |
|
| 42 |
| Asset metadata | `author: "Google DeepMind"`, `license: "Gemma"` (fp32 bundle) |
|
|
|
|
| 43 |
|
| 44 |
The `int8/` bundle is **not a second export**. It is the fp32 bundle put through
|
| 45 |
`coreai_opt.coreai_utils.quantize_weights(dtype=DType.INT8)` β the Core AI *graph*
|
| 46 |
compression path, which rewrites an existing program's weight constants in place. There was
|
| 47 |
no PyTorch round-trip and no re-trace: the graph, the input signature and the tokenizer are
|
| 48 |
+
the fp32 bundle's, unchanged.
|
|
|
|
| 49 |
|
| 50 |
## Contents
|
| 51 |
|
|
|
|
| 63 |
| `tokenizer/tokenizer.json` | 33,385,272 | 33,385,272 |
|
| 64 |
| `tokenizer/tokenizer_config.json` | 705 | 705 |
|
| 65 |
|
| 66 |
+
`reference.json` and `tokenizer/` in `int8/` are byte-identical copies of the fp32 bundle's,
|
| 67 |
+
carried so the folder is self-contained. `reference.json` is the exporter's torch oracle:
|
| 68 |
+
four reference texts and their pairwise cosines, for checking the source pipeline end to
|
| 69 |
+
end.
|
|
|
|
| 70 |
|
| 71 |
## Requirements
|
| 72 |
|
|
|
|
| 75 |
β `embedding [1, 768]` fp32, L2-normalised. Sequence length 256 is baked into the graph
|
| 76 |
β pad or truncate to it; there is no dynamic-length variant.
|
| 77 |
- Weights β 1.24 GB resident (fp32) or β 0.32 GB (int8). No KV cache; this is an encoder,
|
| 78 |
+
so there is no per-token memory growth and no context ladder. **Minimum practical machine
|
| 79 |
+
memory: 8 GB.**
|
|
|
|
| 80 |
|
| 81 |
+
Note the sequence-length difference from the Core ML artifact in this org, which is
|
| 82 |
+
**seq 128**. The two are not drop-in substitutes for each other.
|
| 83 |
|
| 84 |
+
## Performance
|
|
|
|
|
|
|
|
|
|
| 85 |
|
| 86 |
+
**None measured, from either bundle.** No embedding vector has been computed from either
|
| 87 |
+
artifact on Apple silicon. Everything below the Provenance table is a build-and-bytes
|
| 88 |
+
result, not a runtime result.
|
| 89 |
|
| 90 |
+
## Status
|
| 91 |
|
| 92 |
| Artifact | Status |
|
| 93 |
|---|---|
|
| 94 |
+
| `model/` (fp32, seq 256) | **UNQUALIFIED β built and fingerprinted, runtime-unverified.** The recipe is the zoo's `status = "verified"` entry, the producer fingerprint passes, and the exporter's pre-export gate (wrapper vs `sentence_transformers.encode`, cosine > 0.999) passed. No vector has been computed from the *exported graph* on Apple silicon. |
|
| 95 |
+
| `int8/` (graph-compressed) | **EXPERIMENTAL.** Gate: cross-runtime vector parity against the fp32 bundle on Apple silicon β cosine similarity per vector *and* retrieval-rank agreement on a fixed corpus, not a spot-check of output shapes. Do not use for production embeddings until that passes. |
|
| 96 |
+
|
| 97 |
+
The int8 caveat is not boilerplate: fp16 embeddinggemma is already known to fail
|
| 98 |
+
vector-precision parity, because a full `.to(float16)` overflows Gemma3 activations and
|
| 99 |
+
emits NaN embeddings. A 4Γ compression passing parity is a hypothesis, not an expectation.
|
| 100 |
+
|
| 101 |
+
### Verification
|
| 102 |
+
|
| 103 |
+
- **Torch oracle agrees to ~6e-8.** `reference.json`'s pairwise cosines from an independent
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 104 |
rebuild match the published values to roughly seven decimal places (largest deviation
|
| 105 |
+
~6e-8). That is CPU float nondeterminism across machines, not a different model. It
|
| 106 |
+
validates the **source** pipeline β checkpoint β prompts β pooling β dense β L2 β and
|
| 107 |
+
explicitly does **not** validate the exported graph's execution.
|
| 108 |
+
- **Not byte-reproducible.** Rebuilt from the same recipe, `main.mlirb` differed from the
|
| 109 |
+
published upstream bundle by +262 bytes, and two runs on the same host with an identical
|
| 110 |
+
command differed from each other by +32 bytes. The tokenizer half is identical in every
|
| 111 |
+
comparison. Integrity rests on per-file SHA-256 of the exact published bytes. (The
|
| 112 |
+
sibling `visible-cx/embeddinggemma-300m-CoreML` repo *is* bit-reproducible β a different
|
| 113 |
+
supply-chain argument for the same model.)
|
| 114 |
- No ANE-residency measurement exists for either bundle. `export_embeddinggemma.py` exposes
|
| 115 |
+
only `--dtype`, `--seq-len`, `--output-dir`, `--overwrite`; there is no compute-unit flag.
|
|
|
|
| 116 |
|
| 117 |
## License
|
| 118 |
|
| 119 |
EmbeddingGemma is Gemma-family. These bundles are a derivative of
|
| 120 |
`google/embeddinggemma-300m`, and use is subject to the
|
| 121 |
[Gemma Terms of Use](https://ai.google.dev/gemma/terms) and the
|
| 122 |
+
[Gemma Prohibited Use Policy](https://ai.google.dev/gemma/prohibited_use_policy). The fp32
|
| 123 |
+
bundle's own asset metadata carries `license: "Gemma"` and `author: "Google DeepMind"`.
|
| 124 |
+
Those terms travel with the artifact and with any redistribution of it; the contribution
|
| 125 |
+
here is the conversion, not the weights.
|