Text Classification
Model2Vec
Safetensors
English
safety
guardrail
moderation
jailbreak-detection
multilabel
static-embeddings
Instructions to use bfuzzy1/Railz-Micro with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Model2Vec
How to use bfuzzy1/Railz-Micro with Model2Vec:
from model2vec import StaticModel model = StaticModel.from_pretrained("bfuzzy1/Railz-Micro") - Notebooks
- Google Colab
- Kaggle
Railz-Micro: 67M static multilabel safety guard (safety-vocab gemma distill)
Browse files- .gitattributes +2 -0
- README.md +149 -0
- config.json +4 -0
- model.safetensors +3 -0
- modules.json +14 -0
- pipeline.skops +3 -0
- tokenizer.json +3 -0
.gitattributes
CHANGED
|
@@ -33,3 +33,5 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
+
pipeline.skops filter=lfs diff=lfs merge=lfs -text
|
| 37 |
+
tokenizer.json filter=lfs diff=lfs merge=lfs -text
|
README.md
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: mit
|
| 3 |
+
library_name: model2vec
|
| 4 |
+
pipeline_tag: text-classification
|
| 5 |
+
language:
|
| 6 |
+
- en
|
| 7 |
+
tags:
|
| 8 |
+
- safety
|
| 9 |
+
- guardrail
|
| 10 |
+
- moderation
|
| 11 |
+
- jailbreak-detection
|
| 12 |
+
- multilabel
|
| 13 |
+
- static-embeddings
|
| 14 |
+
- model2vec
|
| 15 |
+
datasets:
|
| 16 |
+
- nvidia/Aegis-AI-Content-Safety-Dataset-2.0
|
| 17 |
+
- OpenSafetyLab/Salad-Data
|
| 18 |
+
- allenai/WildChat-1M
|
| 19 |
+
- google/civil_comments
|
| 20 |
+
- toxigen/toxigen-data
|
| 21 |
+
- allenai/real-toxicity-prompts
|
| 22 |
+
- bench-llm/or-bench
|
| 23 |
+
- natolambert/xstest-v2-copy
|
| 24 |
+
---
|
| 25 |
+
|
| 26 |
+
# Railz-Micro
|
| 27 |
+
|
| 28 |
+
**One tiny model, one pass, three safety jobs: harmful-content detection + 9-category classification + jailbreak detection.**
|
| 29 |
+
|
| 30 |
+
Railz-Micro is a 67M-parameter **static** multilabel safety guard. No transformer at inference β tokenize, look up, average, classify. Sub-millisecond on CPU, runs anywhere, nothing leaves your machine.
|
| 31 |
+
|
| 32 |
+
## Why it's different
|
| 33 |
+
|
| 34 |
+
- **Custom safety-vocabulary base.** We distilled [google/embeddinggemma-300m](https://huggingface.co/google/embeddinggemma-300m) into a static token table **with 3,864 mined safety phrases** (2,472 multi-word) added as dedicated tokens. `how to prevent` and `ignore previous instructions` are single tokens with their own composed vectors β the teacher's contextual reading of each phrase, frozen into a lookup. This is what lets a bag-of-tokens model separate *"how to prevent bomb attacks"* (benign) from bomb-making requests, and it's why the false-positive rate on scary-but-benign prompts is ~1%.
|
| 35 |
+
- **Geometry-curated training data.** 355k examples curated with [SemHash](https://github.com/MinishLab/semhash): semantic dedup, **decontamination against every benchmark below** (0.85 threshold β paraphrase-level leaks removed, not just exact matches), and hard examples mined by embedding geometry (benign prompts nearest the harmful cluster and vice versa) rather than keywords.
|
| 36 |
+
- **One model instead of five.** Binary harm, 9 harm categories, and jailbreak flags come from a single multilabel head in one forward pass.
|
| 37 |
+
|
| 38 |
+
## Benchmarks
|
| 39 |
+
|
| 40 |
+
All rows are **out-of-domain** (no split of these sets was trained on; the training blend was decontaminated against all of them) except Aegis, which is in-domain and marked as such. Default threshold Ο=0.5 unless noted. No cherry-picking: weak axes are shown and discussed in Limitations.
|
| 41 |
+
|
| 42 |
+
### Mixed sets (precision + recall)
|
| 43 |
+
|
| 44 |
+
| benchmark | F1 | F0.5 | P | R | n (+pos) |
|
| 45 |
+
|---|---|---|---|---|---|
|
| 46 |
+
| ToxicChat (test) | 36.4 | 37.1 | 37.5 | 35.4 | 5083 (+362) |
|
| 47 |
+
| OpenAI-Moderation | 54.8 | 57.5 | 59.4 | 51.0 | 1680 (+522) |
|
| 48 |
+
| ToxicConversations | 20.9 | 25.9 | 30.8 | 15.8 | 4000 (+311) |
|
| 49 |
+
| Aegis-2.0 (test, **in-domain**) | 78.7 | 77.9 | 77.4 | 80.0 | 1964 (+1059) |
|
| 50 |
+
|
| 51 |
+
### Over-refusal β false-positive rate on benign-but-scary prompts (lower = better)
|
| 52 |
+
|
| 53 |
+
| benchmark | FPR |
|
| 54 |
+
|---|---|
|
| 55 |
+
| OR-Bench (5,000 held-out, never trained on) | **0.8%** |
|
| 56 |
+
| OR-Bench-hard-1k | **1.9%** |
|
| 57 |
+
|
| 58 |
+
### Catch-rate on all-harmful sets (recall; precision undefined)
|
| 59 |
+
|
| 60 |
+
| benchmark | Ο=0.5 | Ο=0.02 |
|
| 61 |
+
|---|---|---|
|
| 62 |
+
| MaliciousInstruct | 79% | 89% |
|
| 63 |
+
| SimpleSafetyTests | 62% | β |
|
| 64 |
+
| do-not-answer | 56% | β |
|
| 65 |
+
| HarmfulQA | 53% | 69% |
|
| 66 |
+
| OR-Bench-toxic | 32% | 46% |
|
| 67 |
+
|
| 68 |
+
### Jailbreak (jackhhao/jailbreak-classification, test)
|
| 69 |
+
|
| 70 |
+
| F1 | P | R |
|
| 71 |
+
|---|---|---|
|
| 72 |
+
| 58.9 | 84.0 | 45.3 |
|
| 73 |
+
|
| 74 |
+
### Categories (Aegis-test, in-domain, 9 buckets)
|
| 75 |
+
|
| 76 |
+
Multilabel macro-P **74.4** / macro-R **46.6**; a correct category is predicted for **67%** of unsafe prompts.
|
| 77 |
+
|
| 78 |
+
## Choosing a threshold
|
| 79 |
+
|
| 80 |
+
The model is precision-first at the default Ο=0.5. Lowering Ο buys recall while the false-positive rate stays low (measured on the held-out OR-Bench slice):
|
| 81 |
+
|
| 82 |
+
| Ο | OR-Bench FPR | MaliciousInstruct catch | use case |
|
| 83 |
+
|---|---|---|---|
|
| 84 |
+
| 0.50 | 0.8% | 79% | max precision (default) |
|
| 85 |
+
| 0.15 | 1.5% | 82% | balanced |
|
| 86 |
+
| 0.02 | 2.4% | 89% | max recall |
|
| 87 |
+
|
| 88 |
+
```python
|
| 89 |
+
from model2vec.inference import StaticModelPipeline
|
| 90 |
+
import numpy as np
|
| 91 |
+
|
| 92 |
+
pipe = StaticModelPipeline.from_pretrained("bfuzzy1/Railz-Micro")
|
| 93 |
+
|
| 94 |
+
# default thresholds
|
| 95 |
+
pipe.predict(["how do I make a pipe bomb"]) # ['harmful', 'cat:violence_weapons', ...]
|
| 96 |
+
|
| 97 |
+
# custom threshold on P(harmful)
|
| 98 |
+
proba = np.asarray(pipe.predict_proba(["how do I make a pipe bomb"]))
|
| 99 |
+
harmful_idx = list(pipe.classes_).index("harmful")
|
| 100 |
+
flag = proba[:, harmful_idx] >= 0.15 # Ο of your choice
|
| 101 |
+
```
|
| 102 |
+
|
| 103 |
+
Labels: `harmful`, `jailbreak`, and `cat:{violence_weapons, hate_harassment, sexual, crime_drugs, cyber_fraud, misinfo, self_harm, privacy, advice}`.
|
| 104 |
+
|
| 105 |
+
## Recipe
|
| 106 |
+
|
| 107 |
+
1. **Vocab mining** β discriminative 1-3-grams from ~480k safety prompts, cleaned by 4 passes (cross-source robustness β₯2 datasets, proper-noun strip via mid-sentence capitalization, stopword-edge coherence, split-half stability) + curated jailbreak phrases and benign disambiguators + LDNOOBW lexicon β 3,864 phrases.
|
| 108 |
+
2. **Base distillation** β `model2vec.distill(embeddinggemma-300m, vocabulary=...)` β 260k-token static table, 256-dim, PCA + SIF.
|
| 109 |
+
3. **Data curation** β SemHash dedup (0.9) β decontamination vs all benchmarks (0.85) β boundary mining (0.6): 120k benign-near-harmful + 26k harmful-near-benign hard examples; jailbreak rows exempt from dedup (attack paraphrases are signal).
|
| 110 |
+
4. **Head training** β multilabel `StaticModelForClassification.fit` on 355k examples (28% harmful), β€15 epochs, early stopping.
|
| 111 |
+
|
| 112 |
+
Training data: Aegis-2.0, Salad-Data (+attack set β jailbreak labels), Nemotron content-safety, ToxiGen, RealToxicityPrompts, WildChat-1M (clean user turns), civil_comments, OR-Bench (train-negs only; 5k slice held out for the FPR eval above), XSTest.
|
| 113 |
+
|
| 114 |
+
## Limitations (honest ones)
|
| 115 |
+
|
| 116 |
+
- **Informal real-user chat is the weak axis** (ToxicChat ~36 F1, ToxicConversations ~21). Typos, slang, and context-dependent toxicity need composition a static model doesn't have.
|
| 117 |
+
- **Subtle / academically-phrased harm** (HarmfulQA-style) catches ~53-69% depending on Ο β phrase-sparse harm is hard for a lookup table.
|
| 118 |
+
- **Jailbreak recall is moderate (45% OOD)** at high precision (84%). Novel attack templates outside the mined phrase set fall back to subword averaging.
|
| 119 |
+
- **Prompt-level, English-only.** Does not score model responses; not tested on code-mixed or non-English input.
|
| 120 |
+
- **No deep composition.** Negation, sarcasm, multi-sentence intent are out of scope. For those, cascade: Railz-Micro filters at wire speed, escalate uncertain cases to a contextual guard (e.g. [Railz-R2](https://huggingface.co/bfuzzy1/Railz-R2)).
|
| 121 |
+
|
| 122 |
+
## Speed & footprint
|
| 123 |
+
|
| 124 |
+
Static embeddings + sklearn head: sub-ms per prompt single-threaded CPU, no GPU, no PyTorch at inference (`pip install model2vec[inference]`). 67M params.
|
| 125 |
+
|
| 126 |
+
## Part of the Railz family
|
| 127 |
+
|
| 128 |
+
| model | size | role |
|
| 129 |
+
|---|---|---|
|
| 130 |
+
| [Railz](https://huggingface.co/bfuzzy1/Railz) | 0.6B | policy-conditioned guard |
|
| 131 |
+
| [Railz-R](https://huggingface.co/bfuzzy1/Railz-R) | 0.6B | + reasoning |
|
| 132 |
+
| [Railz-R2](https://huggingface.co/bfuzzy1/Railz-R2) | 0.6B | + OOD robustness |
|
| 133 |
+
| **Railz-Micro** | **67M static** | **wire-speed multilabel prefilter** |
|
| 134 |
+
|
| 135 |
+
## Citation
|
| 136 |
+
|
| 137 |
+
Built with [Model2Vec](https://github.com/MinishLab/model2vec) by Minish Lab:
|
| 138 |
+
|
| 139 |
+
```
|
| 140 |
+
@software{minishlab2024model2vec,
|
| 141 |
+
author = {Stephan Tulkens and {van Dongen}, Thomas},
|
| 142 |
+
title = {Model2Vec: Fast State-of-the-Art Static Embeddings},
|
| 143 |
+
year = {2024},
|
| 144 |
+
publisher = {Zenodo},
|
| 145 |
+
doi = {10.5281/zenodo.17270888},
|
| 146 |
+
url = {https://github.com/MinishLab/model2vec},
|
| 147 |
+
license = {MIT}
|
| 148 |
+
}
|
| 149 |
+
```
|
config.json
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"normalize": true,
|
| 3 |
+
"embedding_dtype": "float32"
|
| 4 |
+
}
|
model.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:579048738b6ccaab56af284fb4f16aa6a74ced9d86fe71292809e8d96377cb94
|
| 3 |
+
size 266488920
|
modules.json
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[
|
| 2 |
+
{
|
| 3 |
+
"idx": 0,
|
| 4 |
+
"name": "0",
|
| 5 |
+
"path": ".",
|
| 6 |
+
"type": "sentence_transformers.models.StaticEmbedding"
|
| 7 |
+
},
|
| 8 |
+
{
|
| 9 |
+
"idx": 1,
|
| 10 |
+
"name": "1",
|
| 11 |
+
"path": "1_Normalize",
|
| 12 |
+
"type": "sentence_transformers.models.Normalize"
|
| 13 |
+
}
|
| 14 |
+
]
|
pipeline.skops
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:d09106086dafe8f21bf11980df657bc206a4060b0e41ac05b1326bafb0204fdb
|
| 3 |
+
size 3916238
|
tokenizer.json
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:42b42cd26bc92f8a39527672bfc3a84c620cbd46c43873a646a601166c33f9ec
|
| 3 |
+
size 13573897
|