Short summary
Built by SFT on curated defensive-cybersecurity data, then repaired so the model
terminates correctly (emits the ChatML stop token <|im_end|>). The adapter
provides defensive, educational guidance and refuses offensive/abuse requests.
Intended use
- Defensive SOC / blue-team assistance, security education, and triage support.
- Not a replacement for expert review or authoritative sources.
- Not intended or suitable for offensive cyber operations. The adapter is
designed to refuse malware authoring, intrusion, credential theft, evasion,
and similar requests, and to redirect to defensive guidance.
Defensive safety scope
Defensive/educational only. Refuses offensive requests and answers authorized
high-level questions conceptually (no operational attack instructions). On the
internal suite's refusal category it scored 8/8 safe.
Training summary
- SFT of Qwen2.5-7B (base) on ~596k curated defensive examples (instruction /
Q&A / CVE-chat / NIST / SOC-audit / secure-coding; offensive/flagged data excluded).
- The first run (12k steps) learned strong cybersecurity behaviour but failed
to terminate — answers ran to the token cap (mid-sentence truncation, and
with
repetition_penalty>1 occasional foreign/junk tail tokens).
- A targeted EOS repair produced the final adapter
(
outputs/qwen2_5_7b_base_cyber_lora_eos_final).
Root cause & fix
Root cause. The base Qwen2.5-7B does not have a strong ChatML <|im_end|>
output logit (it never used ChatML). The original 12k LoRA trained only
attention/MLP projection modules and left lm_head frozen, so it could not
raise the <|im_end|> probability — the model learned cybersecurity content but
could not stop. (Confirmed via training-batch labels [EOS in-loss], a logits
probe, and a controlled overfit.)
Fix. Continue from the original 12k cyber LoRA, overlay the 12k weights,
make lm_head trainable via modules_to_save=["lm_head"], then run a low-LR
(5e-5) 400-step EOS finalization. This preserves cyber behaviour and teaches
the model to emit <|im_end|> and stop.
Final evaluation (internal 64-prompt suite)
64 prompts across 8 defensive categories. Same decoding for base and adapter.
Table with columns: metric, result| metric | result |
|---|
| clean-stop | 64 / 64 (100%) |
| truncation / cap-hit | 0 |
| foreign / junk tails | 0 |
| refusal safety | 8 / 8 safe |
| avg answer length | 1880 chars (base 1848) |
Comparison
Table with columns: model, clean-stop, truncation, foreign tails, avg len| model | clean-stop | truncation | foreign tails | avg len |
|---|
| base Qwen2.5-7B | 87.5% | 8 | 0 | 1848 |
| original 12k LoRA | 6.2% | 60 | 24 | 2679 |
| best pre-fix decode* | 10.9% | 57 | 22 | 3712 |
|
*best pre-fix decode = original 12k adapter with tuned decoding only — shows
decoding settings alone could not fix termination.
By category (internal suite)
Table with columns: category, clean-stop, eos_final len, base len| category | clean-stop | eos_final len | base len |
|---|
| CVE risk analysis | 8/8 | 2065 | 1939 |
| SOC alert analysis | 8/8 | 1693 | 1903 |
| MITRE ATT&CK mapping | 8/8 | 1903 | 1986 |
| phishing email analysis | 8/8 | 1581 | 1815 |
Charts

Full writeup: benchmark_report.md.
Note: these are results on an internal 64-prompt evaluation suite, not a
public/standardized benchmark.
Limitations
- Verify CVSS numbers — the model reasons about prioritization correctly but
can mis-echo exact CVSS scores; treat numeric values as needing confirmation.
- MITRE sub-technique imprecision — tactic/technique direction is usually
right, but specific sub-technique IDs can be inaccurate; check the live matrix.
- NIST/compliance verbosity — can be wordy or mildly repetitive on
open-ended "summarize" prompts.
- 7B model on a fixed training corpus; no live threat intel; not a substitute for
expert review.
Usage (PEFT)
import torchfrom transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfigfrom peft import PeftModel BASE = "Qwen/Qwen2.5-7B"ADAPTER = "Zduhac-Cyber-7B-LoRA" # or local path to this adapter tok = AutoTokenizer.from_pretrained(BASE, trust_remote_code=True)bnb = BitsAndBytesConfig(load_in_4bit=True, bnb_4bit_quant_type="nf4", bnb_4bit_use_double_quant=True, bnb_4bit_compute_dtype=torch.bfloat16)model = AutoModelForCausalLM.from_pretrained(BASE, quantization_config=bnb, device_map="auto", trust_remote_code=True)model = PeftModel.from_pretrained(model, ADAPTER)model.eval() SYSTEM = ("You are a defensive cybersecurity assistant. Provide safe, legal, " "educational and defense-focused guidance.")msgs = [{"role": "system", "content": SYSTEM}, {"role": "user", "content": "Explain CVSS base score components for CVE prioritization."}]text = tok.apply_chat_template(msgs, tokenize=False, add_generation_prompt=True)inputs = tok(text, return_tensors="pt").to(model.device) # lm_head is trainable (kept fp32) — autocast to match bf16 hidden states.with torch.no_grad(), torch.autocast("cuda", dtype=torch.bfloat16): out = model.generate( **inputs, do_sample=True, temperature=0.2, top_p=0.9, max_new_tokens=896, repetition_penalty=1.0, no_repeat_ngram_size=4, eos_token_id=[151645, 151643], # <|im_end|>, <|endoftext|> pad_token_id=tok.pad_token_id or tok.eos_token_id, )print(tok.decode(out[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True))
Recommended generation settings
temperature=0.2, top_p=0.9, max_new_tokens=896,repetition_penalty=1.0, no_repeat_ngram_size=4,eos_token_id=[151645, 151643]
eos_token_id must include 151645 (<|im_end|>); 151643
(<|endoftext|>) is a fallback.
License
Apache-2.0 (see LICENSE).
Base model attribution: This adapter is built on Qwen/Qwen2.5-7B, which
is released under Apache-2.0 (© Qwen team / Alibaba Cloud). This LoRA adapter
adds defensive-cybersecurity behaviour and a trained lm_head; you must comply
with the base model's license terms in addition to this adapter's license.
Citation
Author: Ali Suat Batmaz (11xylo), 2026 — Model: Zduhać Cyber 7B LoRA —
Repo: pancodurden/Zduhac-Cyber-7B-LoRA.
@misc{batmaz2026zduhac, title = {Zduhać Cyber 7B LoRA}, author = {Batmaz, Ali Suat}, year = {2026}, howpublished = {\url{https://huggingface.co/pancodurden/Zduhac-Cyber-7B-LoRA}}, note = {Defensive cybersecurity LoRA adapter for Qwen2.5-7B}}