How to Train Your own Decision Model like Jev using Unsloth

In this article, you will learn how to turn an open-weight language model into a decision model that classifies user intent, by fine-tuning Qwen3.5-4B on the CLINC150 dataset with Unsloth.

Topics we will cover include:

  • What decision models are, and how Unsloth’s FastDecisionModel scores a fixed set of choices instead of generating text.
  • How to convert CLINC150 into Unsloth’s decision format and fine-tune Qwen3.5-4B with 4-bit LoRA in Google Colab.
  • How to evaluate, calibrate, test, and save the resulting intent classifier.

How to Train Your own Decision Model like Jev using Unsloth

What if you could turn a regular language model into a decision model that chooses an answer instead of generating a long response?

Models like Jev, Laya, and Clef are designed to make structured decisions. Instead of generating text token by token, they select from predefined options and return probability estimates.

Unsloth now supports training decision models from open-weight language models such as Qwen and Gemma. Its official decision-model training guide explains the method and provides ready-to-run notebooks.

In this tutorial, I’m using Google Colab, Unsloth, and Qwen3.5-4B to build a custom intent classifier using the CLINC150 dataset. We will:

  • Prepare the dataset
  • Train the model using LoRA
  • Evaluate its performance
  • Test whether it can correctly identify what users want from their messages

By the end, you’ll have your own decision model that can classify user requests and return structured predictions with confidence scores. So, let’s get started.

What Are Decision Models?

Traditional language models generate responses one token at a time. However, many applications don’t need an explanation. They just need a decision.

For example, suppose a user sends the following message:

“Can you help me check the balance in my savings account?”

A traditional LLM might explain how to check an account balance. A decision model can instead classify the request:

Decision models are useful for intent classification, content moderation, routing requests, sentiment analysis, and agent workflows where choosing an action matters more than generating text.

Unsloth’s FastDecisionModel converts a pretrained LLM into a decision model by adding a specialized decision head. The model processes the input and available choices and scores the possible answers without generating a conventional text completion.

It supports three main question types:

  • Choice: Select one option from multiple possibilities
  • Noul: Return a yes-or-no decision
  • Score: Select a level from an ordered set of categories

For our experiment, we’ll focus on the Choice question type because we want the model to identify the intent behind a user’s message.

Getting Started with Unsloth and Qwen3.5

I’m running the entire experiment in Google Colab, so you can follow along without setting up CUDA or drivers locally. Start with Unsloth’s official decision-model guide or open the Qwen3.5-4B Decision Model notebook in Google Colab. Make a copy of the notebook in your Google Drive before making changes.

Under Runtime → Change runtime type, select an available NVIDIA GPU. I used a Tesla T4 with approximately 14.6 GB of GPU memory. The setup can run on that GPU, but training takes longer than it would on a newer GPU.

For this tutorial, we’ll use:

Component Selection
Base model Qwen3.5-4B
Framework Unsloth
Dataset CLINC150
Training method 4-bit LoRA
Decision type Choice
Environment Google Colab

Step 1: Installing Unsloth

I used the dependency installation cell from Unsloth’s Colab notebook. It installs uv, the compatible PyTorch and Transformers versions, Unsloth, and the required GPU packages. Run this in a Colab cell before loading the model.

The cell uses %%capture to keep the installation logs out of the notebook. Once it completes, continue to load the model.

Step 2: Loading Qwen3.5-4B

Next, we’ll load Qwen3.5-4B using FastDecisionModel instead of the usual language-model loader.

We use 4-bit quantization to reduce memory consumption. The decision head is initialized for training, while the pretrained model provides the language understanding capabilities.

Output:

Step 3: Configuring LoRA

Rather than updating all the model’s parameters, we’ll use LoRA.

LoRA allows us to train a relatively small number of additional parameters while keeping most of the base model unchanged. The decision head itself is also trained.

A LoRA rank of 16 gives us a reasonable starting point for this experiment. Gradient checkpointing helps reduce GPU memory usage during training.

Preparing the CLINC150 Dataset

For this tutorial, we’ll use CLINC150, a dataset designed for intent classification and detecting requests that fall outside a system’s supported capabilities.

It contains 150 intent categories covering areas such as banking, travel, shopping, and everyday assistant tasks.

The full dataset includes 15,000 in-scope training examples, 3,000 validation examples, and 4,500 in-scope test examples, along with separate out-of-scope examples.

Step 4: Downloading and Exploring CLINC150

We’ll download the original dataset and inspect its structure.

Each example contains a user message and its corresponding intent label.

Output:

Step 5: Converting CLINC150 into Decision Model Format

This is the most important part of the tutorial.

