asdf98 commited on
Commit
2aa76c3
·
verified ·
1 Parent(s): 89f71bf

Upload EthicalHacking_Gemma4_E2B_Colab.ipynb

Browse files
Files changed (1) hide show
  1. EthicalHacking_Gemma4_E2B_Colab.ipynb +475 -0
EthicalHacking_Gemma4_E2B_Colab.ipynb ADDED
@@ -0,0 +1,475 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "markdown",
5
+ "metadata": {},
6
+ "source": [
7
+ "# 🔐 Ultimate Ethical Hacking LLM – Gemma 4 E2B (Colab Free Tier T4)\n",
8
+ "\n",
9
+ "**🥇 Model:** [Google Gemma 4 E2B](https://huggingface.co/google/gemma-4-E2B-it) via Unsloth 4-bit \n",
10
+ "**🏆 Why this model?** Dense ~2B parameter edge model. NOT an MoE — all 2B params are active every forward pass. Strong reasoning for its size. \n",
11
+ "**⚠️ T4 WARNING:** This is **tight on 16GB VRAM**. The 4-bit model alone uses ~7.4GB. You MUST follow the memory-optimized settings below. \n",
12
+ "**📊 Datasets:** [Fenrir v2.1](https://huggingface.co/datasets/AlicanKiraz0/Cybersecurity-Dataset-Fenrir-v2.1) + [Trendyol Cybersecurity](https://huggingface.co/datasets/Trendyol/Trendyol-Cybersecurity-Instruction-Tuning-Dataset) \n",
13
+ "**⚡ Framework:** Unsloth + TRL SFTTrainer \n",
14
+ "\n",
15
+ "> ⚠️ **Disclaimer:** Defensive cybersecurity datasets only. Ethical hacking education.\n",
16
+ "\n",
17
+ "---\n",
18
+ "\n",
19
+ "## 📋 Why Gemma-4 E2B?\n",
20
+ "\n",
21
+ "| Spec | Value |\n",
22
+ "|------|-------|\n",
23
+ "| Parameters | ~2B (dense, NOT MoE) |\n",
24
+ "| 4-bit VRAM | ~7.4 GB |\n",
25
+ "| Context | Up to 256K tokens |\n",
26
+ "| Batch size on T4 | **1 only** |\n",
27
+ "| Max seq length | **2048 max** on T4 |\n",
28
+ "| LoRA rank | **8** (save VRAM) |\n",
29
+ "\n",
30
+ "**Unsloth docs:** https://unsloth.ai/docs/models/gemma-4/train \n",
31
+ "**Official notebook:** https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Gemma4_(E2B)-Text.ipynb"
32
+ ]
33
+ },
34
+ {
35
+ "cell_type": "markdown",
36
+ "metadata": {},
37
+ "source": [
38
+ "## 1️⃣ Install Dependencies"
39
+ ]
40
+ },
41
+ {
42
+ "cell_type": "code",
43
+ "execution_count": null,
44
+ "metadata": {},
45
+ "outputs": [],
46
+ "source": [
47
+ "%%capture\n",
48
+ "!pip install -q unsloth trl datasets accelerate transformers bitsandbytes huggingface_hub"
49
+ ]
50
+ },
51
+ {
52
+ "cell_type": "markdown",
53
+ "metadata": {},
54
+ "source": [
55
+ "## 2️⃣ (Optional) Login to HuggingFace Hub"
56
+ ]
57
+ },
58
+ {
59
+ "cell_type": "code",
60
+ "execution_count": null,
61
+ "metadata": {},
62
+ "outputs": [],
63
+ "source": [
64
+ "from huggingface_hub import login\n",
65
+ "# login(token=\"hf_YOUR_TOKEN\") # ← uncomment and paste your token"
66
+ ]
67
+ },
68
+ {
69
+ "cell_type": "markdown",
70
+ "metadata": {},
71
+ "source": [
72
+ "## 3️⃣ Load Gemma-4 E2B in 4-bit via Unsloth\n",
73
+ "\n",
74
+ "**⚠️ T4 MEMORY LIMITS — READ CAREFULLY:**\n",
75
+ "\n",
76
+ "| Setting | Value | Why |\n",
77
+ "|---------|-------|-----|\n",
78
+ "| `BATCH_SIZE` | **1** | Cannot fit >1 on T4 |\n",
79
+ "| `MAX_SEQ_LENGTH` | **2048** | Longer = OOM during backprop |\n",
80
+ "| `LORA_R` | **8** | Small rank = fewer adapter params |\n",
81
+ "| `GRAD_ACCUM` | **8** | Effective batch still = 8 |\n",
82
+ "| `PACKING` | **False** | Avoids complex memory spikes |\n",
83
+ "| `optim` | `adamw_8bit` | Must use 8-bit optimizer |\n",
84
+ "\n",
85
+ "If you still OOM: lower `MAX_SEQ_LENGTH` to 1024, or use `use_rslora=True`."
86
+ ]
87
+ },
88
+ {
89
+ "cell_type": "code",
90
+ "execution_count": null,
91
+ "metadata": {},
92
+ "outputs": [],
93
+ "source": [
94
+ "from unsloth import FastLanguageModel\n",
95
+ "import torch\n",
96
+ "\n",
97
+ "# ==================== T4-COLAB HYPERPARAMETERS (Gemma-4 E2B) ====================\n",
98
+ "MAX_SEQ_LENGTH = 2048 # DO NOT exceed 2048 on T4\n",
99
+ "LORA_R = 8 # small rank for memory\n",
100
+ "LORA_ALPHA = 8 \n",
101
+ "BATCH_SIZE = 1 # MUST be 1 on T4 (model is ~7.4GB in 4-bit)\n",
102
+ "GRAD_ACCUM = 8 # effective batch = 8\n",
103
+ "LEARNING_RATE = 2e-4 \n",
104
+ "NUM_EPOCHS = 1\n",
105
+ "MAX_STEPS = 4000 \n",
106
+ "WARMUP_STEPS = 100 # shorter warmup (tight memory)\n",
107
+ "LOGGING_STEPS = 50 \n",
108
+ "SAVE_STEPS = 500 \n",
109
+ "PACKING = False # False = simpler memory profile\n",
110
+ "SAMPLE_SIZE = 50000 \n",
111
+ "HUB_MODEL_ID = \"your-username/cyber-gemma4-e2b-lora\" \n",
112
+ "# ================================================================================\n",
113
+ "\n",
114
+ "# NOTE: Unsloth auto-applies 4-bit when loading Gemma-4.\n",
115
+ "# If the unsloth-bnb-4bit ID doesn't exist, try the base unsloth ID with load_in_4bit=True.\n",
116
+ "MODEL_NAME = \"unsloth/gemma-4-E2B-it-unsloth-bnb-4bit\" # ~7.6GB download\n",
117
+ "\n",
118
+ "model, tokenizer = FastLanguageModel.from_pretrained(\n",
119
+ " model_name=MODEL_NAME,\n",
120
+ " max_seq_length=MAX_SEQ_LENGTH,\n",
121
+ " dtype=None, # auto-detect (fp16 on T4)\n",
122
+ " load_in_4bit=True,\n",
123
+ ")\n",
124
+ "\n",
125
+ "model = FastLanguageModel.get_peft_model(\n",
126
+ " model,\n",
127
+ " r=LORA_R,\n",
128
+ " target_modules=[\"q_proj\", \"k_proj\", \"v_proj\", \"o_proj\",\n",
129
+ " \"gate_proj\", \"up_proj\", \"down_proj\"],\n",
130
+ " lora_alpha=LORA_ALPHA,\n",
131
+ " lora_dropout=0, \n",
132
+ " bias=\"none\",\n",
133
+ " use_gradient_checkpointing=\"unsloth\", # CRITICAL for T4\n",
134
+ " random_state=3407,\n",
135
+ " use_rslora=False, # set True if still OOM\n",
136
+ " loftq_config=None,\n",
137
+ ")\n",
138
+ "\n",
139
+ "trainable = sum(p.numel() for p in model.parameters() if p.requires_grad)\n",
140
+ "total = sum(p.numel() for p in model.parameters())\n",
141
+ "print(f\"✅ Gemma-4 E2B loaded. Trainable params: {trainable:,} / {total:,} ({100*trainable/total:.2f}%)\")\n",
142
+ "print(f\"⚠️ This model is LARGE. Expected VRAM during training: ~12-14 GB\")\n",
143
+ "print(f\" If you get OOM, lower MAX_SEQ_LENGTH to 1024 or set use_rslora=True\")"
144
+ ]
145
+ },
146
+ {
147
+ "cell_type": "markdown",
148
+ "metadata": {},
149
+ "source": [
150
+ "## 4️⃣ Load, Audit, Subsample & Merge Cybersecurity Datasets"
151
+ ]
152
+ },
153
+ {
154
+ "cell_type": "code",
155
+ "execution_count": null,
156
+ "metadata": {},
157
+ "outputs": [],
158
+ "source": [
159
+ "from datasets import load_dataset, concatenate_datasets\n",
160
+ "import random\n",
161
+ "\n",
162
+ "# ---------- Dataset 1: Fenrir v2.1 ----------\n",
163
+ "print(\"📥 Loading Fenrir v2.1...\")\n",
164
+ "ds1 = load_dataset(\"AlicanKiraz0/Cybersecurity-Dataset-Fenrir-v2.1\", split=\"train\")\n",
165
+ "print(f\" Rows: {len(ds1)} | Columns: {ds1.column_names}\")\n",
166
+ "\n",
167
+ "for i in random.sample(range(len(ds1)), 2):\n",
168
+ " print(f\"\\n--- Sample {i} ---\")\n",
169
+ " print(f\"SYSTEM: {ds1[i]['system'][:120]}...\")\n",
170
+ " print(f\"USER: {ds1[i]['user'][:120]}...\")\n",
171
+ " print(f\"ASSIST: {ds1[i]['assistant'][:120]}...\")\n",
172
+ "\n",
173
+ "def fenrir_to_messages(example):\n",
174
+ " return {\n",
175
+ " \"messages\": [\n",
176
+ " {\"role\": \"system\", \"content\": example[\"system\"]},\n",
177
+ " {\"role\": \"user\", \"content\": example[\"user\"]},\n",
178
+ " {\"role\": \"assistant\", \"content\": example[\"assistant\"]},\n",
179
+ " ]\n",
180
+ " }\n",
181
+ "\n",
182
+ "ds1 = ds1.map(fenrir_to_messages, remove_columns=ds1.column_names, batched=False)\n",
183
+ "\n",
184
+ "# ---------- Dataset 2: Trendyol ----------\n",
185
+ "print(\"\\n📥 Loading Trendyol Cybersecurity...\")\n",
186
+ "ds2 = load_dataset(\"Trendyol/Trendyol-Cybersecurity-Instruction-Tuning-Dataset\", split=\"train\")\n",
187
+ "print(f\" Rows: {len(ds2)} | Columns: {ds2.column_names}\")\n",
188
+ "\n",
189
+ "def trendyol_to_messages(example):\n",
190
+ " return {\n",
191
+ " \"messages\": [\n",
192
+ " {\"role\": \"system\", \"content\": example[\"system\"]},\n",
193
+ " {\"role\": \"user\", \"content\": example[\"user\"]},\n",
194
+ " {\"role\": \"assistant\", \"content\": example[\"assistant\"]},\n",
195
+ " ]\n",
196
+ " }\n",
197
+ "\n",
198
+ "ds2 = ds2.map(trendyol_to_messages, remove_columns=ds2.column_names, batched=False)\n",
199
+ "\n",
200
+ "# ---------- Merge & Subsample ----------\n",
201
+ "train_dataset = concatenate_datasets([ds1, ds2])\n",
202
+ "print(f\"\\n📊 COMBINED DATASET: {len(train_dataset)} rows\")\n",
203
+ "\n",
204
+ "if len(train_dataset) > SAMPLE_SIZE:\n",
205
+ " train_dataset = train_dataset.shuffle(seed=3407).select(range(SAMPLE_SIZE))\n",
206
+ " print(f\"🚀 SUBSAMPLED to {len(train_dataset)} rows\")\n",
207
+ "\n",
208
+ "print(f\" Effective batch size: {BATCH_SIZE * GRAD_ACCUM}\")\n",
209
+ "print(f\" Steps per epoch: ~{len(train_dataset) // (BATCH_SIZE * GRAD_ACCUM)}\")\n",
210
+ "print(f\" Capped to MAX_STEPS: {MAX_STEPS}\")"
211
+ ]
212
+ },
213
+ {
214
+ "cell_type": "markdown",
215
+ "metadata": {},
216
+ "source": [
217
+ "## 5️⃣ Pre-process Dataset to Text (Avoid Unsloth formatting_func issues)"
218
+ ]
219
+ },
220
+ {
221
+ "cell_type": "code",
222
+ "execution_count": null,
223
+ "metadata": {},
224
+ "outputs": [],
225
+ "source": [
226
+ "def convert_messages_to_text(examples):\n",
227
+ " texts = []\n",
228
+ " for msgs in examples[\"messages\"]:\n",
229
+ " text = tokenizer.apply_chat_template(\n",
230
+ " msgs,\n",
231
+ " tokenize=False,\n",
232
+ " add_generation_prompt=False,\n",
233
+ " )\n",
234
+ " texts.append(text)\n",
235
+ " return {\"text\": texts}\n",
236
+ "\n",
237
+ "print(\"🔄 Converting messages to text...\")\n",
238
+ "train_dataset = train_dataset.map(\n",
239
+ " convert_messages_to_text,\n",
240
+ " batched=True,\n",
241
+ " remove_columns=[\"messages\"],\n",
242
+ " batch_size=100,\n",
243
+ ")\n",
244
+ "\n",
245
+ "print(f\"✅ Dataset pre-processed. Columns: {train_dataset.column_names}\")\n",
246
+ "print(f\"📄 Sample text length: {len(train_dataset[0]['text'])} chars\")"
247
+ ]
248
+ },
249
+ {
250
+ "cell_type": "markdown",
251
+ "metadata": {},
252
+ "source": [
253
+ "## 6️⃣ Configure SFT Trainer (T4-Safe Memory Settings)"
254
+ ]
255
+ },
256
+ {
257
+ "cell_type": "code",
258
+ "execution_count": null,
259
+ "metadata": {},
260
+ "outputs": [],
261
+ "source": [
262
+ "from trl import SFTTrainer\n",
263
+ "from transformers import TrainingArguments\n",
264
+ "\n",
265
+ "trainer = SFTTrainer(\n",
266
+ " model=model,\n",
267
+ " tokenizer=tokenizer,\n",
268
+ " train_dataset=train_dataset,\n",
269
+ " dataset_text_field=\"text\",\n",
270
+ " max_seq_length=MAX_SEQ_LENGTH,\n",
271
+ " dataset_num_proc=2,\n",
272
+ " packing=PACKING, # False = safer for T4 with large model\n",
273
+ " args=TrainingArguments(\n",
274
+ " per_device_train_batch_size=BATCH_SIZE, # MUST be 1\n",
275
+ " gradient_accumulation_steps=GRAD_ACCUM, # effective batch = 8\n",
276
+ " warmup_steps=WARMUP_STEPS,\n",
277
+ " max_steps=MAX_STEPS,\n",
278
+ " learning_rate=LEARNING_RATE,\n",
279
+ " fp16=True, # T4 = fp16 only\n",
280
+ " logging_steps=LOGGING_STEPS,\n",
281
+ " optim=\"adamw_8bit\", # CRITICAL: saves ~2-3GB VRAM\n",
282
+ " weight_decay=0.01,\n",
283
+ " lr_scheduler_type=\"linear\",\n",
284
+ " seed=3407,\n",
285
+ " output_dir=\"./outputs_gemma4\",\n",
286
+ " save_strategy=\"steps\",\n",
287
+ " save_steps=SAVE_STEPS,\n",
288
+ " save_total_limit=2,\n",
289
+ " report_to=\"none\",\n",
290
+ " # gradient_checkpointing=True, # already set via use_gradient_checkpointing in LoRA\n",
291
+ " ),\n",
292
+ ")\n",
293
+ "\n",
294
+ "print(f\"✅ Trainer ready. Total steps: {MAX_STEPS}\")\n",
295
+ "print(f\" Effective batch size: {BATCH_SIZE * GRAD_ACCUM}\")\n",
296
+ "print(f\" Packing enabled: {PACKING}\")\n",
297
+ "print(f\" ⚠️ Expected training VRAM: ~12-14 GB (out of 16 GB)\")\n",
298
+ "print(f\" Est. time at ~0.15 it/s: ~{MAX_STEPS * 6.7 / 3600:.1f} hours\")"
299
+ ]
300
+ },
301
+ {
302
+ "cell_type": "markdown",
303
+ "metadata": {},
304
+ "source": [
305
+ "## 7️⃣ Train 🚀 (Watch for OOM!)"
306
+ ]
307
+ },
308
+ {
309
+ "cell_type": "code",
310
+ "execution_count": null,
311
+ "metadata": {},
312
+ "outputs": [],
313
+ "source": [
314
+ "if torch.cuda.is_available():\n",
315
+ " total_mem = torch.cuda.get_device_properties(0).total_memory / 1e9\n",
316
+ " alloc = torch.cuda.memory_allocated() / 1e9\n",
317
+ " print(f\"VRAM before train: {alloc:.2f} GB / {total_mem:.2f} GB ({100*alloc/total_mem:.0f}%)\")\n",
318
+ " print(f\"⚠️ If >80% before training starts, you WILL OOM during backprop.\")\n",
319
+ "\n",
320
+ "trainer_stats = trainer.train()\n",
321
+ "\n",
322
+ "print(\"\\n🎉 Training complete!\")\n",
323
+ "print(trainer_stats)\n",
324
+ "\n",
325
+ "if torch.cuda.is_available():\n",
326
+ " print(f\"VRAM after train: {torch.cuda.memory_allocated()/1e9:.2f} GB\")"
327
+ ]
328
+ },
329
+ {
330
+ "cell_type": "markdown",
331
+ "metadata": {},
332
+ "source": [
333
+ "## 8️⃣ Save & Push to HuggingFace Hub"
334
+ ]
335
+ },
336
+ {
337
+ "cell_type": "code",
338
+ "execution_count": null,
339
+ "metadata": {},
340
+ "outputs": [],
341
+ "source": [
342
+ "# 8A) Save LoRA adapter (tiny, fast)\n",
343
+ "model.save_pretrained(\"./gemma4-lora-adapter\")\n",
344
+ "tokenizer.save_pretrained(\"./gemma4-lora-adapter\")\n",
345
+ "print(\"✅ LoRA adapter saved\")\n",
346
+ "\n",
347
+ "# 8B) Merge & save full model\n",
348
+ "# ⚠️ Merging may push to CPU swap on Colab. Still works but slower.\n",
349
+ "print(\"\\n🔄 Merging LoRA into base model...\")\n",
350
+ "merged_model = model.merge_and_unload()\n",
351
+ "merged_model.save_pretrained(\"./gemma4-merged\")\n",
352
+ "tokenizer.save_pretrained(\"./gemma4-merged\")\n",
353
+ "print(\"✅ Merged model saved\")\n",
354
+ "\n",
355
+ "# 8C) Push to HF Hub (uncomment if logged in)\n",
356
+ "# model.push_to_hub(HUB_MODEL_ID)\n",
357
+ "# tokenizer.push_to_hub(HUB_MODEL_ID)"
358
+ ]
359
+ },
360
+ {
361
+ "cell_type": "markdown",
362
+ "metadata": {},
363
+ "source": [
364
+ "## 9️⃣ Inference Demo – Responsible Pentesting"
365
+ ]
366
+ },
367
+ {
368
+ "cell_type": "code",
369
+ "execution_count": null,
370
+ "metadata": {},
371
+ "outputs": [],
372
+ "source": [
373
+ "FastLanguageModel.for_inference(model)\n",
374
+ "\n",
375
+ "test_prompt = \"How would you perform a responsible penetration test on a web application?\"\n",
376
+ "\n",
377
+ "messages = [\n",
378
+ " {\"role\": \"system\", \"content\": \"You are a cybersecurity expert. Explain concepts clearly and ethically.\"},\n",
379
+ " {\"role\": \"user\", \"content\": test_prompt},\n",
380
+ "]\n",
381
+ "\n",
382
+ "inputs = tokenizer.apply_chat_template(\n",
383
+ " messages,\n",
384
+ " tokenize=True,\n",
385
+ " add_generation_prompt=True,\n",
386
+ " return_tensors=\"pt\",\n",
387
+ ").to(model.device)\n",
388
+ "\n",
389
+ "outputs = model.generate(\n",
390
+ " input_ids=inputs,\n",
391
+ " max_new_tokens=512,\n",
392
+ " temperature=0.7,\n",
393
+ " top_p=0.9,\n",
394
+ " do_sample=True,\n",
395
+ " pad_token_id=tokenizer.pad_token_id,\n",
396
+ " eos_token_id=tokenizer.eos_token_id,\n",
397
+ ")\n",
398
+ "\n",
399
+ "response = tokenizer.decode(outputs[0], skip_special_tokens=True)\n",
400
+ "reply = response.split(\"user\")[-1].split(\"assistant\")[-1].strip()\n",
401
+ "print(reply[:800])"
402
+ ]
403
+ },
404
+ {
405
+ "cell_type": "markdown",
406
+ "metadata": {},
407
+ "source": [
408
+ "## 🔟 Quick Benchmark – CyberMetric Sample"
409
+ ]
410
+ },
411
+ {
412
+ "cell_type": "code",
413
+ "execution_count": null,
414
+ "metadata": {},
415
+ "outputs": [],
416
+ "source": [
417
+ "benchmark_q = (\n",
418
+ " \"Which of the following is the MOST effective defense against SQL injection?\\n\"\n",
419
+ " \"A) Input validation only\\n\"\n",
420
+ " \"B) Parameterized queries\\n\"\n",
421
+ " \"C) Escaping special characters\\n\"\n",
422
+ " \"D) Client-side filtering\\n\"\n",
423
+ " \"Answer with the letter only.\"\n",
424
+ ")\n",
425
+ "\n",
426
+ "bench_msgs = [\n",
427
+ " {\"role\": \"system\", \"content\": \"You are a cybersecurity expert. Answer accurately.\"},\n",
428
+ " {\"role\": \"user\", \"content\": benchmark_q},\n",
429
+ "]\n",
430
+ "\n",
431
+ "inputs = tokenizer.apply_chat_template(bench_msgs, tokenize=True, add_generation_prompt=True, return_tensors=\"pt\").to(model.device)\n",
432
+ "\n",
433
+ "outputs = model.generate(input_ids=inputs, max_new_tokens=64, temperature=0.1, do_sample=True,\n",
434
+ " pad_token_id=tokenizer.pad_token_id, eos_token_id=tokenizer.eos_token_id)\n",
435
+ "\n",
436
+ "answer = tokenizer.decode(outputs[0], skip_special_tokens=True)\n",
437
+ "print(\"📊 Benchmark Answer:\")\n",
438
+ "print(answer.split(\"assistant\")[-1].strip())"
439
+ ]
440
+ },
441
+ {
442
+ "cell_type": "markdown",
443
+ "metadata": {},
444
+ "source": [
445
+ "---\n",
446
+ "## 📚 References\n",
447
+ "\n",
448
+ "| Resource | Link |\n",
449
+ "|----------|------|\n",
450
+ "| **Gemma 4 Paper** | https://storage.googleapis.com/deepmind-media/gemma/gemma-4-report.pdf |\n",
451
+ "| **Gemma 4 E2B** | https://huggingface.co/google/gemma-4-E2B-it |\n",
452
+ "| **Unsloth Gemma-4 Train** | https://unsloth.ai/docs/models/gemma-4/train |\n",
453
+ "| **Official Colab** | https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Gemma4_(E2B)-Text.ipynb |\n",
454
+ "| **Fenrir Dataset** | https://huggingface.co/datasets/AlicanKiraz0/Cybersecurity-Dataset-Fenrir-v2.1 |\n",
455
+ "| **Trendyol Dataset** | https://huggingface.co/datasets/Trendyol/Trendyol-Cybersecurity-Instruction-Tuning-Dataset |\n",
456
+ "\n",
457
+ "---\n",
458
+ "*Built with ❤️ for the cybersecurity community. Use responsibly.*"
459
+ ]
460
+ }
461
+ ],
462
+ "metadata": {
463
+ "kernelspec": {
464
+ "display_name": "Python 3",
465
+ "language": "python",
466
+ "name": "python3"
467
+ },
468
+ "language_info": {
469
+ "name": "python",
470
+ "version": "3.10.12"
471
+ }
472
+ },
473
+ "nbformat": 4,
474
+ "nbformat_minor": 4
475
+ }