CodePecker is an LLM fine-tuned on hundreds of thousands of real vulnerability samples to detect security bugs. By understanding code semantics and context rather than just pattern matching, it identifies complex vulnerabilities like logic flaws, race conditions, and injection attacks. CodePecker not only finds these hidden threats but explains why they're dangerous and suggests how to fix them – pecking out the bugs that matter before they bite.
- Detect vulnerabilities in C code with detailed explanations
- Identify CWE types (buffer overflows, use-after-free, etc.)
- Suggest fixes based on real security patches from the wild
- Explain the why - not just binary classification
# Sync dependencies with uv
uv syncCodePecker uses a three-stage training pipeline:
- SFT (Supervised Fine-Tuning): Teaches the model to answer vulnerability questions
- DPO (Direct Preference Optimization): Teaches the model to prefer secure code over vulnerable code
- GRPO (Group Relative Policy Optimization): Optimizes fix quality using online RL with reward signals
# Train on full BigVul dataset
uv run python -m codepecker.sft.train
# Quick test with limited samples
uv run python -m codepecker.sft.train --max-train-samples 1000 --max-eval-samples 100
# Resume from checkpoint
uv run python -m codepecker.sft.train --resume-from-checkpoint ./codepecker_sft_model/checkpoint-500After SFT training completes, run DPO training to teach preference for secure code:
# Train DPO on SFT model
uv run python -m codepecker.dpo.train \
--base-model ./codepecker_sft_model \
--output-dir ./codepecker_dpo_model
# Quick test with limited samples
uv run python -m codepecker.dpo.train \
--base-model ./codepecker_sft_model \
--max-train-samples 1000
# Resume from checkpoint
uv run python -m codepecker.dpo.train \
--base-model ./codepecker_sft_model \
--resume-from-checkpoint ./codepecker_dpo_model/checkpoint-100After DPO training, run GRPO to optimize fix quality using online RL:
# Train GRPO on DPO model
uv run python -m codepecker.grpo.train \
--base-model ./codepecker_dpo_model \
--output-dir ./codepecker_grpo_model \
--reward-type similarity
# With more generations for better learning
uv run python -m codepecker.grpo.train \
--base-model ./codepecker_dpo_model \
--num-generations 8
# Quick test with limited samples
uv run python -m codepecker.grpo.train \
--base-model ./codepecker_dpo_model \
--max-train-samples 1000
# Resume from checkpoint
uv run python -m codepecker.grpo.train \
--base-model ./codepecker_dpo_model \
--resume-from-checkpoint ./codepecker_grpo_model/checkpoint-50# Analyze a code snippet
uv run python -m codepecker.inference \
--model-path ./codepecker_model \
--code "void foo() { char* p = malloc(100); free(p); free(p); }"
# Analyze code from file
uv run python -m codepecker.inference \
--model-path ./codepecker_model \
--code-file ./vulnerable.c
# Evaluate on test set
uv run python -m codepecker.inference \
--model-path ./codepecker_model \
--evaluate \
--max-samples 100 \
--output results.jsonfrom codepecker.sft import train
# Stage 1: Supervised Fine-Tuning
trainer = train(
output_dir="./codepecker_sft_model",
max_train_samples=5000, # Optional: limit for testing
max_eval_samples=500
)from codepecker.dpo import train_dpo
# Stage 2: Direct Preference Optimization
dpo_trainer = train_dpo(
base_model_path="./codepecker_sft_model", # Use SFT-trained model
output_dir="./codepecker_dpo_model",
max_train_samples=5000 # Optional: limit for testing
)What is DPO?
DPO teaches the model to prefer secure code patterns over vulnerable ones using preference pairs:
- Chosen response: Fixed/secure code (
func_afterfrom BigVul) - Rejected response: Vulnerable/buggy code (
func_beforefrom BigVul)
This preference-based learning makes the model better at suggesting secure fixes rather than just identifying vulnerabilities.
from codepecker.grpo import train_grpo
# Stage 3: Group Relative Policy Optimization
grpo_trainer = train_grpo(
base_model_path="./codepecker_dpo_model", # Use DPO-trained model
output_dir="./codepecker_grpo_model",
reward_type="similarity", # or "verification"
num_generations=4, # Generate 4 completions per prompt
max_train_samples=5000 # Optional: limit for testing
)What is GRPO?
GRPO is online reinforcement learning that optimizes fix quality through automated evaluation:
- Generates multiple completions per prompt (4-128) during training
- Evaluates each with a reward function (0.0-1.0 score based on code quality)
- Learns from the best responses in each group
Reward Functions:
- Similarity: Compares generated fix to ground truth (fast, simple)
- Verification: Uses static analysis to verify vulnerability is fixed (advanced, robust)
This online learning process produces higher-quality fixes than offline methods alone.
from codepecker.inference import CodePeckerInference
# Load model
engine = CodePeckerInference(
model_path="./codepecker_model",
temperature=0.7
)
# Analyze code
code = """
void process_data(char* input) {
char buffer[100];
strcpy(buffer, input); // Buffer overflow!
}
"""
result = engine.analyze_code(code)
print(result)Example Output:
**Vulnerability Detected: Yes**
**CWE-120: Buffer Copy without Checking Size of Input**
**Explanation:**
The function uses strcpy() without bounds checking, allowing an
attacker to overflow the buffer if input is longer than 100 bytes.
**Suggested Fix:**
Use strncpy() or strlcpy() with proper size limits, or validate
input length before copying.
**Fixed Code:**
void process_data(char* input) {
char buffer[100];
strncpy(buffer, input, sizeof(buffer) - 1);
buffer[sizeof(buffer) - 1] = '\0';
}
CodePecker is trained on BigVul - a large-scale vulnerability dataset:
- Source: HuggingFace
benjis/bigvul - Size: 200k+ C code samples
- Labels: Real CVE/CWE from major projects (Linux kernel, Chrome, tcpdump, etc.)
- Content: Before/after patches with commit messages
CodePecker uses a three-stage training pipeline to achieve superior vulnerability detection and fix generation:
SFT teaches the model to understand and respond to vulnerability analysis questions:
Input format:
System: You are CodePecker, a security-focused code analysis assistant...
User: Analyze the following C code for security vulnerabilities:
[vulnerable code]
Output format:
Vulnerability Detected: Yes/No
CWE-XXX: [Weakness type]
Explanation: [Why it's vulnerable]
Suggested Fix: [How to fix it]
Fixed Code: [Corrected version]
Dataset transformation: Each BigVul sample → Q&A pair with vulnerability analysis
DPO teaches the model to prefer secure code patterns over vulnerable ones:
Preference pairs:
- Chosen: Fixed/secure code (
func_afterfrom BigVul patches) - Rejected: Vulnerable/buggy code (
func_beforefrom BigVul patches)
How it works:
- Takes the SFT-trained model as starting point
- Shows the model pairs of (vulnerable code, secure code)
- Optimizes the model to assign higher probability to secure code
- Uses implicit reference model for memory efficiency
Benefits:
- Better fix suggestions (prefers real-world secure patterns)
- More confident in distinguishing safe vs unsafe code
- Learns from actual security patches in the wild
Example preference pair:
Prompt: "Fix the buffer overflow in: strcpy(buf, input);"
Chosen: "strncpy(buf, input, sizeof(buf)-1); buf[sizeof(buf)-1] = '\0';"
Rejected: "strcpy(buf, input);" # Original vulnerable codeThe model learns to strongly prefer the chosen (secure) response over the rejected (vulnerable) one.
GRPO optimizes fix quality using online reinforcement learning with automated reward evaluation:
How it works:
- Takes the DPO-trained model as starting point
- For each prompt, generates multiple completions (4-128 responses)
- Evaluates each completion with a reward function (0.0-1.0 score)
- Learns from the highest-reward responses in each group
- Iteratively improves generation quality through online feedback
Reward Functions:
Similarity-based (default):
# Compares generated fix to ground truth (func_after)
# Rewards: 1.0 if highly similar, proportional otherwise
reward = similarity(generated_code, ground_truth_code)Verification-based (advanced):
# Uses static analysis to verify vulnerability is fixed
# Rewards: 1.0 if fixed + compiles, 0.5 if fixed only, 0.0 otherwise
reward = verify_vulnerability_fixed(original, generated, cwe_id)Benefits:
- Generates higher-quality fixes (optimized through feedback)
- Learns from actual evaluation during training (online learning)
- Adapts to reward signal (can optimize for different metrics)
- Produces more diverse solutions (generates multiple options)
Example GRPO training step:
Prompt: "Fix the buffer overflow in: strcpy(buf, input);"
Generated completions:
1. "strcpy(buf, input);" → Reward: 0.0 (no fix)
2. "strncpy(buf, input, 99);" → Reward: 0.6 (partial fix)
3. "strncpy(buf, input, sizeof(buf)-1); buf[sizeof(buf)-1] = '\0';" → Reward: 1.0 ✓
4. "strlcpy(buf, input, sizeof(buf));" → Reward: 0.9 (good alternative)
Model learns to prefer completion #3 (highest reward)
- Base Model: Qwen/Qwen2.5-Coder-1.5B
- Training Method: QLoRA (4-bit quantization + LoRA adapters)
- Trainable Params: ~9.4M (0.6% of total)
- Memory: ~6GB VRAM for training, ~4GB for inference
- Model Format: SafeTensors (secure, no pickle vulnerabilities)
Edit codepecker/config.py to customize:
# Model settings
BASE_MODEL = "Qwen/Qwen2.5-Coder-1.5B"
USE_QUANTIZATION = True # 4-bit quantization
USE_LORA = True
# Security settings
SAFE_SERIALIZATION = True # Use SafeTensors format (secure)
# LoRA settings
LORA_R = 16
LORA_ALPHA = 32
# SFT training settings
LEARNING_RATE = 2e-4
NUM_EPOCHS = 3
BATCH_SIZE = 4
MAX_SEQ_LENGTH = 2048# DPO-specific settings
BETA = 0.2 # KL divergence coefficient (controls preference strength)
LEARNING_RATE = 5e-5 # Lower LR for DPO (more stable)
NUM_EPOCHS = 1 # Usually 1-2 epochs for DPO
BATCH_SIZE = 1 # Smaller batch for preference pairs
GRADIENT_ACCUMULATION_STEPS = 8
LOSS_TYPE = "sigmoid" # Options: sigmoid, hinge, ipo, kto
USE_REF_MODEL = False # False = implicit reference (more memory efficient)# GRPO-specific settings
LEARNING_RATE = 5e-6 # Even lower LR for online RL (very stable)
NUM_EPOCHS = 1 # Usually 1 epoch for GRPO
BATCH_SIZE = 1 # Per device
GRADIENT_ACCUMULATION_STEPS = 8
NUM_GENERATIONS = 4 # Generate N completions per prompt (4-128)
REWARD_TYPE = "similarity" # "similarity" or "verification"
SIMILARITY_THRESHOLD = 0.7 # Min similarity for full rewardcodepecker/
├── __init__.py
├── config.py # Configuration (SFT + DPO + GRPO)
├── inference.py # Inference engine
├── sft/ # Supervised Fine-Tuning
│ ├── __init__.py
│ ├── train.py # SFT training script
│ └── data/
│ ├── __init__.py
│ └── dataset.py # BigVul Q&A format
├── dpo/ # Direct Preference Optimization
│ ├── __init__.py
│ ├── train.py # DPO training script
│ └── data/
│ ├── __init__.py
│ └── dataset.py # BigVul preference pairs
└── grpo/ # Group Relative Policy Optimization
├── __init__.py
├── train.py # GRPO training script
├── reward.py # Reward functions (similarity/verification)
└── data/
├── __init__.py
└── dataset.py # BigVul prompts + ground truth
Training:
- GPU: 16GB+ VRAM (with 4-bit quantization)
- RAM: 32GB recommended
- Storage: ~50GB (model + dataset cache)
Inference:
- GPU: 8GB+ VRAM recommended (CPU also supported)
- RAM: 16GB
Faster Training:
- Reduce
MAX_SEQ_LENGTHto 1024 or 512 - Increase
GRADIENT_ACCUMULATION_STEPSto reduce memory - Use smaller model:
Qwen/Qwen2.5-Coder-0.5B
Better Quality:
- Train for more epochs (5-10)
- Increase LoRA rank to 32-64
- Use full dataset (don't limit samples)
Memory Optimization:
- Use
USE_REF_MODEL = False(implicit reference, saves ~50% memory) - Reduce
BATCH_SIZEto 1 (DPO needs less due to preference pairs) - Increase
GRADIENT_ACCUMULATION_STEPSfor effective batch size
Better Preference Learning:
- Adjust
BETA(0.1-0.5): Higher = stronger preference, lower = more exploration - Try different
LOSS_TYPE:sigmoid(default),hinge,ipo,kto - Usually 1-2 epochs is enough for DPO (over-training can hurt)
Training Order:
- Always run SFT first (model needs base understanding)
- Then run DPO on the SFT checkpoint
- Use DPO model for final inference
Memory Optimization:
- GRPO generates multiple completions, so memory usage is higher
- Use
NUM_GENERATIONS = 4for testing, increase to 8-16 for better results - Reduce
BATCH_SIZEto 1 if running out of memory
Better Quality Optimization:
- Increase
NUM_GENERATIONS(8-32): More diverse responses, better learning - Adjust
SIMILARITY_THRESHOLD(0.5-0.9): Higher = stricter, lower = more lenient - Try
REWARD_TYPE = "verification"for advanced static analysis (requires setup)
Training Order:
- Run SFT first (base understanding)
- Run DPO second (preference learning)
- Run GRPO third (quality optimization)
- Use GRPO model for final inference (highest quality)
When to use GRPO:
- ✅ When you need highest-quality fixes (critical systems)
- ✅ When you have compute budget for online RL
- ✅ When you want to optimize for specific metrics
- ❌ Skip if DPO results are sufficient (GRPO is slower)
CodePecker uses SafeTensors format for all model weights and adapters:
- ✅ No pickle vulnerabilities - Cannot execute arbitrary code
- ✅ Secure by default - Safe to download and share models
- ✅ Fast loading - Memory-mapped for efficient loading
- ✅ Cross-platform - Works across PyTorch, TensorFlow, JAX
All model files (.safetensors) are validated on load to prevent corruption or tampering.
