flashvenom commited on
Commit
5b107df
·
verified ·
1 Parent(s): ce056af

Reframe card around the capability and its boundary

Browse files

Lead with what the model does — tool calling against a known catalog as structured extraction at 48M params — rather than a scoreboard row.

- Results split into known-catalog / unknown-catalog tables; Needle 2 stays as a named yardstick column so the numbers keep their scale.
- New 'Where it stops working' section with per-category BFCL evidence.
- Negative-result count reconciled to 11.
- Deployment figure corrected: 184MB fp32 as shipped (was 168MB bf16, a stale figure from the 44.1M era).

Files changed (1) hide show
  1. README.md +75 -28
README.md CHANGED
@@ -65,47 +65,73 @@ model-index:
65
  value: 23.5
66
  name: BFCL v4 single-turn
67
  ---
68
-
69
  # 🧵 Thimble
70
 
71
- **A 48M-parameter tool-calling model that beats [Needle 2](https://cactuscompute.com/needle)
72
- on 3 of its 5 published benchmarks — including their toughest, Seal-Tools with 150× less training data.**
73
 
74
- [**GitHub (code, evals, full experimental record)**](https://github.com/nikshepsvn/thimble) · MIT · 48.12M params · 11.5MB at 2-bit · $260 total build cost
75
 
76
  ![Results](results.png)
77
 
78
- ## TL;DR
79
-
80
- | Suite | Thimble v6 | Needle 2 (45M) | |
81
- |---|---:|---:|---|
82
- | Seal-Tools in-domain (700) | **33.1** | 32.6 | ✅ their flagship suite |
83
- | Mobile Actions (961) | **86.3** | 63.7 | ✅ +22.6 |
84
- | DroidCall (200) | **52.5** | 17.0 | ✅ 3.1× |
85
- | Well-formed JSON | **100.0** | 93.4 | by construction |
86
- | Seal-Tools out-of-domain (654) | 28.1 | **28.7** | −0.6 |
87
- | BFCL v4 single-turn (3,641) | 23.5 | **42.6** | their data moat |
88
-
89
- Metric: **ordered strict exact match** a row passes only if the function names,
90
- call order, and *every* argument value match. Their metric, their published
91
- numbers, unmodified. Needle 2 trained on **153B tokens**; Thimble saw **~1B**.
92
-
93
- Two things to know before quoting the table: the Seal-in margin (+0.5 on 700
94
- rows) is within sampling noise and we say so, and the pre-registered model
95
- selector actually picked a sibling checkpoint that scored worse — the failure is
96
- diagnosed, both models' results are published, and the full story is in
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
  [RESULTS.md](https://github.com/nikshepsvn/thimble/blob/master/RESULTS.md).
98
 
99
- ## Why a thimble beats a needle
100
 
101
  **1. Tool calling is five decisions, not a generation problem.** A grammar
102
  compiled from the tool schemas force-feeds all JSON structure — braces, quotes,
103
  and every argument key. The model is consulted at exactly five choice points:
104
  *refuse or call · which tool · include this optional? · what value · stop or
105
  continue*. Malformed JSON, hallucinated parameter names, and calls to
106
- nonexistent tools are **unreachable, not unlikely**. At 45M parameters, capacity
107
  spent learning that `{` follows `[` is capacity wasted.
108
 
 
 
 
 
 
109
  **2. Every training example earns its place.** Row accuracy factors as
110
  `P(name sequence) × pⁿ`. Each version measured which factor was binding and
111
  attacked only that. The final data round was synthesized directly against the
@@ -116,8 +142,8 @@ check (+3.3 points at constant LR, attributable to the corrective data alone).
116
  **3. Anneal, don't retrain.** A controlled twin experiment: the corrective
117
  corpus fed from scratch *diluted* (28.4); the same corpus **annealed into the
118
  learning-rate decay phase** of a continued run *concentrated* (33.1). The decay
119
- phase is where a WSD-trained model crystallizes — that's where the good data
120
- belongs.
121
 
122
  ## What didn't work (measured, not guessed)
123
 
@@ -134,11 +160,32 @@ The most reusable part of the project. Each idea was killed by an A/B, not an ar
134
  | RLOO fine-tune on the annealed checkpoint | diverges at every LR — sharp minima and policy gradients don't mix |
135
  | Matching Seal's gold numeric typing | not learnable — 74% of params are mixed-convention noise |
136
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
137
  ## Model details
138
 
139
  | | |
140
  |---|---|
141
- | Parameters | 48.12M (fp32; ~11.5MB at Needle's own 2-bit standard vs their 14MB) |
142
  | Architecture | deep-thin gated trunk: d=448, 20 layers, GQA 8/4, SwiGLU ×2.0, QK-norm, sandwich RMSNorm, tied embeddings |
143
  | Tokenizer | 16,384 BPE, digits as singletons, JSON structural chars as singletons |
144
  | Context | 768 tokens |
 
65
  value: 23.5
66
  name: BFCL v4 single-turn
67
  ---
 
68
  # 🧵 Thimble
69
 
70
+ **Tool calling in 48M parameters.** 86.3% ordered strict exact match on a real
71
+ app-intent catalog, 100% well-formed JSON by construction.
72
 
73
+ [**GitHub (code, evals, full experimental record)**](https://github.com/nikshepsvn/thimble) · MIT · 48.12M params · 768-token context · $260 total build cost
74
 
75
  ![Results](results.png)
76
 
77
+ Calling tools against a *known* catalog is not an emergent capability of large
78
+ models — it is a structured extraction problem, and it fits in 48M parameters.
79
+ This card covers what the model does, how it was built, and exactly where it
80
+ stops working.
81
+
82
+ ## What it does
83
+
84
+ Ordered strict exact match: a row passes only if the function names, the call
85
+ order, and *every* argument value match. The right-hand column is a yardstick, not a
86
+ rival: Needle 2 (Cactus Compute, 45M params, 153B training tokens), their
87
+ published numbers on their metric. It is there so the left column has a scale —
88
+ 86.3 means little until you know what else scores on that suite.
89
+
90
+ **Known catalog** represented in training, eval rows firewalled out:
91
+
92
+ | suite | Thimble v6 | Needle 2 (45M) |
93
+ |---|---:|---:|
94
+ | Mobile Actions (961) | **86.3** | 63.7 |
95
+ | DroidCall (200) | **52.5** | 17.0 |
96
+ | Seal-Tools in-domain (700) | **33.1** | 32.6 |
97
+ | Well-formed JSON | **100.0** | 93.4 |
98
+
99
+ **Unknown catalog** — schemas the model has never seen:
100
+
101
+ | suite | Thimble v6 | Needle 2 (45M) |
102
+ |---|---:|---:|
103
+ | Seal-Tools out-of-domain (654) | 28.1 | 28.7 |
104
+ | BFCL v4 single-turn (3,641) | 23.5 | 42.6 |
105
+
106
+ Those two tables are the whole finding. Familiar catalog, it works; unfamiliar
107
+ catalog, it degrades — and the degradation shows up *inside a single suite*:
108
+ Seal-Tools in-domain 33.1 vs out-of-domain 28.1 is the same model on the same
109
+ metric with only the catalogs changed. Name-sequence accuracy tracks it exactly,
110
+ 88% in-domain against 79% out.
111
+
112
+ **Before quoting the table.** Mobile Actions' public train split (8,693 rows,
113
+ disjoint from eval) is in the training mix — that is what "known catalog" means,
114
+ and it is the intended operating condition. The Seal-in margin over the
115
+ calibration column is +0.5 on 700 rows, within sampling noise. The pre-registered
116
+ model selector picked a sibling checkpoint that scored worse; the failure is
117
+ diagnosed and both models' results are published in
118
  [RESULTS.md](https://github.com/nikshepsvn/thimble/blob/master/RESULTS.md).
119
 
120
+ ## How it was built
121
 
122
  **1. Tool calling is five decisions, not a generation problem.** A grammar
123
  compiled from the tool schemas force-feeds all JSON structure — braces, quotes,
124
  and every argument key. The model is consulted at exactly five choice points:
125
  *refuse or call · which tool · include this optional? · what value · stop or
126
  continue*. Malformed JSON, hallucinated parameter names, and calls to
127
+ nonexistent tools are **unreachable, not unlikely**. At 48M parameters, capacity
128
  spent learning that `{` follows `[` is capacity wasted.
129
 
130
+ Measured honestly, the grammar is a *reliability* mechanism rather than an
131
+ accuracy one — on Mobile Actions, free generation and constrained decoding agree
132
+ on 150 of 150 rows. What it buys is that the worst failure modes cannot be
133
+ expressed at all.
134
+
135
  **2. Every training example earns its place.** Row accuracy factors as
136
  `P(name sequence) × pⁿ`. Each version measured which factor was binding and
137
  attacked only that. The final data round was synthesized directly against the
 
142
  **3. Anneal, don't retrain.** A controlled twin experiment: the corrective
143
  corpus fed from scratch *diluted* (28.4); the same corpus **annealed into the
144
  learning-rate decay phase** of a continued run *concentrated* (33.1). The decay
145
+ phase is where a WSD-trained model crystallizes — that is where the good data
146
+ belongs. This is probably the most portable result in the project.
147
 
148
  ## What didn't work (measured, not guessed)
149
 
 
160
  | RLOO fine-tune on the annealed checkpoint | diverges at every LR — sharp minima and policy gradients don't mix |
161
  | Matching Seal's gold numeric typing | not learnable — 74% of params are mixed-convention noise |
162
 
163
+ Two of these reversed conclusions that would otherwise have shipped on intuition.
164
+
165
+ ## Where it stops working
166
+
167
+ - **Unfamiliar catalogs.** Out-of-domain name-sequence accuracy is 79% against
168
+ 88% in-domain. Every out-of-domain deficit traces back to this one number.
169
+ - **Schema dialects.** `simple_python` scores 29.3 on BFCL, but `simple_java`
170
+ 14.0 and `simple_javascript` 8.0 — Java and JS schema conventions are absent
171
+ from a deliberately extractive ~1B-token corpus.
172
+ - **Parallel calls.** `parallel` 12.0 and `live_parallel` 0.0. Multi-call
173
+ composition works when calls are sequentially motivated by the query, not when
174
+ they are parallel instantiations of one schema.
175
+ - **768-token context.** 151 of 3,641 BFCL rows (4.1%) do not fit and score as misses.
176
+ - **Deployment.** 48.12M parameters is ~11.5MB at 2-bit and ~92MB at bf16, but
177
+ what ships here is the 184MB fp32 checkpoint and there is no on-device
178
+ inference engine. The size figure is a property of the parameter count, not of
179
+ a runnable microcontroller artifact.
180
+
181
+ Scale is the honest explanation for most of this: ~1B unique tokens, no
182
+ pretraining phase, a corpus deliberately spent on depth instead of breadth.
183
+
184
  ## Model details
185
 
186
  | | |
187
  |---|---|
188
+ | Parameters | 48.12M (fp32 checkpoint; ~11.5MB at 2-bit) |
189
  | Architecture | deep-thin gated trunk: d=448, 20 layers, GQA 8/4, SwiGLU ×2.0, QK-norm, sandwich RMSNorm, tied embeddings |
190
  | Tokenizer | 16,384 BPE, digits as singletons, JSON structural chars as singletons |
191
  | Context | 768 tokens |