copal-1-mini / README.md
VertexAIco's picture
Upload Copal 1 Mini
4c2e3cd verified
|
Raw
History Blame Contribute Delete
6.78 kB
---
license: gemma
base_model: google/gemma-3-4b-it
language:
- en
library_name: mlx
pipeline_tag: text-generation
tags:
- gemma
- gemma3
- lora
- mlx
- agentic
- tool-calling
- function-calling
- distillation
---
# Copal 1 Mini
**Copal 1 Mini** is an agentic, tool-calling fine-tune of **Gemma 3 4B IT** — trained to decide when to call a tool, select the right one, interpret its result, and either continue acting or respond, using a lightweight text-based `<tool_call>` / `<tool_result>` convention. It is the first model in the Copal series, focused on tool-use judgment rather than general chat.
## Model Details
| | |
|---|---|
| **Developed by** | Independent research project |
| **Base model** | [google/gemma-3-4b-it](https://huggingface.co/google/gemma-3-4b-it) |
| **Fine-tuning base checkpoint** | [mlx-community/gemma-3-4b-it-qat-4bit](https://huggingface.co/mlx-community/gemma-3-4b-it-qat-4bit) |
| **Architecture** | Gemma 3, 4B parameters (dense, decoder-only transformer) |
| **Fine-tuning method** | LoRA (rank 8, scale 20.0), fused into the base weights |
| **Fine-tuning framework** | [MLX](https://github.com/ml-explore/mlx) / `mlx-lm`, on Apple Silicon |
| **Trained modules** | `q_proj`, `k_proj`, `v_proj`, `o_proj`, `gate_proj`, `up_proj`, `down_proj` across 16 layers |
| **Weights** | Released 4-bit quantized (same quantization as the QAT base checkpoint), fused with the adapter — not dequantized |
| **Language** | English |
| **License** | [Gemma Terms of Use](https://ai.google.dev/gemma/terms) |
## Tool-Calling Format
Copal 1 Mini was trained on a simple, model-native text convention rather than a JSON-schema function-calling API. The assistant emits:
```
<tool_call>
{"name": "tool_name", "arguments": {"key": "value"}}
</tool_call>
```
and the caller returns:
```
<tool_result name="tool_name">
{...result...}
</tool_result>
```
as the next user turn. This loop repeats until the model responds with plain text instead of a `<tool_call>` block. See **Usage** below for a full example.
## Training Data
Copal 1 Mini was fine-tuned on **930 cleaned agentic trajectories** (of 1,152 originally generated, with malformed/incomplete ones filtered out), distilled from **`z-ai/glm-5.2`** via the NVIDIA NIM API. Each trajectory is a full multi-turn tool-use episode: a task prompt, the model's tool call(s), simulated tool results, and either further calls or a final response.
Tasks span 10 agentic categories, generated programmatically across many entities (companies, endpoints, databases, file paths, etc.) to avoid template overfitting:
- API orchestration
- State tracking
- Tool selection
- Multi-step planning
- Clarification (recognizing under-specified requests)
- Error recovery
- Read-and-decide (branching on tool output)
- Concise execution
- Browser workflow
- Structured output
## Training Procedure
- **Method:** Supervised fine-tuning via LoRA (rank 8, dropout 0.0, scale 20.0)
- **Optimizer:** Adam, learning rate 1e-5 (constant schedule)
- **Sequence length:** 4096 tokens (agentic trajectories run long — multiple tool round-trips per example)
- **Gradient checkpointing:** enabled
- **Training steps:** 2,500 iterations, with validation every 50 steps
- **Checkpoint selection:** the released weights use the **iteration 2,250 checkpoint**, selected for lowest validation loss (0.236); validation loss plateaued with noise from ~iteration 1,000 onward rather than continuing to improve, so later checkpoints offered no reliable benefit on this dataset size
## Evaluation
Evaluated against the un-tuned base model on 12 held-out agentic tasks (not seen during training), using the same simulated tool environment and RNG seed for both arms so they see identical tool results:
| | Used tools when appropriate | Tool-call parse errors |
|---|---|---|
| Base (Gemma 3 4B IT) | 8 / 12 | 0 |
| **Copal 1 Mini** | **11 / 12** | 0 |
Copal invokes tools in more of the situations that call for them, with no degradation in output-format reliability.
## Intended Use
Copal 1 Mini is intended for experimentation with lightweight, locally-run agentic/tool-calling assistants — task automation, API orchestration, and agent-loop research on consumer hardware. It is **not** intended for high-stakes, safety-critical, or production use, and it does not use a JSON-schema/OpenAI-style function-calling interface — integrate it via the `<tool_call>`/`<tool_result>` convention above, or adapt your tool-calling harness to it.
## Limitations
- Trained on a small (930-example), synthetically generated dataset — behavior can be inconsistent outside the categories represented in training.
- Distilled from a single teacher model without human review of every trajectory; teacher biases or occasional tool-use mistakes may be present.
- Uses a custom tool-call text format, not a standardized function-calling schema — not a drop-in replacement for APIs expecting OpenAI-style tool calls.
- Inherits the general limitations and knowledge cutoff of its base model, Gemma 3 4B IT.
- This is an early, first-generation checkpoint in an ongoing series.
## Usage
```python
from mlx_lm import load, generate
from mlx_lm.sample_utils import make_sampler
model, tokenizer = load("VertexAIco/copal-1-mini")
system_prompt = """You are Copal, an agentic assistant with access to tools.
When you need a tool, respond with exactly:
<tool_call>
{"name": "...", "arguments": {...}}
</tool_call>
Otherwise, respond normally in plain text."""
messages = [
{"role": "system", "content": system_prompt},
{"role": "user", "content": "Check the status of https://api.example.com/health and tell me if it's up."},
]
prompt = tokenizer.apply_chat_template(messages, add_generation_prompt=True)
text = generate(model, tokenizer, prompt=prompt, max_tokens=300, sampler=make_sampler(temp=0.0))
print(text)
# -> <tool_call>{"name": "http_request", "arguments": {"method": "GET", "url": "https://api.example.com/health"}}</tool_call>
# Execute the tool yourself, then feed the result back as the next user turn:
messages.append({"role": "assistant", "content": text})
messages.append({"role": "user", "content": '<tool_result name="http_request">\n{"status": 200, "ok": true}\n</tool_result>'})
prompt = tokenizer.apply_chat_template(messages, add_generation_prompt=True)
text = generate(model, tokenizer, prompt=prompt, max_tokens=300, sampler=make_sampler(temp=0.0))
print(text)
```
## Citation
```
@misc{copal1mini,
title = {Copal 1 Mini},
author = {Independent research project},
year = {2026},
note = {LoRA fine-tune of Gemma 3 4B IT for agentic tool-calling, distilled from GLM 5.2}
}
```
This model is built on Gemma and subject to the [Gemma Terms of Use](https://ai.google.dev/gemma/terms).