Fine-Tunes Tool-Calling LLMs with XYZ-Aquila-SFT and Qwen3

Discover a complete pipeline for fine-tuning LLMs to call tools using the XYZ-Aquila-SFT dataset and Qwen3 model with parameter-efficient methods.

By Central
The XYZ-Aquila-SFT dataset and Qwen3-0.6B model enable accessible tool-calling fine-tuning on a single GPU.
Highlights
  • The pipeline uses the XYZ-Aquila-SFT dataset for multi-turn tool-use trajectories.
  • A nesting-safe JSON scanner extracts tool calls from XML tags in assistant messages.
  • Evaluation uses teacher-forced probing to measure function name and argument accuracy.

Fine-tuning large language models (LLMs) to follow instructions and call external tools is a central challenge in building effective AI agents. While many tutorials focus on simple question-answering or single-step function calls, the reality of production agentic systems involves complex, multi-turn conversations where a model must reason, gather context, and invoke the correct tool with the right arguments. A new end-to-end pipeline, built around the XYZ-Aquila-SFT dataset and the Qwen3-0.6B model, provides a detailed, practical blueprint for tackling this complexity using supervised fine-tuning (SFT) with parameter-efficient methods.

This tutorial, featuring the code from the Marktechpost AI-Agents-Projects-Tutorials repository, walks through every stage of the process: from streaming and parsing the dataset, through crafting a loss-masking strategy that preserves reasoning, to training a LoRA adapter and evaluating its tool-calling accuracy. The pipeline is designed to run on a single GPU, such as those available in Google Colab, making advanced agent training techniques accessible to a wider audience of developers and researchers.

Streaming and Parsing the XYZ-Aquila-SFT Dataset for Multi-Turn Tool-Use

The core of the pipeline is the XYZ-Aquila-SFT dataset, loaded from the Hugging Face repository XYZAILab/XYZ-Aquila-SFTcodecodecodecode. The first step involves streaming a subset of the data, specifically 400 English-language examples, to inspect its structure without downloading the entire corpus. This is a crucial practice for working with large datasets, allowing developers to understand the schema and content before committing compute resources.

The dataset is structured around multi-turn trajectories, where each row contains a user question, an answer, a declared number of tool calls, and a full conversation history in a list of messages. The first message is a system prompt that defines available tools, often enclosed in codecodecodecode XML tags. Subsequent messages alternate between user requests, assistant responses (which contain tool calls), and the results of those tool calls, or observations. This conversational structure mirrors the complexity of real-world agent interactions.

Parsing this raw data into structured trajectories is a critical technical step. The provided code defines a Trajectorycodecodecodecode dataclass to hold the question, answer, number of calls, messages, system prompt, tool schemas, and extracted calls. The parse_rowcodecodecodecode function handles the extraction of tool calls from assistant messages. Because tool calls are formatted as JSON objects within codecodecodecode XML tags, a naive regex approach fails on nested JSON structures. The pipeline implements a nesting-safe JSON scanner using Python’s json.JSONDecodercodecodecodecode to correctly extract the complete function call objects, including their nested argumentscodecodecodecode dictionary. This attention to parsing fidelity is essential for creating accurate training data.

Corpus Analysis: What the 400 Trajectories Reveal

After parsing, the pipeline generates comprehensive statistics about the dataset. This analysis is vital for understanding the nature of the training data and setting appropriate hyperparameters. The results from the 400-example stream provide a clear picture of the task’s demands.

Key statistics include:

  • Tool Calls per Trajectory: The mean number of tool calls is 1, with a maximum of 4. The 90th percentile is 2, indicating that most trajectories involve only a few tool invocations.
  • Messages per Trajectory: The average trajectory has roughly 7 messages. The 90th percentile is 9, and the maximum is 10. This shows that conversations are of significant length, incorporating system prompts, user requests, model reasoning, tool calls, and observations.
  • Character Length: Trajectories average over 2,300 characters, with the longest examples being even more substantial. The top 10% of longest trajectories contain over 19% of all the characters in the dataset, highlighting a long-tail distribution of complexity.
  • Tool Distribution: The dataset features a diverse set of tools. The specific tool names and their frequencies are available in the corpus statistics output, providing insights into which functions the model will most commonly need to invoke.

This analysis answers a key question: What is the average complexity of a tool-use trajectory in the XYZ-Aquila-SFT dataset? The average trajectory is a multi-step conversation involving a system prompt, a user request, and between one and four assistant messages that include tool calls and reasoning, all within a sequence of up to 10 messages. The data is not trivial, requiring the model to manage context and execute correct function calls within a structured dialogue.

Converting Tool Schemas and Crafting Qwen-Compatible ChatML with Loss Masking

One of the most technically nuanced parts of the pipeline is the conversion of the raw dataset into a format suitable for training Qwen3, a model from Alibaba’s Qwen family. The dataset contains tool schemas embedded within the system prompt, but for rigorous training, these can be separated and re-rendered. The pipeline provides functions to extract the tool schemas and then reconstruct them into a standard template, verifying byte-exact fidelity with the original system message.

