Fine-tuning a small open LLM to turn plain-English NBA stat questions into working SQL, with a 4-way ablation to isolate what fine-tuning actually contributes.
Drop a screenshot here:assets/screenshots/nba-text-to-sql.png
Overview
When a fine-tuned model gets better at a task, is that because of fine-tuning, or because of the examples in the prompt? I built a text-to-SQL system over a real NBA stats database and ran four separate configurations to find out.
The pipeline pulls a full NBA season through the nba_api package into a SQLite database (teams, players, games, and per-game player stats), then generates and validates 140 natural-language-to-SQL pairs, from simple lookups to multi-step queries requiring conditional logic. Qwen2.5-3B-Instruct is then fine-tuned on this data using QLoRA, a memory-efficient technique that trains a small adapter on top of a 4-bit quantized base model.
Results
Four configurations, tested on a held-out set of 30 questions, isolate fine-tuning from few-shot prompting:
| Configuration | Overall | Easy | Medium | Hard |
|---|---|---|---|---|
| Zero-shot base | 0.0% | 0% | 0% | 0% |
| Zero-shot fine-tuned | 16.7% | 100% | 0% | 0% |
| Few-shot base | 46.7% | 100% | 57.1% | 27.8% |
| Few-shot + fine-tuned | 50.0% | 100% | 57.1% | 33.3% |
Fine-tuning and few-shot prompting turned out to be complementary rather than redundant. The base model could not do this task zero-shot, but fine-tuning alone gave it a real capability with no examples needed. Prompting was already a strong technique on its own, combining both produced the best result with the fine-tuned model's edge concentrated in the hardest question tier requiring correct multi-step conditional logic.
Built with