A QLoRA fine-tuned code review model based on Qwen2.5-Coder-7B-Instruct.
Paste buggy code β get a structured analysis: bug ID, root cause, and auto-fix.
π€ Model Β Β·Β π§© LoRA Adapter Β Β·Β π Live Demo Β Β·Β π W&B Run
Code Autopsy Diagnostic Report: Automated bug identification (mutable default argument), root cause breakdown, 92.3% confidence score, and optimized code generation.
Real-Time Inference State: Live neural diagnostics runner analyzing Python source code with animated status spinner.
flowchart LR
A["π Buggy Code\n(Python / JS)"] --> B["FastAPI\n/review"]
B --> C["Qwen2.5-Coder-7B\n+ LoRA Adapter\n4-bit NF4"]
C --> D["Structured Output"]
D --> E1["π Bug Identified"]
D --> E2["π Root Cause"]
D --> E3["β
Fixed Code"]
D --> E4["π Confidence"]
F["Gradio UI\n(HF Spaces)"] -->|"POST /review\nvia API_URL"| B
G["Ollama\n(local GGUF)"] -->|alternative| C
| Model | BLEU Score | Ξ vs Base |
|---|---|---|
| Base (Qwen2.5-Coder-7B) | 10.63 | β |
| Code Autopsy (fine-tuned) | 70.03 | +59.40 (+558%) |
Fine-tuned in 1 epoch on an RTX 5060 (8 GB VRAM) using 4-bit NF4 QLoRA.
| Metric | Value |
|---|---|
| Final train loss | 0.407 |
| Final eval loss | 0.297 |
| Eval token accuracy | 92.3% |
| Trainable params | 5.05M / 4.36B (0.12%) |
| Code | |
|---|---|
| Buggy | def avg(nums): return sum(nums) / len(nums) |
| Fixed | def avg(nums): return sum(nums) / len(nums) if nums else 0.0 |
Bug Identified: ZeroDivisionError when nums is an empty list.
Root Cause: No guard clause for the empty input case. len([]) returns 0, causing division by zero.
| Code | |
|---|---|
| Buggy | def append(val, lst=[]): lst.append(val); return lst |
| Fixed | def append(val, lst=None): if lst is None: lst = []; lst.append(val); return lst |
Bug Identified: Mutable default argument lst=[] is shared across all calls.
Root Cause: Python evaluates default arguments once at function definition time, not per-call.
| Code | |
|---|---|
| Buggy | const data = response.json(); return data.name; |
| Fixed | const data = await response.json(); return data.name; |
Bug Identified: response.json() returns a Promise, not the parsed data.
Root Cause: Response.json() is asynchronous β without await, data holds the Promise object.
| Code | |
|---|---|
| Buggy | for (var i = 0; i < 3; i++) { setTimeout(() => console.log(i), 100); } |
| Fixed | for (let i = 0; i < 3; i++) { setTimeout(() => console.log(i), 100); } |
Bug Identified: Prints 3, 3, 3 instead of 0, 1, 2.
Root Cause: var is function-scoped; all closures share the same i. Replace with let (block-scoped).
1. Double-click INSTALL.bat β sets up venv + installs everything
2. Fill in your keys in .env
3. Double-click Run_Project.bat β starts API + UI, opens browser
git clone https://github.com/Ares19v/Code-Autopsy.git
cd Code-Autopsy
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
# Install PyTorch first (match your CUDA version)
pip install torch --index-url https://download.pytorch.org/whl/cu124
pip install -r requirements.txtcp .env.example .env
# Fill in: HF_TOKEN, WANDB_API_KEY, GEMINI_API_KEY# Dry-run first (no downloads, validates formatting logic)
python data/prepare_dataset.py --dry-run
# Full run (~20k examples, downloads ~5GB)
python data/prepare_dataset.py --max-samples 20000# Debug: 1 step, no W&B (validates VRAM fits)
python training/train.py --debug
# Full training run (1 epoch, logs to W&B)
python training/train.py# sacreBLEU: base vs fine-tuned
python eval/eval_codebleu.py --adapter ./adapter --max-samples 20
# LLM-as-judge (100 examples, calls Gemini API)
python eval/eval_llm_judge.py --adapter ./adapteruvicorn serve.api:app --host 0.0.0.0 --port 8000
# Test it:
curl -X POST http://localhost:8000/review \
-H "Content-Type: application/json" \
-d '{"code": "def avg(x): return sum(x)/len(x)", "language": "python"}'python demo/app.py
# Opens at http://localhost:7860# Build and run everything (API + Demo)
docker compose up --build
# API only
docker build -f serve/Dockerfile -t code-autopsy-serve .
docker run -p 8000:8000 \
-v $(pwd)/adapter:/app/adapter:ro \
--env-file .env \
--gpus all \
code-autopsy-serve# 1. Merge adapter + convert to GGUF
python publish.py --skip-merge=false # creates ./merged_model/
bash convert_to_gguf.sh # requires llama.cpp
# 2. Create & run
ollama create code-autopsy -f Modelfile
ollama run code-autopsy# Push both merged model + raw adapter
python publish.py
# Adapter only (faster, no merge step)
python publish.py --skip-mergecode-autopsy/
βββ data/
β βββ raw/ # gitignored
β βββ processed/ # gitignored
β βββ prepare_dataset.py
βββ training/
β βββ train.py # SFTTrainer + QLoRA main script
β βββ config.yaml # All hyperparameters
β βββ utils.py # Shared helpers
βββ eval/
β βββ eval_codebleu.py # Quantitative BLEU eval
β βββ eval_llm_judge.py # Gemini LLM-as-judge
β βββ plot_results.py # Results chart generator
β βββ results/ # Saved evaluation outputs
βββ serve/
β βββ api.py # FastAPI /review endpoint
β βββ Dockerfile
βββ demo/
β βββ app.py # Gradio UI
β βββ Dockerfile
βββ tests/
β βββ test_utils.py # CI unit tests (no GPU required)
βββ .github/
β βββ workflows/ci.yml # GitHub Actions CI
βββ publish.py # Merge + push to HF Hub
βββ Modelfile # Ollama config
βββ convert_to_gguf.sh # GGUF conversion
βββ docker-compose.yml # Full stack orchestration
βββ requirements.txt
βββ .env.example
βββ INSTALL.bat # Windows one-click setup
βββ Run_Project.bat # Windows one-click launcher
βββ README.md
Trained on an HP Omen with RTX 5060 using 4-bit NF4 quantization via BitsAndBytes.
| Setting | Value |
|---|---|
| GPU | NVIDIA RTX 5060 (8 GB VRAM) |
| Quantization | NF4 4-bit (BitsAndBytes) |
| Precision | bfloat16 compute |
| Effective batch | 16 (4 Γ 4 grad accum) |
| Max seq length | 512 tokens |
| Optimizer | adamw_8bit |
| Epochs | 1 |
The trained model is available on Hugging Face: devanshty/Code-Autopsy
from huggingface_hub import hf_hub_download
model_path = hf_hub_download(repo_id='devanshty/Code-Autopsy', filename='adapter_model.safetensors')Β© 2026 Devansh Tyagi (Ares19v). All Rights Reserved.
