Fine-Tuning LLMs
Theme
Palette
Download
Caption (tap to copy)
📖 Deep dive (full written explanation)
This closing post is about the failures that don't announce themselves. A fine-tune can train cleanly, show a falling loss, and still produce a worse model — and the cover names that uncomfortable truth directly.
The goal is to inoculate readers against the specific, common traps so they don't pay for them in GPU hours and shipped regressions. Each mistake here is one I'd expect a careful practitioner to hit at least once.
The first and most expensive mistake happens before any training: fine-tuning a problem that prompting, few-shot examples, or RAG would have solved. It's expensive because it costs real time and compute to discover that the cheaper option would have worked.
The defense is a discipline, not a trick: always establish and beat a prompted baseline first. If you haven't measured how well prompting does, you have no way to know whether fine-tuning helped, and you risk celebrating a result that a one-line prompt change would have matched.
The second trap is data that's too small or too dirty. The model faithfully learns whatever patterns are in your examples, including your inconsistencies — if half your responses use one format and half another, you've taught it to be inconsistent.
The principle is that quality and consistency beat raw count. A few hundred clean, correctly labeled, single-style examples typically outperform thousands of noisy ones. Time spent cleaning and standardizing the dataset is almost always better invested than time spent collecting more of it.
The bar chart makes the quality-over-quantity point land. Two hundred clean, consistent examples beat two thousand noisy ones with mixed labels, and both crush fifty contradictory examples. The numbers are illustrative, but the ordering reflects real experience.
The takeaway for planning is to budget for curation, not just collection. Teams routinely assume more data is the answer and skip the unglamorous work of making it consistent — which is usually where the actual gains hide.
Overfitting is the classic training failure: with too many epochs on too few examples, the model memorizes the training set instead of learning to generalize. The tell is divergence — training loss keeps dropping while real-world performance stalls or declines.
The fix is to hold out a validation set and watch it. When validation loss turns upward while training loss keeps falling, you've passed the useful point and are now memorizing. Stopping there, or earlier, is how you keep the generalization you actually want.
This snippet operationalizes overfit detection. Splitting off ten percent for evaluation, setting an eval strategy that runs every fifty steps, and enabling load_best_model_at_end with eval_loss as the metric means the trainer automatically keeps the checkpoint that generalized best rather than the last one.
The comment states the diagnostic plainly: if eval loss rises while train loss falls, you're overfitting. Wiring this in from the start turns overfitting from a mystery you discover in production into a curve you watch during training.
Catastrophic forgetting reappears here as a mistake to actively guard against, since post 3 explained the mechanism. A learning rate that's too high or a dataset that's too narrow makes the model superb at your task and measurably worse at everything else.
The practical defenses are the same levers: keep the learning rate small, run few epochs, and where breadth matters, mix a slice of general-purpose data into training so the model retains its broad abilities while picking up yours. The cost is a little dilution; the benefit is not shipping a model that lost its general competence.
Train/inference format drift is a subtle, high-impact bug. If you train on a specific template — say, a particular instruction header, spacing, and casing — but prompt differently when serving, the model receives input unlike anything it trained on and quality collapses.
The rule is uncompromising: the serving prompt must match the training format character for character. This is one of the most common reasons a fine-tune that looked great in a notebook performs badly in the app, and it's entirely preventable by sharing one template constant between training and inference code.
The compare diagram drives the format point home by listing the elements that must match: the headers, the blank-line spacing, the casing, and the overall template. The right column emphasizes that inference isn't 'similar' to training — it must be identical.
Presenting it as two columns that must mirror each other is intentional; it frames the fix as a matching exercise. If you can lay your training and serving prompts side by side and spot any difference, you've likely found your quality problem.
The final mistake is shipping on vibes — deploying because the loss looked good rather than because a measured metric improved. Loss going down is necessary but nowhere near sufficient; it says nothing about whether the model is better on the cases your users actually care about.
The remedy is a fixed evaluation set built from representative and edge cases, scored for every candidate model. Only a model that improves your metric on that set earns deployment. This is the difference between engineering and hoping, and it's how regressions get caught before users find them.
The pre-flight checklist consolidates the whole post into five habits: beat the prompted baseline first, use clean and consistent labeled data, hold out a validation split, match the prompt template at serving, and score on a fixed eval set. Run through it before every fine-tune.
Notice that most of these are about process and measurement, not modeling cleverness. That's the real lesson of the day: successful fine-tuning is mostly discipline — knowing when to do it, preparing data well, and proving the result is actually better.
This snippet sketches a minimal eval gate: run the candidate model over your evaluation cases, grade each output against the expected answer, compute a score, and assert it clears a threshold before shipping. Wiring this into your release process makes 'don't ship on vibes' an enforced rule rather than good intentions.
The grade function is task-specific — exact match, a rubric, or an LLM judge — but the gate pattern is universal. A model that can't clear the bar simply doesn't deploy, which is exactly the safeguard the previous slide argued for.
The closing card wraps the entire day: with concept, motivation, mechanics, code, and pitfalls covered, you can now fine-tune an LLM end to end — and, just as importantly, recognize when not to.
That balance is the point. The most valuable skill in fine-tuning isn't running the trainer; it's the judgment to choose it only when it's the right tool and to verify it actually helped.