Unsloth expects each decision-training example to contain three fields:

  • state: The input that the model will analyze
  • questions: The decisions we want the model to make
  • gold: The correct answers used during training

Unlike a standard classification dataset, we need to define the available choices explicitly.

To make the first experiment practical on Colab, we’ll select 10 intents from CLINC150. You can increase NUM_INTENTS to use more categories, although the larger choice set will increase the input length and training requirements.

Output:

Now we’ll construct a Choice question using the selected intents.

Next, we convert the original CLINC150 records into Unsloth’s required format.

Each converted row now contains a natural-language user request, the set of available intents, and the correct intent label.

We deliberately exclude the out-of-scope records for this first experiment. Their detection is a separate task that we’ll discuss after evaluating the classifier.

Output:

Step 6: Building the Training Dataset

Now we’ll tokenize and prepare our examples using Unsloth’s built-in dataset builder.

This method converts the raw examples into the format required by the decision head.

Notice that we’re using CLINC150’s original training, validation, and test partitions. This keeps the final test data separate from training and calibration.

Output:

Training Our Decision Model

With the dataset ready, we can start fine-tuning Qwen3.5-4B.

Step 7: Evaluating the Model Before Training

Before training, let’s measure the model’s initial performance.

Because the decision head is newly initialized, its initial predictions may be close to random guessing.

For our 10-class experiment, random guessing would achieve approximately 10% accuracy on a balanced dataset.

This gives us a baseline for comparison after training.

Output:

Step 8: Configuring Training

We’ll use Unsloth’s DecisionTrainer, which is designed specifically for fine-tuning decision models.

We’re using 60 training steps to make the experiment manageable.

The official Unsloth notebook also uses 60 steps for its quick-training example. For a more complete run, you can increase the number of steps or train for multiple epochs.

Step 9: Fine-Tuning the Model

Now we can start training.

During training, Unsloth reports metrics such as training loss and runtime.

Output:

Evaluating the Fine-Tuned Decision Model

Now that training has finished, we want to understand how much the model improved.

Step 10: Evaluating Accuracy After Training

First, evaluate the model again on the validation set.

Output:

We can compare the accuracy before and after training.

Metric Before Training After Training
Validation accuracy 18.5% 100.0%
Validation expected calibration error (ECE; lower is better) 0.0816 0.00314
Validation loss 2.2937 0.00388
Training duration — 2,260.5 seconds (about 37.7 minutes)

In this run, validation accuracy rose from 18.5% to 100% after fine-tuning. That is an excellent result for this small, deliberately selected 10-intent task, but it does not mean the model is 100% accurate across the full 150-intent dataset or on out-of-scope requests.

Step 11: Calibrating Confidence Scores

A decision model should not only select the correct answer. Ideally, its predicted probabilities should also reflect how often its predictions are correct.

Unsloth includes a built-in calibration method.

Calibration can improve the reliability of the probabilities returned by the model.

One useful metric is ECE, which measures how closely predicted confidence aligns with observed accuracy. Lower ECE is better.

Output:

Step 12: Evaluating on Unseen Test Data

Finally, we’ll evaluate the trained model using CLINC150’s test split.

This is particularly important because the test examples were not used for training or confidence calibration.

Output:

On this held-out 300-example test split, the model classified all examples correctly. The zero loss and ECE are the reported outputs of this run, not a guarantee of perfect generalization. Test it on harder, ambiguous, and out-of-scope messages before deploying it.

Testing Our Decision Model with New Examples

Let’s see how the trained model behaves when we give it a new user message.

Step 13: Making a Prediction

We’ll define a simple function that accepts a user query and returns the model’s predicted intent.

Now test it with a few messages relevant to your selected intent categories.

For each message, the model returns an intent label and a probability for each option.

Output:

Saving Our Trained Decision Model

Once you’re happy with the results, you can save the LoRA adapters and the trained decision head.

If you want a merged model, Unsloth also supports saving a full model:

You can later reload the model using FastDecisionModel.from_pretrained() and use it in your own Python applications or supported decision-model serving workflows.

Conclusion

Decision models are useful when an application needs to make structured choices rather than generate long responses. With Unsloth, you can train one using an existing LLM and a relatively small dataset.

In this example, we trained Qwen3.5-4B on 10 CLINC150 intents and achieved 100% accuracy on the test set. The results are promising, but they are limited to this small experiment. You can use the same approach with your own dataset and explore how decision models fit into your applications.

No comments yet.

Leave a Reply

Machine Learning Mastery is part of Guiding Tech Media, a leading digital media publisher focused on helping people figure out technology. Visit our corporate website to learn more about our mission and team.