Instructions to use aryachakraborty/arya-cfpb-qwen25-7b-lora with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- PEFT
How to use aryachakraborty/arya-cfpb-qwen25-7b-lora with PEFT:
from peft import PeftModel from transformers import AutoModelForCausalLM base_model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen2.5-7B-Instruct") model = PeftModel.from_pretrained(base_model, "aryachakraborty/arya-cfpb-qwen25-7b-lora") - Notebooks
- Google Colab
- Kaggle
File size: 12,221 Bytes
5479868 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 2932e85 5ba44f5 5479868 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 | ---
license: apache-2.0
datasets:
- CFPB/consumer-finance-complaints
language:
- en
base_model:
- Qwen/Qwen2.5-7B-Instruct
new_version: aryachakraborty/arya-cfpb-qwen25-7b-lora
pipeline_tag: text-generation
library_name: peft
tags:
- finance
- AMD
- lora
- peft
---
# Qwen2.5-7B-Instruct β CFPB Banking Complaint Categorisation
A domain-adapted large language model fine-tuned on the CFPB Consumer Complaint Database to automatically convert unstructured customer complaint narratives into structured ticket metadata for banking operations teams.
---
## The Problem
Financial institutions process thousands of customer complaints daily across mobile apps, websites, contact centres, email, and regulatory portals. These complaints arrive as free-form text β often incomplete, ambiguous, or written by customers who do not know which banking product or issue category applies to their situation.
The result is predictable: complaints get routed to the wrong team, require manual review and reassignment, and take longer to resolve than they should. Traditional classification models handle one label at a time and struggle with the nuanced language of consumer finance. A rule-based keyword system breaks down the moment a customer phrases something slightly differently.
This model addresses that by treating complaint categorisation as a **structured generation task** β the model reads the complaint narrative and produces all four required ticket fields in a single inference step.
---
## What the Model Does
Given a customer complaint narrative, the model outputs a structured JSON object containing:
```json
{
"product": "Checking or savings account",
"sub_product": "Checking account",
"issue": "Unauthorized transactions or other transaction problem",
"sub_issue": "Debit card issue"
}
```
These four fields map directly to the CFPB Consumer Complaint taxonomy and can be consumed directly by complaint management systems, business rule engines, and routing workflows β no manual classification required.
### Example
**Input complaint:**
> *"I reported fraudulent transactions on my debit card and the bank reversed my provisional credit without explaining the investigation outcome. I have been trying to reach someone for three weeks and keep getting transferred."*
**Model output:**
```json
{
"product": "Checking or savings account",
"sub_product": "Checking account",
"issue": "Unauthorized transactions or other transaction problem",
"sub_issue": "Debit card issue"
}
```
---
## Model Details
| Property | Value |
|----------|-------|
| Base model | `Qwen/Qwen2.5-7B-Instruct` |
| Fine-tuning method | LoRA (Low-Rank Adaptation) via PEFT |
| Training hardware | AMD Instinct MI300X (192 GB VRAM) |
| Training backend | ROCm 7.2.4 / HIP |
| Model precision | bfloat16 |
| Task type | Structured JSON generation (causal LM) |
| Output format | JSON with 4 fields: product, sub_product, issue, sub_issue |
---
## Training Configuration
### LoRA Adapter
| Parameter | Value |
|-----------|-------|
| Rank (`r`) | 16 |
| Alpha | 32 |
| Dropout | 0.05 |
| Target modules | `q_proj`, `k_proj`, `v_proj`, `o_proj` |
| Trainable parameters | ~1% of total model parameters |
The base model weights are fully frozen. Only the LoRA adapter matrices are updated during training, making this efficient both in compute and storage β the saved adapter is significantly smaller than the full model.
### Training Hyperparameters
| Parameter | Value |
|-----------|-------|
| Epochs | 5 (with early stopping, patience=3) |
| Batch size per device | 8 |
| Gradient accumulation steps | 4 |
| Effective batch size | 32 |
| Learning rate | 1e-4 |
| Optimiser | AdamW (PyTorch native) |
| LR scheduler | Linear |
| Precision | bf16 |
| Max sequence length | 1024 tokens |
Early stopping was applied with a patience of 3 evaluation checkpoints. Prior experiments on smaller model variants showed validation loss plateauing around epoch 2β3, so early stopping prevents wasted compute without sacrificing quality.
### Dataset
**Source:** CFPB Consumer Complaint Database (formatted as multi-turn chat JSONL)
**Splits used:**
| Split | Size |
|-------|------|
| Train | Full dataset (no cap) |
| Validation | 500 |
| Test | 500 |
**Sampling strategy:** Training data was sampled using proportional stratification by `product Γ issue` combination. This ensures that long-tail complaint categories β which would appear only once or twice in a random 500-sample draw β receive proportional representation. Without this, the model sees most issue labels fewer than 3 times, which is insufficient for reliable generation.
**Chat template:** Qwen's built-in `apply_chat_template` was used to format each example into a single training string with `<|im_start|>` / `<|im_end|>` special tokens. The assistant turn (the JSON output) was included in full β no generation prompt was added at training time.
---
## Inference with Constrained Decoding
At inference time, this model uses a **two-pass constrained decoding** approach:
1. **Pass 1** β Standard greedy decoding generates the JSON output.
2. **Pass 2** β Each field value is snapped to the nearest canonical CFPB label using TF-IDF cosine similarity (unigram + bigram features).
This matters because the CFPB taxonomy contains 80+ canonical issue strings with very similar phrasing. A model that generates *"unauthorized transaction"* when the canonical label is *"unauthorized transactions or other transaction problem"* would score zero on exact match β but is semantically correct. The constrained decoder corrects these surface-level mismatches without changing the underlying prediction.
Jaccard similarity was evaluated as an alternative snapping strategy but proved insufficient for near-duplicate labels (e.g., *"problem with fees"* vs *"other fee"*) where single-word differences produce high Jaccard overlap. TF-IDF on bigrams separates these reliably.
---
## Evaluation Results
Evaluated on 500 held-out test examples from the CFPB dataset. Baseline is the unmodified `Qwen2.5-7B-Instruct` base model with no fine-tuning.
### Primary Metrics β Structured JSON Extraction
| Metric | Baseline | Fine-tuned | Ξ |
|--------|----------|------------|---|
| Exact JSON Match | 0.0000 | 0.2280 | +0.2280 |
| Avg Field Accuracy | 0.0030 | 0.5925 | +0.5895 |
| Micro F1 | 0.0030 | 0.5925 | +0.5895 |
| Macro F1 | 0.0008 | 0.2395 | +0.2387 |
| Weighted F1 | 0.0059 | 0.5814 | +0.5755 |
**Per-field accuracy:**
| Field | Baseline | Fine-tuned | Ξ |
|-------|----------|------------|---|
| product | 0.010 | **0.910** | +0.900 |
| sub_product | 0.002 | **0.628** | +0.626 |
| issue | 0.000 | **0.336** | +0.336 |
| sub_issue | 0.000 | **0.496** | +0.496 |
`product` accuracy of 91% is expected β the CFPB product taxonomy has around a dozen top-level categories and the model learns them well. `issue` at 33.6% reflects the genuine difficulty of the field: 80+ canonical strings with overlapping phrasing, many appearing infrequently even in the full training set.
### Secondary Metrics β Generative Quality
These metrics measure output fluency and n-gram overlap. They are secondary to the structured metrics above, but confirm the model is generating coherent, well-formed text.
| Metric | Baseline | Fine-tuned | Ξ |
|--------|----------|------------|---|
| ROUGE-1 | 0.4592 | 0.7035 | +0.2443 |
| ROUGE-2 | 0.2523 | 0.6049 | +0.3526 |
| ROUGE-L | 0.4258 | 0.6915 | +0.2657 |
| BLEU | 0.0003 | 0.1905 | +0.1902 |
| SacreBLEU | 19.77 | 65.07 | +45.30 |
| METEOR | 0.1133 | 0.6309 | +0.5176 |
The SacreBLEU jump from 19.77 to 65.07 and METEOR from 0.11 to 0.63 indicate the fine-tuned model is generating outputs that are not just structurally similar to references, but lexically aligned β which for this task means using the correct canonical CFPB terminology consistently.
---
## How to Use
### Load the adapter
```python
from peft import PeftModel
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
base_model_name = "Qwen/Qwen2.5-7B-Instruct"
adapter_path = "your-hf-username/qwen2.5-7b-cfpb-complaint-categorisation"
tokenizer = AutoTokenizer.from_pretrained(adapter_path)
base = AutoModelForCausalLM.from_pretrained(
base_model_name,
torch_dtype=torch.bfloat16,
device_map="auto",
)
model = PeftModel.from_pretrained(base, adapter_path)
model.eval()
```
### Run inference
```python
def categorise_complaint(complaint_text: str, model, tokenizer) -> dict:
messages = [
{
"role": "system",
"content": (
"You are a banking complaint classification assistant. "
"Given a consumer complaint narrative, extract the CFPB ticket fields "
"as a JSON object with keys: product, sub_product, issue, sub_issue."
),
},
{
"role": "user",
"content": complaint_text,
},
]
prompt = tokenizer.apply_chat_template(
messages,
tokenize=False,
add_generation_prompt=True,
)
inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
with torch.no_grad():
output = model.generate(
**inputs,
max_new_tokens=128,
do_sample=False,
pad_token_id=tokenizer.eos_token_id,
)
prompt_len = inputs["input_ids"].shape[1]
generated = tokenizer.decode(output[0][prompt_len:], skip_special_tokens=True)
return generated
complaint = """
I reported fraudulent transactions on my debit card and the bank reversed
my provisional credit without explaining the investigation outcome.
"""
result = categorise_complaint(complaint, model, tokenizer)
print(result)
# {"product": "Checking or savings account", "sub_product": "Checking account",
# "issue": "Unauthorized transactions or other transaction problem",
# "sub_issue": "Debit card issue"}
```
---
## Dependencies
```
transformers==4.44.0
peft==0.12.0
accelerate==0.34.0
datasets==2.21.0
torch (ROCm-compatible build for AMD, or standard CUDA build)
scikit-learn
rouge-score
sacrebleu
nltk
```
---
## Limitations
- **CFPB taxonomy only.** The model is trained on and constrained to CFPB Consumer Complaint Database labels. It is not a general-purpose complaint classifier and should not be used with complaint taxonomies from other regulatory bodies or internal systems without retraining.
- **Issue field accuracy.** The `issue` field (33.6% accuracy) is the weakest link. The CFPB issue taxonomy contains 80+ canonical strings with overlapping phrasing. Expanding training data and further tuning the constrained decoder are the most direct paths to improvement.
- **English language only.** All training data is in English. Performance on non-English complaints is untested and likely poor.
- **Context length.** Complaints longer than 1024 tokens will be truncated. Most CFPB complaints are well within this limit, but very long narratives may lose relevant context.
---
## Intended Use
This model is intended for use by:
- Banking operations teams automating first-touch complaint categorisation
- Compliance teams processing regulatory complaint filings
- Contact centre platforms routing incoming complaints before agent assignment
- Research teams studying LLM adaptation for financial NLP tasks
It is not intended for consumer-facing deployment without human review of outputs, or for use in jurisdictions where automated complaint classification decisions have legal or regulatory implications without appropriate oversight.
---
## Training Infrastructure
Trained on an AMD Instinct MI300X GPU (192 GB HBM3 VRAM) running ROCm 7.2.4. The training stack is fully ROCm-native β `bitsandbytes` (CUDA-only) is not used. Model precision is bfloat16, which is the native compute type for the CDNA3 architecture.
---
## Citation
If you use this model in research or production, please cite the CFPB Consumer Complaint Database as the data source:
```
Consumer Financial Protection Bureau (CFPB)
Consumer Complaint Database
https://www.consumerfinance.gov/data-research/consumer-complaints/
``` |