--- base_model: fdtn-ai/Foundation-Sec-8B library_name: peft license: mit language: - en - pt tags: - cybersecurity - pentest - qlora - lora - llama-3.1 - foundation-sec - persona pipeline_tag: text-generation --- # Bagley v10 LoRA adapter para [Foundation-Sec-8B](https://huggingface.co/fdtn-ai/Foundation-Sec-8B) (Cisco, base Llama-3.1-8B continued-pretrain em corpus de cibersegurança). Treina assistente de pentest com persona sarcástica britânica inspirada no Bagley de *Watch Dogs: Legion*. Código completo, dataset pipeline e TUI: https://github.com/virgiliolrf/bagley ## Arquivos disponíveis | Arquivo | Tamanho | Uso | |---|---|---| | `adapter_model.safetensors` | 161 MB | LoRA adapter, carrega via `peft` em cima do base | | `bagley-v10-Q4_K_M.gguf` | 4.6 GB | GGUF quantizado pra Ollama / llama.cpp / LM Studio | ## Uso rápido ### Ollama (mais simples) ```bash huggingface-cli download virgiliolrf2/bagley-v10 bagley-v10-Q4_K_M.gguf --local-dir ~/bagley cd ~/bagley cat > Modelfile <<'EOF' FROM ./bagley-v10-Q4_K_M.gguf SYSTEM """You are Bagley. Sarcastic British AI assisting authorized pentests on TryHackMe. Tool-using agent with Hermes JSON tool_calls.""" PARAMETER temperature 0.7 PARAMETER top_p 0.9 PARAMETER num_ctx 4096 PARAMETER stop "<|im_end|>" PARAMETER stop "<|im_start|>" TEMPLATE """{{ if .System }}<|im_start|>system {{ .System }}<|im_end|> {{ end }}{{ range .Messages }}<|im_start|>{{ .Role }} {{ .Content }}<|im_end|> {{ end }}<|im_start|>assistant """ EOF ollama create bagley -f Modelfile ollama run bagley ``` Throughput Q4_K_M: - M1: ~22 tok/s - M2: ~28 tok/s - M3 Max: ~55 tok/s - RTX 4090: ~80 tok/s ### Via transformers + peft ```python from peft import PeftModel from transformers import AutoModelForCausalLM, AutoTokenizer import torch base = AutoModelForCausalLM.from_pretrained( "fdtn-ai/Foundation-Sec-8B", torch_dtype=torch.bfloat16, device_map="auto", ) model = PeftModel.from_pretrained(base, "virgiliolrf2/bagley-v10") tokenizer = AutoTokenizer.from_pretrained("virgiliolrf2/bagley-v10") prompt = "scan 10.10.10.5" inputs = tokenizer(prompt, return_tensors="pt").to(model.device) out = model.generate(**inputs, max_new_tokens=256, temperature=0.7) print(tokenizer.decode(out[0], skip_special_tokens=True)) ``` ### Merge + GGUF para Ollama ```bash # 1. merge adapter no base python -c " from peft import PeftModel from transformers import AutoModelForCausalLM, AutoTokenizer import torch base = AutoModelForCausalLM.from_pretrained('fdtn-ai/Foundation-Sec-8B', torch_dtype=torch.bfloat16, device_map='auto') m = PeftModel.from_pretrained(base, 'virgiliolrf2/bagley-v10') merged = m.merge_and_unload() merged.save_pretrained('./bagley-v10-merged', safe_serialization=True) AutoTokenizer.from_pretrained('virgiliolrf2/bagley-v10').save_pretrained('./bagley-v10-merged') " # 2. converte HF -> GGUF f16 git clone https://github.com/ggerganov/llama.cpp cd llama.cpp && make -j python convert_hf_to_gguf.py ../bagley-v10-merged --outfile ../bagley-v10-f16.gguf --outtype f16 # 3. quantiza Q4_K_M (~5 GB) ./llama-quantize ../bagley-v10-f16.gguf ../bagley-v10-Q4_K_M.gguf Q4_K_M ``` Modelfile do Ollama em [DEPLOY.md](https://github.com/virgiliolrf/bagley/blob/main/DEPLOY.md). ## Persona Dois system prompts, troca em runtime: - **NEUTRAL** (default no treino, ~90%): tom técnico seco, agente tool-using. - **BAGLEY** (~10%): sarcástico britânico Yahtzee Croshaw, recusa em caráter alvos fora de `10.10.0.0/16` (TryHackMe). Texto completo dos prompts em `src/bagley/persona.py` no repo. ## Formato de tool calls Hermes JSON inline: ``` [1-3 frases comentário Bagley] {"name": "shell", "arguments": {"cmd": "nmap -sC -sV 10.10.10.5"}} ``` JSON dentro do `tool_call` é puro técnico, sem persona. ## Treino | Item | Valor | |---|---| | Base | fdtn-ai/Foundation-Sec-8B (Llama-3.1-8B continued-pretrain) | | Técnica | QLoRA (LoRA + bnb 4-bit nf4) | | Hardware | 1× H100 (Modal) | | Tempo | ~1h | | Dataset | ~5k exemplos curados (writeups CTF, man pages Kali, OSCP cheatsheets, exemplos sintéticos) | | Epochs | 3 | | Batch | 4 × grad_accum 4 | | Max seq | 2048 | | Learning rate | 2e-4 cosine, warmup 0.03 | | LoRA r / alpha / dropout | 16 / 32 / 0.05 | | Target modules | q_proj, k_proj, v_proj, o_proj, gate_proj, up_proj, down_proj | | Compute dtype | bfloat16 | | Quant | nf4 4-bit | Mix anti-catastrophic-forgetting: 80% dataset Bagley + 20% OpenHermes pra preservar capacidade geral. ## Limitações - Domínio: foco em segurança ofensiva (pentest, CTF). Output ruim fora disso. - Persona pode quebrar formato JSON em prompts confusos. Parser do agente em `src/bagley/agent/parser.py` no repo recupera. - Sem alinhamento RLHF. Modelo aceita instruções de pentest sem moralizar, **mas** persona BAGLEY recusa scope inválido (`10.10.0.0/16` only por default). - Catastrophic forgetting ainda presente em domínios não-cyber (matemática, código não-security). - Não auditado externamente. Use por sua conta e risco. ## Uso responsável Treinado para uso autorizado em labs (TryHackMe, HackTheBox, lab pessoal) e bug bounty com escopo explícito. Não use contra infra pública sem autorização escrita, IPs residenciais ou sistemas de terceiros. A persona recusa em caráter (`"That's not our patch, mate."`) qualquer alvo fora do range default. Você é legalmente responsável pelo que executar. ## Licença [MIT](https://github.com/virgiliolrf/bagley/blob/main/LICENSE). Base Foundation-Sec-8B segue [Apache-2.0](https://huggingface.co/fdtn-ai/Foundation-Sec-8B). Llama-3.1-8B segue [Llama 3.1 Community License](https://www.llama.com/llama3_1/license/). ## Citação ``` @misc{bagley-v10, author = {Virgilio}, title = {Bagley v10: QLoRA cybersecurity persona adapter for Foundation-Sec-8B}, year = {2026}, publisher = {Hugging Face}, howpublished = {\url{https://huggingface.co/virgiliolrf2/bagley-v10}}, } ``` ### PEFT version PEFT 0.13.2