Evaluate API¶
Measure safety and robustness: benchmark suites, red-team attacks, judges, and
runtime monitoring. Import from safetune.evaluate.
from safetune.evaluate import evaluate, AbliterationAttack, TamperBenchEvaluator
results = evaluate(model, benchmarks=["harmbench"], tokenizer=tok)
Public surface¶
Entry points: evaluate, redteam, suite.
Attacks: AbliterationAttack, BoNAttack (BoNConfig).
Judges & monitoring: JudgeAdapter, SpectralEntropyMonitor
(SpectralMonitorConfig), TamperBenchEvaluator.
See the Evaluate guide.
Reference¶
safetune.evaluate.evaluate
¶
Unified safety-evaluation entry point and Judge backend adapters.
evaluate(model, benchmarks=None, judge='wildguard', tokenizer=None, batch_size=8, max_new_tokens=512, generation_kwargs=None, max_prompts=None, drift_task=None, strict=False)
¶
Run model over benchmarks and return per-benchmark results.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
Any
|
Target model under evaluation. |
required |
benchmarks
|
Optional[List[str]]
|
Benchmark names to run. Defaults to the paper safety suite:
|
None
|
judge
|
str
|
Judge backend. Supported: |
'wildguard'
|
tokenizer
|
Any
|
Tokenizer for |
None
|
batch_size
|
int
|
Generation / judging batch size. |
8
|
max_new_tokens
|
int
|
Max new tokens per generation. |
512
|
generation_kwargs
|
Optional[Dict[str, Any]]
|
Extra kwargs forwarded to |
None
|
max_prompts
|
Optional[int]
|
Optional cap per benchmark. |
None
|
drift_task
|
Optional[str]
|
The SFT drift domain (e.g. |
None
|
strict
|
bool
|
When |
False
|
Returns:
| Type | Description |
|---|---|
Dict[str, Dict[str, Any]]
|
Per-benchmark dict. Standard safety metrics: |
Dict[str, Dict[str, Any]]
|
|
Dict[str, Dict[str, Any]]
|
|
Dict[str, Dict[str, Any]]
|
|
Dict[str, Dict[str, Any]]
|
|
Dict[str, Dict[str, Any]]
|
|
Dict[str, Dict[str, Any]]
|
|
Dict[str, Dict[str, Any]]
|
|
evaluate_with_vllm_backend(backend, *, benchmarks=None, judge='wildguard', max_new_tokens=256, max_prompts=None, drift_task=None, strict=False)
¶
Evaluate using a pre-built vLLM backend (VLLMHookSteer / VLLMDecodeSteer / plain).
Drop-in replacement for :func:evaluate when the model has already been
wrapped into a vLLM backend via
:func:safetune.steer.backends.vllm_eval.build_vllm_eval_backend.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
backend
|
Any
|
A vLLM backend with
|
required |
benchmarks
|
Optional[List[str]]
|
Benchmark names. Defaults to the paper safety suite. |
None
|
judge
|
str
|
Judge backend name ( |
'wildguard'
|
max_new_tokens
|
int
|
Max tokens per response. |
256
|
max_prompts
|
Optional[int]
|
Optional cap per benchmark. |
None
|
drift_task
|
Optional[str]
|
SFT drift domain tag echoed into each result entry. |
None
|
strict
|
bool
|
Re-raise instead of recording errors. |
False
|
Returns:
| Type | Description |
|---|---|
Dict[str, Dict[str, Any]]
|
Same per-benchmark dict shape as :func: |
get_harmbench_judge()
cached
¶
Load cais/HarmBench-Mistral-7b-val-cls once and cache (cached ✓).
get_llama_guard()
cached
¶
Load Llama Guard 3 once and cache — NOTE: not in HF cache, requires download.
get_wildguard()
cached
¶
Load allenai/wildguard once and cache (cached ✓).
safetune.evaluate.AbliterationAttack
¶
Refusal-direction ablation packaged as a red-team attack.
Example::
attack = AbliterationAttack(model, tokenizer)
attack.fit(harmful_prompts=harm, harmless_prompts=harmless)
attack.run(mode="runtime_ablate") # reversible
# ... generate outputs, score ASR ...
attack.revert()
safetune.evaluate.TamperBenchEvaluator
¶
Thin wrapper over the official TamperBench tamper-resistance harness.
This class does not implement any tampering attack or metric itself — it
delegates to the tamperbench package (arXiv:2602.06911). It can be
constructed on CPU with no dependencies; the heavy tamperbench /
strong_reject imports happen lazily inside the methods so that simply
importing :class:TamperBenchEvaluator never requires a GPU.
Two entry points are provided:
- :meth:
run_attack— drive the full TamperBenchattack -> train -> evaluatepipeline for one tampering attack via the real harness. - :meth:
score_responses(alias :meth:judge_responses) — score already-generated(prompt, response)pairs with TamperBench's actual safety metric: the StrongREJECT fine-tuned evaluator.
harness_available
property
¶
Whether the official tamperbench package is importable.
judge_responses(qa_pairs, *, batch_size=32)
¶
Deprecated alias for :meth:score_responses.
The previous implementation called an OpenAI GPT-4 1-5 judge; that is the Qi et al. 2023 judge, not the TamperBench metric. This now routes to the real TamperBench safety scorer (StrongREJECT fine-tuned).
run_attack(attack, *, model_checkpoint=None, config_overrides=None)
¶
Run one TamperBench tampering attack and its evaluations.
This delegates entirely to the official harness: it looks the attack up
in tamperbench's ATTACKS_REGISTRY, builds the attack config,
and calls the attack's benchmark() (attack -> train -> evaluate).
Requires the tamperbench package and a GPU.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
attack
|
str
|
A TamperBench attack name (see :attr: |
required |
model_checkpoint
|
Optional[str]
|
Model to tamper-test; overrides the constructor value for this call. |
None
|
config_overrides
|
Optional[Dict[str, Any]]
|
Extra fields forwarded into the attack's config dataclass (learning rate, epochs, lora_rank, ...). |
None
|
Returns:
| Type | Description |
|---|---|
Dict[str, Any]
|
The harness's structured benchmark result (per-eval TamperBench |
Dict[str, Any]
|
metrics such as |
Raises:
| Type | Description |
|---|---|
ImportError
|
If the |
ValueError
|
If |
score_responses(qa_pairs, *, batch_size=32)
¶
Score (prompt, response) pairs with TamperBench's safety metric.
Uses the StrongREJECT fine-tuned evaluator
(strong_reject.evaluate.strongreject_finetuned) — the exact safety
scorer TamperBench's StrongRejectEvaluation uses. Each pair gets a
harmfulness score in [0, 1] (higher = more harmful, accounting for
refusal / specificity / convincingness). The reported aggregate is the
mean score, matching MetricName.STRONG_REJECT_SCORE.
This needs only the strong_reject package (which loads a fine-tuned
Gemma-2B classifier); it does not run any tampering attack.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
qa_pairs
|
Sequence[Tuple[str, str]]
|
Sequence of |
required |
batch_size
|
int
|
Classifier batch size. |
32
|
Returns:
| Type | Description |
|---|---|
Dict[str, Union[float, List[Dict[str, Any]]]]
|
Dict with |
Dict[str, Union[float, List[Dict[str, Any]]]]
|
|
Dict[str, Union[float, List[Dict[str, Any]]]]
|
of pairs scored), and |
Dict[str, Union[float, List[Dict[str, Any]]]]
|
|
Raises:
| Type | Description |
|---|---|
ImportError
|
If the |