addyo07's picture
Restructure: model/pytorch/, model/onnx/, scripts/
fe775e3 verified
|
Raw
History Blame Contribute Delete
5.37 kB
---
language:
- en
- hi
license: mit
library_name: transformers
tags:
- distilbert
- onnx
- int8
- query-classification
- generic-semantic
- multilingual
- text-classification
datasets:
- addyo07/query-classification-dataset
metrics:
- accuracy
pipeline_tag: text-classification
model-index:
- name: distilbert-query-classifier
results:
- task:
type: text-classification
name: Generic vs Semantic Classification
dataset:
name: query-classification-dataset
type: addyo07/query-classification-dataset
split: test
metrics:
- type: accuracy
value: 0.9839
name: Accuracy
- type: precision
value: 0.9844
name: Precision
- type: recall
value: 0.9834
name: Recall
- type: f1
value: 0.9839
name: F1
widget:
- text: "my name is John"
- text: "hello"
- text: "मेरा नाम रवि है"
- text: "नमस्ते"
- text: "I love spicy food"
- text: "stop"
---
# Query Sieve Classifier
**DistilBERT multilingual** fine-tuned to classify user queries as **GENERIC** or **SEMANTIC** — filtering chit-chat from durable knowledge worth storing.
## Model Description
- **Architecture**: `distilbert-base-multilingual-cased` (134M params)
- **Quantization**: INT8 dynamic (ONNX Runtime)
- **Input**: Short text queries in English or Hindi (≤10 words; longer sentences bypass to SEMANTIC)
- **Output**: Binary — GENERIC (0) or SEMANTIC (1)
- **Inference**: ONNX Runtime CPU, single-thread P99 = **16.87ms**
## Repository Structure
```
distilbert-query-classifier/
├── README.md # Model card (this file)
├── model/
│ ├── pytorch/ # PyTorch safetensors (for transformers library)
│ │ ├── model.safetensors # Full precision PyTorch weights
│ │ ├── config.json # Model configuration
│ │ ├── tokenizer.json # HuggingFace tokenizer
│ │ └── tokenizer_config.json
│ └── onnx/ # ONNX INT8 quantized (for CPU inference)
│ └── model_quantized.onnx # INT8 quantized model (~130 MB)
├── scripts/ # Python training pipeline
│ ├── config.py # Constants and paths
│ ├── generate_dataset.py # Synthetic data generation via Ollama
│ ├── train.py # Fine-tuning + ONNX export + latency benchmark
│ └── ...
```
## Usage
### Python (with transformers + ONNX Runtime)
```python
from transformers import AutoTokenizer
import onnxruntime as ort
# Load tokenizer from the pytorch folder
tokenizer = AutoTokenizer.from_pretrained(
"addyo07/distilbert-query-classifier",
subfolder="model/pytorch",
)
# Load ONNX model
session = ort.InferenceSession("model/onnx/model_quantized.onnx")
def classify(text: str) -> str:
inputs = tokenizer(text, return_tensors="np", max_length=64, truncation=True, padding="max_length")
logits = session.run(None, {
"input_ids": inputs["input_ids"].astype(np.int64),
"attention_mask": inputs["attention_mask"].astype(np.int64),
})[0]
return "SEMANTIC" if logits[0][1] > logits[0][0] else "GENERIC"
```
### Rust (with query-sieve crate)
```toml
[dependencies]
query-sieve = { git = "https://github.com/addy-47/query-sieve-rs" }
```
```rust
use query_sieve::GenericSemanticClassifier;
let classifier = GenericSemanticClassifier::load(
"model/onnx/model_quantized.onnx",
"model/pytorch/tokenizer.json",
)?;
let result = classifier.classify("my name is John")?;
```
### Download individual files
```bash
# ONNX model (for CPU inference)
wget https://huggingface.co/addyo07/distilbert-query-classifier/resolve/main/model/onnx/model_quantized.onnx
# PyTorch weights (for fine-tuning)
wget https://huggingface.co/addyo07/distilbert-query-classifier/resolve/main/model/pytorch/model.safetensors
# Tokenizer
wget https://huggingface.co/addyo07/distilbert-query-classifier/resolve/main/model/pytorch/tokenizer.json
```
## Performance
| Split | Accuracy |
|-------|----------|
| Test (15% holdout) | **98.39%** |
### Latency
| Mode | P50 | P99 |
|------|-----|-----|
| Multi-thread CPU | 8.39 ms | 11.81 ms |
| Single-thread CPU (intra_op_threads=1) | 14.81 ms | 16.87 ms |
## Training Data
Dataset: [addyo07/query-classification-dataset](https://huggingface.co/datasets/addyo07/query-classification-dataset)
12,044 synthetic examples generated by `llama3.1:8b`:
| Category | English | Hindi |
|----------|---------|-------|
| GENERIC | 3,003 | 3,019 |
| SEMANTIC | 3,017 | 3,005 |
The SEMANTIC category contains ~40% short standalone statements (3-7 words) to prevent the model from learning "semantic = long sentence."
## Training Scripts
The `scripts/` directory contains the full training pipeline:
1. `python scripts/generate_dataset.py --category en_semantic` — generate synthetic data via Ollama
2. `python scripts/train.py` — fine-tune DistilBERT + export ONNX INT8 + benchmark
## Rust Crate
The `query-sieve` Rust crate provides the inference runtime:
- **GitHub**: [addy-47/query-sieve-rs](https://github.com/addy-47/query-sieve-rs)
- ONNX Runtime (ort) with HuggingFace tokenizer
- Configurable single/multi-thread CPU
- >10 word bypass (long sentences auto-classify as SEMANTIC)
## License
MIT