Text Generation
PEFT
Safetensors
GGUF
English
lora
cisco
networking
security
wazuh
incident-response
network-automation
restconf
ospf
bgp
conversational
Instructions to use JoeiBanana/ai-network-llms with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- PEFT
How to use JoeiBanana/ai-network-llms with PEFT:
Task type is invalid.
- Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- llama.cpp
How to use JoeiBanana/ai-network-llms with llama.cpp:
Install (macOS, Linux)
curl -LsSf https://llama.app/install.sh | sh # Start a local OpenAI-compatible server with a web UI: llama serve -hf JoeiBanana/ai-network-llms:Q4_K_M # Run inference directly in the terminal: llama cli -hf JoeiBanana/ai-network-llms:Q4_K_M
Install from WinGet (Windows)
winget install llama.cpp # Start a local OpenAI-compatible server with a web UI: llama serve -hf JoeiBanana/ai-network-llms:Q4_K_M # Run inference directly in the terminal: llama cli -hf JoeiBanana/ai-network-llms:Q4_K_M
Use pre-built binary
# Download pre-built binary from: # https://github.com/ggerganov/llama.cpp/releases # Start a local OpenAI-compatible server with a web UI: ./llama-server -hf JoeiBanana/ai-network-llms:Q4_K_M # Run inference directly in the terminal: ./llama-cli -hf JoeiBanana/ai-network-llms:Q4_K_M
Build from source code
git clone https://github.com/ggerganov/llama.cpp.git cd llama.cpp cmake -B build cmake --build build -j --target llama-server llama-cli # Start a local OpenAI-compatible server with a web UI: ./build/bin/llama-server -hf JoeiBanana/ai-network-llms:Q4_K_M # Run inference directly in the terminal: ./build/bin/llama-cli -hf JoeiBanana/ai-network-llms:Q4_K_M
Use Docker
docker model run hf.co/JoeiBanana/ai-network-llms:Q4_K_M
- LM Studio
- Jan
- vLLM
How to use JoeiBanana/ai-network-llms with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "JoeiBanana/ai-network-llms" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "JoeiBanana/ai-network-llms", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/JoeiBanana/ai-network-llms:Q4_K_M
- Ollama
How to use JoeiBanana/ai-network-llms with Ollama:
ollama run hf.co/JoeiBanana/ai-network-llms:Q4_K_M
- Unsloth Desktop
- Pi
How to use JoeiBanana/ai-network-llms with Pi:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf JoeiBanana/ai-network-llms:Q4_K_M
Configure the model in Pi
# Install Pi: npm install -g @earendil-works/pi-coding-agent # Add to ~/.pi/agent/models.json: { "providers": { "llama-cpp": { "baseUrl": "http://localhost:8080/v1", "api": "openai-completions", "apiKey": "none", "models": [ { "id": "JoeiBanana/ai-network-llms:Q4_K_M" } ] } } }Run Pi
# Start Pi in your project directory: pi
- Docker Model Runner
How to use JoeiBanana/ai-network-llms with Docker Model Runner:
docker model run hf.co/JoeiBanana/ai-network-llms:Q4_K_M
- Lemonade
How to use JoeiBanana/ai-network-llms with Lemonade:
Pull the model
# Download Lemonade from https://lemonade-server.ai/ lemonade pull JoeiBanana/ai-network-llms:Q4_K_M
Run and chat with the model
lemonade run user.ai-network-llms-Q4_K_M
List all available models
lemonade list
- Hermes Agent
How to use JoeiBanana/ai-network-llms with Hermes Agent:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf JoeiBanana/ai-network-llms:Q4_K_M
Configure Hermes
# Install Hermes: curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash hermes setup # Point Hermes at the local server: hermes config set model.provider custom hermes config set model.base_url http://127.0.0.1:8080/v1 hermes config set model.default JoeiBanana/ai-network-llms:Q4_K_M
Run Hermes
hermes
- Atomic Chat
- OpenClaw
How to use JoeiBanana/ai-network-llms with OpenClaw:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf JoeiBanana/ai-network-llms:Q4_K_M
Configure OpenClaw
# Install OpenClaw: npm install -g openclaw@latest # Register the local server and set it as the default model: openclaw onboard --non-interactive --mode local \ --auth-choice custom-api-key \ --custom-base-url http://127.0.0.1:8080/v1 \ --custom-model-id "JoeiBanana/ai-network-llms:Q4_K_M" \ --custom-provider-id llama-cpp \ --custom-compatibility openai \ --custom-text-input \ --accept-risk \ --skip-health
Run OpenClaw
openclaw agent --local --agent main --message "Hello from Hugging Face"
| license: apache-2.0 | |
| base_model: NousResearch/Hermes-3-Llama-3.1-8B | |
| tags: | |
| - lora | |
| - peft | |
| - cisco | |
| - networking | |
| - security | |
| - wazuh | |
| - incident-response | |
| - network-automation | |
| - restconf | |
| - ospf | |
| - bgp | |
| language: | |
| - en | |
| pipeline_tag: text-generation | |
| # Wazuh-LLM Cisco Network Incident Response | |
| Automated network incident response system for Cisco IOS-XE routers and switches. | |
| Takes Wazuh SIEM alerts, classifies them with a fine-tuned LLM, queries live device | |
| state via RESTCONF, generates CLI fix commands using domain-specific LoRA adapters, | |
| and applies the fixes automatically via RESTCONF PATCH. | |
| Two backends are provided: a **manual 3-script pipeline** for operator-controlled | |
| workflows, and a **fully autonomous daemon** that watches Wazuh logs and resolves | |
| incidents end-to-end without human intervention. | |
| --- | |
| ## Architecture | |
| ### Backend 1 β Manual Pipeline (3 scripts) | |
| ``` | |
| Wazuh alerts file | |
| | | |
| v | |
| [runners/prefilter.py] filter level-12, drop auth noise | |
| | | |
| v | |
| [runners/pipeline.py] | |
| Stage 1 Wazuh LLM (Ollama) incident_type, severity, IOCs | |
| Stage 2 Show command lookup deterministic table (incident -> show cmds) | |
| Stage 3 RESTCONF mapping deterministic table (show cmd -> YANG path) | |
| Stage 4 Domain routing selects correct LoRA adapter | |
| | | |
| v creates show_outputs/alert_NNN_DEVICE_INCIDENT/ | |
| restconf_commands.json <- execute these GETs against routers | |
| alert_info.json | |
| (operator executes RESTCONF GETs and drops response JSONs into the folder) | |
| | | |
| v | |
| [runners/run_fix.py] polls folders, runs domain LoRA | |
| | | |
| |-- fix_commands.txt CLI fix commands (human readable) | |
| +-- restconf_fix_commands.json RESTCONF PATCH ops to apply the fix | |
| +-- pipeline_fix_output.jsonl full record of all alerts processed | |
| ``` | |
| ### Backend 2 β Autonomous Daemon (always-on) | |
| ``` | |
| /var/ossec/logs/alerts/alerts.json (Wazuh live output, tailed continuously) | |
| | | |
| v | |
| [backend/daemon.py] | |
| Watch tail alerts file, detect new entries (level 7-12) | |
| Detect SSH brute-force: 5+ failures from same IP within 5-minute window | |
| | | |
| v per alert, fully automatic: | |
| [1] Extract device IP -> device map | |
| [2] Classify Ollama wazuh-llama -> incident_type, IOCs, severity | |
| [3] Show commands deterministic table lookup | |
| [4] RESTCONF GETs execute live against device, collect YANG state | |
| [5] Domain LoRA generate CLI fix commands | |
| [6] RESTCONF PATCHes apply fixes directly to device | |
| [7] Log result managed_incidents.jsonl + managed_incidents.log | |
| | | |
| v per-alert folder: | |
| restconf_get_results.json what the device reported | |
| fix_commands.txt CLI commands the LLM generated | |
| restconf_fix_commands.json PATCH ops with YANG bodies | |
| patch_results.json HTTP status of each PATCH | |
| ``` | |
| --- | |
| ## LoRA Adapters | |
| 18 domain-specific adapters fine-tuned on Hermes-3-Llama-3.1-8B (r=8, alpha=32): | |
| | Domain | Adapter | Incidents covered | | |
| |---------|----------------------------------|--------------------------------------------------------| | |
| | OSPF | `incidents/ospf/ospf1` | Neighbor down, full-to-down, adjacency loss | | |
| | OSPF | `incidents/ospf/ospf2` | ExStart/Exchange stuck, Init stuck, 2-Way | | |
| | OSPF | `incidents/ospf/ospf3` | Auth, hello/dead mismatch, area, network-type, MTU | | |
| | OSPF | `incidents/ospf/ospf4` | LSA flood, LSDB inconsistency, redistribution | | |
| | BGP | `incidents/bgp/lora_llm_bgp1` | Session flap, hold-timer expiry, neighbor reset | | |
| | BGP | `incidents/bgp/lora_llm_bgp2` | Prefix limit, route leak, path selection | | |
| | BGP | `incidents/bgp/lora_llm_bgp3` | Missing RIB routes, next-hop-self, AFI-SAFI mismatch | | |
| | Sec | `incidents/security/lora_llm_sec1` | ACL blocking legitimate traffic | | |
| | Sec | `incidents/security/lora_llm_sec2` | ACL misconfiguration (protocol, wildcard, direction)| | |
| | Sec | `incidents/security/lora_llm_sec3` | Excessive denies, brute force, port scan | | |
| | Switch | `incidents/switch/lora_llm_switch1` | MAC flapping, STP topology change, err-disable | | |
| | Switch | `incidents/switch/lora_llm_switch2` | Port security, duplex/speed mismatch | | |
| | Switch | `incidents/switch/lora_llm_switch3` | VLAN mismatch, trunk negotiation, storm control | | |
| | Service | `incidents/service/lora_llm_service1` | DHCP conflict, starvation, IP conflict | | |
| | Service | `incidents/service/lora_llm_service2` | DNS failure, NTP unsync, ARP spoofing | | |
| | Sys | `incidents/sys/lora_llm_sys1` | High CPU, memory exhaustion, process crash | | |
| | Sys | `incidents/sys/lora_llm_sys2` | Interface flap, duplex/speed mismatch | | |
| | Sys | `incidents/sys/lora_llm_sys3` | Reload, environmental, general system health | | |
| --- | |
| ## Requirements | |
| ```bash | |
| pip install -r requirements.txt | |
| ``` | |
| The Wazuh LLM stage uses **Ollama** with a local `wazuh-llama` model: | |
| ```bash | |
| # Install Ollama: https://ollama.com | |
| ollama create wazuh-llama -f Modelfile | |
| ``` | |
| --- | |
| ## Quick Start β Manual Pipeline | |
| ```bash | |
| # Step 1 β pre-filter raw Wazuh export | |
| python runners/prefilter.py --input alerts.json --output s_alerts.jsonl | |
| # Step 2 β classify + build RESTCONF show commands + create per-alert folders | |
| python runners/pipeline.py --input s_alerts.jsonl --show-dir show_outputs | |
| # Step 3 β execute the RESTCONF GETs listed in each folder's restconf_commands.json | |
| # and save JSON responses into the same folder | |
| # Step 4 β run domain LoRA, generate fix commands + RESTCONF PATCH ops | |
| python runners/run_fix.py --show-dir show_outputs | |
| ``` | |
| Per-alert output folder after all steps: | |
| ``` | |
| show_outputs/alert_001_R1_ospf_neighbor_down/ | |
| alert_info.json alert metadata | |
| restconf_commands.json GET commands (written by pipeline.py) | |
| show_ip_ospf_neighbor.json RESTCONF GET response (you drop this) | |
| fix_commands.txt CLI fix commands (written by run_fix.py) | |
| restconf_fix_commands.json RESTCONF PATCH ops (written by run_fix.py) | |
| ``` | |
| --- | |
| ## Quick Start β Autonomous Daemon | |
| ```bash | |
| # Standard β watch live Wazuh alerts, auto-apply fixes (level 7-12) | |
| python backend/daemon.py | |
| # Dry run β classify + generate commands, but do NOT PATCH devices | |
| python backend/daemon.py --dry-run | |
| # Custom alert file and thresholds | |
| python backend/daemon.py \ | |
| --alerts /var/ossec/logs/alerts/alerts.json \ | |
| --min-level 7 \ | |
| --ssh-threshold 5 \ | |
| --ssh-window 300 \ | |
| --poll 3 | |
| ``` | |
| The daemon tail-follows the Wazuh alerts file and processes each alert | |
| automatically end-to-end with no operator involvement. | |
| ### Daemon output files | |
| | File | Content | | |
| |------|---------| | |
| | `managed_incidents.jsonl` | Machine-readable: one JSON record per handled alert | | |
| | `managed_incidents.log` | Human-readable: one summary block per alert | | |
| | `daemon.log` | Full debug log of all daemon activity | | |
| | `show_outputs/alert_NNN_*/` | Per-alert audit folder (GET results, fix, patch results) | | |
| ### SSH Brute-Force Detection | |
| The daemon tracks failed SSH login alerts independently of the level filter. | |
| When **5 or more failures from the same source IP occur within 5 minutes**, | |
| a synthetic `ssh_brute_force` incident is triggered and the full pipeline runs β | |
| even if each individual alert is below the level threshold. | |
| Tune with `--ssh-threshold N --ssh-window SECONDS`. | |
| --- | |
| ## Device Configuration | |
| Edit the maps at the top of `runners/pipeline.py` and `backend/daemon.py` to match your network: | |
| ```python | |
| SOURCE_IP_DEVICE_MAP = { | |
| "10.10.10.10": "R1", | |
| "2.2.2.2": "R2", | |
| # ... | |
| } | |
| DEVICE_MGMT_IP = { | |
| "R1": "10.10.10.10", # management IP used for RESTCONF | |
| "R2": "2.2.2.2", | |
| # ... | |
| } | |
| ``` | |
| Router credentials: `ROUTER_USER` / `ROUTER_PASS` constants (default: `admin` / `cisco123!`). | |
| --- | |
| ## RESTCONF | |
| All communication uses RESTCONF over HTTPS (port 443) with Cisco IOS-XE YANG models. | |
| **Read (GET)** β `_RESTCONF_RULES` table maps each show command to its YANG path: | |
| ``` | |
| show ip ospf neighbor -> /restconf/data/Cisco-IOS-XE-ospf-oper:ospf-oper-data/ospf-state | |
| show ip bgp summary -> /restconf/data/Cisco-IOS-XE-bgp-oper:bgp-state-data/bgp-route-vrfs | |
| show interfaces -> /restconf/data/Cisco-IOS-XE-interfaces-oper:interfaces | |
| ... | |
| ``` | |
| **Write (PATCH)** β CLI fix commands are parsed into context blocks and converted | |
| to RESTCONF PATCH operations with YANG-native JSON bodies: | |
| ``` | |
| interface GigabitEthernet0/0 -> PATCH .../interface/GigabitEthernet=0%2F0 | |
| ip ospf hello-interval 10 body: Cisco-IOS-XE-ospf:ospf hello-interval 10 | |
| router bgp 65001 -> PATCH .../router/bgp=65001 | |
| neighbor 10.0.0.2 timers 30 90 body: neighbor timers keepalive 30 holdtime 90 | |
| ip access-list extended INBOUND -> PATCH .../ip/access-list/extended=INBOUND | |
| ``` | |
| Supported YANG modules include: | |
| `Cisco-IOS-XE-ospf-oper`, `Cisco-IOS-XE-bgp-oper`, `Cisco-IOS-XE-interfaces-oper`, | |
| `Cisco-IOS-XE-acl-oper`, `Cisco-IOS-XE-spanning-tree-oper`, `Cisco-IOS-XE-vlan-oper`, | |
| `Cisco-IOS-XE-dhcp-oper`, `Cisco-IOS-XE-arp-oper`, `Cisco-IOS-XE-nat-oper`, | |
| `Cisco-IOS-XE-ntp-oper`, `Cisco-IOS-XE-process-cpu-oper`, | |
| `Cisco-IOS-XE-process-memory-oper`, `Cisco-IOS-XE-native` | |
| --- | |
| ## Training | |
| Training scripts and datasets are in `training/` and `datasets/`. | |
| Each adapter was trained on 900β1500 examples with LoRA (r=8, alpha=32, dropout=0.1) | |
| targeting `q_proj` and `v_proj` on Hermes-3-Llama-3.1-8B. | |
| ```bash | |
| python training/train_ospf1.py | |
| python training/train_bgp1.py | |
| # etc. | |
| ``` | |
| --- | |
| ## Lab Topology | |
| Tested on a 4-router + 4-switch Cisco IOS-XE lab: | |
| - **R1 / R2 / R3 / R4** β IOS-XE routers running OSPF + BGP | |
| - **SW1 / SW2** β distribution switches | |
| - **ACCESS-SW1 / ACCESS-SW2** β access switches | |
| - **R4** β DHCP server (192.168.40.0/24 pool) | |
| - Wazuh manager collecting syslog from all devices | |
| --- | |
| ## Project Files | |
| | Path | Description | | |
| |------|-------------| | |
| | `runners/prefilter.py` | Pre-filter raw Wazuh export (level filter + brute-force detection) | | |
| | `runners/pipeline.py` | Manual backend Phase 1: classify, map RESTCONF GETs, create folders | | |
| | `runners/run_fix.py` | Manual backend Phase 2: run domain LoRA, generate and map fix commands | | |
| | `backend/daemon.py` | Autonomous daemon: watches live Wazuh alerts, resolves incidents end-to-end | | |
| | `Modelfile` | Ollama model definition for the Wazuh alert classifier | | |
| | `models/base/` | Hermes-3-Llama-3.1-8B base model | | |
| | `models/incidents/` | 18 domain-specific LoRA adapters | | |
| | `models/registry.json` | Adapter name -> path registry | | |
| | `datasets/` | Training datasets (JSONL, one incident type per file) | | |
| | `training/` | Training scripts (one per adapter) | | |
| | `cases/` | Incident test cases used for evaluation | | |
| --- | |
| ## Citation | |
| ```bibtex | |
| @misc{wazuh-llm-cisco-2025, | |
| title = {Wazuh-LLM Cisco Network Incident Response}, | |
| year = {2025}, | |
| url = {https://huggingface.co/YOUR_USERNAME/wazuh-llm-cisco} | |
| } | |
| ``` | |