What you need
- A 24GB NVIDIA GPU (RTX 3090/4090) โ or rent one by the hour for ~2โฌ total (see RunPod vs Vast.ai)
- Linux or Windows + WSL2, Python 3.10+, ~40GB free disk
- A dataset: 500โ5,000 examples of the behavior you want (we build it in step 1)
Step 1 โ Build the dataset (the part that decides everything)
One JSON object per line (train.jsonl), in chat format:
The rules that matter more than any hyperparameter:
- Consistency beats volume. 800 examples with identical formatting/tone beat 20,000 noisy ones. Every inconsistency in the data becomes a behavior the model learns.
- Show the target behavior, don't describe it. The assistant turns must BE what you want to get.
- Hold out 30โ50 examples in a separate eval.jsonl โ never trained on, used in step 6.
Step 2 โ Install Unsloth (5 min)
Unsloth wraps the PEFT/TRL stack with heavy optimizations โ roughly 2ร faster and lighter on VRAM than vanilla setups, which is what makes a 14B comfortable on 24GB.
Step 3 โ The training script (train.py)
The knobs, decoded: r=16 is the adapter capacity (8โ32 is the sane range; higher learns more and forgets more), 2 epochs is the default for behavior tuning, and effective batch = 2ร8 = 16 via gradient accumulation. This configuration uses roughly 16โ20GB of VRAM.
Step 4 โ Train and read the loss (30โ90 min)
- Healthy run: loss starts ~1.5โ2.5 and declines smoothly toward ~0.5โ1.0.
- Loss flat from the start โ data format problem (usually the chat template mapping).
- Loss near zero โ memorization; the model will parrot training examples. Fewer epochs.
Step 5 โ Load into Ollama (5 min)
The script already exported a merged Q4_K_M GGUF into out_gguf/. Create a Modelfile:
Your model now works everywhere Ollama does โ including the Open WebUI setup from our first tutorial and the vLLM server (use the merged FP16 export + AWQ for that path).
Step 6 โ Evaluate honestly (the step everyone skips)
- Run your held-out eval.jsonl questions against BOTH the base model and your fine-tune. Count: target behavior achieved? format correct?
- Then ask both models 10 GENERAL questions unrelated to your domain โ if the tuned model got notably worse at them, that's catastrophic forgetting: retrain with fewer epochs or lower r.
- Keep the eval set forever: rerun it on every future retrain and base-model upgrade.
Troubleshooting
- CUDA out of memory โ lower max_seq_length to 1024, then batch size to 1 (raise gradient_accumulation_steps to keep effective batch ~16).
- Model answers in the wrong format after tuning โ inconsistent training data, or you served it with a different system prompt than the one trained on. Align them.
- It parrots training examples verbatim โ overfitting: 1 epoch, or more diverse data.
- No 24GB GPU at hand โ the whole tutorial runs identically on a rented cloud GPU: a 1โ2 hour session costs a couple of euros.