Text Generation
Transformers
Safetensors
ravenguard
guardrail
content-safety
moderation
multilingual
cross-lingual
multilingual-safety
agent-safety
custom_code
Instructions to use netis-ai/RavenGuard-gen with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use netis-ai/RavenGuard-gen with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="netis-ai/RavenGuard-gen", trust_remote_code=True)# Load model directly from transformers import AutoModelForCausalLM model = AutoModelForCausalLM.from_pretrained("netis-ai/RavenGuard-gen", trust_remote_code=True, device_map="auto") - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use netis-ai/RavenGuard-gen with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "netis-ai/RavenGuard-gen" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "netis-ai/RavenGuard-gen", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker
docker model run hf.co/netis-ai/RavenGuard-gen
- SGLang
How to use netis-ai/RavenGuard-gen with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "netis-ai/RavenGuard-gen" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "netis-ai/RavenGuard-gen", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "netis-ai/RavenGuard-gen" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "netis-ai/RavenGuard-gen", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }' - Docker Model Runner
How to use netis-ai/RavenGuard-gen with Docker Model Runner:
docker model run hf.co/netis-ai/RavenGuard-gen
File size: 14,364 Bytes
07bb941 a9816d4 07bb941 a9816d4 07bb941 a9816d4 07bb941 a9816d4 07bb941 a9816d4 07bb941 a9816d4 07bb941 0daf984 07bb941 2d2f68b 07bb941 2d2f68b 07bb941 2d2f68b 0daf984 a9816d4 07bb941 2d2f68b 752d194 8993dbf 752d194 07bb941 2d2f68b 07bb941 2d2f68b 07bb941 0daf984 31199ea 0daf984 752d194 0daf984 a9816d4 752d194 0daf984 07bb941 40ee3bf 07bb941 d1182f1 5be5643 8993dbf 40ee3bf 07bb941 40ee3bf 8993dbf d1182f1 8993dbf 40ee3bf 07bb941 40ee3bf 07bb941 d1182f1 40ee3bf 8993dbf 40ee3bf 8993dbf 40ee3bf d1182f1 8993dbf 07bb941 d1182f1 5be5643 31199ea 5be5643 8993dbf d1182f1 07bb941 5be5643 07bb941 5be5643 07bb941 752d194 40ee3bf d1182f1 8993dbf 752d194 07bb941 5be5643 752d194 8993dbf 5be5643 752d194 5be5643 752d194 5be5643 752d194 8993dbf 752d194 5be5643 07bb941 2d2f68b 07bb941 0daf984 07bb941 2d2f68b 07bb941 | 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 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 | ---
license: apache-2.0
language:
- en
- zh
- hi
- es
- ar
- bn
- pt
- ru
- ja
- de
- fr
- ko
- it
- vi
- th
- id
- sw
- jv
tags:
- guardrail
- content-safety
- moderation
- multilingual
- cross-lingual
- multilingual-safety
- agent-safety
pipeline_tag: text-generation
library_name: transformers
---
# RavenGuard-Gen β Multilingual Safety Guard for LLM Agents
**RavenGuard-Gen** is a compact, multilingual safety guard for LLM agents. Multilingual
support is a first-class design goal rather than an English model plus translated safety
examples: the tokenizer, pretraining mixture, backbone, safety taxonomy, and evaluation
protocol were built to handle different scripts and language families from the start.
RavenGuard is built on **Netis Amniota**, a decoder language model trained from random
initialisation by Netis rather than fine-tuned from a Qwen, Llama, or other existing
backbone. Its 65,536-entry tokenizer and NetisMix multilingual data recipe were developed
together with the model. Pretraining and mid-training processed more than **13.6B tokens**;
safety post-training processed approximately **4.5B tokens**, for more than **18B training
tokens in total**. This count is the cumulative number of tokens presented to the model,
including repeated post-training passes, not the size of a deduplicated source corpus.
The model officially covers **18 languages**: English, Chinese, Hindi, Spanish, Arabic,
Bengali, Portuguese, Russian, Japanese, German, French, Korean, Italian, Vietnamese, Thai,
Indonesian, Swahili, and Javanese. This includes right-to-left Arabic, non-segmented Thai,
CJK scripts, Indic scripts, and broad Southeast Asian coverage. The model is compact
(β0.8B) and is designed as a low-latency trust layer in front of enterprise LLM agents.
**RavenGuard-Gen** is a generative whole-input / whole-output guard. It reads a prompt or a
full response and, in a short greedy decode, emits a structured label block
(`Decision / Risk / Severity / Categories / Refusal`); the binary verdict is the `Severity`
line, and a reference soft score is the calibrated softmax at the `Severity` token (see
**Usage** below). Use it as a prompt filter or an end-of-response check.
> A companion **streaming** guard, RavenGuard-Stream β a per-token 3-way classification head
> on the same Netis Amniota backbone that flags harmful content *while it is being generated* β
> is released separately in its own repository. This card covers RavenGuard-Gen only.
Repository: [`netis-ai/RavenGuard-gen`](https://huggingface.co/netis-ai/RavenGuard-gen).
---
## Multilingual design and coverage
Multilingual guardrails are not solved by translating an English policy dataset. Languages
differ in writing direction, word-boundary conventions, morphology, tokenisation length,
regional usage, and the way harmful intent is expressed indirectly. These differences are
especially consequential for a 0.8B model: inefficient tokenisation consumes context and
model capacity before the safety decision is even made.
RavenGuard addresses this at three levels:
1. **Tokenizer and backbone:** the 65,536-entry tokenizer was trained for multilingual use
and is native to Netis Amniota; the released RavenGuard-Gen configuration uses 20 decoder
layers, a 1,280 hidden dimension, 10 attention heads, and a 2,048-token context window.
2. **Training recipe:** NetisMix introduces multilingual data during pretraining instead of
adding target languages only at the final safety-tuning stage. Safety post-training then
uses a shared severity and risk-category grammar across languages.
3. **Evaluation and calibration:** ChineseSafe measures Chinese safety directly; PolyGuard
compares all guards on the same 2,039 examples across 17 languages. Production thresholds
should still be calibrated per language and domain, on the deployment's own traffic.
The 18-language list above is the model's declared training coverage. PolyGuard's 17-language
set is a benchmark-specific evaluation slice and is not the product language list.
---
## Cross-model comparison
All comparisons below are computed on shared public benchmarks over **identical sample
sets** with identical gold labels and a common decision rule.
### Chinese safety β ChineseSafe (same 500-sample set, all models)

| Model | Size | F1 | Precision | Recall | FPR | AUROC Β² |
|---|---|---|---|---|---|---|
| **RavenGuard-Gen** | **0.8B** | **86.3** | 95.6 | 78.6 | 3.6 | **89.1** |
| Qwen3Guard-Gen-8B | 8B | 70.2 | 93.9 | 56.0 | 3.6 | β ΒΉ |
| Qwen3Guard-Gen-4B | 4B | 68.5 | 90.1 | 55.2 | 6.0 | β ΒΉ |
| Granite-Guardian-3.1-8B | 8B | 65.4 | 93.3 | 50.4 | 3.6 | 78.0 |
| ShieldGemma-9B | 9B | 46.2 | 97.4 | 30.2 | 0.8 | 77.8 |
| Llama-Guard-3-8B | 8B | 40.0 | 94.0 | 25.4 | 1.6 | 61.8 |
ΒΉ Qwen3Guard-Gen emits a categorical verdict with no probability, so a threshold-free AUROC
is not defined for it; every model that does emit a score is scored below.
Β² RavenGuard's AUROC is a reference metric: the calibrated softmax read at the generated
`Severity` token (the same score `guardbench` and `reproduce_eval.py` emit). Baseline AUROCs
are each model's own continuous score. Treat AUROC as a rough separability indicator, not the
headline β the usable comparison is F1/recall at a calibrated operating point.
RavenGuard-Gen leads every evaluated guard on Chinese F1 (by β₯16 points) at roughly one-tenth
the parameter count. Precision is uniformly high across guards; the gap is almost entirely
recall: the
8β9B guards catch only 25β56% of Chinese harm, RavenGuard 78.6%.

### General multilingual β PolyGuard response (same 2,039-sample set, 17 languages)

| Model | Size | F1 | Recall | FPR | AUROC Β² |
|---|---|---|---|---|---|
| Qwen3Guard-Gen-4B | 4B | 88.6 | 83.2 | 4.7 | β ΒΉ |
| Qwen3Guard-Gen-0.6B | 0.6B | 85.5 | 78.4 | 5.1 | β ΒΉ |
| **RavenGuard-Gen** | **0.8B** | **83.1** | 77.1 | 8.5 | 87.0 |
| Granite-Guardian-3.1-8B | 8B | 72.9 | 59.1 | 2.9 | 92.1 |
| Llama-Guard-3-8B | 8B | 70.3 | 55.0 | 1.5 | 93.3 |
| ShieldGemma-9B | 9B | 47.6 | 31.6 | 1.1 | 82.7 |
ΒΉ Qwen3Guard-Gen emits categorical verdicts (no probability β AUROC undefined).
Β² RavenGuard AUROC is the calibrated `Severity`-token read (reference only, see footnote Β² above);
baseline AUROCs are each model's own continuous score.
On **usable F1/recall**, RavenGuard-Gen (0.8B) sits with the Qwen generative guards at the top
(F1 83.1, recall 77.1) and far above the 8β9B guards, which catch only 32β59% of harm. On
threshold-free AUROC RavenGuard (87.0) reads a few points below the 8B guards (Granite 92.1,
Llama 93.3) β its edge is not raw separability but the recall-first operating point: the 8B
guards buy their low FPR (1β3%) by sitting at conservative operating points that discard most
of that recall, while RavenGuard's higher FPR here (8.5) is the flip side of keeping recall
high β the subject of the next section.
### RavenGuard on the full heldout (n=6,800)
| Model | AUROC Β³ | F1 | Recall | R@1% FPR Β³ | FPR | p50 latency |
|---|---|---|---|---|---|---|
| RavenGuard-Gen (0.8B) | 86.5 | 66.3 | 75.9 | 69.9 | 10.5 | ~372 ms |
Β³ AUROC and R@1%FPR here are the calibrated `Severity`-token figures β the same score source as
every other table in this card, and what `guardbench` reproduces. Treat them as reference
separability indicators; F1/Recall/FPR (read from the `Severity` line) are the usable
operating-point metrics.
FPR here (10.5%) is on PolyGuard's own benign responses, which include dual-use and borderline
content; it reflects the recall-tuned operating point rather than any particular deployment's
traffic. The p50 latency is the generative moderation call on an H200.
### Over-refusal: real traffic vs. adversarial benchmarks
"False-positive rate" depends entirely on how benign the benign set is:
- **OR-Bench-Toxic** (prompts that read as toxic but are benign): **0.0%** over-block.
- **XSTest** (crafted over-refusal probes): **5.6%** over-block.
- **PolyGuard heldout benign** (includes dual-use and borderline responses): a **6β16%**
per-language band.
The spread is deliberate: RavenGuard-Gen is tuned for harm recall, which raises
false-positives on adversarial benchmark-benign. How that operating point behaves on a given
deployment's traffic depends on that traffic β measure it before rollout, and calibrate the
per-language threshold to your own false-positive budget.
### Why RavenGuard does not chase the PolyGuard score
The PolyGuard table above rewards a specific behaviour: label its "benign" responses as safe.
But a large share of those responses are **dual-use** β a fluent, detailed answer to a
harmful-adjacent question (how a certain toxin acts on the body; how an exploit class works;
how a scam is structured) that the dataset marks benign because it reads educational. A guard
optimised to score well there learns to *let that content through*.
That is a policy choice disguised as a metric. Consider a concrete case: a detailed,
competent explanation of how to synthesise a controlled substance, framed as "for a
chemistry class." PolyGuard's benign label says *allow it*; a strict enterprise guard says
*flag it*. Counting the flag as a false-positive doesn't make the guard wrong β it makes the
benchmark's boundary more permissive than the deployment's.
You can see the cost of chasing the score in the same tables. The 8β9B guards post the lowest
PolyGuard FPR (1β3%) β and the lowest real recall: 25β56% on ChineseSafe, 32β59% on PolyGuard.
Their low false-positive rate is bought by being lenient on exactly the ambiguous content that
matters. RavenGuard's higher benchmark-FPR is not a capability gap but a deliberate
operating-point choice: it accepts a higher benchmark-FPR to keep recall high, where the 8B
guards sit conservative and discard recall. The choice of operating point is the product. What that
choice costs on real traffic is a property of the traffic, and is left to the deployment to
measure β see `release/REPRODUCE.md` for the harness and `docs/prodsim-v2-results.md` for a
worked measurement on public real-traffic data.
---
## Usage
RavenGuard-Gen ships as a self-contained `trust_remote_code` model (the custom backbone is
bundled in the repo). Weights are byte-faithful to the trained checkpoint. The guard reads a
prompt (or a prompt + response) under the policy prompt below and, in a short greedy decode,
emits a fixed label block:
```
Decision: <allow|block|rewrite|ask_clarification|require_approval|human_review>
Risk: <comma-separated risk names, or none>
Severity: <Safe|Controversial|Unsafe>
Categories: <comma-separated S-codes, or None>
Refusal: <Yes|No>
```
The **binary safe/unsafe verdict** is the generated `Severity` line β this is the deployment
decision. For a soft score (AUROC / threshold tuning) read the calibrated softmax at the
generated `Severity` token: P(Unsafe βͺ Controversial) vs P(Safe). Treat this as a
calibrated-severity read for reference, not a free-threshold ranking score.
```python
import os
os.environ.setdefault("NETIS_AMNIOTA_ATTN_BACKEND", "sdpa") # see "Runtime notes" below
from transformers import AutoModelForCausalLM
model = AutoModelForCausalLM.from_pretrained(
"netis-ai/RavenGuard-gen", trust_remote_code=True,
torch_dtype="float32").cuda().eval()
```
For the complete, self-contained inference recipe β the exact policy prompt, the greedy
decode, the label parse, and the `Severity`-token calibrated score β see **`reproduce_eval.py`
in this repo** (`Guard.classify`). It runs the model end to end with no `guardbench` install
and no network.
### Runtime notes (please read before running)
- **Attention backend:** set `NETIS_AMNIOTA_ATTN_BACKEND=sdpa`. The default FlashAttention-4
(CuTeDSL) path raises a `window_size_left` error on GPUs that support only FlashAttention-2
(e.g. consumer Blackwell / RTX 5090, sm_120). SDPA is portable and numerically identical.
- **Batch size 1 only, for now.** The bundled `forward` does not yet consume `attention_mask`,
so a left-padded batch would be scored **incorrectly and silently**. Moderate one sequence
at a time until the batched (`attention_mask` / KV-cache / `generate`) path is released.
- Runtime dependencies beyond `transformers`: `torch`, `tiktoken`, `rustbpe`, `filelock`.
## Intended use
RavenGuard-Gen performs input and output moderation: run it as a prompt filter before the
main model, as an end-of-response check before a reply reaches the user, or both. It suits
multilingual input/output moderation and end-of-turn checks, including Chinese-, Arabic-,
Spanish-, Portuguese-, Hindi-, and Thai-heavy workloads. For latency-sensitive streaming
deployments where harmful content must be interrupted mid-generation, pair it with the
companion RavenGuard-Stream model (released separately).
## Operating notes
- RavenGuard is a probabilistic classifier. Operating thresholds are calibrated per
language and should be re-calibrated to the target false-positive budget of each
deployment.
- Validate tokenisation, recall, and false-positive rates on the deployment's own language
varieties, code-switching patterns, and regional vocabulary. Declared language support
does not remove the need for domain-specific calibration and monitoring.
- Cross-model figures in this card are computed on shared public benchmarks (ChineseSafe
n=500, PolyGuard response n=2,039) with identical sample sets and gold labels.
## Evaluation methodology
All figures come from a reproducible harness (`guardbench`) with an `EVAL_ONLY` firewall
between training and test corpora, per-language threshold calibration, and threshold-free
capability metrics (AUROC, Recall@FPR). Cross-model comparisons are computed on identical id
sets with identical gold labels. See `docs/ravenguard-technical-report.md` for the full
protocol.
## Citation
```bibtex
@misc{ravenguard2026,
title = {RavenGuard: Multilingual Safety Guards for LLM Agents},
author = {netis},
year = {2026},
url = {https://huggingface.co/netis-ai/RavenGuard-gen}
}
```
|