SupratimRK's picture
Sync model from GitHub repository
302132f verified
|
Raw History Blame Contribute Delete
8.67 kB
metadata
language:
  - en
license: mit
library_name: onnx
pipeline_tag: text-classification
tags:
  - name-classification
  - onnx
  - quantized
  - fast-inference
  - text-classification
  - scratch
  - low-latency
metrics:
  - accuracy
  - f1
model-index:
  - name: CompactNameClassifier
    results:
      - task:
          type: text-classification
          name: Binary Name Classification
        dataset:
          name: Curated Human Names vs Non-Names
          type: custom
        metrics:
          - name: F1 Score
            type: f1
            value: 0.9621
          - name: Accuracy
            type: accuracy
            value: 0.9445
widget:
  - text: Sayantika Biswas
    example_title: Real Name (Bengali)
  - text: Supratim Mondal
    example_title: Real Name (De-biased)
  - text: Alexander Hamilton
    example_title: Real Name (Western)
  - text: ShadowHunter99
    example_title: Gamer Tag / Username
  - text: AYAN CSE3048
    example_title: Roll Number / Code
  - text: 112_SAYANTIKA BISWAS
    example_title: Prefix Noisy Handle

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

  1. Custom Domain WordPiece Tokenizer (100% Uncased, 4,000 Vocab):

    • Configured with Sequence([NFKC(), Lowercase(), StripAccents()]) and pre-tokenized via Sequence([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.
  2. 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.
  3. Pre-LN Transformer Encoder:

    • 2-layer, 128-hidden, 4-attention heads with GELU activations and Pre-LayerNorm (norm_first=True) for fast, stable convergence.
  4. 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.
  5. V8 & Runtime Optimization:

    • ONNX graph accepts int32 inputs, allowing Node.js and Python runtimes to pass native 32-bit buffers with minimal overhead.

πŸ“¦ 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.