The critical insight here is the decision to avoid using the model’s built-in apply_chat_templatecodecodecodecode method. The tutorial explains the reasoning directly: applying the standard Qwen3 chat template to the trajectories deletes the thinkingcodecodecodecode and responsecodecodecodecode blocks from all but the last assistant turn. This would silently discard the majority of the reasoning supervision that the training process is intended to learn. To preserve this crucial information, the pipeline manually renders each trajectory in ChatML format using the codecodecodecode and codecodecodecode tokens.

With the ChatML format established, the pipeline implements assistant-only loss masking. For each training example, tokens corresponding to user messages, system prompts, and tool observations have their labels set to -100, meaning the loss function will ignore them. Only the tokens generated by the assistant (the body of the response) are used for calculating the loss. This forces the model to learn to generate the correct tool calls, reasoning, and responses, rather than simply predicting the attention mask or the structure of the conversation. The processed examples show that the supervised token ratio—the proportion of tokens that are used for training—averages around 0.3, meaning only 30% of the sequence length is directly supervised, with the rest serving as context.

Fine-Tuning Qwen3-0.6B with LoRA for Tool-Calling

The training phase leverages LoRA (Low-Rank Adapters), a parameter-efficient fine-tuning technique. The model, Qwen/Qwen3-0.6Bcodecodecodecode, is loaded with bfloat16 precision (if supported) and attn_implementation="sdpa"codecodecodecode for efficient scaled dot-product attention. LoRA adapters are configured with a rank of 16 and applied to all linear layers. This setup dramatically reduces the number of trainable parameters, making it feasible to fine-tune the model on a single consumer-grade GPU.

The training loop itself is robust and production-ready. It uses:

  • Gradient Accumulation: With a batch size of 1 and 8 accumulation steps, the effective batch size is 8. This helps stabilize training.
  • Mixed Precision: The loop uses torch.ampcodecodecodecode with gradient scaling to handle FP16 or BF16 training, improving speed and memory efficiency.
  • Gradient Checkpointing: Enabled to reduce memory consumption during the forward pass.
  • Cosine Learning Rate Schedule: A warmup of 5 steps followed by a cosine decay to zero over the total 30 training steps.
  • Optimizer: AdamW with a learning rate of 1e-4 and specific beta values (0.9, 0.95).

The training runs for 30 steps on the processed training data. While the tutorial explicitly notes that 30 steps on 350 trajectories is a “smoke test” and not a representative result, the process serves to validate the entire pipeline. The final adapter and tokenizer are saved to the configured output directory.

Evaluating Tool-Call Prediction: Teacher-Forced Probes

Measuring the impact of fine-tuning on tool-calling ability is done through a teacher-forced evaluation strategy. The pipeline constructs evaluation probes by cutting each trajectory in the evaluation set right before an assistant turn that contains a tool call. The model is then asked to generate the next tokens, and the generated text is parsed for tool calls. This setup directly tests the model’s ability to issue a correct function call given a specific conversational context.

The evaluation metrics are specific and informative:

  • Tool-Name Accuracy: What fraction of the generated calls have the correct function name?
  • Argument-Key F1 Score: An F1 score measuring the overlap between the set of keys in the generated arguments dictionary and the gold standard arguments. This is a more nuanced metric than simple accuracy, as it considers partial correctness.

For demonstration purposes, the pipeline runs this evaluation before and after the 30 training steps. The baseline (pre-training) and post-training (LoRA) metrics are logged, and a delta is computed. As expected, the delta is marginal due to the small training budget. However, the framework for robust, repeatable evaluation is established. This answers the question: How can we evaluate whether a fine-tuned model is better at tool calling? By using teacher-forced probes that isolate the moment of a tool call, we can measure both the accuracy of the function name and the overlap of the argument keys, providing a granular assessment of performance.

Exporting Structured Data and Corpus Statistics

Finally, the pipeline exports reusable artifacts. All parsed trajectories are saved as a JSONL file containing the messages, tool schemas, questions, and answers in a clean, structured format. A separate JSON report aggregates all corpus-level statistics, including the tool frequency distribution, trajectory length distributions, supervised-token ratios, and the final evaluation results. This ensures that the work is not ephemeral; the processed data and analysis can be used for further experimentation, exploration with different models, or for documentation.

This complete workflow offers a strong foundation for anyone looking to move beyond simple instruction tuning and into the domain of tool-augmented language models. By preserving the full reasoning context, implementing precise loss masking, and using parameter-efficient fine-tuning, the pipeline makes sophisticated agent training accessible. The explicit focus on parsing fidelity, the manual ChatML rendering, and the structured evaluation set this work apart from more superficial tutorials, providing a practical, authoritative template for building more capable and reliable AI agents.

Share This Article