Instructions to use 79Labs/astraforge-8b-TCR with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- PEFT
How to use 79Labs/astraforge-8b-TCR with PEFT:
from peft import PeftModel from transformers import AutoModelForCausalLM base_model = AutoModelForCausalLM.from_pretrained("unsloth/Meta-Llama-3.1-8B-Instruct") model = PeftModel.from_pretrained(base_model, "79Labs/astraforge-8b-TCR") - Notebooks
- Google Colab
- Kaggle
v3.0.0: all-domain distillation arm (distill4/ck54) replaces v2.0.0 (ck2079); bfcl_all 0.829 [0.802,0.853] vs 0.556 [0.522,0.589] n=840, same session; irrelevance 0.930/0.790 vs 0.010/0.050
Browse files
README.md
CHANGED
|
@@ -1,165 +1,73 @@
|
|
| 1 |
---
|
| 2 |
-
|
| 3 |
-
base_model: meta-llama/Llama-3.1-8B-Instruct
|
| 4 |
library_name: peft
|
| 5 |
pipeline_tag: text-generation
|
| 6 |
tags:
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
- rag
|
| 13 |
-
- reasoning
|
| 14 |
-
language:
|
| 15 |
-
- en
|
| 16 |
-
model-index:
|
| 17 |
-
- name: astraforge-8b-TCR
|
| 18 |
-
results:
|
| 19 |
-
- task:
|
| 20 |
-
type: text-generation
|
| 21 |
-
name: Agentic tool-calling (first call correct)
|
| 22 |
-
dataset:
|
| 23 |
-
type: in-house-tool-eval-v2
|
| 24 |
-
name: 79Labs tool eval v2, held-out real tools (n=60)
|
| 25 |
-
metrics:
|
| 26 |
-
- type: accuracy
|
| 27 |
-
name: first-call accuracy
|
| 28 |
-
value: 1.000
|
| 29 |
-
- type: accuracy
|
| 30 |
-
name: argument exact match
|
| 31 |
-
value: 0.983
|
| 32 |
-
- task:
|
| 33 |
-
type: text-generation
|
| 34 |
-
name: Retrieval-augmented answering
|
| 35 |
-
dataset:
|
| 36 |
-
type: in-house-rag
|
| 37 |
-
name: 79Labs RAG eval (n=600)
|
| 38 |
-
metrics:
|
| 39 |
-
- type: accuracy
|
| 40 |
-
name: row pass
|
| 41 |
-
value: 0.972
|
| 42 |
---
|
| 43 |
|
| 44 |
-
# astraforge-8b-TCR
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
>
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
arithmetic. The 9B sibling family (Qwen3.5-based) reaches 0.950 / 1.000 on the same set.
|
| 106 |
-
|
| 107 |
-
### Not re-measured for v2
|
| 108 |
-
|
| 109 |
-
v1's `confirmed_first` (asks before acting, 0.89), elicitation and GSM8K (0.75) figures came from a
|
| 110 |
-
different harness and **were not re-run on v2**, so this card claims nothing about them. If those
|
| 111 |
-
behaviours matter to you, test them, or pin `v1.0.0`.
|
| 112 |
-
|
| 113 |
-
## Prompt format
|
| 114 |
-
|
| 115 |
-
v2 is trained on the template in [`chat_template.jinja`](./chat_template.jinja), and **you must pass
|
| 116 |
-
it**. Llama-3.1's built-in template rejects assistant turns that carry more than one tool call, and
|
| 117 |
-
this model makes several per turn. Tool calls come out as XML:
|
| 118 |
-
|
| 119 |
-
```
|
| 120 |
-
<atem:function_calls>
|
| 121 |
-
<atem:invoke name="get_quote">
|
| 122 |
-
<atem:parameter name="symbol">NSE:RELIANCE</atem:parameter>
|
| 123 |
-
</atem:invoke>
|
| 124 |
-
<atem:invoke name="get_news">
|
| 125 |
-
<atem:parameter name="query">Reliance Industries</atem:parameter>
|
| 126 |
-
</atem:invoke>
|
| 127 |
-
</atem:function_calls>
|
| 128 |
-
```
|
| 129 |
-
|
| 130 |
-
Parse the `invoke` blocks and coerce each parameter to its schema type.
|
| 131 |
-
|
| 132 |
-
## Usage
|
| 133 |
-
|
| 134 |
-
```python
|
| 135 |
-
from transformers import AutoTokenizer, AutoModelForCausalLM
|
| 136 |
-
from peft import PeftModel
|
| 137 |
-
import torch
|
| 138 |
-
|
| 139 |
-
base = "meta-llama/Llama-3.1-8B-Instruct"
|
| 140 |
-
tok = AutoTokenizer.from_pretrained("79Labs/astraforge-8b-TCR") # loads chat_template.jinja (the ATEM template)
|
| 141 |
-
model = AutoModelForCausalLM.from_pretrained(base, torch_dtype=torch.bfloat16, device_map="auto")
|
| 142 |
-
model = PeftModel.from_pretrained(model, "79Labs/astraforge-8b-TCR")
|
| 143 |
-
|
| 144 |
-
messages = [{"role": "user", "content": "Price and latest news for Reliance?"}]
|
| 145 |
-
tools = [...] # OpenAI-style JSON schemas
|
| 146 |
-
ids = tok.apply_chat_template(messages, tools=tools, add_generation_prompt=True, return_tensors="pt").to(model.device)
|
| 147 |
-
out = model.generate(ids, max_new_tokens=512, do_sample=False)
|
| 148 |
-
print(tok.decode(out[0, ids.shape[1]:], skip_special_tokens=False))
|
| 149 |
-
```
|
| 150 |
-
|
| 151 |
-
## Limitations
|
| 152 |
-
|
| 153 |
-
- Reasoning without a tool is weak (0.706). Route arithmetic through a calculator tool.
|
| 154 |
-
- The tool benchmarks use one product's catalogue, a financial-markets console. Expect weaker results on
|
| 155 |
-
catalogues that look very different, and evaluate on your own tools.
|
| 156 |
-
- With 1,000+ tools the catalogue will not fit in one prompt: 1,000 full schemas come to about 145k
|
| 157 |
-
tokens against a 131k context. Shortlist with a retriever first.
|
| 158 |
-
- English only. Not financial advice.
|
| 159 |
-
|
| 160 |
-
## Versions
|
| 161 |
-
|
| 162 |
-
| version | date | notes |
|
| 163 |
-
|---|---|---|
|
| 164 |
-
| 2.0.0 | 2026-10-05 | multi-call ATEM format, RAG, calculator reasoning; benchmarked against Claude on the same harness |
|
| 165 |
-
| 1.0.0 | earlier | tag `v1.0.0`: single-call agentic adapter with elicitation and confirm-first evaluations |
|
|
|
|
| 1 |
---
|
| 2 |
+
base_model: unsloth/Meta-Llama-3.1-8B-Instruct
|
|
|
|
| 3 |
library_name: peft
|
| 4 |
pipeline_tag: text-generation
|
| 5 |
tags:
|
| 6 |
+
- base_model:adapter:unsloth/Meta-Llama-3.1-8B-Instruct
|
| 7 |
+
- lora
|
| 8 |
+
- function-calling
|
| 9 |
+
- tool-use
|
| 10 |
+
license: apache-2.0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
---
|
| 12 |
|
| 13 |
+
# astraforge-8b-TCR — v3.0.0
|
| 14 |
+
|
| 15 |
+
A LoRA (r=16, alpha=32) on `unsloth/Meta-Llama-3.1-8B-Instruct` that emits tool
|
| 16 |
+
calls in the **ATEM** XML surface (`<atem:function_calls>` / `<atem:invoke
|
| 17 |
+
name=...>` / `<atem:parameter name=...>`), including multi-call and parallel
|
| 18 |
+
turns, and answers without calling when no tool fits.
|
| 19 |
+
|
| 20 |
+
This release replaces **v2.0.0** (`astraforge-v4/checkpoint-2079`) with the
|
| 21 |
+
all-domain distillation arm `astraforge-distill4/checkpoint-54`.
|
| 22 |
+
|
| 23 |
+
## Evaluation — head-to-head, same splits, same serving session
|
| 24 |
+
|
| 25 |
+
Both adapters were served in one vLLM session on the same base and scored on the
|
| 26 |
+
identical BFCL-v4-derived splits (`n=840`), so the comparison is apples to
|
| 27 |
+
apples. Full JSON for both runs is in `benchmarks/`.
|
| 28 |
+
|
| 29 |
+
| split | n | v3.0.0 (this) | v2.0.0 (ck2079) |
|
| 30 |
+
|---|---|---|---|
|
| 31 |
+
| bfcl_simple | 100 | 0.940 | 0.860 |
|
| 32 |
+
| bfcl_multiple | 100 | 0.900 | 0.850 |
|
| 33 |
+
| bfcl_parallel | 100 | 0.850 | 0.750 |
|
| 34 |
+
| bfcl_parallel_multiple | 100 | 0.850 | 0.730 |
|
| 35 |
+
| bfcl_live_simple | 100 | 0.690 | 0.660 |
|
| 36 |
+
| bfcl_live_multiple | 100 | 0.750 | 0.600 |
|
| 37 |
+
| bfcl_live_parallel | 16 | 0.688 | 0.312 |
|
| 38 |
+
| bfcl_live_parallel_multiple | 24 | 0.625 | 0.458 |
|
| 39 |
+
| bfcl_irrelevance | 100 | 0.930 | 0.010 |
|
| 40 |
+
| bfcl_live_irrelevance | 100 | 0.790 | 0.050 |
|
| 41 |
+
| multi_domain | 100 | 0.730 | 0.740 |
|
| 42 |
+
| unseen_family | 100 | 1.000 | 1.000 |
|
| 43 |
+
| **bfcl_all** | **840** | **0.829 [0.802, 0.853]** | **0.556 [0.522, 0.589]** |
|
| 44 |
+
|
| 45 |
+
**The decisive change is the irrelevance heads.** v2.0.0 made a tool call on
|
| 46 |
+
essentially every row where the correct behaviour is to call nothing
|
| 47 |
+
(`bfcl_irrelevance` 0.010, `bfcl_live_irrelevance` 0.050); v3.0.0 abstains on
|
| 48 |
+
0.930 / 0.790. The two 95% CIs on `bfcl_all` do not overlap.
|
| 49 |
+
|
| 50 |
+
**Where it still stands.** Against the DeepSeek-V4.1-Flash teacher on the same
|
| 51 |
+
splits — 0.857 [0.832, 0.879] — v3.0.0 is 0.028 below and the CIs overlap, so
|
| 52 |
+
this is not a claim of parity.
|
| 53 |
+
|
| 54 |
+
## Training
|
| 55 |
+
|
| 56 |
+
- Distillation from a local DeepSeek-V4.1-Flash teacher: the teacher is given the
|
| 57 |
+
same system prompt and offered catalogue and produces up to 3 tool-calling
|
| 58 |
+
rounds, each fed the real recorded tool result, then a written answer.
|
| 59 |
+
- Base `unsloth/Meta-Llama-3.1-8B-Instruct`; LoRA r=16, alpha=32 on all seven
|
| 60 |
+
projection modules; LR 5e-6.
|
| 61 |
+
- Corpus: `corpus_distill_astra_frozen1` (419 rows) — this line is corpus-bound,
|
| 62 |
+
not step-bound; checkpoint 25/50/54 sit within noise of one another.
|
| 63 |
+
|
| 64 |
+
## Use
|
| 65 |
+
|
| 66 |
+
Load the base with the ATEM chat template
|
| 67 |
+
(`train/templates/llama31_atem.jinja`) and this adapter on top. The adapter
|
| 68 |
+
config's `base_model_name_or_path` is `unsloth/Meta-Llama-3.1-8B-Instruct`.
|
| 69 |
+
|
| 70 |
+
## Provenance
|
| 71 |
+
|
| 72 |
+
Adapter and benchmark JSONs are byte-identical to the local artifacts; the
|
| 73 |
+
safetensors LFS sha256 was verified against the local file after upload.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|