Downloads · 30 days
45
26% of all-time downloads
StrictlyInsecure/discord-moderation-minilm
discord-moderation-minilm is a text classification model from StrictlyInsecure. Use it when you need a label for a piece of text. It is set up for transformers. The card lists the license as apache-2.0.
A 23 MB INT8 ONNX text classifier for chat moderation, built for edge deployment — it runs on a Raspberry Pi, not just a GPU box.
Downloads · 30 days
45
26% of all-time downloads
All-time downloads
170
Public
Parameters
22.7M
114 MB on disk
Likes
0
Public
Click a slice to open those files.
.safetensors90.9 MB · 79%
From the Hugging Face model README
A 23 MB INT8 ONNX text classifier for chat moderation, built for edge deployment — it runs on a Raspberry Pi, not just a GPU box.
This is the speed variant of a pair (numbers are in-domain, on held-out data the model never trained on — see Results):
| size | latency | false positives | missed abuse | |
|---|---|---|---|---|
| this model (L6) | 23 MB | ~1.9 ms | 2.7% | 3.5% |
discord-moderation-minilm-l12 | 33 MB | ~4.1 ms | 3.9% | 2.2% |
Use this one on a Pi or at very high volume — it flags fewer innocent messages at the default threshold. Use L12 for a lower miss rate. Both are honest generalization numbers; the threshold is a knob (see Thresholding).
| Classes | benign · abusive · spam · flood |
| Size | 23 MB (INT8 ONNX) · 91 MB (fp32 safetensors) |
| Latency | ~1.9 ms/message, INT8 ONNX desktop CPU |
| Base | sentence-transformers/all-MiniLM-L6-v2 (22M params) |
| Context | 200 tokens |
Most open toxicity classifiers have two problems for chat moderation:
Measured on a held-out test set the model never trained on (excluded from training by construction), split by domain because register matters. Counts are FP/FN, threshold 0.85, INT8 ONNX.
In-domain — chat-register text (Wikipedia/Jigsaw + synthetic chat), what this model is for:
| metric | count | rate |
|---|---|---|
| false positives (innocent flagged) | 30/1,124 | 2.7% |
| false negatives (abuse missed) | 51/1,462 | 3.5% |
| per-class recall | harassment 98% · spam 100% · flood 100% · toxicity ~87% | |
identity-term bias probe (bias_test.py, 592 benign identity sentences) | 11 flagged | 1.9% |
| surface-form robustness (casing, markdown, punctuation) | 107/110 | |
| out-of-distribution suite (39 hand-written: short messages, banter, threats) | 38/39 | |
| latency | INT8 ONNX, desktop CPU | ~1.9 ms |
Out-of-domain — real game chat (CONDA, a register this model was NOT trained on):
| metric | count | rate |
|---|---|---|
| false positives | 152/718 | 21.2% |
| false negatives | 261/680 | 38.4% |
Game chat is the honest weakness — this model is Wikipedia/Jigsaw-register, not gaming slang. The larger L12 is cleaner on the identity probe (0/592 vs this model's 11/592); at 22M params, L6 has less capacity to fully absorb the debiasing. If identity fairness is critical for your deployment, prefer L12.
Note on prior revisions. Earlier uploads reported ~2.7% FP / 1.9% FN. Those were train-on-test inflated (the eval set overlapped the training data) and the weights carried an identity-term bias. This revision excludes the holdout from training (so the numbers above are real generalization) and applies counterfactual augmentation to cut identity bias to 1.9%.
For scale: general-purpose LLM judges prompted for moderation measured far worse on the same
yardsticks at 40–100× the size (phi3:mini, 2.2 GB: F1 ~48 on game chat; llama-guard3:1b: missed
~84% of interpersonal abuse).
from optimum.onnxruntime import ORTModelForSequenceClassification
from transformers import AutoTokenizer, pipeline
REPO = "strictlyinsecure/discord-moderation-minilm"
model = ORTModelForSequenceClassification.from_pretrained(REPO, subfolder="onnx", file_name="model.onnx")
tok = AutoTokenizer.from_pretrained(REPO)
clf = pipeline("text-classification", model=model, tokenizer=tok, top_k=None, device=-1)
clf("i'm gonna destroy you in rocket league tonight lmao")
# → benign (0.992)
clf("FREE NITRO for everyone, claim here bit.ly/x9k2")
# → spam (0.993)
clf("shut up you idiot nobody likes you")
# → abusive (0.991)
Requires pip install optimum[onnxruntime].
from transformers import pipeline
clf = pipeline("text-classification", model="strictlyinsecure/discord-moderation-minilm", top_k=None)
clf("FREE NITRO click here bit.ly/x9k2")
# [{'label': 'spam', 'score': 0.99}, ...]
The model is bimodal — it outputs ~0.99 or ~0.003 and little in between. On the held-out set, the trade-off curve is nearly flat between 0.3 and 0.9, so the threshold is not a delicate choice:
| threshold | abuse caught | false positives |
|---|---|---|
| 0.30 | 98.8% | 38 / 399 |
| 0.85 | 97.4% | 26 / 399 |
| 0.95 | 95.6% | 20 / 399 |
all-MiniLM-L6-v2, 4-class sequence classification head, max_length=200.abusive for everything.toxicity and harassment are merged into one abusive class. On the labeled corpus, two
annotators (Jigsaw's humans and an LLM judge) disagreed about which of those two buckets an
abusive message belonged in 48% of the time. That boundary was training noise, not signal, and
most moderation pipelines take the same action for both.
A fast first-pass filter in a moderation pipeline — cheap enough to run on every message, with a human or a stronger model handling escalation. It is not a substitute for human moderators, and it should not be the sole basis for automated bans.
Apache-2.0. See NOTICE for the attribution required on redistribution.
Trained on the Jigsaw Toxic Comment Classification dataset (CC0). The underlying comment text originates from Wikipedia and is licensed CC-BY-SA-3.0.
Base model sentence-transformers/all-MiniLM-L6-v2 is Apache-2.0.