Banking Intent Classification — Qwen3-8B (LoRA)

Fine-tuned Qwen3-8B (4-bit QLoRA via Unsloth) on the Banking77 dataset for customer intent classification across 77 banking categories.

Model Performance

Evaluated on the Banking77 test set (NVIDIA A100-SXM4-40GB):

Mode Dataset Accuracy
Zero-Shot (base Qwen3-8B) 200 stratified samples 68.00%
Fine-Tuned (this model) 200 stratified samples 90.00%
Fine-Tuned (this model) Full test set (3,080 samples) 91.85%

Macro F1: 0.9182 across all 77 intent classes.

Training Details

Parameter Value
Base model unsloth/Qwen3-8B
Quantization 4-bit (QLoRA)
Max sequence length 2048
LoRA rank (r) 16
LoRA alpha 32
LoRA dropout 0.05
Epochs 1
Batch size 2 (grad accum 4 → effective 8)
Learning rate 2e-4
LR scheduler cosine
Optimizer adamw_8bit

Usage

from unsloth import FastLanguageModel

model, tokenizer = FastLanguageModel.from_pretrained(
    model_name="minhthien/banking-intent-unsloth",
    max_seq_length=2048,
    load_in_4bit=True,
)
FastLanguageModel.for_inference(model)

INTENT_LABELS = [
    "Refund_not_showing_up", "activate_my_card", "age_limit",
    "apple_pay_or_google_pay", "atm_support", "automatic_top_up",
    # ... (77 labels total, see Banking77 dataset)
]

SYSTEM_PROMPT = (
    "You are a banking intent classifier. "
    "Given a customer message, output exactly one intent label from the list below. "
    "Output only the label, nothing else.\n\n"
    "Labels:\n" + "\n".join(f"- {l}" for l in INTENT_LABELS)
)

def classify(text: str) -> str:
    messages = [
        {"role": "system", "content": SYSTEM_PROMPT},
        {"role": "user", "content": text},
    ]
    input_ids = tokenizer.apply_chat_template(
        messages, tokenize=True, add_generation_prompt=True, return_tensors="pt"
    ).to("cuda")
    output = model.generate(input_ids=input_ids, max_new_tokens=32, do_sample=False)
    decoded = tokenizer.decode(output[0][input_ids.shape[1]:], skip_special_tokens=True)
    return decoded.strip()

print(classify("I lost my credit card, how do I order a replacement?"))
# → lost_or_stolen_card

Or use the full IntentClassification class from the project repo:

import sys
sys.path.insert(0, "scripts")
from inference import IntentClassification

clf = IntentClassification("configs/inference.yaml", mode="finetuned")
result = clf("I lost my credit card, how do I order a replacement?")
print(result)  # → "lost_or_stolen_card"

Dataset

Banking77 — 13,083 customer service queries across 77 intent categories.

  • Train: 10,003 samples
  • Test: 3,080 samples (40 per intent)

Repo

Training code, evaluation scripts, and notebooks: nguyenvmthien/banking-intent-unsloth

Downloads last month
122
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for minhthien/banking-intent-unsloth

Finetuned
Qwen/Qwen3-8B
Finetuned
unsloth/Qwen3-8B
Adapter
(38)
this model

Dataset used to train minhthien/banking-intent-unsloth