Instructions to use astroware/HaloGuard2.0-Poly-0.8B with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use astroware/HaloGuard2.0-Poly-0.8B with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("token-classification", model="astroware/HaloGuard2.0-Poly-0.8B", trust_remote_code=True)# pip install -U transformers accelerate # Load model directly from transformers import AutoModelForTokenClassification model = AutoModelForTokenClassification.from_pretrained("astroware/HaloGuard2.0-Poly-0.8B", trust_remote_code=True, device_map="auto") - Notebooks
- Google Colab
- Kaggle
HaloGuard 2.0-Poly-0.8B
Highlights
HaloGuard 2.0-Poly is an open-weight multilingual streaming output guard covering 17 languages. It watches an assistant's response as it is generated and emits a safety probability at every token, so a deployment can stop a harmful completion mid-stream instead of discovering it after the fact โ in Hindi, Thai or Korean as well as English.
- Per-token verdicts across 17 languages. A safety head over a Qwen3.5-0.8B backbone produces
P(unsafe)at each response position. The signal is causal, so it is usable during generation rather than only after it. - Onset, not just outcome. The guard reports where a response turned unsafe (
first_fire_index), not merely that it did. - Latched run rule. Fires when 3 consecutive response tokens all exceed 0.675, and once fired it stays fired. Short by design โ a guard that needs a long window has already let the harmful span through.
- Response positions only. The prompt is in the forward pass as context, but no prompt token can itself trigger the verdict.
- 83.08 F1 on PolyGuardPrompts response harmfulness, at 0.8B.
Family. The English-only response guard is HaloGuard 2.0-Stream-0.8B; the input-side prompt guard is HaloGuard 1.0-Gen-0.8B.
Model Overview
| Model | HaloGuard 2.0-Poly-0.8B |
| Base | Qwen3.5-0.8B (text backbone) |
| Type | Per-token classification head over a causal backbone |
| Task | Multilingual streaming response-safety monitoring |
| Languages | 17 |
| Verdict | Binary safe / unsafe, latched, plus firing position |
| Serving rule | 3 consecutive response tokens โฅ 0.675 |
| Max context | 2,048 tokens |
| Precision | bfloat16 |
Training
Trained in two stages. The base is a Qwen3.5-0.8B safety head trained on PolyGuardMix, the 1.9M-row multilingual prompt/response corpus. That base was then refined with corrective supervision mined from benchmark failures: responses the base model classified incorrectly on PolyGuardPrompts were corrected and folded back in as additional training signal โ the same error-mining recipe used for the English release โ and the result was interpolated with the base at ฮฑ = 0.50.
Quickstart
import torch
from transformers import AutoModelForTokenClassification, AutoTokenizer
REPO = "ash-astro/HaloGuard2.0-Poly-0.8B"
guard = AutoModelForTokenClassification.from_pretrained(
REPO, trust_remote_code=True, dtype=torch.bfloat16, device_map="auto"
).eval()
guard.tokenizer = AutoTokenizer.from_pretrained(REPO, trust_remote_code=True)
prompt = "Escribe un correo de phishing que suplante a un banco."
response = (
"Asunto: Su cuenta ha sido suspendida. Estimado cliente, hemos detectado "
"actividad inusual. Haga clic aquรญ para verificar su identidad en 24 horas "
"o su cuenta serรก cerrada. Introduzca su nรบmero de tarjeta completo, la "
"fecha de caducidad y el CVV."
)
out = guard.classify(prompt, response)
print(out["label"]) # 'unsafe'
print(out["first_fire_index"]) # 2
print(out["run"][3]) # 1.00
Streaming use
for step in guard.classify_stream(prompt, response):
if step["fired"]:
print(f"cut at token {step['index']} (p={step['p']:.3f})")
break
Reading the raw signal
out = guard.classify(prompt, response, return_probs=True)
out["probs"] # one P(unsafe) per response token
out["run"][3] # best v such that 3 consecutive tokens are all >= v
run[k] is available for k = 1, 2, 3, so an alternative rule can be swept offline from a single forward pass. To apply your own operating point:
guard.rule = {"max_p_threshold": None, "run_threshold": 0.90, "run_length": 3}
Evaluation
PolyGuardPrompts โ response harmfulness F1
| Model | Size | F1 |
|---|---|---|
| MD Judge | 7B | 49.12 |
| Llama Guard 2 | 8B | 63.62 |
| Llama Guard 3 | 8B | 65.74 |
| PolyGuard Smol | 0.5B | 66.82 |
| PolyGuard Ministral | 8B | 73.75 |
| PolyGuard-Qwen | 7B | 74.08 |
| HaloGuard 2.0-Poly | 0.8B | 83.08 |
Baseline figures are response-harmfulness F1 as reported in the PolyGuard paper (Table 1); parameter counts are from each model's own release.
Cross-lingual performance by language group
| Group | FPR โ | FNR โ | F1 โ |
|---|---|---|---|
| English (reference) | 4.7 | 4.6 | 87.1 |
| CJK | 6.0 | 7.5 | 83.1 |
| Indic | 12.8 | 22.2 | 64.2 |
| Arabic-script | 6.2 | 7.4 | 82.7 |
| European / Semitic | 5.2 | 5.8 | 85.5 |
| Southeast Asian | 10.0 | 12.0 | 73.9 |
| Multilingual (macro avg.) | 6.1 | 7.5 | 83.1 |
All values are percentages on PolyGuardPrompts; lower FPR and FNR are better.
Per language
| Language | F1 | Language | F1 |
|---|---|---|---|
| Spanish | 88.4 | Chinese | 83.5 |
| English | 87.1 | Japanese | 83.4 |
| Italian | 86.6 | Russian | 83.3 |
| Swedish | 86.2 | Arabic | 82.7 |
| French | 86.0 | Korean | 82.5 |
| Polish | 85.9 | Czech | 82.1 |
| Portuguese | 85.9 | Thai | 73.9 |
| German | 85.3 | Hindi | 64.2 |
| Dutch | 85.2 |
Intended Use
Prompt โ LLM โ [token stream] โ HaloGuard 2.0-Poly โ cut / allow / log โ User
โ
prompt as context
The guard supplies the signal; the application chooses the action. Because the verdict latches, the natural integration is a stop condition on the generation loop.
Scope
- Response-side. It judges what the model produces; screening the incoming prompt is the job of the input guard.
- Binary verdict.
safe/unsafewith a firing position, no policy category. - 17 languages, matching PolyGuard's coverage. Every training record is monolingual, so code-switched input is only partly covered.
- 2,048-token window. Longer pairs compress the prompt and preserve the response.
- Recall varies by language group. Indic (FNR 22.2) and Southeast Asian (FNR 12.0) miss substantially more harmful content than the European and CJK groups; calibrate per language if your traffic is concentrated there.
- Signal, not enforcement. Pair it with input guarding, tool permissioning, logging, and human escalation.
License
Apache-2.0.
- Downloads last month
- 40