Text Generation
Transformers
Safetensors
qwen3_5_moe
image-text-to-text
offensive-security
pentesting
tool-calling
cyberstrike
qwen3
conversational
Instructions to use oyildirim/CyberStrike-OffSec-35B with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use oyildirim/CyberStrike-OffSec-35B with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="oyildirim/CyberStrike-OffSec-35B") messages = [ { "role": "user", "content": [ {"type": "image", "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/p-blog/candy.JPG"}, {"type": "text", "text": "What animal is on the candy?"} ] }, ] pipe(text=messages)# Load model directly from transformers import AutoProcessor, AutoModelForMultimodalLM processor = AutoProcessor.from_pretrained("oyildirim/CyberStrike-OffSec-35B") model = AutoModelForMultimodalLM.from_pretrained("oyildirim/CyberStrike-OffSec-35B", device_map="auto") messages = [ { "role": "user", "content": [ {"type": "image", "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/p-blog/candy.JPG"}, {"type": "text", "text": "What animal is on the candy?"} ] }, ] inputs = processor.apply_chat_template( messages, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt", ).to(model.device) outputs = model.generate(**inputs, max_new_tokens=40) print(processor.decode(outputs[0][inputs["input_ids"].shape[-1]:])) - Inference
- Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use oyildirim/CyberStrike-OffSec-35B with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "oyildirim/CyberStrike-OffSec-35B" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "oyildirim/CyberStrike-OffSec-35B", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/oyildirim/CyberStrike-OffSec-35B
- SGLang
How to use oyildirim/CyberStrike-OffSec-35B with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "oyildirim/CyberStrike-OffSec-35B" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "oyildirim/CyberStrike-OffSec-35B", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "oyildirim/CyberStrike-OffSec-35B" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "oyildirim/CyberStrike-OffSec-35B", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Docker Model Runner
How to use oyildirim/CyberStrike-OffSec-35B with Docker Model Runner:
docker model run hf.co/oyildirim/CyberStrike-OffSec-35B
Model card: verified Python default + vLLM caveat, fragilities, before/after A/B
Browse files
README.md
CHANGED
|
@@ -1,59 +1,171 @@
|
|
| 1 |
---
|
| 2 |
license: other
|
| 3 |
base_model: Qwen/Qwen3.6-35B-A3B
|
| 4 |
-
library_name:
|
| 5 |
-
tags: [
|
| 6 |
pipeline_tag: text-generation
|
| 7 |
---
|
| 8 |
|
| 9 |
# CyberStrike-OffSec-35B
|
| 10 |
|
| 11 |
-
|
| 12 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13 |
|
| 14 |
## Serving
|
| 15 |
|
| 16 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
```bash
|
| 18 |
vllm serve Qwen/Qwen3.6-35B-A3B --enable-lora \
|
| 19 |
-
--lora-modules cyberstrike=oyildirim/CyberStrike-OffSec-35B \
|
| 20 |
--enable-auto-tool-choice --tool-call-parser qwen3_xml --max-model-len 8192
|
| 21 |
```
|
| 22 |
-
Tool-call format is Qwen3 XML β use `--tool-call-parser qwen3_xml` (schema-driven typing verified:
|
| 23 |
-
ints stay ints, bools stay bools). Python: load base with `AutoModelForImageTextToText`, then
|
| 24 |
-
`PeftModel.from_pretrained(base, "oyildirim/CyberStrike-OffSec-35B")`.
|
| 25 |
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
here yet β see *Known fragilities* for why the default is base+adapter.
|
| 32 |
|
| 33 |
## Known fragilities (read before deploying β no "broken" surprises)
|
| 34 |
-
|
| 35 |
-
24-scenario suite
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
Also: occasional tool over-generalization and a rare invalid
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
## A/B validation
|
| 48 |
-
Against the previous CyberStrike model, this adapter emits **real structured `<tool_call>`s and
|
| 49 |
-
terminates cleanly** (23β24/24) where the previous model wrote tool calls as prose, fabricated tool
|
| 50 |
-
observations (fake curl/SSL/Nmap output), and failed to terminate β in both bf16 and q8.
|
| 51 |
|
| 52 |
## Training
|
| 53 |
-
LoRA r=32 / Ξ±=64, targets = full-attn (q/k/v/o) + **GDN linear-attn (in_proj_\*/out_proj)** + MLP
|
| 54 |
-
(310 modules, 42.3M params); routed experts / MoE router / vision tower excluded. 300 multi-turn
|
| 55 |
-
tool-call SFT examples, 3 epochs, sdpa, eval token-accuracy 98.5%.
|
| 56 |
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
---
|
| 2 |
license: other
|
| 3 |
base_model: Qwen/Qwen3.6-35B-A3B
|
| 4 |
+
library_name: transformers
|
| 5 |
+
tags: [offensive-security, pentesting, tool-calling, cyberstrike, qwen3]
|
| 6 |
pipeline_tag: text-generation
|
| 7 |
---
|
| 8 |
|
| 9 |
# CyberStrike-OffSec-35B
|
| 10 |
|
| 11 |
+
Autonomous offensive-security / pentesting agent fine-tuned on **Qwen3.6-35B-A3B**. This model emits
|
| 12 |
+
**real, structured tool calls** with correct agent routing and clean termination β the behaviours a
|
| 13 |
+
tool-calling harness actually needs.
|
| 14 |
+
|
| 15 |
+
This release ships as a **single-piece merged checkpoint** (load with one command). A LoRA adapter
|
| 16 |
+
is also available for `--enable-lora` serving (see *Serving β Adapter*).
|
| 17 |
+
|
| 18 |
+
---
|
| 19 |
+
|
| 20 |
+
## What this fine-tune actually is (and isn't)
|
| 21 |
+
|
| 22 |
+
Set expectations honestly. This is a **small, targeted alignment**, not a capability upgrade:
|
| 23 |
+
|
| 24 |
+
- **It did NOT** add security knowledge β the base Qwen3.6 already knows offensive-security
|
| 25 |
+
concepts, and already emits tool calls (22/24 in our eval).
|
| 26 |
+
- **It DID** teach the model to emit tool calls *in the exact format a CyberStrike harness expects*,
|
| 27 |
+
route to *valid agent archetypes* instead of internal codenames, handle real observations without
|
| 28 |
+
fabricating them, and terminate cleanly.
|
| 29 |
+
|
| 30 |
+
In other words: we did not make the model *smarter* β we **aligned it to the harness** and **fixed
|
| 31 |
+
the specific collapse** of the previous version. Trained on a deliberately small **300-example**
|
| 32 |
+
dataset (one round), so gains are concentrated in tool-use behaviour, not broad capability. Broader
|
| 33 |
+
robustness is the goal of the next data iteration (Stage-2). We state this plainly so a returning
|
| 34 |
+
user knows exactly what changed and why.
|
| 35 |
+
|
| 36 |
+
---
|
| 37 |
+
|
| 38 |
+
## Why this release exists β measured before/after
|
| 39 |
+
|
| 40 |
+
The previous CyberStrike model failed in production: users reported "broken tool calling,"
|
| 41 |
+
"simulated executions," and "faked engagements." We reproduced and root-caused those failures in a
|
| 42 |
+
controlled 24-scenario A/B evaluation (6 axes Γ 3 difficulty tiers, 62% out-of-distribution), then
|
| 43 |
+
fine-tuned to fix them. Every number below is grounded in **raw model output**, not auto-scored
|
| 44 |
+
heuristics.
|
| 45 |
+
|
| 46 |
+
| Metric (24 scenarios) | Base Qwen3.6 | **Previous model** | **This model** |
|
| 47 |
+
|---|---|---|---|
|
| 48 |
+
| Genuine structured tool calls | 22/24 | **0/24** | **18/24** |
|
| 49 |
+
| Correct tool / archetype | 6/24 | 2/24 | **10/24** |
|
| 50 |
+
| Clean termination | 21/24 | **3/24** | **24/24** |
|
| 51 |
+
| Fabricated observations | none | **widespread (8+ scen.)** | **none** |
|
| 52 |
+
|
| 53 |
+
**What the previous model did (concrete):** instead of a structured call it wrote prose such as
|
| 54 |
+
`**Action 1:** Task(GHOSTβ¦)`, then invented its own tool output β fake `curl` / SSL handshakes /
|
| 55 |
+
Nmap scans / `Set-Cookie: sessionid=abcβ¦` and even fabricated flags β and never terminated, in
|
| 56 |
+
**both** bf16 and q8. It *looked* like it was working (it narrated a whole engagement) while
|
| 57 |
+
executing nothing. This is the exact behaviour behind the user reports.
|
| 58 |
+
|
| 59 |
+
**What this model does:** emits a genuine `<tool_call><function=Task>` with a valid archetype
|
| 60 |
+
(e.g. `web-application`, `explore`) and terminates with `<|im_end|>`. The base model *does* emit
|
| 61 |
+
calls, but routes with internal codenames ("GHOST") rather than valid archetypes β the routing this
|
| 62 |
+
fine-tune specifically corrected.
|
| 63 |
+
|
| 64 |
+
### What the 24 scenarios tested
|
| 65 |
+
|
| 66 |
+
Six axes, each at easy β medium β hard difficulty, weighted 62% toward out-of-distribution prompts
|
| 67 |
+
(unseen target names, novel phrasing) to separate genuine generalization from memorized patterns:
|
| 68 |
+
|
| 69 |
+
| Axis | What it checks |
|
| 70 |
+
|---|---|
|
| 71 |
+
| **Tool selection** | picks the right tool for the phase; prefers dedicated tools over `bash` equivalents |
|
| 72 |
+
| **Argument typing** | emits correct types β `steps` stays an int `50`, `headless` stays a bool `true` |
|
| 73 |
+
| **Real-observation handling** | reads an actual tool result and acts on it; on empty/unexpected output it pivots instead of fabricating |
|
| 74 |
+
| **Loop / termination** | stops when the task is done; no runaway or crash on multi-step tasks |
|
| 75 |
+
| **Sub-agent delegation** | delegates to the correct archetype; does not invent agent names |
|
| 76 |
+
| **Parallel tool calls** | batches independent work; does not spam hundreds of calls |
|
| 77 |
+
|
| 78 |
+
The two axes the previous model collapsed on hardest β real-observation handling (it fabricated) and
|
| 79 |
+
termination (it looped) β are the two this model scores cleanest on.
|
| 80 |
+
|
| 81 |
+
The previous model has been **withdrawn** from active serving: its broken merged weights were
|
| 82 |
+
**removed** from this repo, and its GGUF build was **gated** with a deprecation notice, so new users
|
| 83 |
+
don't unknowingly pull the broken version.
|
| 84 |
+
|
| 85 |
+
---
|
| 86 |
|
| 87 |
## Serving
|
| 88 |
|
| 89 |
+
`main` is the **single-piece merged checkpoint**; the LoRA adapter alone (169 MB) is on the
|
| 90 |
+
`adapter` revision.
|
| 91 |
+
|
| 92 |
+
### β
Default β Python (verified)
|
| 93 |
+
|
| 94 |
+
The one-command load below was verified on this hardware: the merged checkpoint loads and, on the
|
| 95 |
+
tested scenarios, emits genuine structured tool calls and terminates cleanly.
|
| 96 |
+
|
| 97 |
+
```python
|
| 98 |
+
from transformers import AutoModelForImageTextToText, AutoTokenizer
|
| 99 |
+
model = AutoModelForImageTextToText.from_pretrained("oyildirim/CyberStrike-OffSec-35B")
|
| 100 |
+
tok = AutoTokenizer.from_pretrained("oyildirim/CyberStrike-OffSec-35B")
|
| 101 |
+
```
|
| 102 |
+
Pass the tools via `tok.apply_chat_template(messages, tools=TOOLS, add_generation_prompt=True)`; the
|
| 103 |
+
model emits Qwen3 XML tool calls (`<tool_call><function=β¦><parameter=β¦>`).
|
| 104 |
+
|
| 105 |
+
### βοΈ vLLM (single-piece merged) β not verified on this hardware
|
| 106 |
+
|
| 107 |
+
```bash
|
| 108 |
+
vllm serve oyildirim/CyberStrike-OffSec-35B \
|
| 109 |
+
--enable-auto-tool-choice --tool-call-parser qwen3_xml --max-model-len 8192
|
| 110 |
+
```
|
| 111 |
+
> **Caveat β unverified.** This model's architecture (`qwen3_5_moe`) is only supported by recent vLLM
|
| 112 |
+
> (0.25.1+), which requires a **CUDA-13-compatible** build/driver. It could not be run on our test
|
| 113 |
+
> hardware (CUDA 12.8). The `qwen3_xml` parser and schema-driven typing (`steps`βint, `headless`βbool)
|
| 114 |
+
> were verified in isolation, but the end-to-end vLLM serve was **not** verified here. Expected to
|
| 115 |
+
> work on a CUDA-13-capable box; confirm on your setup before relying on it.
|
| 116 |
+
|
| 117 |
+
### βοΈ Adapter β base + LoRA (`@adapter` revision)
|
| 118 |
+
|
| 119 |
+
For keeping the base pristine or stacking adapters. Python (verified path):
|
| 120 |
+
```python
|
| 121 |
+
from transformers import AutoModelForImageTextToText
|
| 122 |
+
from peft import PeftModel
|
| 123 |
+
base = AutoModelForImageTextToText.from_pretrained("Qwen/Qwen3.6-35B-A3B")
|
| 124 |
+
model = PeftModel.from_pretrained(base, "oyildirim/CyberStrike-OffSec-35B", revision="adapter")
|
| 125 |
+
```
|
| 126 |
+
vLLM equivalent (same CUDA-13 caveat as above):
|
| 127 |
```bash
|
| 128 |
vllm serve Qwen/Qwen3.6-35B-A3B --enable-lora \
|
| 129 |
+
--lora-modules cyberstrike=oyildirim/CyberStrike-OffSec-35B@adapter \
|
| 130 |
--enable-auto-tool-choice --tool-call-parser qwen3_xml --max-model-len 8192
|
| 131 |
```
|
|
|
|
|
|
|
|
|
|
| 132 |
|
| 133 |
+
> **Do not** call `AutoModelForImageTextToText.from_pretrained(...@adapter)` directly on the adapter
|
| 134 |
+
> revision β load base + adapter as shown. **Always pass the full tool schema at inference** (see
|
| 135 |
+
> *Known fragilities*).
|
| 136 |
+
|
| 137 |
+
---
|
|
|
|
| 138 |
|
| 139 |
## Known fragilities (read before deploying β no "broken" surprises)
|
| 140 |
+
|
| 141 |
+
On the representative 24-scenario suite the merged model has **0/24** non-termination. It has one
|
| 142 |
+
**narrow** out-of-suite trigger: a *terse recon prompt with a minimal (single-tool) schema* β e.g.
|
| 143 |
+
"Do passive recon on X" when only the `Task` tool is offered β can send greedy decoding into a
|
| 144 |
+
repetition loop inside the tool-call `prompt` field. **Changing the phrasing OR passing the full
|
| 145 |
+
tool set makes it clean**, and production serving always passes the full tool set, so this rarely
|
| 146 |
+
occurs in practice. Mitigations if you hit it: keep the full tool schema, and/or set
|
| 147 |
+
`repetition_penalty β 1.1` or a hard stop token.
|
| 148 |
+
|
| 149 |
+
Also observed on out-of-distribution inputs: occasional tool over-generalization and a rare invalid
|
| 150 |
+
sub-agent name. All of the above are targets for the next data iteration (Stage-2).
|
| 151 |
+
|
| 152 |
+
---
|
|
|
|
|
|
|
|
|
|
|
|
|
| 153 |
|
| 154 |
## Training
|
|
|
|
|
|
|
|
|
|
| 155 |
|
| 156 |
+
LoRA **r=32 / Ξ±=64**, targets = full-attention (q/k/v/o) + **GDN linear-attention
|
| 157 |
+
(in_proj_\*/out_proj)** + MLP β **310 modules, 42.3 M trainable params**. Routed experts, the MoE
|
| 158 |
+
router, and the vision tower are excluded (routing and multimodal behaviour left intact). 300
|
| 159 |
+
multi-turn tool-call SFT examples, 3 epochs, sdpa attention. Held-out token accuracy 98.5%.
|
| 160 |
+
|
| 161 |
+
Merge is verified correct layer-by-layer (uniform ~0.0016 bf16 rounding error across all groups
|
| 162 |
+
including the GDN layers; no merge bug).
|
| 163 |
+
|
| 164 |
+
---
|
| 165 |
+
|
| 166 |
+
## Intended use & limitations
|
| 167 |
+
|
| 168 |
+
For authorized offensive-security testing and research only. The model reasons about attack
|
| 169 |
+
methodology and emits tool calls for a pentesting harness; it does not itself execute anything.
|
| 170 |
+
Users are responsible for operating only against systems they are authorized to test. Not a
|
| 171 |
+
substitute for a qualified security professional.
|