minar-svn commited on
Commit
adf0a72
·
verified ·
1 Parent(s): d8b4733

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. README.md +42 -138
README.md CHANGED
@@ -5,210 +5,114 @@ language:
5
  - en
6
  tags:
7
  - cybersecurity
8
- - detection-engineering
9
- - threat-detection
10
  - soc-triage
11
- - qwen
12
- - qwen3
13
  - qlora
14
  - peft
15
- - security
16
- - malware-detection
17
  pipeline_tag: text-generation
18
  library_name: peft
19
  ---
20
 
21
  # ThreatQwen-1.7B-Detect
22
 
23
- A QLoRA fine-tune of **Qwen3-1.7B-Instruct** for **cybersecurity event triage**.
24
-
25
- Given a raw security event (Sysmon, CloudTrail, HTTP log, etc.), the model returns a structured JSON verdict classifying the event as **malicious** or **benign**.
26
-
27
- ---
28
 
29
  ## Results
30
 
31
- Evaluated on a balanced held-out test set of **882 samples (441 malicious + 441 benign)**,
32
- same examples presented to all models:
33
-
34
- | Model | Size | Accuracy | Mal. Recall | Ben. Recall | Macro F1 |
35
- |---|---|---|---|---|---|
36
- | **ThreatQwen-1.7B-Detect (ours)** | **1.7B** | **98.1%** | **96.1%** | **100.0%** | **0.981** |
37
- | Base Qwen3-1.7B (no fine-tune) | 1.7B | 85.1% | 92.1% | 78.2% | 0.851 |
38
- | GPT-4o (Azure, zero-shot) | ~200B+ | 51.8% | 85.0% | 18.6% | 0.458 |
39
- | GPT-4o-mini (Azure, zero-shot) | ~8B | 51.9% | 59.6% | 44.2% | 0.516 |
40
 
41
- **Fine-tuning improves the base model by +13 percentage points.**
42
- **ThreatQwen-1.7B outperforms GPT-4o by +46.3 percentage points on this task.**
43
-
44
- ---
 
 
45
 
46
- ## What Changed from v1 (ThreatQwen-1.5B-Detect)
47
-
48
- - Upgraded base model from Qwen2.5-Coder-1.5B → **Qwen3-1.7B**
49
- - Benign recall improved from **0% → 100%** via:
50
- - 4x benign oversampling during training
51
- - Removal of severity field (was causing data leakage)
52
- - 1,500 additional GPT-4o-generated benign examples covering Windows,
53
- web, email, database, and VPN/remote-access activity
54
- - Output schema simplified to verdict-only JSON (removed MITRE field —
55
- 63.9% of training examples had empty MITRE arrays)
56
- - MAX_SEQ_LEN reduced 1024 → 512 (covers 100% of data, 2x faster training)
57
- - Full test set evaluation: 882 samples vs 50 in v1
58
-
59
- ---
60
 
61
  ## Output Schema
62
 
63
  ```json
64
- {
65
- "verdict": "malicious | benign"
66
- }
67
  ```
68
 
69
- ---
70
-
71
  ## Training
72
 
73
  | Parameter | Value |
74
  |---|---|
75
  | Base model | unsloth/Qwen3-1.7B-unsloth-bnb-4bit |
76
- | Method | QLoRA (4-bit NF4) |
77
  | LoRA rank / alpha | 16 / 32 |
78
- | Target modules | q/k/v/o_proj, gate/up/down_proj |
79
  | Epochs | 3 |
80
- | Batch size | 4 (grad accum 4, effective batch 16) |
81
- | Learning rate | 2e-4 (cosine schedule) |
82
- | MAX_SEQ_LEN | 512 tokens |
83
  | Hardware | Tesla T4 (Kaggle free tier) |
84
- | Training time | ~10 minutes |
85
-
86
- ---
87
 
88
  ## Dataset
89
 
90
- Training data combines:
91
-
92
- | Source | Type | Examples |
93
- |---|---|---|
94
- | SigmaHQ detection rules | Real malicious | ~1,968 |
95
- | Elastic Detection Rules | Real malicious | ~1,358 |
96
- | Nuclei Templates | Real malicious | ~2,497 |
97
- | synthetic_benign | Synthetic benign | ~1,255 |
98
- | synthetic_web_benign | Synthetic benign | ~1,000 |
99
- | synthetic_ambiguous | Mixed | ~376 |
100
- | GPT-4o generated (Windows) | Synthetic benign | ~499 |
101
- | GPT-4o generated (Web) | Synthetic benign | ~500 |
102
- | GPT-4o generated (Email/DB/VPN) | Synthetic benign | ~989 |
103
-
104
- After deduplication and cleaning: **~9,400 unique examples**.
105
-
106
- ---
107
 
108
  ## Deployment
109
 
