CompactNameClassifier: Ultra-Efficient Name Classifier Trained From Scratch
CompactNameClassifier is a state-of-the-art, ultra-lightweight neural text classifier trained from scratch on a curated, de-biased dataset of 1,606,412 records (1,458,041 train + 148,371 val; 1.18M clean human names across global and regional cultures + 280k non-names, unigrams, gamer tags, and alphanumeric codes).
Unlike generic large language models or pretrained BERT variants, CompactNameClassifier has zero external pretrained dependencies, weighs just ~632 KB (INT8 ONNX), and delivers sub-millisecond CPU inference (< 0.45 ms per query).
β‘ Performance Highlights
| Metric | Previous Pretrained Model | CompactNameClassifier (Scratch) | Improvement |
|---|---|---|---|
| Model Size (INT8 ONNX) | 4.30 MB (2.45 MB pruned) | ~632 KB | 74%β85% smaller |
| Total Parameters | 4,380,000 params | 532,482 params | 88% parameter reduction |
| Vocabulary Size | 30,522 tokens | 4,000 tokens | 87% smaller vocabulary |
| Sequence Length | 16 tokens | 20 tokens | No truncation blind spots |
| CPU Latency (Single Thread) | ~1.20 ms | 0.449 ms | ~2.7x faster inference |
| Throughput | ~800 queries/sec | 2,228 queries/sec | Single CPU core in Node.js |
| Validation Accuracy | β | 94.45% | Evaluated on 148k val split |
| Validation F1-Score | β | 96.21% | Weighted F1 score |
| Corner Cases Benchmark | 52.9% (9/17) | 94.1% (16/17) | Resistant to handle/roll-code leakage |
π§ Architectural Innovations
Custom Domain WordPiece Tokenizer (100% Uncased, 4,000 Vocab):
- Configured with
Sequence([NFKC(), Lowercase(), StripAccents()])and pre-tokenized viaSequence([Whitespace(), Punctuation(), Digits(individual_digits=True)]). - Normalizes all input to lowercase at the Rust tokenizer level, making the model completely immune to uppercase/titlecase domain mismatches.
- Isolates individual digits (
0β9), allowing alphanumeric noise (112_,3048,99) to be recognized without exploding the vocabulary.
- Configured with
Factorized Embeddings:
- Projects token vocabulary through
Embedding(4000, 64) -> Linear(64, 128, bias=False). - Cuts embedding parameter footprint in half with zero loss in representational capacity.
- Projects token vocabulary through
Pre-LN Transformer Encoder:
- 2-layer, 128-hidden, 4-attention heads with GELU activations and Pre-LayerNorm (
norm_first=True) for fast, stable convergence.
- 2-layer, 128-hidden, 4-attention heads with GELU activations and Pre-LayerNorm (
Masked Dual Pooling (MeanPool + MaxPool):
- Concatenates Masked Mean Pooling (128) + Masked Max Pooling (128) into a 256-dimensional representation.
- Max Pooling acts as an anomaly detectorβif even one token in the sequence indicates non-name noise (e.g.,
_,CSE3048,112), the max-pooled features spike and alert the classifier immediately.
V8 & Runtime Optimization:
- ONNX graph accepts
int32inputs, allowing Node.js and Python runtimes to pass native 32-bit buffers with minimal overhead.
- ONNX graph accepts
π¦ Files in this Repository
| File | Size | Description |
|---|---|---|
model_int8.onnx |
~647 KB | Quantized INT8 ONNX model (recommended for production) |
model.onnx |
~2.2 MB | Full precision (FP32) ONNX model |
model_weights.pt |
~2.1 MB | PyTorch model checkpoint / state dictionary |
tokenizer.json |
~84 KB | Fast Tokenizers JSON configuration |
tokenizer_config.json |
~260 B | Tokenizer metadata |
vocab.txt |
~26 KB | 4,000 WordPiece vocabulary entries |
config.json |
~350 B | Model architecture parameters & label mappings |
model.py |
~4 KB | Standalone PyTorch CompactNameClassifier architecture |
predict.py |
~7 KB | Ready-to-run inference script |
π Quickstart & Usage
1. Clone Repository & Setup
git clone https://github.com/SupratimRK/.model.base.nc.git
cd .model.base.nc
npm install
2. Download Model from Hugging Face Hub
from huggingface_hub import hf_hub_download
import os
repo_id = "SupratimRK/compact-name-classifier"
# Download ONNX model and tokenizer
onnx_path = hf_hub_download(repo_id=repo_id, filename="model_int8.onnx")
tok_path = hf_hub_download(repo_id=repo_id, filename="tokenizer.json")
3. Python Inference (ONNX Runtime)
import numpy as np
import onnxruntime as ort
from tokenizers import Tokenizer
# Load tokenizer and session
tokenizer = Tokenizer.from_file("tokenizer.json")
tokenizer.enable_padding(length=20, pad_token="[PAD]", pad_id=0)
tokenizer.enable_truncation(max_length=20)
session = ort.InferenceSession("model_int8.onnx")
# Tokenize
names = ["Sayantika Biswas", "ShadowHunter99", "CSE3048"]
encodings = tokenizer.encode_batch(names)
input_ids = np.array([e.ids for e in encodings], dtype=np.int32)
attention_mask = np.array([e.attention_mask for e in encodings], dtype=np.int32)
# Run Inference
logits = session.run(None, {"input_ids": input_ids, "attention_mask": attention_mask})[0]
exp_logits = np.exp(logits - np.max(logits, axis=-1, keepdims=True))
probs = exp_logits / np.sum(exp_logits, axis=-1, keepdims=True)
labels = {0: "NON_NAME", 1: "REAL_NAME"}
for text, prob in zip(names, probs):
pred = int(np.argmax(prob))
print(f"{text:20} => {labels[pred]} ({prob[pred]*100:.1f}%)")
Output:
Sayantika Biswas => REAL_NAME (97.7%)
ShadowHunter99 => NON_NAME (99.8%)
CSE3048 => NON_NAME (99.9%)
4. Node.js Native Inference (onnxruntime-node)
import { CompactNameClassifier } from './scripts/classifier.mjs';
const classifier = new CompactNameClassifier();
await classifier.init();
const result = await classifier.predict('Sayantika Biswas');
console.log(result);
// {
// text: 'Sayantika Biswas',
// classification: 'REAL_NAME',
// confidence: 0.998,
// raw_probs: { non_name: 0.002, real_name: 0.998 }
// }
5. PyTorch Inference
import torch
from scripts.model import CompactNameClassifier
model = CompactNameClassifier(
vocab_size=4000,
emb_dim=64,
hidden_dim=128,
num_layers=2,
num_heads=4,
max_len=20,
dropout=0.0
)
model.load_state_dict(torch.load("models/model_weights.pt", weights_only=True))
model.eval()
π Training Data
- Total Dataset Size: 510,162 examples
- Positive Examples (Real Names): 247,864 entries (audited, 100% pure alphabetic, spanning diverse global cultures: Western, South Asian, East Asian, Hispanic, Middle Eastern, African).
- Negative Examples (Non-Names): 262,298 entries including gaming handles, social media usernames, alphanumeric serial numbers, code identifiers, and 52k curated high-frequency English vocabulary words.
- Split: 90% Training / 10% Validation (459,206 Train / 50,956 Val)
π License
This model and its associated weights and tokenizers are released under the MIT License.
- Downloads last month
- 42
Evaluation results
- F1 Score on Curated Human Names vs Non-Namesself-reported0.962
- Accuracy on Curated Human Names vs Non-Namesself-reported0.945