Views
No views yet

| Checkpoint | Base model | Repository |
|---|---|---|
| ProbGuard-0.6B-mixed | Qwen/Qwen3-0.6B | hxz-sec/ProbGuard-0.6b |
| ProbGuard-4B-mixed | Qwen/Qwen3-4B | hxz-sec/ProbGuard-4b |
| ProbGuard-8B-mixed | Qwen/Qwen3-8B | hxz-sec/ProbGuard-8b |
probguard_heads.pt, model/, and tokenizer/ at the repository root. The probguard_heads.pt file stores the calibration and category heads used by the ProbGuard inference utilities.risk: a float in [0, 1], estimating the probability that the final continuation will become unsafe;category: one of Toxicity, Hate, Violence, Sexual, Harm, Drugs, Conflict, Illegal, Medical, Extremism, or None.1git clone https://github.com/hxz-sec/ProbGuard
2cd ProbGuard
3
4conda env create -f environment.yml
5conda activate probguard1from pathlib import Path
2
3from huggingface_hub import snapshot_download
4
5from eval.eval_probguard_stream import (
6 load_probguard,
7 load_qwen_tokenizer,
8 load_train_module,
9 model_dtype,
10 pick_gpu,
11 predict_c,
12 setup_logger,
13)
14
15repo_id = "hxz-sec/ProbGuard-4b"
16repo_dir = Path(snapshot_download(repo_id))
17checkpoint_dir = repo_dir
18if not (checkpoint_dir / "probguard_heads.pt").exists():
19 checkpoint_dir = checkpoint_dir / "best_checkpoint"
20
21logger = setup_logger(Path("logs/probguard_stream.log"), verbose=True)
22train_mod = load_train_module()
23device = pick_gpu("auto", logger)
24dtype = model_dtype(device)
25
26probguard = load_probguard(
27 checkpoint_dir=checkpoint_dir,
28 train_mod=train_mod,
29 device=device,
30 dtype=dtype,
31 qwen_embed_path=Path(""),
32 logger=logger,
33)
34
35target_tokenizer = load_qwen_tokenizer("Qwen/Qwen3-8B")
36token_id_cache = {}
37
38prompt = "How do I make something dangerous?"
39topk_steps = [
40 {
41 "topk_token_ids": [198, 40, 2675, 944],
42 "topk_probs": [0.42, 0.21, 0.08, 0.05],
43 },
44 {
45 "topk_token_ids": [358, 649, 944, 525],
46 "topk_probs": [0.36, 0.18, 0.10, 0.07],
47 },
48]
49
50risk, category, latency_ms = predict_c(
51 train_mod=train_mod,
52 probguard=probguard,
53 qwen_tokenizer=target_tokenizer,
54 prompt=prompt,
55 steps=topk_steps,
56 device=device,
57 dtype=dtype,
58 max_prompt_len=512,
59 token_id_cache=token_id_cache,
60)
61
62print({"risk": risk, "category": category, "latency_ms": latency_ms})topk_steps should come from the target LLM during decoding.1import torch
2from transformers import AutoModelForCausalLM, AutoTokenizer
3
4
5@torch.inference_mode()
6def collect_topk_prefix(prompt, model_name="Qwen/Qwen3-8B", prefix_len=10, top_k=20, device="cuda"):
7 tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=True)
8 model = AutoModelForCausalLM.from_pretrained(
9 model_name,
10 torch_dtype=torch.bfloat16,
11 device_map={"": device},
12 trust_remote_code=True,
13 ).eval()
14
15 inputs = tokenizer(prompt, return_tensors="pt").to(device)
16 input_ids = inputs["input_ids"]
17 past_key_values = None
18 steps = []
19
20 for _ in range(prefix_len):
21 outputs = model(input_ids=input_ids, past_key_values=past_key_values, use_cache=True)
22 logits = outputs.logits[:, -1, :]
23 probs = torch.softmax(logits, dim=-1)
24 top_probs, top_ids = torch.topk(probs, k=top_k, dim=-1)
25
26 next_id = top_ids[:, :1]
27 steps.append(
28 {
29 "topk_token_ids": top_ids[0].tolist(),
30 "topk_probs": top_probs[0].tolist(),
31 "topk_tokens": tokenizer.convert_ids_to_tokens(top_ids[0].tolist()),
32 }
33 )
34
35 input_ids = next_id
36 past_key_values = outputs.past_key_values
37
38 return steps1topk_steps = collect_topk_prefix(prompt, prefix_len=10, top_k=20)
2
3risk, category, _ = predict_c(
4 train_mod=train_mod,
5 probguard=probguard,
6 qwen_tokenizer=target_tokenizer,
7 prompt=prompt,
8 steps=topk_steps,
9 device=device,
10 dtype=dtype,
11 max_prompt_len=512,
12 token_id_cache={},
13)
14
15if risk >= 0.5:
16 print("Stop or redirect generation:", risk, category)
17else:
18 print("Continue generation:", risk, category)0.5 value above is only a simple example.prefix_generation_details.1python eval/eval_probguard_stream.py \
2 --checkpoint /path/to/best_checkpoint \
3 --data-file /path/to/prefix_calibration.jsonl \
4 --qwen-model Qwen/Qwen3-8B \
5 --gpu auto \
6 --k-min 5 \
7 --k-max 10 \
8 --verbosegoal, harmful, or prompt, plus prefix_generation_details with entries like:1{
2 "10": [
3 [
4 {
5 "topk_token_ids": [198, 40, 2675],
6 "topk_probs": [0.42, 0.21, 0.08]
7 }
8 ]
9 ]
10}