110
- - Runs fully **offline** — no internet required (air-gapped SOC capable)
111
- - **~3.1 GB VRAM** at inference (4-bit quantized)
112
- - **~18 tokens/sec** on Tesla T4
113
- - **~5–7 sec/event** end-to-end latency
114
- - Adapter size: **~434 MB**
115
- - Minimum GPU: RTX 3060 (8 GB VRAM) or equivalent
116
-
117
- ---
118
 
119
  ## Usage
120
 
121
  ```python
122
  from transformers import AutoModelForCausalLM, AutoTokenizer
123
  from peft import PeftModel
124
- import torch, json, re
125
 
126
- # Load base + adapter
127
  base = AutoModelForCausalLM.from_pretrained(
128
  "unsloth/Qwen3-1.7B-unsloth-bnb-4bit",
129
- torch_dtype = torch.float16,
130
- device_map = "auto",
131
  )
132
- model = PeftModel.from_pretrained(base, "minar-svn/ThreatQwen-1.7B-Detect")
133
  tokenizer = AutoTokenizer.from_pretrained("minar-svn/ThreatQwen-1.7B-Detect")
134
 
135
- SYSTEM_PROMPT = """You are a cybersecurity detection model.
136
- Respond ONLY with valid JSON — no markdown, no explanations, no extra text.
137
 
138
- Format:
139
- {
140
- "verdict": "malicious | benign"
141
- }
142
- """
143
-
144
- event = """EventID: 1 (Process Creation)
145
- Image: C:\\Windows\\System32\\rundll32.exe
146
- ParentImage: C:\\Windows\\System32\\cmd.exe
147
- CommandLine: rundll32.exe C:\\Windows\\System32\\comsvcs.dll MiniDump 624 C:\\temp\\lsass.dmp full
148
- User: admin"""
149
-
150
- messages = [
151
- {"role": "system", "content": SYSTEM_PROMPT},
152
- {"role": "user", "content": f"Analyze this security event:\n\n{event}"},
153
- ]
154
-
155
- prompt = tokenizer.apply_chat_template(
156
- messages, tokenize=False, add_generation_prompt=True
157
- ).strip()
158
 
 
 
159
  inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
 
160
  with torch.no_grad():
161
- out = model.generate(
162
- **inputs,
163
- max_new_tokens = 80,
164
- do_sample = False,
165
- repetition_penalty = 1.02,
166
- pad_token_id = tokenizer.eos_token_id,
167
- )
168
-
169
- response = tokenizer.decode(
170
- out[0][inputs["input_ids"].shape[1]:],
171
- skip_special_tokens=True,
172
- ).strip()
173
-
174
- # Clean and parse
175
- for tok in ["<think>", "</think>", "```json", "```"]:
176
- response = response.replace(tok, "")
177
- response = response.strip()
178
- blocks = [b.strip() for b in response.split("\n\n") if b.strip()]
179
- response = blocks[-1] if blocks else response
180
 
181
- result = json.loads(response)
182
- print(result)
183
- # Output: {"verdict": "malicious"}
 
184
  ```
185
 
186
- ---
187
-
188
  ## Limitations
189
 
190
- - All benign training examples are synthetic — real-world benign generalization is untested
191
- - Best on structured log formats (Sysmon, CloudTrail, HTTP); degrades on free-form text
192
  - English only
193
- - Should be used as an analyst aid, not as a sole decision authority
194
- - May over-flag Windows administrative utilities that share patterns with LOLBAS abuse
195
-
196
- ---
197
 
198
  ## Citation
199
 
200
  ```bibtex
201
  @misc{threatqwen2026,
202
  author = {Md. Minaruzzaman Shovon},
203
- title = {ThreatQwen-1.7B-Detect: A Small Open-Source LLM for Cybersecurity Event Triage},
204
  year = {2026},
205
  publisher = {Hugging Face},
206
  url = {https://huggingface.co/minar-svn/ThreatQwen-1.7B-Detect}
207
  }
208
  ```
209
 
210
- ---
211
-
212
  ## License
213
-
214
- Apache 2.0 — inherits from the Qwen3 base model.
 
5
  - en
6
  tags:
7
  - cybersecurity
 
 
8
  - soc-triage
9
+ - threat-detection
 
10
  - qlora
11
  - peft
12
+ - qwen3
 
13
  pipeline_tag: text-generation
14
  library_name: peft
15
  ---
16
 
17
  # ThreatQwen-1.7B-Detect
18
 
19
+ A QLoRA fine-tune of **Qwen3-1.7B-Instruct** for cybersecurity event triage. Given a raw security event (Sysmon, CloudTrail, HTTP log, etc.), the model returns a structured JSON verdict.
 
 
 
 
20
 
21
  ## Results
22
 
23
+ Evaluated on a balanced held-out test set of **882 samples (441 malicious + 441 benign)**:
 
 
 
 
 
 
 
 
24
 
