Views
No views yet
meta-llama/Llama-3.1-8B backbone. Implements SIREN (LLM Safety From Within: Detecting Harmful Content with Internal Representations, ACL 2026).[0, 1].pip install llm-sirensiren_guard runtime (llm-siren on PyPI). Trained backbone weights are pulled from Hugging Face on first use.1import torch
2from siren_guard import SirenGuard
3
4guard = SirenGuard.from_pretrained(
5 "UofTCSSLab/SIREN-Llama-3.1-8B",
6 device="cuda",
7 dtype=torch.bfloat16,
8)
9
10# Prompt-level moderation
11result = guard.score("How can I make a pipe bomb at home?")
12print(result.score, result.is_harmful) # e.g. 1.0 True
13
14# Response-level moderation (prompt + response, joined as the model was trained)
15result = guard.score(
16 prompt="How can I make a pipe bomb at home?",
17 response="I can't help with that. Building explosive devices is illegal and dangerous.",
18)
19print(result.score, result.is_harmful) # e.g. 0.0 False
20
21# Batch
22results = guard.score_batch([
23 "What is the capital of France?",
24 "Describe in detail how to commit insurance fraud.",
25])
26
27# Streaming — feed the growing assistant text after each generation chunk
28prefix = ""
29for chunk in stream_from_deployed_llm(user_prompt):
30 prefix += chunk
31 if guard.score_streaming(prefix, threshold=0.5).is_harmful:
32 abort_generation()
33 break
34
35# Custom threshold
36strict = guard.score(text, threshold=0.1) # block at 10% predicted harmfulness
37loose = guard.score(text, threshold=0.9) # block only at 90%1def safe_generate(user_prompt: str, deployed_llm) -> str:
2 if guard.score(user_prompt).is_harmful:
3 return DEFAULT_REFUSAL
4
5 response = deployed_llm.generate(user_prompt)
6
7 if guard.score(prompt=user_prompt, response=response).is_harmful:
8 return DEFAULT_REFUSAL
9
10 return responsedeployed_llm) can be any model.SirenGuard.from_pretrained(repo_id_or_path, device=None, dtype=torch.bfloat16, cache_dir=None)
Loads the SIREN classifier head from the artifact and the frozen Llama-3.1-8B backbone from its pinned revision.score(text=None, *, prompt=None, response=None, threshold=None) -> ScoreResult
Score a single string. Pass text= for raw moderation, or prompt=/response= for the response-level form (the library joins them with "\n", matching the SIREN training distribution).score_batch(texts, threshold=None) -> list[ScoreResult]
Score a list of strings in one forward pass.score_streaming(response_so_far, threshold=None) -> ScoreResult
Score a growing assistant-side text prefix during generation. Returns the score for the prefix as a whole.ScoreResult(score: float, is_harmful: bool, threshold: float).0.5, matching the binary decision boundary used during training. Tune it to your deployment's safety policy.| File | Purpose |
|---|---|
siren_config.json | Pinned base-model revision, selected layers, layer weights, per-layer safety-neuron indices, MLP architecture, inference defaults. |
siren.safetensors | Trained MLP classifier weights (~55.9M params). |
meta-llama/Llama-3.1-8B at the pinned commit specified in siren_config.json on first use, then cached locally.| ToxicChat | OpenAIMod | Aegis | Aegis 2 | WildGuard | SafeRLHF | BeaverTails | Avg. |
|---|---|---|---|---|---|---|---|
| 83.1 | 92.0 | 82.9 | 82.9 | 86.7 | 92.5 | 83.8 | 86.3 |
1@article{jiao2026llm,
2 title={LLM Safety From Within: Detecting Harmful Content with Internal Representations},
3 author={Jiao, Difan and Liu, Yilun and Yuan, Ye and Tang, Zhenwei and Du, Linfeng and Wu, Haolun and Anderson, Ashton},
4 journal={arXiv preprint arXiv:2604.18519},
5 year={2026}
6}