Text Generation
PEFT
Safetensors
English
qwen2
cybersecurity
sql-injection
phishing
qlora
lora
instruction-tuning
conversational
Eval Results (legacy)
4-bit precision
bitsandbytes
Instructions to use jayesh20/qlora-cyber-security-classifier with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- PEFT
How to use jayesh20/qlora-cyber-security-classifier with PEFT:
Task type is invalid.
- Notebooks
- Google Colab
- Kaggle
| library_name: peft | |
| base_model: Qwen/Qwen2.5-7B-Instruct | |
| tags: | |
| - cybersecurity | |
| - sql-injection | |
| - phishing | |
| - qlora | |
| - lora | |
| - instruction-tuning | |
| - qwen2 | |
| license: apache-2.0 | |
| datasets: | |
| - syedsaqlainhussain/sql-injection-dataset | |
| - pirocheto/phishing-url | |
| language: | |
| - en | |
| pipeline_tag: text-generation | |
| metrics: | |
| - accuracy | |
| - f1 | |
| - precision | |
| - recall | |
| model-index: | |
| - name: qlora-cyber-security-classifier | |
| results: | |
| - task: | |
| type: text-classification | |
| name: Cybersecurity threat classification | |
| dataset: | |
| name: SQL Injection + Phishing (held-out test split) | |
| type: custom | |
| metrics: | |
| - type: accuracy | |
| value: 0.99 | |
| name: Accuracy | |
| - type: f1 | |
| value: 0.99 | |
| name: Weighted F1 | |
| - type: precision | |
| value: 0.99 | |
| name: Weighted Precision | |
| - type: recall | |
| value: 0.99 | |
| name: Weighted Recall | |
| ## Model Information | |
| **QLoRA Cyber Security Classifier** is a LoRA fine-tuned adapter on top of | |
| [Qwen2.5-7B-Instruct](https://huggingface.co/Qwen/Qwen2.5-7B-Instruct), trained | |
| to detect **SQL injection attempts** and **phishing URLs** and explain the | |
| reasoning behind each classification. It was trained as an instruction-tuned | |
| security triage assistant: given a SQL query or a URL, it returns a | |
| `Classification:` label plus a short `Reason:` for that call. | |
| **Model developer:** [jayesh20](https://huggingface.co/jayesh20) | |
| **Model Architecture:** Qwen2.5-7B-Instruct (decoder-only transformer) with | |
| LoRA adapters injected into attention and MLP projection layers, fine-tuned | |
| under 4-bit NF4 quantization (QLoRA). | |
| | | Training Data | Params (base) | LoRA rank / alpha | Context length | Token count | Base model release | | |
| | :--- | :--- | :--- | :--- | :--- | :--- | :--- | | |
| | QLoRA Cyber Security Classifier | SQL injection (Kaggle) + Phishing URLs (HF) | 7B | 16 / 32 | 256 | ~3K training examples (subset) | Qwen2.5, Sep 2024 | | |
| **Supported tasks:** binary security classification with explanation, for two domains: | |
| - SQL query → `SQL Injection` / `Benign` | |
| - URL → `Phishing` / `Legitimate` | |
| **Model Release Date:** July 2026 | |
| **Status:** This is a research/prototype model trained on a limited subset of | |
| data under a tight compute budget (single T4 GPU). See [Limitations](#limitations) below. | |
| **License:** Apache 2.0 for the adapter weights. The base model | |
| (Qwen2.5-7B-Instruct) carries its own license — check | |
| [Qwen's license terms](https://huggingface.co/Qwen/Qwen2.5-7B-Instruct) before | |
| redistribution or commercial use. | |
| ## Intended Use | |
| **Intended use cases:** Assistive triage in a security pipeline — flagging | |
| suspicious SQL queries or URLs for human review, or as one signal among | |
| several in an automated detection tool. Useful for research and prototyping | |
| LLM-based security classifiers. | |
| **Out of scope:** | |
| - **Not a standalone production security gate.** This does not replace | |
| parameterized queries / prepared statements (the actual defense against SQL | |
| injection), a WAF, or established phishing-detection services. | |
| - Not evaluated against adversarial/obfuscated inputs (encoded payloads, | |
| homoglyph domains, case-mixing evasion). | |
| - Not intended for classification tasks outside SQL queries and URLs. | |
| ## How to use | |
| ```python | |
| import torch | |
| from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig | |
| from peft import PeftModel | |
| BASE_MODEL = "Qwen/Qwen2.5-7B-Instruct" | |
| ADAPTER_REPO = "jayesh20/qlora-cyber-security-classifier" | |
| bnb_config = BitsAndBytesConfig( | |
| load_in_4bit=True, | |
| bnb_4bit_quant_type="nf4", | |
| bnb_4bit_compute_dtype=torch.bfloat16, | |
| bnb_4bit_use_double_quant=True, | |
| ) | |
| tokenizer = AutoTokenizer.from_pretrained(ADAPTER_REPO) | |
| base_model = AutoModelForCausalLM.from_pretrained( | |
| BASE_MODEL, quantization_config=bnb_config, device_map="auto" | |
| ) | |
| model = PeftModel.from_pretrained(base_model, ADAPTER_REPO) | |
| model.eval() | |
| PROMPT = """### Instruction: | |
| {instruction} | |
| ### Input: | |
| {input} | |
| ### Response: | |
| """ | |
| def predict(text, task="sql"): | |
| instruction = ( | |
| "Analyze the following input and determine if it is a SQL injection attempt." | |
| if task == "sql" else | |
| "Analyze this URL and classify whether it is phishing or legitimate." | |
| ) | |
| prompt = PROMPT.format(instruction=instruction, input=text) | |
| inputs = tokenizer(prompt, return_tensors="pt").to(model.device) | |
| with torch.no_grad(): | |
| out = model.generate(**inputs, max_new_tokens=100, do_sample=False, | |
| pad_token_id=tokenizer.eos_token_id) | |
| return tokenizer.decode(out[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True).strip() | |
| print(predict("SELECT * FROM users WHERE id = 1 OR 1=1 --", task="sql")) | |
| print(predict("http://paypa1-secure-login.com/verify", task="phishing")) | |
| ``` | |
| ## Training Data | |
| | Dataset | Source | Role | | |
| | :--- | :--- | :--- | | |
| | SQL Injection Dataset | [syedsaqlainhussain/sql-injection-dataset](https://www.kaggle.com/datasets/syedsaqlainhussain/sql-injection-dataset) (Kaggle) | Labeled SQL queries (benign / injection) | | |
| | Phishing URL Dataset | [pirocheto/phishing-url](https://huggingface.co/datasets/pirocheto/phishing-url) (HuggingFace) | Labeled URLs (phishing / legitimate) | | |
| Both sources were cleaned (leaked header rows and non-numeric label values | |
| removed, deduplicated), converted to `instruction` / `input` / `output` | |
| format, class-balanced to a max 3:1 ratio, and split 85/10/5 into | |
| train/val/test. Training used a **3,000-example subset** of the train split | |
| (and 300 of val) to fit a constrained compute budget — see | |
| [Limitations](#limitations). | |
| ## Training Procedure | |
| **Method:** QLoRA — base model loaded in 4-bit NF4, LoRA adapters trained on | |
| top via plain `transformers.Trainer` (no `trl` dependency). | |
| **LoRA target modules:** `q_proj, k_proj, v_proj, o_proj, gate_proj, up_proj, down_proj` | |
| | Hyperparameter | Value | | |
| | :--- | :--- | | |
| | LoRA rank (r) | 16 | | |
| | LoRA alpha | 32 | | |
| | LoRA dropout | 0.05 | | |
| | Max sequence length | 256 | | |
| | Per-device batch size | 8 | | |
| | Gradient accumulation | 2 | | |
| | Effective batch size | 16 | | |
| | Learning rate | 2e-4 (cosine schedule) | | |
| | Max steps | 300 | | |
| | Precision | bf16 compute, 4-bit NF4 base weights | | |
| | Hardware | 1x Kaggle Tesla T4 | | |
| ### Training Loss | |
| | Step | Training Loss | Validation Loss | | |
| | :--- | :--- | :--- | | |
| | 100 | 0.1922 | 0.2044 | | |
| | 200 | 0.1901 | 0.1922 | | |
| | 300 | 0.1493 | 0.1896 | | |
| **Final training run summary:** | |
| | Metric | Value | | |
| | :--- | :--- | | |
| | Global steps | 300 | | |
| | Epochs completed | ~1.6 | | |
| | Average training loss | 0.2993 | | |
| | Training runtime | 33,671s (~9.35 hours) | | |
| | Samples/sec | 0.143 | | |
| | Steps/sec | 0.009 | | |
| Both training and validation loss decreased steadily with no signs of | |
| divergence, but note that **loss going down does not by itself confirm | |
| classification accuracy** — see Evaluation below. | |
| ## Evaluation | |
| Evaluated on the held-out test split (1,532 examples) using exact-match | |
| comparison between the model's generated `Classification:` label and ground | |
| truth. | |
| | Class | Precision | Recall | F1-score | Support | | |
| | :--- | :---: | :---: | :---: | :---: | | |
| | benign | 1.00 | 1.00 | 1.00 | 585 | | |
| | legitimate | 0.99 | 0.96 | 0.97 | 203 | | |
| | phishing | 0.96 | 0.99 | 0.97 | 182 | | |
| | sql injection | 1.00 | 1.00 | 1.00 | 562 | | |
| | **accuracy** | | | **0.99** | 1532 | | |
| | macro avg | 0.99 | 0.99 | 0.99 | 1532 | | |
| | weighted avg | 0.99 | 0.99 | 0.99 | 1532 | | |
| **Overall test accuracy: 99%.** The SQL injection task (benign / sql | |
| injection) is essentially perfect on this test split. The phishing task | |
| (legitimate / phishing) is slightly softer, with legitimate URLs occasionally | |
| misclassified as phishing (96% recall) and phishing URLs very reliably | |
| caught (99% recall) — i.e., the model is a little more likely to over-flag a | |
| legitimate URL than to miss an actual phishing one. | |
| Note this reflects performance on a **held-out split of the same cleaned | |
| dataset** used for training — it does not measure generalization to | |
| attack patterns or URL structures outside that distribution (see | |
| [Limitations](#limitations)). | |
| ## Limitations | |
| - **Small training subset:** trained on 3,000 of the available examples (not | |
| the full cleaned dataset), and for only ~1.6 epochs, in order to fit a | |
| ~1-hour-scale compute budget on a single T4. This trades off ceiling | |
| accuracy for turnaround time — expect headroom for improvement with more | |
| data/epochs. | |
| - **Templated explanations:** the `Reason:` text is class-templated rather | |
| than generated per-example, so explanations are somewhat generic rather | |
| than deeply input-specific. | |
| - **No adversarial evaluation:** the 99% accuracy above is on a clean | |
| held-out split from the same source datasets. Obfuscated SQL payloads | |
| (encoding, comment tricks, case-mixing) and homoglyph/lookalike phishing | |
| domains were not specifically tested, and performance on those is unknown. | |
| - **Long training time relative to budget:** the run took ~9.35 hours rather | |
| than the intended ~1 hour, most likely due to 7B-parameter 4-bit inference | |
| overhead plus gradient checkpointing on a single T4 — worth profiling | |
| further if iterating on this model. | |
| ## Citation | |
| ```bibtex | |
| @misc{qwen2.5, | |
| title={Qwen2.5 Technical Report}, | |
| author={Qwen Team}, | |
| year={2024} | |
| } | |
| ``` | |
| ## Model Card Contact | |
| [jayesh20](https://huggingface.co/jayesh20) |