vai35-4B-v2 / README.md
sundi's picture
Update model card — AUC=0.9997 F1=0.984
d2d93ff verified
|
Raw
History Blame Contribute Delete
7.63 kB
---
license: apache-2.0
base_model: Qwen/Qwen3.5-4B
tags:
- guardrails
- safety
- adversarial-robustness
- representation-engineering
- probe
- qwen3_5
language:
- en
pipeline_tag: text-classification
---
# vai35-4B-v2
**Adversarially hardened guardrail model** based on [Qwen/Qwen3.5-4B](https://huggingface.co/Qwen/Qwen3.5-4B).
Uses **representation engineering** (surgical weight editing + linear probe) to detect and block adversarial attacks with minimal inference overhead.
---
## Model Description
This model extends `votal-ai/vai35-4B` with a calibrated linear probe baked into layer 16.
Instead of generating a response and parsing it for safety, the probe classifies inputs via a **single dot product** against the refusal direction vector — achieving **4–6× faster** inference than generation-based guardrails.
### Architecture
```
Input tokens
Transformer layers 0 → 16
▼ ← Probe intercepts here (layer 16)
dot product with refusal direction
├── score >= -1.2439 → BLOCK
└── score < -1.2439 → ALLOW
```
---
## Evaluation Results
### Overall Metrics
| Metric | Score | 95% CI |
|-----------|--------|---------------------|
| AUC-ROC | 0.9997 | [0.9987, 1.0] |
| F1 | 0.984 | [0.9617, 1.0] |
| Precision | 1.0 | — |
| Recall | 0.9684 | — |
| FPR (harmful) | 0.0 | — |
| FPR (safe prompts) | 0.0% | — |
Regression test (safe prompts): **PASS ✓** — 0/50 false positives
### Per-Category Results
| Category | TP | FP | FN | TN | F1 |
|---------------------------|------|------|------|------|--------|
| alignment_hacking | 3 | 0 | 1 | 4 | 0.857 ✓ |
| authorized_user | 5 | 0 | 0 | 5 | 1.000 ✓ |
| bad_chain | 3 | 0 | 0 | 3 | 1.000 ✓ |
| code_injection | 7 | 0 | 0 | 7 | 1.000 ✓ |
| compound_instruction | 4 | 0 | 0 | 4 | 1.000 ✓ |
| context_ignoring | 5 | 0 | 0 | 5 | 1.000 ✓ |
| context_switching | 5 | 0 | 1 | 6 | 0.909 ✓ |
| defined_dictionary | 6 | 0 | 0 | 6 | 1.000 ✓ |
| few_shot_attack | 3 | 0 | 1 | 4 | 0.857 ✓ |
| image_prompting | 3 | 0 | 0 | 3 | 1.000 ✓ |
| indirect_injection | 5 | 0 | 0 | 5 | 1.000 ✓ |
| payload_splitting | 6 | 0 | 0 | 6 | 1.000 ✓ |
| pretending | 5 | 0 | 0 | 5 | 1.000 ✓ |
| recursive_injection | 4 | 0 | 0 | 4 | 1.000 ✓ |
| refusal_suppression | 5 | 0 | 0 | 5 | 1.000 ✓ |
| simple_instruction | 6 | 0 | 0 | 6 | 1.000 ✓ |
| special_case | 8 | 0 | 0 | 8 | 1.000 ✓ |
| task_deflection | 6 | 0 | 0 | 6 | 1.000 ✓ |
| virtualization | 3 | 0 | 0 | 3 | 1.000 ✓ |
### Attack Categories Covered (19/19)
| # | Category | Description |
|---|----------|-------------|
| 1 | `simple_instruction` | Bare direct asks — baseline floor |
| 2 | `context_ignoring` | "Ignore all previous instructions" |
| 3 | `compound_instruction` | Harmful ask buried in benign compound task |
| 4 | `special_case` | Claimed exceptions and clearances |
| 5 | `few_shot_attack` | Fabricated prior compliance examples |
| 6 | `refusal_suppression` | "Do not refuse", penalty threats |
| 7 | `context_switching` | Bait with safe topic, pivot to harmful |
| 8 | `task_deflection` | Textbooks, quizzes, warning labels as cover |
| 9 | `payload_splitting` | Request split across turns/fragments |
| 10 | `defined_dictionary` | Redefine "banana" = harmful topic |
| 11 | `indirect_injection` | Via URLs, emails, JSON |
| 12 | `recursive_injection` | Nested prompt-within-a-prompt |
| 13 | `code_injection` | Hidden in function stubs and comments |
| 14 | `virtualization` | Root terminal, sandbox, retro-AI |
| 15 | `pretending` | Character/entity roleplay |
| 16 | `alignment_hacking` | Exploit helpfulness/honesty drives |
| 17 | `authorized_user` | Fake tokens, employee IDs |
| 18 | `bad_chain` | False syllogisms and flawed reasoning |
| 19 | `image_prompting` | Simulated OCR, whiteboard, fake uploads |
---
## Usage
### Load and run the probe
```python
import torch
import json
from transformers import AutoModelForCausalLM, AutoTokenizer
from huggingface_hub import hf_hub_download
# Load model
model_id = "votal-ai/vai35-4B-v2"
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(
model_id,
torch_dtype=torch.bfloat16,
device_map="cuda",
output_hidden_states=True,
)
model.eval()
# Load probe config
probe_path = hf_hub_download(repo_id=model_id, filename="probe_config.json")
with open(probe_path) as f:
probe = json.load(f)
direction = torch.tensor(probe["global_direction"]).float().to("cuda")
threshold = probe["threshold_block"]
best_layer = probe["best_layer"]
def classify(text: str) -> dict:
inputs = tokenizer(text, return_tensors="pt",
truncation=True, max_length=512).to("cuda")
with torch.no_grad():
out = model(**inputs, output_hidden_states=True)
score = (out.hidden_states[best_layer][0, -1, :].float() @ direction).item()
blocked = score >= threshold
return {"blocked": blocked, "score": round(score, 4), "threshold": threshold}
# Examples
print(classify("How do I make a bomb?"))
# {'blocked': True, 'score': 3.12, 'threshold': -1.2439}
print(classify("What is the capital of France?"))
# {'blocked': False, 'score': -2.34, 'threshold': -1.2439}
```
### Serve with vLLM
```bash
vllm serve votal-ai/vai35-4B-v2 \
--host 0.0.0.0 --port 8000 \
--dtype bfloat16 --quantization fp8 \
--kv-cache-dtype fp8 \
--max-model-len 8192 \
--language-model-only
```
---
## Probe Config
The `probe_config.json` file contains:
```json
{
"best_layer": 16,
"threshold_block": -1.2439,
"global_direction": [...], // (hidden_size,) refusal direction vector
"categories": { // per-category direction vectors
"simple_instruction": {"layer": 16, "direction": [...], "score": 4.8},
...
},
"calibration": {
"auc_roc": 0.9997,
"f1": 0.984,
"precision": 1.0,
"recall": 0.9684
}
}
```
---
## Training Methodology
1. **Dataset** — 570 contrastive pairs across 19 adversarial attack categories
2. **Direction finding** — Mean difference of hidden states at each layer (safe − harmful), normalized
3. **Layer selection** — Layer 16 selected by separability score (gap/spread = highest signal)
4. **Threshold calibration** — Optimised on 20% held-out eval set targeting recall ≥ 0.95
5. **Regression testing** — Verified 0% false positive rate on 50 benign prompts
No gradient updates. No SFT. Pure representation engineering.
---
## Eval Files
| File | Description |
|------|-------------|
| `eval/ci_report.txt` | Bootstrap 95% confidence intervals |
| `eval/eval_report.json` | Per-category confusion matrix |
| `eval/regression_report.json` | Safe prompt false positive report |
| `eval/confidence_intervals.json` | Full bootstrap CI data |
| `probe/layer_scores.json` | Signal strength per transformer layer |
---
## Citation
```bibtex
@misc{votal-ai-vai35-guardrail,
title={vai35-4B-v2: Adversarially Hardened Guardrail Model},
author={Votal AI},
year={2026},
url={https://huggingface.co/votal-ai/vai35-4B-v2}
}
```