deepak-jobtoken commited on
Commit
c05fa45
Β·
verified Β·
1 Parent(s): aaeeb80

Update README.md

Browse files
Files changed (1) hide show
  1. README.md +144 -3
README.md CHANGED
@@ -1,5 +1,146 @@
1
  ---
2
- license: other
3
- license_name: licenseref-flowgraph-a2-weights
4
- license_link: LICENSE
 
 
 
 
 
 
 
5
  ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ license: apache-2.0
3
+ library_name: onnx
4
+ pipeline_tag: feature-extraction
5
+ base_model: sentence-transformers/all-MiniLM-L12-v2
6
+ tags:
7
+ - onnx
8
+ - sentence-similarity
9
+ - feature-extraction
10
+ - retrieval
11
+ - knowledge-distillation
12
  ---
13
+
14
+ # flowgraph-a2-student-l12
15
+
16
+ The embedding model used by [FlowGraph](https://github.com/tokenfactory-jobtoken/FlowGraph) β€” a
17
+ local-first desktop app that gives AI tools persistent, graph-shaped memory stored on the user's own
18
+ machine.
19
+
20
+ These are **FlowGraph's own trained weights**: a MiniLM-L12 student **distilled** from a
21
+ permissively-licensed offline teacher. No third-party model is redistributed here. The model runs
22
+ **locally and in-process** via ONNX Runtime β€” no API key, no network call at inference time.
23
+
24
+ ## What's in this repo
25
+
26
+ A single packaged bundle, `embedder-onnx-bundle-a2-student-l12.tar.gz` (~124 MB), which FlowGraph's
27
+ installer downloads by pinned digest. Inside, at the archive root:
28
+
29
+ | file | sha256 |
30
+ |---|---|
31
+ | `model.onnx` | `d99dbe939d43fd691d8ad36665f5f74592930d9d41ec00c47f44e32f0899bb27` |
32
+ | `vocab.txt` | `26e5c70d53771ba1a86b01f21baed1bf6f401236bcc15fd2cb73f0a0ea5aba66` |
33
+ | `config.json` | `be86edead4f536af99471225bfb498006c897aa2db9c754cc36a97d9c7d43783` |
34
+ | `tokenizer.json`, `tokenizer_config.json` | (HuggingFace tokenizer artifacts; unused by FlowGraph's in-tree WordPiece tokenizer, which reads `vocab.txt`) |
35
+
36
+ Bundle identity (`specVersion`, a merkle-sha256 over `model.onnx` + `vocab.txt` + `config.json`):
37
+
38
+ ```
39
+ 96e68b60d45a33a2f3c5a53d37b01f17c36b1378819cd8f3a9f6ad5d8ebee195
40
+ ```
41
+
42
+ Archive sha256: `0946c46dba4c5682e5567b53563a5f4f493abc2199677482ac80090720afd11d`
43
+
44
+ ## Architecture
45
+
46
+ MiniLM-L12 (12 layers, hidden 384, 12 heads, ~34M params) β†’ mean pooling β†’ `Dense(384 β†’ 768, no bias,
47
+ identity activation)` β†’ L2 normalize. The exported ONNX bakes the whole pipeline in: it takes
48
+ `input_ids` + `attention_mask` and emits a single **L2-normalized 768-d `sentence_embedding`** per row.
49
+ There is no `token_type_ids` input.
50
+
51
+ - dimensions: **768**
52
+ - max sequence length: **256**
53
+ - text prefix: **`search_document: `** β€” prepended to *both* passages and queries (see below)
54
+ - tokenizer: BERT WordPiece, uncased, accent-stripping
55
+
56
+ ## Usage
57
+
58
+ ```python
59
+ import numpy as np, onnxruntime as ort
60
+ from tokenizers import Tokenizer
61
+
62
+ tok = Tokenizer.from_file("tokenizer.json"); tok.enable_truncation(max_length=256)
63
+ sess = ort.InferenceSession("model.onnx", providers=["CPUExecutionProvider"])
64
+
65
+ def embed(texts):
66
+ enc = [tok.encode("search_document: " + t).ids for t in texts] # NOTE: same prefix for queries
67
+ L = max(len(e) for e in enc)
68
+ ids = np.zeros((len(enc), L), dtype=np.int64)
69
+ mask = np.zeros((len(enc), L), dtype=np.int64)
70
+ for i, e in enumerate(enc):
71
+ ids[i, :len(e)] = e; mask[i, :len(e)] = 1
72
+ return sess.run(None, {"input_ids": ids, "attention_mask": mask})[0] # already unit-normalized
73
+ ```
74
+
75
+ **The prefix is symmetric.** Unlike nomic-class models, this student was distilled on a single
76
+ `search_document: ` regime, so queries take the *same* prefix as passages. Using `search_query: ` puts
77
+ the input out of distribution.
78
+
79
+ ## Training
80
+
81
+ Distilled from **`nomic-ai/nomic-embed-text-v1.5`** at revision
82
+ `e9b6763023c676ca8431644204f50c2b100d9aab` (Apache-2.0), used strictly as an **offline teacher** β€” its
83
+ weights are not redistributed.
84
+
85
+ | | |
86
+ |---|---|
87
+ | loss | pointwise MSE to the teacher's L2-normalized embedding **+ relational** in-batch pairwise-similarity MSE (match the teacher's *rankings*, not just its coordinates) |
88
+ | corpus | `wikimedia/wikipedia`, config `20231101.simple`, split `train`; texts with `len > 100`, truncated to the first 512 chars, first **150,000** in dataset order |
89
+ | epochs / batch / lr / warmup | 4 / 128 / 2e-4 / 100 |
90
+ | precision | AMP (fp16), single GPU |
91
+ | max seq length | 256 |
92
+ | student init | `sentence-transformers/all-MiniLM-L12-v2` + the Dense projection head + Normalize |
93
+
94
+ The relational term is what made this work: plain MSE-to-embedding plateaued around 59% on an internal
95
+ doc-level proxy regardless of student size (23M / 34M / 110M all landed in the same band), while adding
96
+ the in-batch pairwise-similarity term lifted the 34M student to ~71% β€” about 95% of the teacher at
97
+ roughly a quarter of the parameters.
98
+
99
+ **Reproducibility.** No RNG seed was set during training, so bit-identical retraining is not possible
100
+ by construction. The contract is: the **released checkpoint is pinned by hash** (above) and the
101
+ procedure is documented; reproduction means *equivalent under this procedure*, not bit-identical.
102
+
103
+ ## Export
104
+
105
+ `torch.onnx.export` (legacy exporter, `dynamo=False`), opset **17**, `do_constant_folding=True`, dynamic
106
+ axes `{0: batch, 1: seq}` on the inputs. Attention is forced to **eager** at export time. (For the
107
+ record: an earlier SDPA-traced export produces numerically *identical* vectors β€” cosine 1.00000 and 100%
108
+ top-10 neighbour overlap across a probe set β€” so the attention implementation is pinned for procedure
109
+ fidelity, not because it changes the vector space.)
110
+
111
+ Faithfulness was verified against the PyTorch reference on 200 real corpus texts (including 73 short,
112
+ label-like strings): **min cosine 1.00000, mean 1.00000, top-10 neighbour overlap 100.0%**.
113
+
114
+ ## Evaluation
115
+
116
+ Measured inside FlowGraph's retrieval benchmark at node level, with the **graph held constant** and only
117
+ the embedder swapped (so the numbers isolate the embedder rather than the ingest), 200 labeled queries
118
+ per dataset, `k=10`:
119
+
120
+ | | ArguAna (1000 distractors) | HotpotQA |
121
+ |---|--:|--:|
122
+ | this model β€” vector recall@10 | **38.5%** | **60.5%** |
123
+ | FlowGraph's previous static embedder | 30.5% | 31.0% |
124
+ | teacher (nomic-embed-text-v1.5) | 48.5% | 65.3% |
125
+ | this model β€” hybrid nDCG@10 | **0.330** | **0.611** |
126
+ | teacher β€” hybrid nDCG@10 | 0.340 | 0.612 |
127
+
128
+ On raw vector recall the student reaches 79–93% of its teacher. On the **fused hybrid channel** the app
129
+ actually serves (reciprocal-rank fusion of vector + BM25 + graph walk) it reaches **97–100%** of the
130
+ teacher, and slightly *exceeds* it on HotpotQA MRR. Note that these are node-level scores over an
131
+ LLM-extracted knowledge graph, not standard BEIR document retrieval numbers, so they are not comparable
132
+ to published BEIR leaderboards.
133
+
134
+ Inference is CPU-cheap: roughly **25 ms/text** single-threaded on a 2-core container for short inputs.
135
+
136
+ ## Intended use & limitations
137
+
138
+ Built for retrieval over a personal knowledge graph: short node labels and document chunks, English,
139
+ ≀256 tokens. It is a distilled student β€” on raw semantic recall the teacher is still better, and it
140
+ inherits the teacher's and the Simple-English-Wikipedia corpus's biases. Not evaluated for
141
+ classification, clustering, or non-English text.
142
+
143
+ ## License
144
+
145
+ Apache-2.0. The weights are FlowGraph's own; the teacher was used offline under its own Apache-2.0
146
+ terms and is not redistributed here.