Upload README.md with huggingface_hub
Browse files
README.md
CHANGED
|
@@ -3,30 +3,111 @@ license: gemma
|
|
| 3 |
base_model: google/embeddinggemma-300m
|
| 4 |
library_name: onnx
|
| 5 |
pipeline_tag: sentence-similarity
|
|
|
|
|
|
|
| 6 |
tags:
|
| 7 |
- embeddinggemma
|
| 8 |
- onnx
|
| 9 |
- on-device
|
|
|
|
|
|
|
|
|
|
| 10 |
- tool-routing
|
| 11 |
---
|
| 12 |
|
| 13 |
-
#
|
| 14 |
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
|
|
|
|
|
|
|
|
|
| 18 |
|
| 19 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 20 |
|---|---|---|
|
| 21 |
-
|
|
| 22 |
-
|
|
| 23 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
|
| 25 |
-
-
|
| 26 |
-
-
|
| 27 |
-
-
|
| 28 |
|
| 29 |
## Licence
|
| 30 |
|
| 31 |
-
Gemma is provided under and subject to the Gemma Terms of Use found at ai.google.dev/gemma/terms.
|
| 32 |
-
|
|
|
|
| 3 |
base_model: google/embeddinggemma-300m
|
| 4 |
library_name: onnx
|
| 5 |
pipeline_tag: sentence-similarity
|
| 6 |
+
language:
|
| 7 |
+
- en
|
| 8 |
tags:
|
| 9 |
- embeddinggemma
|
| 10 |
- onnx
|
| 11 |
- on-device
|
| 12 |
+
- android
|
| 13 |
+
- voice-assistant
|
| 14 |
+
- intent-classification
|
| 15 |
- tool-routing
|
| 16 |
---
|
| 17 |
|
| 18 |
+
# EmbeddingGemma-300M Phone Command Router (ONNX, 4-bit)
|
| 19 |
|
| 20 |
+
**What it does:** turns something a person says to their phone ("wake me at half six", "text mom I'm on my way",
|
| 21 |
+
"how long is the drive to Boston") into a ranking of **205 phone actions**: set an alarm, send a text, start
|
| 22 |
+
navigation, add to a list, and so on. It is the first stage of a fully on-device voice assistant for Android: this
|
| 23 |
+
model picks *which* action, and a small companion model,
|
| 24 |
+
[LFM2.5-350M Phone Command Extractor](https://huggingface.co/bpmatt/LFM2.5-350M-Phone-Command-Extractor-GGUF),
|
| 25 |
+
fills in *the details* (times, names, messages).
|
| 26 |
|
| 27 |
+
It is `google/embeddinggemma-300m`, fine-tuned for this task and exported to ONNX with 4-bit weights
|
| 28 |
+
(~195 MB). It runs on a phone CPU in about **30-40 ms** per request.
|
| 29 |
+
|
| 30 |
+
## How it works
|
| 31 |
+
|
| 32 |
+
```
|
| 33 |
+
"remind me in 20 minutes to check the oven"
|
| 34 |
+
│ query text: "task: search result | query: remind me in 20 minutes to check the oven"
|
| 35 |
+
▼
|
| 36 |
+
EmbeddingGemma (this model) → 768-d vector → cosine vs. 205 tool embeddings (tool_embeddings.f32)
|
| 37 |
+
▼
|
| 38 |
+
set_timer 0.64 · add_reminder 0.47 · set_screen_timeout 0.43 …
|
| 39 |
+
▼ the app's keyword rule ("remind me … to …" is a reminder) moves add_reminder to the top
|
| 40 |
+
```
|
| 41 |
+
|
| 42 |
+
## Files
|
| 43 |
+
|
| 44 |
+
| File | What it is |
|
| 45 |
+
|---|---|
|
| 46 |
+
| `model_q4.onnx` + `model_q4.onnx_data` | the model (inputs `input_ids`, `attention_mask`; output `sentence_embedding` [batch, 768]) |
|
| 47 |
+
| `tokenizer.json` | the Gemma tokenizer (for Python / Hugging Face `tokenizers`) |
|
| 48 |
+
| `gemma_tok.bin` | the same tokenizer in a compact format read by the Android app's Java tokenizer |
|
| 49 |
+
| `tools.json` | the 205 actions (name + description), in the row order of the embeddings |
|
| 50 |
+
| `tool_embeddings.f32` | 205 × 768 little-endian float32, unit-length tool embeddings |
|
| 51 |
+
|
| 52 |
+
## Quick start (Python)
|
| 53 |
+
|
| 54 |
+
```python
|
| 55 |
+
import json, numpy as np, onnxruntime as ort
|
| 56 |
+
from huggingface_hub import snapshot_download
|
| 57 |
+
from tokenizers import Tokenizer
|
| 58 |
+
|
| 59 |
+
d = snapshot_download("bpmatt/EmbeddingGemma-300M-Phone-Command-Router-ONNX")
|
| 60 |
+
sess = ort.InferenceSession(f"{d}/model_q4.onnx")
|
| 61 |
+
tok = Tokenizer.from_file(f"{d}/tokenizer.json")
|
| 62 |
+
tools = json.load(open(f"{d}/tools.json"))
|
| 63 |
+
emb = np.fromfile(f"{d}/tool_embeddings.f32", dtype="<f4").reshape(tools["count"], tools["dim"])
|
| 64 |
+
|
| 65 |
+
def route(text, k=5):
|
| 66 |
+
ids = tok.encode(tools["query_prefix"] + text).ids
|
| 67 |
+
out = sess.run(["sentence_embedding"], {"input_ids": np.array([ids], dtype=np.int64),
|
| 68 |
+
"attention_mask": np.ones((1, len(ids)), dtype=np.int64)})[0][0]
|
| 69 |
+
q = out / (np.linalg.norm(out) + 1e-9)
|
| 70 |
+
s = emb @ q
|
| 71 |
+
return [(tools["tools"][i]["name"], round(float(s[i]), 3)) for i in np.argsort(-s)[:k]]
|
| 72 |
+
|
| 73 |
+
print(route("wake me up at half six"))
|
| 74 |
+
```
|
| 75 |
+
|
| 76 |
+
Encode **one query per run**: the 4-bit model is sensitive to padding, so batching changes the scores slightly.
|
| 77 |
+
|
| 78 |
+
## Results
|
| 79 |
+
|
| 80 |
+
Top-1 accuracy (the right action ranked first among 205), on held-out request sets never used for training or tuning:
|
| 81 |
+
|
| 82 |
+
| Set | Requests | Top-1 |
|
| 83 |
|---|---|---|
|
| 84 |
+
| Assistant dev set (everyday phone requests) | 294 | **96.7 %** |
|
| 85 |
+
| Public-dataset dev set (rephrased intents from public benchmarks) | 607 | **95.1 %** |
|
| 86 |
+
|
| 87 |
+
Inside the full assistant (this router + the extractor + safety rules + a confirmation step), 66 % of held-out requests
|
| 88 |
+
are completed correctly with no questions asked, 83 % are completed or settled with a single yes/no, and 4.6 % lead to a
|
| 89 |
+
wrong action.
|
| 90 |
+
|
| 91 |
+
## Training
|
| 92 |
+
|
| 93 |
+
Fine-tuned (contrastive, query → tool description, with hard negatives between easily confused actions) on about
|
| 94 |
+
12,000 examples: synthetic phone commands written for this project, covering every one of the 205 actions, plus samples
|
| 95 |
+
from public intent datasets (MASSIVE, TOPv2, MTOP, CLINC150, SNIPS, Home Assistant intents, and mobile-action datasets),
|
| 96 |
+
mapped onto the 205 actions. Held-out sets were checked for near-duplicates of the training data.
|
| 97 |
+
|
| 98 |
+
## Use in the app
|
| 99 |
+
|
| 100 |
+
The Android app runs this model with ONNX Runtime, then adds a few deterministic rules (keyword anchors for families
|
| 101 |
+
such as alarms vs. timers, a chat filter, and a "Did you mean…?" question when the top two are close). Recognising the
|
| 102 |
+
action is all this model does: dates, numbers and names are filled in by the extractor and checked by app code.
|
| 103 |
+
|
| 104 |
+
## Limitations
|
| 105 |
|
| 106 |
+
- English only; 205 fixed actions (a new action needs a new tool embedding, and ideally fine-tuning).
|
| 107 |
+
- It ranks actions; it does not decide whether a request is a command at all (the app uses a score threshold and rules).
|
| 108 |
+
- Requests that ask for two things at once ("set a timer and text Sam") are ranked as one; the app asks to split them.
|
| 109 |
|
| 110 |
## Licence
|
| 111 |
|
| 112 |
+
Gemma is provided under and subject to the Gemma Terms of Use found at ai.google.dev/gemma/terms. This model is a
|
| 113 |
+
Model Derivative of Gemma; see `NOTICE`, `GEMMA_TERMS_OF_USE.txt` and `GEMMA_PROHIBITED_USE_POLICY.txt`.
|