| --- |
| title: Toxic Comment Classifier |
| emoji: π‘οΈ |
| colorFrom: blue |
| colorTo: indigo |
| sdk: docker |
| pinned: false |
| --- |
| |
| # Code-Mixed Toxic Content Classifier |
|
|
| Production-ready Transformer-based NLP system for detecting toxic content in: |
|
|
| * **Tamil** |
| * **English** |
| * **Tanglish** (Tamil in Latin script) |
|
|
| Built using **MuRIL (google/muril-base-cased)** fine-tuned for 3-class toxicity classification: |
|
|
| * `non_toxic` |
| * `toxic` |
| * `severe_toxic` |
|
|
| Designed for real-world deployment with rate limiting, logging, thresholding, and load testing support. |
|
|
| --- |
|
|
| # π¦ Project Structure |
|
|
| ``` |
| / |
| βββ model_output/ # Trained model, tokenizer, label encoder |
| βββ logs/ # JSONL prediction logs |
| βββ src/ |
| β βββ api.py # Production FastAPI server (rate-limited, logged) |
| β βββ data_loader.py # Hardened dataset loader & cleaner |
| β βββ predict.py # Inference engine with threshold logic |
| β βββ train_muril.py # Production training pipeline |
| βββ locustfile.py # Load testing configuration |
| βββ requirements.txt |
| βββ README.md |
| βββ *.csv # Structured datasets (tamil.csv, english.csv, tanglish.csv) |
| ``` |
|
|
| --- |
|
|
| # π§ Model Overview |
|
|
| * Base Model: `google/muril-base-cased` |
| * Architecture: Transformer (BERT-style sequence classification) |
| * Classes: |
|
|
| * non_toxic |
| * toxic |
| * severe_toxic |
| * Max token length: 192 |
| * Confidence thresholding enabled |
| * Near-duplicate removal during preprocessing |
| * Stratified train/validation split |
| * Macro-F1 monitored during training |
|
|
| --- |
|
|
| # π Dataset Structure |
|
|
| Each CSV file must contain: |
|
|
| ``` |
| text,label |
| ``` |
|
|
| Example: |
|
|
| ``` |
| nee saavu da,severe_toxic |
| I disagree with you,non_toxic |
| you are useless,toxic |
| ``` |
|
|
| Requirements: |
|
|
| * UTF-8 or UTF-16 encoding supported |
| * No empty rows |
| * No duplicate sentences |
| * Clear label boundaries |
|
|
| --- |
|
|
| # βοΈ Setup |
|
|
| ## 1οΈβ£ Create Virtual Environment |
|
|
| ```bash |
| python -m venv venv |
| ``` |
|
|
| Windows: |
|
|
| ```bash |
| .\venv\Scripts\activate |
| ``` |
|
|
| Mac/Linux: |
|
|
| ```bash |
| source venv/bin/activate |
| ``` |
|
|
| --- |
|
|
| ## 2οΈβ£ Install Dependencies |
|
|
| ```bash |
| pip install -r requirements.txt |
| ``` |
|
|
| Optional (recommended): |
|
|
| Set HuggingFace token for stable downloads: |
|
|
| ```bash |
| set HF_TOKEN=your_token # Windows |
| export HF_TOKEN=your_token # Linux/Mac |
| ``` |
|
|
| --- |
|
|
| # ποΈ Training |
|
|
| Train model: |
|
|
| ```bash |
| python src/train_muril.py --epochs 5 --batch_size 16 |
| ``` |
|
|
| Output saved to: |
|
|
| ``` |
| model_output/ |
| ``` |
|
|
| Training includes: |
|
|
| * Dataset audit logging |
| * Label distribution validation |
| * Stratified split |
| * Macro F1 tracking |
| * Best model checkpoint restore |
| * Label encoder persistence |
|
|
| --- |
|
|
| # π§ͺ CLI Inference Test |
|
|
| ```bash |
| python src/predict.py |
| ``` |
|
|
| Verifies: |
|
|
| * Model loads |
| * Threshold logic applied |
| * Batch inference works |
|
|
| --- |
|
|
| # π Run Production API |
|
|
| ### Windows (single worker recommended) |
|
|
| ```bash |
| uvicorn src.api:app --host 0.0.0.0 --port 8000 |
| ``` |
|
|
| Open Swagger UI: |
|
|
| ``` |
| http://localhost:8000/docs |
| ``` |
|
|
| --- |
|
|
| # π API Endpoints |
|
|
| ## Health Check |
|
|
| ``` |
| GET /health |
| ``` |
|
|
| Returns service health. |
|
|
| --- |
|
|
| ## Readiness Probe |
|
|
| ``` |
| GET /ready |
| ``` |
|
|
| Returns 200 only if model loaded and ready. |
|
|
| --- |
|
|
| ## Predict |
|
|
| ``` |
| POST /predict |
| ``` |
|
|
| ### Request |
|
|
| ```json |
| { |
| "text": "nee saavu da π" |
| } |
| ``` |
|
|
| ### Response |
|
|
| ```json |
| { |
| "prediction": "severe_toxic", |
| "raw_prediction": "severe_toxic", |
| "confidence": 0.9867, |
| "process_time_ms": 64.03, |
| "timestamp": "2026-02-22T13:49:24.019Z" |
| } |
| ``` |
|
|
| --- |
|
|
| # π‘οΈ Production Safeguards |
|
|
| * Rate limiting enabled (per IP) |
| * Structured JSONL logging |
| * Confidence threshold enforcement |
| * Input validation |
| * Cleaned text normalization |
| * Graceful startup and shutdown |
| * No model reload per request |
| * Lazy model initialization |
|
|
| --- |
|
|
| # π Load Testing (Locust) |
|
|
| Create `locustfile.py`: |
|
|
| ```python |
| from locust import HttpUser, task, between |
| import random |
| |
| texts = [ |
| "nee saavu da π", |
| "You are useless", |
| "I disagree with you", |
| "k1ll urself", |
| "This is fine" |
| ] |
| |
| class ToxicityUser(HttpUser): |
| wait_time = between(0.5, 1.5) |
| |
| @task |
| def predict(self): |
| self.client.post( |
| "/predict", |
| json={"text": random.choice(texts)} |
| ) |
| ``` |
|
|
| Run: |
|
|
| ```bash |
| locust |
| ``` |
|
|
| Open: |
|
|
| ``` |
| http://localhost:8089 |
| ``` |
|
|
| Test capacity: |
|
|
| * Start with 20 users |
| * Increase gradually |
| * Monitor latency & failure % |
|
|
| --- |
|
|
| # π Performance (CPU, Single Worker) |
|
|
| Expected: |
|
|
| * 60β120ms average latency |
| * ~10β15 RPS stable |
| * 0% failure under safe load |
|
|
| High concurrency requires: |
|
|
| * Linux |
| * Gunicorn workers |
| * Possibly GPU acceleration |
|
|
| --- |
|
|
| # β Known Limitations |
|
|
| * Windows multi-worker mode unstable |
| * Single-process inference bound by CPU |
| * Severe vs toxic boundary sensitive to dataset |
| * Confidence not temperature-calibrated |
|
|
| --- |
|
|
| # π Deployment Recommendations |
|
|
| For real production: |
|
|
| * Deploy on Linux |
| * Use Gunicorn + Uvicorn workers |
| * Reverse proxy (Nginx) |
| * Enable HTTPS |
| * Add monitoring (Prometheus/Grafana) |
| * Add structured metrics endpoint |
| * Implement request tracing |
|
|
| --- |
|
|
| # π§ͺ Monitoring |
|
|
| Logs stored in: |
|
|
| ``` |
| logs/predictions.jsonl |
| ``` |
|
|
| Each entry contains: |
|
|
| * timestamp |
| * text |
| * prediction |
| * confidence |
| * latency |
|
|
| --- |
|
|
| # π Version |
|
|
| - API Version: 1.1.0 |
| - Model: MuRIL fine-tuned (custom dataset) |