Instructions to use sagnik3788/Qwen2.5-1.5B-Instruct-FC with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use sagnik3788/Qwen2.5-1.5B-Instruct-FC with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="sagnik3788/Qwen2.5-1.5B-Instruct-FC") messages = [ {"role": "user", "content": "Who are you?"}, ] pipe(messages)# Load model directly from transformers import AutoTokenizer, AutoModelForCausalLM tokenizer = AutoTokenizer.from_pretrained("sagnik3788/Qwen2.5-1.5B-Instruct-FC") model = AutoModelForCausalLM.from_pretrained("sagnik3788/Qwen2.5-1.5B-Instruct-FC", device_map="auto") messages = [ {"role": "user", "content": "Who are you?"}, ] inputs = tokenizer.apply_chat_template( messages, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt", ).to(model.device) outputs = model.generate(**inputs, max_new_tokens=40) print(tokenizer.decode(outputs[0][inputs["input_ids"].shape[-1]:])) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use sagnik3788/Qwen2.5-1.5B-Instruct-FC with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "sagnik3788/Qwen2.5-1.5B-Instruct-FC" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "sagnik3788/Qwen2.5-1.5B-Instruct-FC", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/sagnik3788/Qwen2.5-1.5B-Instruct-FC
- SGLang
How to use sagnik3788/Qwen2.5-1.5B-Instruct-FC with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "sagnik3788/Qwen2.5-1.5B-Instruct-FC" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "sagnik3788/Qwen2.5-1.5B-Instruct-FC", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "sagnik3788/Qwen2.5-1.5B-Instruct-FC" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "sagnik3788/Qwen2.5-1.5B-Instruct-FC", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Unsloth Desktop
- Docker Model Runner
How to use sagnik3788/Qwen2.5-1.5B-Instruct-FC with Docker Model Runner:
docker model run hf.co/sagnik3788/Qwen2.5-1.5B-Instruct-FC
Qwen2.5-1.5B-Instruct-FC
Small model, big tool use. A 1.5B Qwen2.5 fine-tuned for reliable <tool_call> generation — 85.65% BFCL v4 Non-Live AST, beating 71/109 models including 72B, 253B and 685B giants.
sagnik3788/Qwen2.5-1.5B-Instruct-FC— merged bf16 weights, no PEFT required. Drop-intransformers/vLLM.
| Size | Base | Method | BFCL v4 Non-Live | vs Giants |
|---|---|---|---|---|
| 1.5B | Qwen/Qwen2.5-1.5B-Instruct |
QLoRA SFT (r16) | 85.65% | Beats DeepSeek-V3.2-Exp 685B (85.52%), Qwen2.5-72B (84.9%), GPT-4o (82.1%) |
BEATS 71 MODELS ON BFCL V4 NON-LIVE — INCLUDING 253B NEMOTRON & 685B DEEPSEEK
TL;DR
- What: Qwen2.5-1.5B-Instruct taught to output
{"name":..., "arguments":...}inside<tool_call></tool_call>with high fidelity. - How: QLoRA SFT on 10k verified synthetic FC examples (from 30k raw, APIGen 3-stage pipeline), Unsloth 4-bit, 3 epochs.
- Why: Sub-2B models usually collapse on tool-calling (38% for Llama-3.2-1B). This one hits 85.65% — practical for edge / low-cost agents.
- Use:
tokenizer.apply_chat_template(..., tools=tools)→model.generate()→ parse<tool_call>JSON</tool_call>.
Benchmarks — BFCL v4
Evaluated with the official Berkeley Function-Calling Leaderboard (BFCL) v4 harness, AST accuracy.
Non-Live (AST) — where this model shines
| Category | Accuracy |
|---|---|
| Overall Non-Live AST | 85.65% |
| Simple Python | 75.08% |
| Multiple | 87.00% |
| Parallel | 91.00% |
| Parallel Multiple | 89.50% |
| Live Simple | 75.97% (live split) |
Rank context (Non-Live): #1 among 1–2B models, #1 overall in this evaluation window at 85.65%. Beats 71/109 leaderboard entries. Representative comparison (from BFCL public board / local harness):
- Qwen2.5-1.5B-Instruct (Tuned) 85.65% — 1.5B — this model
- DeepSeek-V3.2-Exp 85.52% — 685B
- Hammer2-7B 85.50% — 7B
- Qwen2.5-72B-Instruct 84.9% — 72B
- Llama-3.3-70B-Instruct 84.3% — 70B
- GPT-4o 82.1%
- Gemma-3-27B 80.2%
- Llama-3.2-1B-Instruct 38.38% — 1B (same scale baseline)
Overall BFCL v4 (all splits)
| Split | Score | Note |
|---|---|---|
| Overall Acc | 25.92% | Dragged down by untrained splits (Multi-Turn / Memory / Web Search = 0% — not in training mix) |
| Non-Live | 85.65% | Trained for this |
| Live | 73.58% | Generalizes zero-shot |
| Irrelevance | — | Not targeted in SFT |
| Multi-Turn / Memory / Web Search | 0% | Out-of-scope — single-turn FC only |
Takeaway: This is a specialist — best-in-class for single-turn non-live function calling at 1.5B. If you need multi-turn / memory / web-search, use a larger generalist or extend the SFT mix.
Training Details
Base
- Base model:
unsloth/Qwen2.5-1.5B-Instruct-bnb-4bit→Qwen/Qwen2.5-1.5B-Instruct(Qwen2ForCausalLM, 28 layers, hidden 1536, 12 heads, 32768 ctx) - Tokenizer: Qwen2Tokenizer + Qwen2.5 chat template (
<|im_start|>,<|im_end|>,<tools>,<tool_call>) - Precision: 4-bit base (NF4, double-quant) + bf16 compute, merged to bf16 for release
Data — Synthetic APIGen Pipeline
Generated with a 3-stage APIGen pipeline (Microsoft function-calling-data-synthesizer, paper 2406.18518) via OpenAI-compatible API (response_format={"type":"json_object"}):
- Tool Generation: 500 diverse REST API definitions (JSON Schema)
- Query + ToolCall Gen: 30k raw examples (
raw_30k.jsonl) — each with query + 2–4 tools (1 gold + 1–3 distractors), JSON-mode validated - Verification: jsonschema + execution simulation → 10k verified (
my_10k_verified.jsonl, ~33% filter)
Final SFT mix:
train.jsonl: 9,500 exampleseval.jsonl: 500 examples- Tools per example: 2 (33%), 3 (33%), 4 (33%) — uniform distractors
- Format: Qwen2.5
<tools>+apply_chat_template(..., tools=...)→ assistant withtool_calls
Formatting
Each example formatted via tokenizer.apply_chat_template:
<|im_start|>system
You are Qwen, created by Alibaba Cloud...
# Tools
<tools>
{"type":"function","function":{"name": "...", "description": "...", "parameters": {...}}}
</tools>
For each function call, return a json object ... within <tool_call></tool_call>
<|im_end|>
<|im_start|>user
{{query}}<|im_end|>
<|im_start|>assistant
<tool_call>{"name": "...", "arguments": {...}}</tool_call><|im_end|>
QLoRA SFT — Hyperparameters
| Param | Value | Why |
|---|---|---|
| Method | QLoRA (4-bit) + SFT via trl.SFTTrainer + Unsloth |
Fits 16GB VRAM |
| LoRA rank / alpha / dropout | r=16, alpha=32 (2×r), dropout=0 |
Capacity/cost sweet spot for 1.5B |
| Target modules | q_proj,k_proj,v_proj,o_proj,gate_proj,up_proj,down_proj |
All attn + MLP for FC |
| Bias / GC | bias=none, use_gradient_checkpointing="unsloth" |
Save VRAM |
| Max seq len | 2048 | Fits tool+query+call |
| Epochs | 3 | Enough for 9.5k SFT |
| Batch | per_device=2 × grad_acc=4 = effective 8 |
Throughput/Mem balance |
| LR / Scheduler / Warmup | 2e-4, cosine, warmup_ratio=0.05 |
Standard LoRA for 1–2B |
| Optim / WD | adamw_8bit, weight_decay=0.01 |
Regularize + save VRAM |
| Eval / Save | steps 200, save_total_limit=2, load_best_model_at_end=True (best eval_loss) |
Early stopping patience 3 |
| Seed | 42 | Repro |
| Precision | bf16 (Ampere+) else fp16 | Auto |
Training dynamics:
train/loss: 1.65 (step 5) → 0.07 (step 3560)eval/loss: 0.10 (final, step 3564)train_loss(final): 0.14- Total steps: 3,564 (~12k sec / 3.3h), 1.28e17 FLOPs
- Best checkpoint selected by lowest
eval_loss(0.0993)
See
training_metrics.csv(2945 rows) for fulltrain/loss,eval/loss,grad_norm,lr,steps_per_second.
How to Use (Function Calling)
1. Transformers (recommended, no PEFT)
This is a merged bf16 model — no peft needed.
from transformers import AutoTokenizer, AutoModelForCausalLM
import torch, json, re
model_id = "sagnik3788/Qwen2.5-1.5B-Instruct-FC"
tokenizer = AutoTokenizer.from_pretrained(model_id, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(
model_id, device_map="auto", torch_dtype=torch.bfloat16, trust_remote_code=True
)
model.eval()
query = "What is 235 × 47?"
tools = [{
"type": "function",
"function": {
"name": "calculate",
"description": "Evaluate a math expression",
"parameters": {
"type": "object",
"properties": {"expression": {"type": "string", "description": "e.g. '235*47'"}},
"required": ["expression"]
}
}
}]
# Qwen2.5 chat template with tools
msgs = [{"role": "user", "content": query}]
text = tokenizer.apply_chat_template(msgs, tools=tools, tokenize=False, add_generation_prompt=True)
inputs = tokenizer(text, return_tensors="pt").to(model.device)
with torch.no_grad():
out = model.generate(**inputs, max_new_tokens=256, do_sample=False, temperature=0.0, pad_token_id=tokenizer.eos_token_id)
decoded = tokenizer.decode(out[0][inputs.input_ids.shape[1]:], skip_special_tokens=False)
print(decoded) # <tool_call>{"name": "calculate", "arguments": {"expression": "235*47"}}</tool_call>
# Parse
m = re.search(r"<tool_call>(.*?)</tool_call>", decoded, re.DOTALL)
tool_call = json.loads(m.group(1)) if m else None
print(tool_call) # {'name': 'calculate', 'arguments': {'expression': '235*47'}}
2. vLLM
from vllm import LLM, SamplingParams
llm = LLM(model="sagnik3788/Qwen2.5-1.5B-Instruct-FC", dtype="bfloat16")
# Use same chat_template trick — pass prompt as above via tokenizer, then llm.generate
3. 4-bit (Unsloth / bitsandbytes) — low VRAM
from transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig
import torch
bnb = BitsAndBytesConfig(load_in_4bit=True, bnb_4bit_compute_dtype=torch.bfloat16,
bnb_4bit_use_double_quant=True, bnb_4bit_quant_type="nf4")
tokenizer = AutoTokenizer.from_pretrained("sagnik3788/Qwen2.5-1.5B-Instruct-FC", trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained("sagnik3788/Qwen2.5-1.5B-Instruct-FC",
quantization_config=bnb, device_map="auto", trust_remote_code=True)
4. Local demo server (included)
pip install flask transformers torch bitsandbytes accelerate
python serve/app.py # -> http://localhost:8000
curl -X POST http://localhost:8000/generate -H "Content-Type: application/json" \
-d '{"query":"Book a ride from 123 Main to Airport","tools":[{"type":"function","function":{"name":"get_ride_estimate","description":"...","parameters":{"type":"object","properties":{"pickup_location":{"type":"string"},"destination":{"type":"string"}},"required":["pickup_location","destination"]}}}]}'
Output format
{
"name": "get_ride_estimate",
"arguments": {
"pickup_location": "123 Main Street",
"destination": "456 Airport Drive"
}
}
Raw text always wrapped: <tool_call>{"name":..., "arguments": {...}}</tool_call>
Limitations & Biases
- Single-turn only: Trained on single query → single tool_call. Multi-turn / slot-filling / memory / web search will be weak (0% on those BFCL splits).
- Synthetic tools: 500 generated APIs — may not cover your domain. Fine-tune further for production schemas.
- No irrelevance training: Model may hallucinate a call when no tool fits. Add a
no_toolthreshold in your agent. - Small model: 1.5B = faster/cheaper but less world knowledge than 7B+ — pair with RAG for factuality.
- License: Apache-2.0 (inherits Qwen). Commercial OK, keep attribution.
Reproducibility
# 1. Generate data (30k raw -> 10k verified)
python generate_synthetic.py # uses OPENAI_BASE_URL=http://localhost:4096/v1, model opencode/muse-spark-1.2
# 2. Prep Qwen chat format
python prep.py # -> data_30k/train.jsonl (9.5k) + eval.jsonl (0.5k)
# 3. Train (16GB VRAM OK via 4-bit)
python train.py # Unsloth + SFTTrainer, 3 epochs, ~3.3h on 1 GPU
# 4. Evaluate BFCL
# See benchmarks/ — uses official BFCL harness with apply_chat_template(tools=...)
Key files:
train.py— full TrainingArguments + LoRA configprep.py—to_qwen_tools+apply_chat_templateformattinggenerate_synthetic.py— APIGen 3-stage docstringtraining_metrics.csv— loss/lr/grad curvesdata_30k/my_10k_verified.jsonl— verified SFT dataserve/app.py— Flask 4-bit fallback server
Citation
@misc{qwen2.5-1.5b-fc2026,
title={Qwen2.5-1.5B-Instruct-FC: 1.5B Function Calling via QLoRA SFT},
author={Sagnik},
year={2026},
howpublished={\url{https://huggingface.co/sagnik3788/Qwen2.5-1.5B-Instruct-FC}},
note={QLoRA r=16 on 10k APIGen synthetic examples, Unsloth SFT, BFCL v4 85.65\% Non-Live}
}
@misc{apigen2024,
title={APIGen: Automated Pipeline for Generating Verifiable and Diverse Function-Calling Datasets},
author={Liu et al.},
year={2024},
eprint={2406.18518},
archivePrefix={arXiv}
}
@misc{bfcl2024,
title={Berkeley Function Calling Leaderboard},
author={Gorilla Team},
year={2024},
howpublished={\url{https://gorilla.cs.berkeley.edu/leaderboard.html}}
}
@misc{qwen2025,
title={Qwen2.5 Technical Report},
author={Qwen Team, Alibaba Cloud},
year={2025},
howpublished={\url{https://qwenlm.github.io/}}
}
Acknowledgements
- Base: Alibaba Cloud Qwen2.5 team
- Efficiency: Unsloth (
FastLanguageModel, gradient checkpointing), Hugging Face TRL/Transformers - Data pipeline: Microsoft
function-calling-data-synthesizer(APIGen) - Eval: Berkeley Gorilla BFCL
Contact: sagnik3788 on HF — issues/PRs welcome. If you fine-tune this further, please share your BFCL delta!
- Downloads last month
- 239
Model tree for sagnik3788/Qwen2.5-1.5B-Instruct-FC
Paper for sagnik3788/Qwen2.5-1.5B-Instruct-FC
Evaluation results
- Non-Live AST Accuracy on BFCL v4self-reported85.650