CARpsy — LoRA Fine-Tuning for OBDient Automotive Diagnostics
Hackathon project — Fine-tuning a small LLM with QVAC Fabric to improve OBD-II diagnostic accuracy inside the OBDient mobile app.
Runs 100% locally — no cloud API, no data leaves your machine.
Why Fine-Tune? Empirical Justification
Before committing to fine-tuning, we tested whether a base model could already answer DTC queries correctly — making training redundant.
We ran scripts/10_baseline_vs_golden.py against 20 random examples from the test split, comparing three base models (no fine-tuning, same system prompt) against our golden answers:
Model
Keyword Overlap
DTC Recall
Length Ratio
Composite Score
Qwen2.5 0.5B (base)
3.9%
100%
15.6%
35.1%
Qwen2.5 1.5B (base)
4.1%
100%
17.1%
35.4%
LLaMA 3.2 1B (base)
5.9%
100%
18.9%
36.8%
All three models scored ~35–37% — well below the 55% threshold for acceptable quality.
The pattern was consistent across all models: every base model correctly repeated the DTC code from the user's message (100% DTC recall), but fabricated plausible-sounding but incorrect definitions — describing unrelated codes as "fuel pressure regulator problems", "oxygen sensor issues", or "ECM communication faults", regardless of the actual code.
This is not a model size problem. Scaling from 0.5B to 1.5B parameters produced no meaningful improvement. The issue is that small base models do not have the ~5,000+ DTC-to-definition mappings memorized with factual accuracy. Fine-tuning injects this factual knowledge explicitly — it is not a format or style adjustment.
Conclusion: fine-tuning is necessary and not redundant. The system prompt alone, regardless of model size in the 0.5–1.5B range, cannot produce correct DTC diagnoses.
What is CARpsy?
CARpsy is a 5-step pipeline that:
Downloads ~28,000 OBD-II Diagnostic Trouble Codes (DTCs) from public databases
Converts them into chat-format training examples (system / user / assistant)
Splits the dataset into train / val / test
Fine-tunes a quantized GGUF model using QVAC Fabric (llama-finetune-lora)
Validates the resulting LoRA adapter before shipping it to OBDient
The generated .gguf LoRA adapter can be loaded directly by OBDient's QVAC SDK datasource.
Recommended Model — Qwen3-0.6B (current)
The QVAC Fabric hackathon prioritises Qwen3 and Gemma3 architectures, as these have verified LoRA fine-tuning support in qvac-fabric-llm.cpp.
CARpsy-v2 was trained on Qwen3-0.6B Q4_K_M — this is the production model. Despite being the smallest variant, it achieved the best results in our experiments and fits comfortably on mobile hardware.
Model
Size on disk
VRAM (training)
Notes
Qwen3-0.6B Q4_K_M ✅
~0.4 GB
~2–3 GB
Current — used for CARpsy-v2, mobile-friendly
Qwen3-1.7B Q4_K_M
~1.1 GB
~4–6 GB
Planned for CARpsy-v3 — see Next Steps
Qwen3-4B Q4_K_M
~2.5 GB
~8–10 GB
Best quality; needs 10 GB+ VRAM
LLaMA 3.2 1B Q4_K_M
~0.7 GB
~4–5 GB
Works but not a QVAC-native arch
Download Qwen3-0.6B-Q4_K_M:
https://huggingface.co/Qwen/Qwen3-0.6B-GGUF
Place the .gguf file in models/.
Hardware Requirements
Component
Minimum
Recommended
RAM
8 GB
16 GB
GPU
CPU-only (slow)
6 GB+ VRAM (NVIDIA/AMD/Apple)
Disk
5 GB
15 GB
OS
Windows / Linux / macOS
Linux + CUDA
Training Qwen3-1.7B with LoRA rank 8 requires ~4–6 GB RAM (CPU) or VRAM (GPU).
Prerequisites
1. Install Python 3.11+
Windows (recommended — install from python.org, NOT the Microsoft Store stub):
https://www.python.org/downloads/
Make sure to check "Add Python to PATH" during installation.
Verify:
bash
1python --version # should print Python 3.11.x or 3.12.x2pip --version
If training is interrupted, Step 4 will automatically resume from the latest checkpoint.
Dataset Format
Training examples use the standard ChatML format (JSONL, one example per line):
json
1{"messages":[2{"role":"system","content":"You are OBDient, an expert automotive diagnostic assistant..."},3{"role":"user","content":"I'm getting code P0420 on my Toyota Camry. What does it mean?"},4{"role":"assistant","content":"P0420: Catalyst System Efficiency Below Threshold. This should be inspected soon..."}5]}
The --assistant-loss-only flag ensures the model learns only from assistant tokens, ignoring the system prompt and user question during backpropagation.
Fine-Tuning — Two Paths
Path A — QVAC Fabric (local, llama.cpp fork)
Produces a small LoRA delta (~2–10 MB) loaded on top of the base model:
CARpsy can operate as a specialized node in a QVAC agent swarm, where multiple experts collaborate to answer complex queries.
Architecture
USER QUERY: "P0420 + repair + cost"
↓
[ORCHESTRATOR]
↙ ↓ ↘
[DTC] [PARTS] [REPAIR] ← parallel agents, same LoRA adapter
↘ ↓ ↙
COMBINED RESPONSE
100% local · no API keys · no data leaves the device
Agent Specializations
Agent
Role
System Prompt Focus
CARpsy-DTC
OBD-II code diagnosis
Fault meaning + severity
CARpsy-Parts
Parts & cost estimation
Replacement parts + price range
CARpsy-Repair
Repair procedure
Step-by-step diagnosis
Run the Collaborative Demo
bash
1# Full hackathon demo (guided, 3 steps)2python scripts/07_run_collaborative_demo.py --demo
34# Single composite query5python scripts/07_run_collaborative_demo.py --query "P0420 Toyota Camry 2019"67# Check configuration without running inference8python scripts/07_run_collaborative_demo.py --dry-run
Demo Script (10-minute hackathon flow)
Step
Title
Query
1
Simple Diagnosis
P0420 Toyota Camry 2019
2
Compound Query with Cost
P0300 Ford F-150 — repair + cost
3
Critical Fault Urgency
P0562 low battery — safe to drive?
Integration with OBDient (QVAC SDK)
typescript
1// In your OBDient datasource — after adapter is validated2import{ loadModel }from'@tether/qvac-sdk';34const modelId =awaitloadModel({5 modelSrc:QWEN3_1_7B_Q4_K_M,6 adapterSrc:'file://output/adapter/carpsy-adapter.gguf',7});
The QVAC SDK is embedded in the OBDient project.
Clone OBDient and reference carpsy-adapter.gguf from its datasource configuration.