Instructions to use VertexAIco/copal-1-mini with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- MLX
How to use VertexAIco/copal-1-mini with MLX:
# Make sure mlx-lm is installed # pip install --upgrade mlx-lm # Generate text with mlx-lm from mlx_lm import load, generate model, tokenizer = load("VertexAIco/copal-1-mini") prompt = "Write a story about Einstein" messages = [{"role": "user", "content": prompt}] prompt = tokenizer.apply_chat_template( messages, add_generation_prompt=True ) text = generate(model, tokenizer, prompt=prompt, verbose=True) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- LM Studio
- MLX LM
How to use VertexAIco/copal-1-mini with MLX LM:
Generate or start a chat session
# Install MLX LM uv tool install mlx-lm # Interactive chat REPL mlx_lm.chat --model "VertexAIco/copal-1-mini"
Run an OpenAI-compatible server
# Install MLX LM uv tool install mlx-lm # Start the server mlx_lm.server --model "VertexAIco/copal-1-mini" # Calling the OpenAI-compatible server with curl curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "VertexAIco/copal-1-mini", "messages": [ {"role": "user", "content": "Hello"} ] }'
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 |
| Fine-tuning base checkpoint | 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 / 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 |
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
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.
- Downloads last month
- -
4-bit
# Make sure mlx-lm is installed # pip install --upgrade mlx-lm # Generate text with mlx-lm from mlx_lm import load, generate model, tokenizer = load("VertexAIco/copal-1-mini") prompt = "Write a story about Einstein" messages = [{"role": "user", "content": prompt}] prompt = tokenizer.apply_chat_template( messages, add_generation_prompt=True ) text = generate(model, tokenizer, prompt=prompt, verbose=True)