File size: 7,299 Bytes
e38602d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22c5381
e38602d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7225bc2
e38602d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
af349f2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e38602d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
---
license: apache-2.0
language:
- en
tags:
- prompt-routing
- complexity-classifier
- deberta-v3
- llm-router
- cost-optimization
datasets:
- RowRed/ComplexityRouter
- OpenAssistant/oasst2
base_model:
- microsoft/deberta-v3-base
---

# ComplexityRouter: A Complexity based LLM Router

Introducing ComplexityRouter, a lightweight prompt complexity classifier finetuned from **microsoft/deberta-v3-base**. Using prompts from [Open Assistant Conversations Dataset Release 2 (OASST2)](https://huggingface.co/datasets/OpenAssistant/oasst2), some from myself, and some made more complex by Qwen3.5-4B (non-thinking mode), I created a synthetic dataset classifying 4,400 of the prompts using [Qwen3.5-4B Non Thinking Mode](https://huggingface.co/Qwen/Qwen3.5-4B). 

It assigns prompts to one of 4 complexity levels, making it useful for routing queries to the appropriate LLM tier.

## Model Details

### Model Description

- **Model type:** Text Classification (multi‑class)
- **Language:** English
- **Backbone:** microsoft/deberta-v3-base
- **License:** Apache‑2.0
- **Finetuned from model:** microsoft/deberta-v3-base
- **Training data:** OASST2 + synthetic augmentations + manually created prompts  
  Labels generated by **Qwen3.5‑4B** (non‑thinking mode).

### Model Sources

- **Dataset repository:** https://huggingface.co/datasets/RowRed/ComplexityRouter

## Uses

### Direct Use

Route prompts to appropriate LLM tiers based on predicted complexity:

| Level | Meaning | Suggested LLM Tier |
|-------|---------|-------------------|
| 0 (Trivial) | Simple lookups, basic Q&A (e.g., “What is 2+2?”) | Fast/cheap local model |
| 1 (Simple) | Moderate reasoning, basic domain knowledge | Mid‑tier model |
| 2 (Moderate) | Complex reasoning, deep knowledge required | Strong model |
| 3 (Complex) | Very complex reasoning, niche expertise | Frontier API model |

**Recommended routing strategy:** Group levels **0 and 1** together (fast/cheap tier), level 2 as standard, level 3 as premium. The model achieves **93.0% adjacent accuracy** on my test, meaning it rarely misroutes by more than one tier.

### Out‑of‑Scope Use

- Multi‑turn conversation routing (single prompts only).
- Non‑English prompts (training data was English‑only).
- Prompts requiring image or multimodal understanding.

## Bias, Risks, and Limitations

- Training data is synthetic and may not represent all real‑world prompt distributions.
- Level 1 (Simple) and Level 2 (Moderate) have lower per‑class F1 scores – boundary cases are inherently ambiguous.
- The model may struggle with very domain‑specific technical jargon.
- Performance may degrade on prompts that are very different from the training distribution.

## Notice
This is my first attempt making a widespread finetune. There are probably lots of issues, but thought the idea was sound. I might make a second (hopefully better) version eventually, but am not sure where to get lots of high-quality open source data.

## Training Details
### Training Data

| Split       | Samples | Source File          | Notes |
|-------------|---------|----------------------|-------|
| Training    | 2,800   | TRAINING.jsonl       | Used for model training |
| Validation  | 600     | TRAINING.jsonl       | Used for early stopping / hyperparameter tuning |
| Test (internal) | 600 | TRAINING.jsonl      | Used for in‑distribution evaluation |
| Test (held‑out) | 400 | TEST.jsonl   | Fully independent test set (reported results) |

**Total unique prompts:** 4,400

Class distribution (training):
Level 0: 762 (27.2%) • Level 1: 674 (24.1%) • Level 2: 795 (28.4%) • Level 3: 569 (20.3%)

## Training Procedure
- Hardware: NVIDIA T4 (16 GB VRAM, Google Colab)
- Framework: PyTorch 2.11 + Hugging Face Transformers
- Optimizer: AdamW (lr=2e-5, weight_decay=0.01)
- Scheduler: Linear warmup (10% of steps) → linear decay
- Loss: Weighted Cross‑Entropy (classification) + MSE (regression)
- Batch size: 16 (effective 32 with gradient accumulation)
- Epochs: 7 (early stopping patience = 3)
- Training time: ~18 minutes
- Class balancing: sqrt‑scaled class weights + weighted random sampler

## Evaluation Results

Reported on 600 held‑out samples from TRAINING.jsonl (internal test).
|Metric|Value|
|----|----|
|Exact Match Accuracy|64.5%|
|Adjacent (±1) Accuracy|93.0%|
|Macro F1|0.663|
|Weighted F1|0.653|

Per‑Class Performance (internal test, 600 samples)
|Level|Precision|Recall|F1|Support|
|----|----|----|----|----|
|L0 (Trivial)|0.658|0.626|0.642|163|
|L1 (Simple)|0.457|0.628|0.529|145|
|L2 (Moderate)|0.683|0.571|0.622|170|
|L3 (Complex)|0.933|0.795|0.858|122|

Confusion Matrix (internal test, 600 samples)

|    |Pred L0|Pred L1|Pred L2|Pred L3|
|----|----|----|----|----|
|True L0|102|46|13|2|
|True L1|35|91|18|1|
|True L2|15|54|97|4|
|True L3|3|8|14|97|

## How to Get Started with the Model

```python
from transformers import AutoTokenizer, AutoModel
import torch
import torch.nn as nn

class PromptComplexityRouter(nn.Module):
    def __init__(self, backbone="microsoft/deberta-v3-base", num_labels=4):
        super().__init__()
        self.backbone = AutoModel.from_pretrained(backbone)
        hidden_size = self.backbone.config.hidden_size
        self.classifier = nn.Sequential(
            nn.Dropout(0.1),
            nn.Linear(hidden_size, 256),
            nn.GELU(),
            nn.Dropout(0.1),
            nn.Linear(256, num_labels),
        )
    
    def forward(self, input_ids, attention_mask):
        outputs = self.backbone(input_ids=input_ids, attention_mask=attention_mask)
        cls_output = outputs.last_hidden_state[:, 0, :]
        return self.classifier(cls_output)

# Load
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
tokenizer = AutoTokenizer.from_pretrained("RowRed/ComplexityRouter")
model = PromptComplexityRouter()
model.load_state_dict(
    torch.load("pytorch_model.bin", map_location=device),
    strict=False
)
model.to(device)
model.eval()

# Predict
prompts = ["What is 2+2?", "Explain quantum entanglement in detail."]
encoded = tokenizer(prompts, padding=True, truncation=True, return_tensors="pt").to(device)
with torch.no_grad():
    logits = model(encoded["input_ids"], encoded["attention_mask"])
    probs = torch.softmax(logits, dim=-1)
    predictions = torch.argmax(probs, dim=-1)

for prompt, level in zip(prompts, predictions):
    print(f"Level {level.item()}: {prompt}")
```

## Citation
If you use this model, please cite:

```bibtex
@software{ComplexityRouter,
  author = {RowRed},
  title = {ComplexityRouter},
  year = {2026},
  url = {https://huggingface.co/RowRed/ComplexityRouter}
}
```

Additionally, acknowledge the base dataset and labeling model:

```bibtex
@dataset{oasst2,
  author = {OpenAssistant Contributors},
  title = {Open Assistant Conversations Dataset Release 2},
  year = {2023},
  url = {https://huggingface.co/datasets/OpenAssistant/oasst2}
}

@software{qwen3.5-4b,
  author = {Qwen Team},
  title = {Qwen3.5-4B},
  year = {2026},
  url = {https://huggingface.co/Qwen/Qwen3.5-4B}
}
```

## License
This model is released under Apache‑2.0.
The backbone (microsoft/deberta-v3-base) is MIT‑licensed.
The training dataset is derived from OASST2 (Apache‑2.0) and Qwen3.5‑4B outputs (Apache‑2.0).