File size: 5,877 Bytes
e74af81 2e3e2b8 e74af81 2e3e2b8 | 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 | ---
license: cc0-1.0
language:
- en
tags:
- text-classification
- onnx
- onnxruntime
- hate-speech-detection
- offensive-language
- int8
- quantization
pipeline_tag: text-classification
widget:
- text: "I really love this community, everyone is so supportive and kind!"
example_title: "Neutral"
- text: "Shut up, you are being so damn annoying and stupid."
example_title: "Offensive Language"
- text: "Those people are subhuman and don't belong in our country, kick them all out."
example_title: "Hate Speech"
---
# Hate Speech & Offensive Language Classifier (ONNX & INT8)
A lightweight, high-performance text classification model fine-tuned to distinguish between **targeted hate speech**, **offensive language (profanity)**, and **neutral content**.
Both the **Full Precision ONNX (FP32)** and an ultra-compact **Dynamic INT8 Quantized (8q)** model are included for production-ready, ultra-low latency inference on CPUs and edge devices.
---
## Key Features
* **Fine-Grained Distinction**: Accurately differentiates between general offensive language/profanity and genuinely dangerous hate speech.
* **Dual ONNX Models**:
* `model/hatespeech.onnx` (FP32, ~255 MB)
* `model/hatespeech_int8.onnx` (INT8 Quantized, **~64 MB**, **~75% size reduction**)
* **Ultra-Low Latency**: ~**17 ms** per sample on standard CPU with ONNX Runtime.
* **Balanced Class Weighting**: Trained with normalized inverse-frequency class weights to combat severe class imbalance (Hate speech is only ~5.8% of the training dataset).
* **Anti-Overfitting Protection**: Stratified split, weight decay ($0.01$), dropout ($0.2$), and early stopping monitoring **Validation Macro F1**.
---
## Classes
| Class ID | Label | Description |
| :---: | :--- | :--- |
| `0` | **Hate Speech** | Targeted hostility, incitement of violence, or dehumanization against protected groups. |
| `1` | **Offensive Language** | Swear words, slang, insults, and vulgarity without targeted hatred. |
| `2` | **Neither** | Neutral, positive, benign, or conversational language. |
---
## Benchmark & Model Specifications
| Property | Raw ONNX | INT8 Quantized (Recommended) |
| :--- | :--- | :--- |
| **File** | `model/hatespeech.onnx` | `model/hatespeech_int8.onnx` |
| **Precision** | Float32 | Quantized Int8 (Weights) |
| **File Size** | ~255 MB | **64.27 MB** |
| **Inference Engine** | ONNX Runtime | ONNX Runtime |
| **Average Latency (CPU)** | ~28 ms | **~17 ms** |
| **Dynamic Inputs** | Dynamic Batch & Sequence Length | Dynamic Batch & Sequence Length |
---
## Quickstart
### 1. Installation
Install dependencies using `pip` or `uv`:
```bash
pip install onnxruntime transformers numpy
# or using uv:
uv add onnxruntime transformers numpy
```
### 2. Standalone Inference with ONNX Runtime
You can run predictions with just **ONNX Runtime** and Hugging Face's `AutoTokenizer`:
```python
import numpy as np
import onnxruntime as ort
from transformers import AutoTokenizer
LABEL_NAMES = {0: "Hate Speech", 1: "Offensive Language", 2: "Neither"}
# 1. Load ONNX model and tokenizer
model_path = "./model/hatespeech_int8.onnx"
session = ort.InferenceSession(model_path, providers=["CPUExecutionProvider"])
tokenizer = AutoTokenizer.from_pretrained("./model")
# 2. Tokenize input text
text = "I really love this community, everyone is so supportive and kind!"
inputs = tokenizer(text, padding=True, truncation=True, max_length=128, return_tensors="np")
# 3. Run inference
ort_inputs = {
"input_ids": inputs["input_ids"].astype(np.int64),
"attention_mask": inputs["attention_mask"].astype(np.int64),
}
logits = session.run(None, ort_inputs)[0]
# 4. Softmax probabilities
exp_logits = np.exp(logits - np.max(logits, axis=-1, keepdims=True))
probs = exp_logits / np.sum(exp_logits, axis=-1, keepdims=True)
pred_id = int(np.argmax(probs, axis=-1)[0])
print(f"Prediction: {LABEL_NAMES[pred_id]} ({probs[0][pred_id] * 100:.2f}%)")
```
---
## CLI & Interactive Usage
This repository includes [`hatespeech.py`](./hatespeech.py) for easy command-line testing:
```bash
# Run benchmark examples
python hatespeech.py
# Predict a custom sentence
python hatespeech.py --text "Stop being so annoying!"
# Start live interactive prompt
python hatespeech.py --interactive
# Use raw FP32 model instead of INT8
python hatespeech.py --raw
```
---
## Training & Architecture
* **Base Model**: `distilbert-base-uncased`
* **Dataset**: Davidson et al. (2017) *Automated Hate Speech and Offensive Language Detection* (~24,783 annotated samples).
* **Data Split**: Stratified 80% Train, 10% Validation, 10% Holdout Test.
* **Loss Function**: `nn.CrossEntropyLoss` with balanced class weights:
$$w_c = \frac{N_{\text{total}}}{N_{\text{classes}} \times N_c}$$
* **Optimizer**: `AdamW` (learning rate: $2 \times 10^{-5}$, weight decay: $0.01$).
* **LR Scheduler**: Linear warmup ($10\%$ of steps) followed by linear decay.
* **Early Stopping**: Monitored on validation Macro F1 score with patience of 2 epochs.
* **Quantization**: Dynamic INT8 quantization executed using `onnxruntime.quantization.quantize_dynamic`.
To reproduce training:
```bash
python train.py --epochs 3 --batch_size 32
```
---
## Citation
If you use this model or dataset in your research, please cite the underlying dataset by Davidson et al.:
```bibtex
@inproceedings{davidson2017automated,
title={Automated Hate Speech Detection and the Problem of Offensive Language},
author={Davidson, Thomas and Warmsley, Dana and Macy, Michael and Weber, Ingmar},
booktitle={Proceedings of the 11th International AAAI Conference on Web and Social Media},
series={ICWSM '17},
pages={512--515},
year={2017}
}
```
---
## License
This repository and model card are released under the [Creative Commons Zero v1.0 Universal (CC0-1.0)](https://creativecommons.org/publicdomain/zero/1.0/) license.
|