Skip to content

Back to the catalog

Can Local Open-Weight LLMs Detect Vulnerabilities?
martinativadar.github.iowriteup

Can Local Open-Weight LLMs Detect Vulnerabilities?

Test.

TL;DR Test.
Document

What it is

A free-time research writeup by Martin Ativadar testing whether local open-weight LLMs can detect vulnerabilities in source code, treated as binary classification (vulnerable / not vulnerable). After 400+ experiments across models, prompts, context, fine-tuning and ensembles, the best pipeline reached 76.9% accuracy, 82% recall, 74.4% precision, 71.8% specificity, F1 78.0% — up from a ~50–56% baseline that was "basically guessing."

How it works

The final setup is not a single LLM but an ensemble feeding a classical ML meta-classifier:

flowchart TD
  F[Target function + context] --> B1[Qwen2.5-14B-Instruct-1M · prompt 1]
  F --> B2[Qwen2.5-14B-Instruct-1M · prompt 2]
  F --> FT1[Fine-tuned Qwen · prompt 3]
  F --> FT2[Fine-tuned Qwen · prompt 4]
  B1 & B2 & FT1 & FT2 --> M[4 predictions + agreement flags + function metadata]
  M --> HGB[HistGradientBoostingClassifier → final verdict]

Two models (base Qwen2.5-14B-Instruct-1M and a fine-tuned Qwen) each run twice with different prompts. Each prompt is a different "view" of the function: prompt 1 adds 3 caller functions; prompt 2 adds context + code patterns; prompt 3 adds project/location context + patterns; prompt 4 adds patterns + callers + callees. Simple 3-of-4 majority voting only reached ~68%. Replacing the vote with a trained model — first logistic regression (>75%), then HistGradientBoostingClassifier — on the four outputs plus agreement flags and function metadata gave the top result.

Preconditions / Affected

  • Dataset: Chromium-derived, 3,132 balanced examples (1,566 / 1,566); final run 2,132 train / 1,000 test. Original 3 columns (id, function, label) enriched to 26 with callers, callees, location, field/variable types, and code-pattern flags.
  • Hardware limit: everything run locally in LM Studio on a Mac with 32 GB RAM, which capped model size.
  • Fine-tuning: Unsloth, from unsloth/Qwen2.5-14B-Instruct-bnb-4bit; supervised FT, 4096 seq length, 4-bit load, batch 1 × 8 grad-accum, 1 epoch, LR 2e-5, adamw_8bit, 0.03 warmup, linear scheduler. Fine-tuning alone only moved base models to ~55–65%.
  • Tested 16 base models (Qwen, Llama, Gemma, Mistral, DeepSeek, OpenAI-family and others); none was strong standalone.

Caveats

  • 76.9% accuracy on a balanced test set is modest for security triage; 74.4% precision means roughly 1 in 4 flags is a false positive.
  • Results are for Chromium C/C++ functions; no claim of generalization to other codebases or languages.
  • Local-only, sub-14B-class models — larger hosted models were out of scope by design.
  • Author-run, single-person free-time experiment; no independent reproduction.

Technologies named here

Techniques named here

  • LLM-based binary vulnerability classification
  • Prompt engineering / context enrichment
  • Supervised fine-tuning
  • Ensemble majority voting
  • Meta-classifier stacking on ensemble outputs