25
+ | Model | Accuracy | Mal. Recall | Ben. Recall | Macro F1 |
26
+ |---|---|---|---|---|
27
+ | **ThreatQwen-1.7B-Detect (ours)** | **95.1%** | **96.1%** | **94.2%** | **0.951** |
28
+ | Base Qwen3-1.7B (no fine-tune) | 85.1% | 92.1% | 78.2% | 0.851 |
29
+ | GPT-4o (Azure, zero-shot) | 51.8% | 85.0% | 18.6% | 0.458 |
30
+ | GPT-4o-mini (Azure, zero-shot) | 51.9% | 59.6% | 44.2% | 0.516 |
31
 
32
+ Fine-tuning improves the base model by **+10 percentage points** and outperforms GPT-4o by **+43.3 percentage points**.
 
 
 
 
 
 
 
 
 
 
 
 
 
33
 
34
  ## Output Schema
35
 
36
  ```json
37
+ {"verdict": "malicious | benign"}
 
 
38
  ```
39
 
 
 
40
  ## Training
41
 
42
  | Parameter | Value |
43
  |---|---|
44
  | Base model | unsloth/Qwen3-1.7B-unsloth-bnb-4bit |
45
+ | Method | QLoRA 4-bit NF4 |
46
  | LoRA rank / alpha | 16 / 32 |
 
47
  | Epochs | 3 |
48
+ | Effective batch size | 16 (batch 4 × accum 4) |
49
+ | Learning rate | 2e-4 cosine |
50
+ | MAX_SEQ_LEN | 512 |
51
  | Hardware | Tesla T4 (Kaggle free tier) |
52
+ | Training time | ~10 min |
 
 
53
 
54
  ## Dataset
55
 
56
+ Combines SigmaHQ, Elastic Detection Rules, and Nuclei templates (~5,823 real malicious events) with GPT-4o-generated synthetic benign examples (~3,743 benign covering Windows, web, email, database, VPN/remote-access). Full dataset: [minar-svn/ThreatQwen-detection-dataset](https://huggingface.co/datasets/minar-svn/ThreatQwen-detection-dataset)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
 
58
  ## Deployment
59
 
60
+ - Fully offline — no internet required (air-gapped SOC capable)
61
+ - ~3.1 GB VRAM (4-bit quantized)
62
+ - ~18 tokens/sec on Tesla T4
63
+ - ~5–7 sec/event latency
64
+ - Adapter: ~434 MB
65
+ - Min GPU: RTX 3060 (8 GB)
 
 
66
 
67
  ## Usage
68
 
69
  ```python
70
  from transformers import AutoModelForCausalLM, AutoTokenizer
71
  from peft import PeftModel
72
+ import torch, json
73
 
 
74
  base = AutoModelForCausalLM.from_pretrained(
75
  "unsloth/Qwen3-1.7B-unsloth-bnb-4bit",
76
+ torch_dtype=torch.float16, device_map="auto",
 
77
  )
78
+ model = PeftModel.from_pretrained(base, "minar-svn/ThreatQwen-1.7B-Detect")
79
  tokenizer = AutoTokenizer.from_pretrained("minar-svn/ThreatQwen-1.7B-Detect")
80
 
81
+ SYSTEM = 'You are a cybersecurity detection model. Respond ONLY with valid JSON. Format: {"verdict": "malicious | benign"}'
 
82
 
83
+ event = "EventID: 1 Image: rundll32.exe CommandLine: comsvcs.dll MiniDump User: admin"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
 
85
+ msgs = [{"role":"system","content":SYSTEM},{"role":"user","content":f"Analyze:\n\n{event}"}]
86
+ prompt = tokenizer.apply_chat_template(msgs, tokenize=False, add_generation_prompt=True).strip()
87
  inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
88
+
89
  with torch.no_grad():
90
+ out = model.generate(**inputs, max_new_tokens=40, do_sample=False,
91
+ pad_token_id=tokenizer.eos_token_id)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
 
93
+ response = tokenizer.decode(out[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True).strip()
94
+ blocks = [b.strip() for b in response.split("\n\n") if b.strip()]
95
+ print(json.loads(blocks[-1]))
96
+ # {"verdict": "malicious"}
97
  ```
98
 
 
 
99
  ## Limitations
100
 
101
+ - All benign test examples are synthetic — real-world benign generalization untested
 
102
  - English only
103
+ - Analyst aid only not a sole decision authority
 
 
 
104
 
105
  ## Citation
106
 
107
  ```bibtex
108
  @misc{threatqwen2026,
109
  author = {Md. Minaruzzaman Shovon},
110
+ title = {ThreatQwen-1.7B-Detect},
111
  year = {2026},
112
  publisher = {Hugging Face},
113
  url = {https://huggingface.co/minar-svn/ThreatQwen-1.7B-Detect}
114
  }
115
  ```
116
 
 
 
117
  ## License
118
+ Apache 2.0