Robokid1134 commited on
Commit
4e4253a
·
verified ·
1 Parent(s): 2681723

Update README.md

Browse files
Files changed (1) hide show
  1. README.md +308 -160
README.md CHANGED
@@ -18,223 +18,372 @@ tags:
18
  - lora
19
  - cpu
20
  - gguf
21
- - text-generation-inference
22
  ---
23
 
24
  # TinyToolRouter-0.6B
25
- **My Github** ['roboroyce'](https://github.com/roboroyce/)
26
- A 0.6B-parameter, **CPU-first tool router**. Given a natural-language request
27
- plus a list of available tool schemas, it returns exactly **one** tool call:
 
 
 
 
 
 
 
 
 
28
 
29
  ```json
30
- {"name": "get_weather", "arguments": {"city": "Oslo"}}
 
 
 
 
 
31
  ```
32
 
33
- or, when no listed tool applies, it **abstains**:
34
 
35
  ```json
36
- {"name": "no_tool", "arguments": {}}
 
 
 
37
  ```
38
 
39
- - **Base model:** [`Qwen/Qwen3-0.6B`](https://huggingface.co/Qwen/Qwen3-0.6B) (Apache-2.0)
40
- - **Method:** LoRA supervised fine-tuning (PEFT), merged into the base weights
41
- - **Size:** 0.6B parameters (fp16/bf16 safetensors ≈ 1.2 GB; Q4_K_M GGUF ≈ 397 MB)
42
- - **Language:** English
43
- - **License:** Apache-2.0
44
-
45
- Small models are usually *shaky* at tool routing: they hallucinate tools, emit
46
- prose instead of JSON, or force a tool when none fits. This model is tuned
47
- narrowly for reliable routing, valid structured output, and honest abstention —
48
- and its improvement over the base model is published as a reproducible
49
- benchmark rather than an assertion.
50
-
51
- ## Results
52
-
53
- Evaluated on a **held-out set of 231 cases** across three families:
54
-
55
- | Family | n | What it tests |
56
- |---|---|---|
57
- | `seen_paraphrase` | 131 | unseen *phrasing* of tools seen in training |
58
- | `unseen_schema` | 60 | tools **never seen during training** |
59
- | `no_tool` | 40 | requests matching no tool → must abstain |
60
-
61
- Both models were run with identical prompts, `do_sample=False`,
62
- `max_new_tokens=128`.
63
-
64
- | Metric | Qwen3-0.6B (base) | **TinyToolRouter-0.6B** |
65
- |---|---|---|
66
- | **Exact match** (headline) | 0.5195 | **0.9221** |
67
- | Valid structured output | 0.9913 | **0.9913** |
68
- | Tool selection | 0.9351 | **0.9870** |
69
- | Argument accuracy | 0.5195 | **0.9221** |
70
- | `no_tool` precision | 0.7647 | **0.9756** |
71
- | `no_tool` recall | 0.9750 | **1.0000** |
72
- | `no_tool` F1 | 0.8571 | **0.9877** |
73
-
74
- By family (exact match):
75
-
76
- | Family | base | **fine-tuned** |
77
- |---|---|---|
78
- | seen_paraphrase | 0.229 | **0.9237** |
79
- | unseen_schema | 0.850 | **0.8667** |
80
- | no_tool | 0.975 | **1.0000** |
81
-
82
- The largest gain is on paraphrased requests (+69.5 pts); generalisation to
83
- genuinely unseen tool schemas improves only modestly (+1.7 pts) and is not
84
- " solved".
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
 
86
  ## Quickstart
87
 
 
 
88
  ```bash
89
- pip install transformers torch
90
  ```
91
 
 
 
92
  ```python
93
  import json
 
94
  from transformers import AutoModelForCausalLM, AutoTokenizer
95
 
96
  model_id = "Robokid1134/TinyToolRouter-0.6B"
97
- tok = AutoTokenizer.from_pretrained(model_id)
98
- model = AutoModelForCausalLM.from_pretrained(model_id)
99
 
100
- tools = [{
101
- "name": "get_weather",
102
- "description": "Get the current weather for a city.",
103
- "parameters": {
104
- "type": "object",
105
- "properties": {"city": {"type": "string"}},
106
- "required": ["city"],
107
- },
108
- }]
 
 
 
 
 
 
 
 
109
 
110
- SYSTEM = (
111
- "You are a tool router. You are given a list of available tools and a user "
112
- "request. Reply with exactly one JSON object of the form "
113
- '{"name": <tool_name>, "arguments": {<argument>: <value>}}. '
114
- "Use only the listed tools and only their declared arguments. "
115
  'If no listed tool applies, reply {"name": "no_tool", "arguments": {}}. '
116
- "Output JSON only, no prose."
117
  )
118
 
119
  messages = [
120
- {"role": "system", "content": SYSTEM},
121
- {"role": "user", "content": json.dumps(
122
- {"tools": tools, "request": "What's the weather in Oslo?"})},
 
 
 
 
 
123
  ]
124
 
125
- prompt = tok.apply_chat_template(
126
- messages, tokenize=False, add_generation_prompt=True, enable_thinking=False)
127
- inputs = tok(prompt, return_tensors="pt")
128
- out = model.generate(**inputs, max_new_tokens=128, do_sample=False)
129
- print(tok.decode(out[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True))
130
- # {"name": "get_weather", "arguments": {"city": "Oslo"}}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
  ```
132
 
133
- `enable_thinking=False` is recommended: the router should answer directly
134
- rather than emit a reasoning block.
 
135
 
136
- ### GGUF (CPU / llama.cpp / Ollama)
137
 
138
- The repository ships GGUF builds under `gguf/`:
 
 
 
 
139
 
140
- | File | Size | Use |
141
- |---|---|---|
142
- | `gguf/model-Q4_K_M.gguf` | ≈ 397 MB | best size/quality for CPU |
143
- | `gguf/model-Q8_0.gguf` | ≈ 639 MB | near-lossless |
144
- | `gguf/model-f16.gguf` | ≈ 1.2 GB | full precision |
145
 
146
  ```bash
147
- # llama.cpp
148
- llama-cli -m gguf/model-Q4_K_M.gguf -p "<your prompt>"
 
149
  ```
150
 
151
- > Note: the GGUF builds were converted from the merged model but have **not**
152
- > been separately re-benchmarked; the metrics above come from the safetensors
153
- > model.
 
 
154
 
155
- ## About the tool schemas
156
 
157
- The model reads JSON-Schema-style tool definitions supplied in the user turn:
158
 
159
  ```json
160
- {"tools": [{"name": "...", "description": "...",
161
- "parameters": {"type": "object",
162
- "properties": {"...": {"type": "..."}},
163
- "required": ["..."]}}],
164
- "request": "natural-language request"}
 
 
 
 
 
 
 
 
 
 
 
 
 
165
  ```
166
 
167
- It was trained on `string`, `integer`, `number`, `boolean`, `array<string>`
168
- and `array<number>` arguments, with required and optional parameters, and with
169
- distractor tools present in the list.
 
 
 
 
 
 
 
 
 
 
 
170
 
171
  ## Training
172
 
173
- | | |
174
  |---|---|
175
- | Base | `Qwen/Qwen3-0.6B` @ `c1899de289a04d12100db370d81485cdf75e47ca` |
176
- | Method | LoRA (PEFT), merged |
177
- | LoRA | r=16, α=32, dropout=0.05, all attention+MLP projections |
178
- | Epochs | 3 (57 steps) |
179
- | LR | 1e-4, cosine, warmup 3% |
180
- | Batch | 8 × grad-accum 4, max_len 512 |
181
- | Precision | bf16 |
182
- | Seed | 7 |
183
- | Examples | 599 (train) / 231 (held-out) |
184
- | Hardware | NVIDIA A10G 24 GB |
185
- | Train time | ≈ 150 s |
186
- | Libs | torch 2.5.1, transformers 4.57.6, peft 0.17.1, Python 3.9 |
187
-
188
- Loss is computed on the assistant JSON only (prompt tokens masked).
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
189
 
190
  ## Dataset
191
 
192
- **Original synthetic data** authored for this project (Apache-2.0). No scraped
193
- text, no chat logs, no personal data. Slot values are invented
194
- (`sam@example.com`, `2026-11-02T09:00`, city names, …).
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
195
 
196
- - **Seen tools (9):** `get_weather`, `send_email`, `create_calendar_event`,
197
- `search_web`, `convert_currency`, `set_timer`, `translate_text`,
198
- `filter_items`, `tag_note`
199
- - **Unseen tools (5, evaluation only):** `play_music`, `get_stock_price`,
200
- `book_restaurant`, `draw_chart`, `create_reminder`
201
 
202
- **Split hygiene:** training and held-out sets use disjoint templates, disjoint
203
- value pools and disjoint example ids; the `unseen_schema` family uses tools
204
- absent from training entirely. A `no_tool` abstention set is present in
205
- training with requests disjoint from the held-out `no_tool` set.
206
 
207
  ## Limitations
208
 
209
- - **English only**; 14 tools; synthetic data. It teaches routing discipline and
210
- schema reading, not world knowledge.
211
- - **Not an assistant.** It does not execute tools, hold conversations, or answer
212
- general questions — those requests should map to `no_tool`.
213
- - **Unseen-schema gains are modest** (+1.7 pts). Robustness to radically novel
214
- schemas is improved but not solved.
215
- - **Arguments usually appear verbatim in the request.** The hard capability
216
- measured here is selection + correct typing, not open-world extraction.
217
- - **Single seed.** One reproducible run; multi-seed variance is unreported.
218
- - **Small evaluation set** (231 cases). Treat differences of a few cases as
219
- noise.
220
- - **GGUF builds unverified numerically.**
221
- - Trained with `max_len` 512; very long tool lists may be truncated by the user.
222
-
223
- ## Intended use & out-of-scope
224
-
225
- **Use:** local agents on CPU-only or low-VRAM machines; as a cheap routing
226
- front-end before a larger model; as a reproducible baseline for tiny-model
227
- tool-calling research.
228
-
229
- **Do not use for:** safety-critical decisions, executing shell/system commands
230
- without human review, or any task where a wrong tool call causes harm. The
231
- model emits *proposed* calls; the caller must validate them.
 
 
 
232
 
233
  ## Citation
234
 
 
 
235
  ```bibtex
236
  @misc{tinytoolrouter06b,
237
- title = {TinyToolRouter-0.6B: a CPU-first, schema-strict tool router},
238
  author = {Robokid1134},
239
  year = {2026},
240
  note = {LoRA fine-tune of Qwen/Qwen3-0.6B},
@@ -242,9 +391,8 @@ model emits *proposed* calls; the caller must validate them.
242
  }
243
  ```
244
 
245
- ## Attribution & license
 
 
246
 
247
- Fine-tuned from [`Qwen/Qwen3-0.6B`](https://huggingface.co/Qwen/Qwen3-0.6B),
248
- licensed **Apache-2.0**. This derivative is released under the same
249
- **Apache-2.0** license; the upstream copyright notice and license are
250
- preserved. Code and generated dataset for this project are Apache-2.0.
 
18
  - lora
19
  - cpu
20
  - gguf
 
21
  ---
22
 
23
  # TinyToolRouter-0.6B
24
+
25
+ **A lightweight, CPU-first tool router fine-tuned from Qwen3-0.6B.**
26
+
27
+ **GitHub:** [@roboroyce](https://github.com/roboroyce/)
28
+
29
+ TinyToolRouter-0.6B is a 0.6-billion-parameter language model designed to select tools from a supplied list of tool schemas. Given a natural-language request and the available tools, it produces exactly one structured JSON tool call or explicitly abstains when no tool applies.
30
+
31
+ ### Example
32
+
33
+ **Input request:** `What's the weather in Oslo?`
34
+
35
+ **Output:**
36
 
37
  ```json
38
+ {
39
+ "name": "get_weather",
40
+ "arguments": {
41
+ "city": "Oslo"
42
+ }
43
+ }
44
  ```
45
 
46
+ When no listed tool applies, the model abstains:
47
 
48
  ```json
49
+ {
50
+ "name": "no_tool",
51
+ "arguments": {}
52
+ }
53
  ```
54
 
55
+ ## Key features
56
+
57
+ - **Small footprint:** 0.6B parameters, suitable for CPU-first inference.
58
+ - **Schema-aware routing:** Selects from tool definitions supplied at inference time.
59
+ - **Structured output:** Produces a single JSON object representing a proposed tool call.
60
+ - **Explicit abstention:** Supports a dedicated `no_tool` response.
61
+ - **Paraphrase robustness:** Evaluated on requests phrased differently from the training examples.
62
+ - **Unseen-schema evaluation:** Tested on tools absent from the training set.
63
+ - **Multiple formats:** Safetensors and GGUF builds are available in this repository.
64
+
65
+ ## Model details
66
+
67
+ | Property | Value |
68
+ |---|---|
69
+ | Model | TinyToolRouter-0.6B |
70
+ | Base model | [Qwen/Qwen3-0.6B](https://huggingface.co/Qwen/Qwen3-0.6B) |
71
+ | Parameters | 0.6B |
72
+ | Fine-tuning | Supervised fine-tuning with LoRA (PEFT) |
73
+ | Deployment | Merged fine-tuned weights |
74
+ | Primary language | English |
75
+ | License | Apache-2.0 |
76
+ | Intended hardware | CPU-only and low-VRAM systems |
77
+ | Safetensors size | Approximately 1.2 GB |
78
+ | GGUF Q4_K_M size | Approximately 397 MB |
79
+ | GGUF Q8_0 size | Approximately 639 MB |
80
+ | GGUF F16 size | Approximately 1.2 GB |
81
+
82
+ File sizes are approximate and may vary slightly by build.
83
+
84
+ ## Benchmark results
85
+
86
+ TinyToolRouter was evaluated on a held-out set of **231 cases** covering three distinct evaluation families.
87
+
88
+ ### Overall performance
89
+
90
+ | Metric | Qwen3-0.6B (base) | TinyToolRouter-0.6B |
91
+ |---|---:|---:|
92
+ | **Exact match** | 51.95% | **92.21%** |
93
+ | Valid structured output | 99.13% | 99.13% |
94
+ | Tool selection | 93.51% | **98.70%** |
95
+ | Argument accuracy | 51.95% | **92.21%** |
96
+ | `no_tool` precision | 76.47% | **97.56%** |
97
+ | `no_tool` recall | 97.50% | **100.00%** |
98
+ | `no_tool` F1 | 85.71% | **98.77%** |
99
+
100
+ Exact match improved by **40.26 percentage points** over the base model.
101
+
102
+ ### Performance by evaluation family
103
+
104
+ | Evaluation family | Cases | Base model | Fine-tuned |
105
+ |---|---:|---:|---:|
106
+ | `seen_paraphrase` | 131 | 22.90% | **92.37%** |
107
+ | `unseen_schema` | 60 | 85.00% | **86.67%** |
108
+ | `no_tool` | 40 | 97.50% | **100.00%** |
109
+
110
+ **What these results mean**
111
+
112
+ - **Paraphrase robustness:** Exact match increased from 22.90% to 92.37% on requests that use unseen phrasing for tools encountered during training.
113
+ - **Unseen tool schemas:** Exact match increased from 85.00% to 86.67% on tools absent from the training set. This is a modest improvement, not evidence of fully general tool-schema understanding.
114
+ - **Abstention:** The fine-tuned model correctly abstained on all 40 held-out `no_tool` cases, with 97.56% measured precision.
115
+
116
+ ### Evaluation methodology
117
+
118
+ Both models were evaluated using identical prompts and generation settings:
119
+
120
+ - `do_sample=False`
121
+ - `max_new_tokens=128`
122
+ - Held-out evaluation set: 231 cases
123
+ - Evaluation metric: exact match of the expected structured output
124
+
125
+ The benchmark separates familiar tool schemas with paraphrased requests, genuinely unseen tool schemas, and requests that should not trigger a tool call.
126
+
127
+ The reported metrics are from the **safetensors model**. The GGUF conversions have not been independently benchmarked, so equivalent performance across formats should not be assumed.
128
 
129
  ## Quickstart
130
 
131
+ ### Install dependencies
132
+
133
  ```bash
134
+ pip install torch transformers
135
  ```
136
 
137
+ ### Run with Transformers
138
+
139
  ```python
140
  import json
141
+ import torch
142
  from transformers import AutoModelForCausalLM, AutoTokenizer
143
 
144
  model_id = "Robokid1134/TinyToolRouter-0.6B"
 
 
145
 
146
+ tokenizer = AutoTokenizer.from_pretrained(model_id)
147
+ model = AutoModelForCausalLM.from_pretrained(model_id)
148
+ model.eval()
149
+
150
+ tools = [
151
+ {
152
+ "name": "get_weather",
153
+ "description": "Get the current weather for a city.",
154
+ "parameters": {
155
+ "type": "object",
156
+ "properties": {
157
+ "city": {"type": "string"}
158
+ },
159
+ "required": ["city"],
160
+ },
161
+ }
162
+ ]
163
 
164
+ system_prompt = (
165
+ "You are a tool router. You are given a list of available tools "
166
+ "and a user request. Reply with exactly one JSON object of the form "
167
+ '{"name": "<tool_name>", "arguments": {"<argument>": "<value>"}}. '
168
+ "Use only the listed tools and their declared arguments. "
169
  'If no listed tool applies, reply {"name": "no_tool", "arguments": {}}. '
170
+ "Output JSON only, with no additional prose."
171
  )
172
 
173
  messages = [
174
+ {"role": "system", "content": system_prompt},
175
+ {
176
+ "role": "user",
177
+ "content": json.dumps({
178
+ "tools": tools,
179
+ "request": "What's the weather in Oslo?"
180
+ }),
181
+ },
182
  ]
183
 
184
+ prompt = tokenizer.apply_chat_template(
185
+ messages,
186
+ tokenize=False,
187
+ add_generation_prompt=True,
188
+ enable_thinking=False,
189
+ )
190
+
191
+ inputs = tokenizer(prompt, return_tensors="pt")
192
+
193
+ with torch.inference_mode():
194
+ output = model.generate(
195
+ **inputs,
196
+ max_new_tokens=128,
197
+ do_sample=False,
198
+ )
199
+
200
+ new_tokens = output[0][inputs["input_ids"].shape[1]:]
201
+ response = tokenizer.decode(
202
+ new_tokens,
203
+ skip_special_tokens=True,
204
+ )
205
+
206
+ print(response)
207
+ ```
208
+
209
+ Expected output:
210
+
211
+ ```json
212
+ {"name": "get_weather", "arguments": {"city": "Oslo"}}
213
  ```
214
 
215
+ **Note:** `enable_thinking=False` is recommended for direct routing output. The example uses the Qwen3 chat template and assumes a Transformers version that supports this argument.
216
+
217
+ ## GGUF: CPU inference
218
 
219
+ GGUF builds are available in the repository's `gguf/` directory.
220
 
221
+ | File | Approximate size | Intended use |
222
+ |---|---:|---|
223
+ | `gguf/model-Q4_K_M.gguf` | 397 MB | Compact CPU inference |
224
+ | `gguf/model-Q8_0.gguf` | 639 MB | Higher quantization fidelity |
225
+ | `gguf/model-f16.gguf` | 1.2 GB | Full-precision weight storage |
226
 
227
+ Run a GGUF model using llama.cpp:
 
 
 
 
228
 
229
  ```bash
230
+ llama-cli \
231
+ -m gguf/model-Q4_K_M.gguf \
232
+ -p "<your prompt>"
233
  ```
234
 
235
+ The prompt should follow the model's expected chat template and include the available tool schemas and user request.
236
+
237
+ For repeated use, a dedicated prompt template or a compatible Ollama model configuration can simplify integration.
238
+
239
+ > **Benchmark caveat:** The GGUF files were converted from the merged fine-tuned model but have not been independently re-evaluated. The benchmark figures above apply to the safetensors model.
240
 
241
+ ## Tool schema format
242
 
243
+ The model expects a JSON object containing a list of available tools and a natural-language request.
244
 
245
  ```json
246
+ {
247
+ "tools": [
248
+ {
249
+ "name": "get_weather",
250
+ "description": "Get the current weather for a city.",
251
+ "parameters": {
252
+ "type": "object",
253
+ "properties": {
254
+ "city": {
255
+ "type": "string"
256
+ }
257
+ },
258
+ "required": ["city"]
259
+ }
260
+ }
261
+ ],
262
+ "request": "What's the weather in Oslo?"
263
+ }
264
  ```
265
 
266
+ The schema format is JSON-Schema-style, with a `name`, `description`, and `parameters` object for each tool.
267
+
268
+ Training covered the following argument types:
269
+
270
+ - `string`
271
+ - `integer`
272
+ - `number`
273
+ - `boolean`
274
+ - `array` of strings
275
+ - `array` of numbers
276
+
277
+ Examples included required and optional arguments, along with distractor tools that should not be selected.
278
+
279
+ The model returns a proposed tool name and its arguments. It does not execute the tool or verify that the underlying action succeeds.
280
 
281
  ## Training
282
 
283
+ | Setting | Value |
284
  |---|---|
285
+ | Base checkpoint | `Qwen/Qwen3-0.6B` |
286
+ | Base revision | `c1899de289a04d12100db370d81485cdf75e47ca` |
287
+ | Fine-tuning method | LoRA using PEFT |
288
+ | Adapter rank | 16 |
289
+ | LoRA alpha | 32 |
290
+ | LoRA dropout | 0.05 |
291
+ | Target modules | Attention and MLP projections |
292
+ | Epochs | 3 |
293
+ | Training steps | 57 |
294
+ | Learning rate | `1e-4` |
295
+ | Scheduler | Cosine |
296
+ | Warmup ratio | 3% |
297
+ | Batch size | 8 |
298
+ | Gradient accumulation | 4 |
299
+ | Maximum sequence length | 512 tokens |
300
+ | Training precision | BF16 |
301
+ | Random seed | 7 |
302
+ | Training examples | 599 |
303
+ | Held-out examples | 231 |
304
+ | Hardware | NVIDIA A10G, 24 GB VRAM |
305
+ | Approximate training time | 150 seconds |
306
+ | PyTorch | 2.5.1 |
307
+ | Transformers | 4.57.6 |
308
+ | PEFT | 0.17.1 |
309
+ | Python | 3.9 |
310
+
311
+ The LoRA adapter was merged into the base model for deployment.
312
+
313
+ Training loss was computed on the assistant's JSON output, with prompt tokens masked from the loss.
314
 
315
  ## Dataset
316
 
317
+ The dataset consists of original synthetic examples authored for this project and released under Apache-2.0.
318
+
319
+ No scraped text, chat logs, or personal data were used. Slot values are synthetic, including example email addresses, dates, and city names.
320
+
321
+ ### Tool coverage
322
+
323
+ **Tools represented in training (9):**
324
+
325
+ - `get_weather`
326
+ - `send_email`
327
+ - `create_calendar_event`
328
+ - `search_web`
329
+ - `convert_currency`
330
+ - `set_timer`
331
+ - `translate_text`
332
+ - `filter_items`
333
+ - `tag_note`
334
+
335
+ **Unseen tools reserved for evaluation (5):**
336
+
337
+ - `play_music`
338
+ - `get_stock_price`
339
+ - `book_restaurant`
340
+ - `draw_chart`
341
+ - `create_reminder`
342
+
343
+ ### Data separation
344
 
345
+ The training and held-out sets use disjoint templates, value pools, and example IDs.
 
 
 
 
346
 
347
+ The `unseen_schema` evaluation family contains tools absent from training entirely. The training set also includes abstention examples, while the held-out `no_tool` requests are disjoint from those training examples.
348
+
349
+ These design choices help test whether the model learned useful routing patterns rather than simply memorizing identical examples. They do not eliminate every possible source of dataset bias or leakage.
 
350
 
351
  ## Limitations
352
 
353
+ - **English only:** The model was trained and evaluated on English-language examples.
354
+ - **Limited tool coverage:** Training covers nine tool schemas, with five additional schemas used for evaluation.
355
+ - **Synthetic data:** Performance on real-world agent requests may differ from the reported benchmark.
356
+ - **Modest unseen-schema gains:** The improvement on unseen schemas is only 1.67 percentage points.
357
+ - **Limited argument extraction:** Arguments often appear explicitly in the request. The evaluation primarily tests tool selection, argument correctness, and structured output rather than unrestricted information extraction.
358
+ - **Small evaluation set:** Results are based on 231 held-out examples. Small differences may reflect only a few cases.
359
+ - **Single random seed:** Multi-seed variance has not been measured.
360
+ - **Quantized models not re-benchmarked:** The reported metrics do not establish equivalent performance for the GGUF builds.
361
+ - **Context length:** Training used a maximum sequence length of 512 tokens. Long tool lists may exceed the model's familiar input distribution or be truncated by an inference pipeline.
362
+
363
+ ## Intended use
364
+
365
+ TinyToolRouter-0.6B is intended for:
366
+
367
+ - Local AI agents running on CPU-only or low-VRAM machines.
368
+ - Lightweight tool-selection front ends for larger language models.
369
+ - Routing between a predefined set of application tools.
370
+ - Explicitly declining requests that do not match any available tool.
371
+ - Research into compact language models, tool calling, and structured generation.
372
+ - Reproducible experiments comparing a small base model against a narrowly fine-tuned router.
373
+
374
+ ### Out of scope
375
+
376
+ This model is not a general-purpose assistant. It is not intended to independently answer general questions, execute tools, or make safety-critical decisions.
377
+
378
+ Do not rely on its output alone to authorize sensitive actions or execute shell commands. The calling application should validate the selected tool, enforce an allowlist, validate arguments against the actual schema, and require appropriate authorization before executing an action.
379
 
380
  ## Citation
381
 
382
+ If you use this model in research or another project, you can cite it as follows:
383
+
384
  ```bibtex
385
  @misc{tinytoolrouter06b,
386
+ title = {TinyToolRouter-0.6B: A CPU-First, Schema-Strict Tool Router},
387
  author = {Robokid1134},
388
  year = {2026},
389
  note = {LoRA fine-tune of Qwen/Qwen3-0.6B},
 
391
  }
392
  ```
393
 
394
+ ## Attribution and license
395
+
396
+ TinyToolRouter-0.6B is fine-tuned from [Qwen/Qwen3-0.6B](https://huggingface.co/Qwen/Qwen3-0.6B), which is released under the Apache-2.0 license.
397
 
398
+ This derivative model is distributed under Apache-2.0, with the applicable upstream license and copyright notices preserved. The project's original code and generated dataset are also released under Apache-2.0.