Go underneath · Advanced

Fine-Tuning, and When Not To

Draft, open for academic review

The case against fine-tuning first, then how to do it properly.

Your progress here is recorded once you pass the Running Models Yourself exam.

9 modules. 84 lessons.

Deciding whether to fine-tune at all

9 lessons · 1 h 20

You will be able toDiagnose a model failure as a format, knowledge, style, capability or cost problem, name the cheapest lever that fixes that class, and defend in writing a decision to fine-tune (or not to) against the prompt, retrieval, encoder and distillation alternatives and their licence constraints.

  1. 1.1The Honest Answer FirstStart7 min
  2. 1.2What Fine-Tuning Changes, and What It Cannot Add8 min
  3. 1.3Diagnosing the failure before choosing the fix10 min
  4. 1.4Try the retriever first9 min
  5. 1.5When the answer is one of six labels9 min
  6. 1.6Distillation, the case that usually survives10 min
  7. 1.7The cost of owning a model9 min
  8. 1.8Licences, and what you may train on10 min
  9. 1.9Writing the decision down8 min
An illustrative case, built from documented patternsThe custom model that was already announcedA twenty-person logistics firm in Pune, whose support inbox handles about nine hundred shipment queries a week.

Ravi ran operations at a freight forwarder in Pune. Customers wrote in asking where a consignment was, why a duty figure had changed, whether a delivery could be rescheduled. A hosted model drafted replies. It was adequate and it was wrong often enough that two people read every draft before it went out.

In March he took a proposal to the two directors: fine-tune a model on eighteen months of the company’s own correspondence, so that it would answer “the way we answer”. The directors liked it. One of them repeated the phrase “our own AI model” to a customer the following week. A budget of four lakh rupees and six weeks was approved.

The engineer Ravi hired, Sneha, began where the course says to begin. She pulled thirty replies the drafting model had got wrong (real ones, from the archive, not ones anybody invented) and sorted them by what she would have had to change first.

Nineteen of the thirty were knowledge failures. The model did not know the current duty schedule, did not know that one customer had a negotiated rate, did not know which of three warehouses a consignment had been routed through. Six were format: the draft opened with an apology the firm never used, or put the tracking number at the bottom. Three were adherence: the draft ignored two of the four instructions in the prompt. Two were genuine capability failures involving a multi-leg date calculation.

Then she ran the paste test on the nineteen. She put the relevant document into the prompt (the duty circular, the rate card, the routing record) and asked again. Seventeen of the nineteen came back correct.

That is the whole finding, and it was available in a day and a half.

Sneha wrote it up plainly: the firm’s problem was that the model could not see its own records. Retrieval over the rate cards, the duty circulars and the shipment database would fix seventeen of thirty failures. Constrained decoding and five examples in the prompt would fix the six format ones. Fine-tuning was the right tool for perhaps three of the thirty, and for those three it would need a dataset, an evaluation set, and somebody to rebuild it every time the base model moved.

She also costed the version Ravi had proposed. Two thousand examples at five minutes each of somebody’s careful attention. A held-out set of two hundred, built first. Eight to fifteen training runs rather than one. A card to serve it on, or a provider that hosts adapters. And a standing question every six to nine months, when the base model was superseded, about whether to retrain or to stay frozen at last year’s quality.

Ravi read it and saw the difficulty immediately. The technical answer was clear. The organisational one was not. A director had told a customer the firm was building its own model. Coming back with “we are going to write a better prompt and connect the database” sounded, to anyone who had heard the first version, like a retreat.

The cost of the honest answer was a conversation Ravi did not want to have, and the visible shrinking of a project he had proposed. The cost of the other answer was six weeks, four lakh rupees, and a model that would still not know the duty schedule, because no amount of training installs a fact that changes every quarter, and training on those answers would have taught the system to state duty figures confidently whether or not it knew them.

How it played out

Ravi took the one-page finding to the directors himself, with the thirty sorted failures printed out and the paste-test results beside them. He did not soften it. The retrieval work took nine days, including connecting the shipment database, and moved the first-pass acceptance rate from 61 to 88 per cent. The format work took an afternoon. The three adherence failures were left alone.

The firm never fine-tuned anything. Four months later a new base model arrived that handled the multi-leg date calculation correctly, and the two capability failures disappeared without anybody doing work. The dataset Sneha had started (the seventeen hand-written replies from the paste test) became the few-shot examples in the prompt, and were still there a year on.

One director still describes the system as “our own AI”. Ravi has stopped correcting him.

Worth arguing about

  1. Sneha spent a day and a half on diagnosis before proposing anything. What did that day and a half actually buy, given that the project had already been approved?

    One answer

    It converted an approved project into a tested hypothesis. Before it, the firm had a complaint (the drafts are wrong) and a fashionable remedy. After it, it had thirty labelled failures, a paste test showing that seventeen of nineteen knowledge failures resolved when the document was in the context window, and therefore a specific prediction about what each remedy would fix. Approval is not evidence, and a budget that has been granted is exactly the situation in which nobody checks.

  2. Suppose the firm had trained on three thousand question-and-answer pairs drawn from the archive, without retrieval. What specific failure would that have produced, and why is it worse than the original problem?

    One answer

    It would have produced a hallucination amplifier. Every one of those examples demonstrates the same lesson: when asked about a shipment or a duty figure, produce a specific, confident answer in the house style. Asked about something outside the training set, the model does exactly that: it invents the figure. The result is worse than the starting point because the replies now sound like the firm’s most experienced clerk while being wrong, so the two people reading drafts have lost the cue that used to make them look twice.

  3. The directors had already told a customer the firm was building its own model. How should a decision record have handled that, and what would it have cost?

    One answer

    The record should have carried the failure quantified, the diagnosis with its evidence, a frozen baseline and a stated kill criterion, all written before any work started, so that abandoning the fine-tune was a pre-agreed outcome of a test rather than a reversal by one person. Its cost is twenty minutes and a more uncomfortable first meeting, because writing ‘we stop if retrieval closes the gap’ in front of the directors forces the smaller version of the project to be visible at the point of approval rather than six weeks later.

Test yourself6 questions on this modulePractice. Nothing is recorded and no score is kept.
  1. 1

    You take twenty real failures, hand-write the output you wanted for each, put five into the prompt and run the other fifteen. Thirteen now come out right. But at production volume your prompt has no room for the examples. What has the test told you?

  2. 2

    A team builds three thousand question-and-answer pairs from an internal wiki and trains on them without ever showing the model the wiki. What does the model learn?

  3. 3

    Your retrieval-augmented system answers 51 per cent of questions correctly. Measuring recall at five on fifty questions with known source passages gives 0.62. What follows?

  4. 4

    A routing task has six fixed queues and two thousand labelled tickets. What does a fine-tuned 150M encoder buy over prompting a large hosted model, and what does it cost?

  5. 5

    A student is distilled from a teacher that is wrong on six per cent of your inputs, with no filter between them. What happens to those six per cent?

  6. 6

    A fine-tune works well, and the base model family ships a meaningful upgrade every six to nine months. Which artefact decides whether that upgrade is an improvement or a threat?

How training actually works

9 lessons · 1 h 22

You will be able toTrace one optimisation step from a batch of tokens to a changed weight, and predict which way loss, memory and stability move when you change the learning rate, the batch size, the precision or the number of epochs.

  1. 2.1One training step, taken apart10 min
  2. 2.2Reading the loss number9 min
  3. 2.3Optimisers, and what their state costs9 min
  4. 2.4Learning rate, warmup and the schedule9 min
  5. 2.5Batch size, accumulation and the token count9 min
  6. 2.6Precision, and why bf16 ended a class of bugs9 min
  7. 2.7Where the memory actually goes10 min
  8. 2.8Epochs, overfitting and checkpoint selection9 min
  9. 2.9Regularisation that helps, and the kind that does not8 min
An illustrative case, built from documented patternsA free T4, a deadline, and a learning rateA district education office in Madhya Pradesh, adapting a small model to summarise school inspection reports in Hindi.

The office had four hundred school inspection reports a month, each two to six pages of Hindi prose written by a visiting officer, and a requirement that each be reduced to a six-line summary for the block education officer. Two clerks did this. It took them most of a week.

Anjali, on contract from a state technology cell, was given a month and no budget. No budget meant a free Kaggle notebook: a T4, sessions of up to twelve hours, roughly thirty GPU-hours a week.

Her first run diverged. The loss fell for forty steps, spiked, and became NaN at step 212. She restarted it. It reached step 190 and did the same. The logs were full of lines about the gradient scaler halving its scale.

She had copied a configuration from a tutorial: QLoRA on an 8B model, learning rate 2e-4, no warmup because the tutorial’s author had removed it, sequence length 1,024. The configuration was not unreasonable. It was written for an A100.

The T4 is a Turing card and has no bf16. Everything ran in fp16, which has a maximum representable value of 65,504 and a smallest normal value around six times ten to the minus five. Gradients below that round to zero, so fp16 training multiplies the loss by a large constant before the backward pass and divides it out afterwards; and when that constant is too large, gradients overflow to infinity and the framework throws the step away and halves the scale. A healthy fp16 run discards a step occasionally. Anjali’s was discarding them every few steps, and then diverging outright.

She had three ways forward, and a deadline in eleven days.

The first was to pay. A rented 24 GB card with bf16 costs somewhere around fifty rupees an hour on a community marketplace, and her whole run was perhaps two hours. The obstacle was not the money, which was trivial; it was that the office had no mechanism to spend it. A purchase of any size needed a sanction that took three weeks.

The second was to lower the learning rate and keep the free card. Halving it to 1e-4 and adding ten steps of warmup would very probably stabilise the run. It would also mean the adapter travelled less far in the same number of steps, and she would need more steps to reach the same place, on a card that was already the slow part.

The third was to use a smaller model. A 1.5B model in fp16 with a LoRA fits a T4 comfortably at sequence 2,048, trains several times faster, and at that size full fine-tuning is affordable too. The summaries would be less fluent. Hindi tokenisation on the 8B model she had chosen was already producing about three tokens per word, which was eating her sequence budget; a model with better Devanagari coverage would help more than any hyperparameter.

She ran the cheap experiment first, because it cost half an hour. Three runs of 150 steps each, at 1e-4, 2e-4 and 5e-4, on the 8B model, and she looked at the training loss curves rather than at anybody’s advice. At 5e-4 it spiked in the first fifty steps. At 2e-4 it fell and then rose. At 1e-4 it showed the shape she wanted: a fast drop in the first fifty steps, then a smoother decline, no scaler messages.

How it played out

Anjali took the second route and added the third. She trained at 1e-4 with ten steps of warmup on the 8B model overnight on Kaggle, and in parallel checked the tokeniser on a paragraph of real inspection prose across three model families. The 8B model she had started with produced 412 tokens; a model with better Devanagari coverage produced 168 for the same paragraph.

She switched to the second model, kept the learning rate at 1e-4, and the run finished in four hours inside one Kaggle session with checkpoints pushed to a private Hub repository every two hundred steps. Her sequence length now covered the ninety-fifth percentile of real reports rather than truncating a third of them.

Two things she recorded in the run log turned out to matter more than the training itself. Tokens per optimiser step, which she had to compute herself because nothing printed it, came out at 5,900: low, but not the 900 that would have made any learning rate useless. And a note that the divergence had been fp16, not a data problem, which stopped the next person in the office spending a day looking for a corrupted example.

The clerks now spend a morning a month checking summaries instead of a week writing them.

Worth arguing about

  1. Anjali’s first instinct could have been to look for a corrupted example in the data. Why was the hardware the right place to look first?

    One answer

    Because the symptom named the mechanism. Repeated messages about the gradient scaler reducing its scale are specific to fp16 loss scaling: they mean gradients are overflowing the format’s maximum of 65,504 and steps are being discarded. Corrupt data produces NaN too, but it does not produce a scaler that is working hard and halving repeatedly. The T4 has no bf16, so fp16 was forced, and a configuration written for an A100 carried a learning rate that a card with fp32’s exponent range would have tolerated.

  2. Why did changing the base model help more than any hyperparameter, and what did it change besides quality?

    One answer

    Tokeniser efficiency on Devanagari. The first model split the same paragraph into 412 tokens and the second into 168. That changes three things at once: how much real text fits in a fixed sequence length, how much of each example survives truncation, and how many positions a long-range dependency has to span. A word split into six fragments is harder to learn a representation for than one split into two, so the tokeniser was setting a ceiling that no learning rate could lift.

  3. The three 150-step runs cost half an hour on a free card. Why is that the cheapest half hour in the project, and what does each curve shape tell you?

    One answer

    Because the learning rate is the one hyperparameter that decides whether a run works at all, and a curve answers it directly. Loss falling slowly and roughly linearly with no elbow means the rate is too low. A clear fast drop in the first fifty steps followed by a smoother decline means it is about right. An early drop then a rise, visible spikes, or NaN means it is too high. Copying a number from a tutorial trained on different data, a different batch size and a different card is what the half hour replaces.

Test yourself6 questions on this modulePractice. Nothing is recorded and no score is kept.
  1. 1

    Some label positions in a training batch are set to minus one hundred. What does that do?

  2. 2

    You switch on completion-only masking and your training loss jumps from 0.9 to 1.6. What has happened?

  3. 3

    Why does a LoRA make the optimiser almost irrelevant to your memory planning?

  4. 4

    Why does a LoRA want a learning rate ten to twenty times higher than a full fine-tune?

  5. 5

    A config has per-device batch 2 and gradient accumulation 8 on one GPU, and logs 900 tokens per optimiser step. What should you change first?

  6. 6

    You are training on a free T4 and the log repeatedly reports the gradient scaler reducing its scale. What is happening?

Full, LoRA and the parameter-efficient family

9 lessons · 1 h 22

You will be able toPredict on paper the memory a given model, method and sequence length will need, choose between full fine-tuning, LoRA, QLoRA and the tiny methods for a stated budget, and justify a rank, an alpha and a target-module set.

  1. 3.1Full, LoRA, QLoRA, and the Memory Arithmetic10 min
  2. 3.2What LoRA is actually doing9 min
  3. 3.3Choosing rank, alpha and which modules to touch9 min
  4. 3.4QLoRA: quantising the part you are not training10 min
  5. 3.5DoRA, rsLoRA and the variant question9 min
  6. 3.6Soft prompts and prefixes8 min
  7. 3.7The tiny methods, and a gotcha in one of them8 min
  8. 3.8Full fine-tuning, when it is genuinely right9 min
  9. 3.9Training on a free or nearly free budget10 min
An illustrative case, built from documented patternsOne card, in the buildingA 180-bed hospital in Nashik, adapting a model to turn dictated ward notes into a structured discharge summary.

The hospital had one constraint that removed most of the options: patient notes could not leave its premises. No hosted model, no rented card in somebody else’s data centre, no batch endpoint. Whatever ran, ran on a single 24 GB workstation card that the radiology department had bought for something else and was willing to share overnight.

Dr Menon, who ran the project with one contract engineer, had three thousand dictated notes with a matching discharge summary written by a registrar. The task was narrow and well specified: take the dictation, produce eleven fields in a fixed order, in the hospital’s house phrasing, with the medication list formatted as the pharmacy wanted it.

The engineer, Faiz, laid out three options on one page, with the memory arithmetic done before anything was rented or downloaded.

Full fine-tuning an 8B model was out. Mixed precision with AdamW costs about sixteen bytes per parameter of persistent state: four for the fp32 master weights, four for the gradients, eight for AdamW’s two moment buffers. That is 128 GB before a single activation, on a card that has 24. Sharding across cards was not available; there was one card.

QLoRA on an 8B model fitted. The frozen base in NF4 is about 4.1 GB, the adapter and its optimiser state under a gigabyte, activations with gradient checkpointing a few more. Call it ten or eleven gigabytes, comfortably inside the card. The costs were real but bounded: roughly a quarter to a third lower throughput than an unquantised LoRA, because every matrix multiplication dequantises its weights on the fly; and an adapter fitted against a four-bit base, which makes merging into the full-precision base an approximation rather than an identity.

Full fine-tuning a 1.5B model also fitted. Sixteen bytes per parameter on 1.5 billion parameters is 24 GB, which is the whole card; but with 8-bit AdamW the optimiser state term falls from eight bytes to two, giving ten bytes per parameter, or 15 GB, with room for activations. Simpler: no adapters, no quantisation, no merging question at the end, one ordinary model to serve.

The decision was not obvious, and both sides had a cost the hospital would feel.

The 8B model would write better prose. Discharge summaries are read by general practitioners who did not see the patient, and fluency is not decoration there. But serving it meant the same card during the day, running a quantised model at a few requests a minute, and a merging step whose effect on quality nobody had measured.

The 1.5B model would be markedly faster to train and to serve, would run on the ward’s own machines if it ever needed to, and would be one artefact with no adapter to keep aligned with a base revision. Against that: a small model collapses rather than degrades when an input is unlike anything it saw. A dictation that wandered (and registrars’ dictations wander) would get triage-shaped output confidently.

Faiz did what the module recommends and ran the cheap version first. A QLoRA on the 8B model over the three thousand notes, two epochs, effective batch of sixteen, took under three hours overnight and told him something he had not expected: the eleven-field structure was learned almost perfectly within one epoch, and what the second epoch added was memorisation of individual registrars’ phrasings.

How it played out

Both models were trained and both were evaluated against the same two hundred held-out notes, split by registrar so that no author appeared on both sides.

The 8B QLoRA scored 0.94 on field-level exact match and its prose was preferred by two consultants in a blind pairwise comparison at a rate of about two to one. The fully fine-tuned 1.5B scored 0.91 on fields, and its prose lost the comparison.

What decided it was a third number neither of them had planned to collect. On fifty deliberately awkward dictations (interrupted, bilingual, with a correction spoken mid-sentence) the 1.5B model produced a confident, well-formatted, wrong summary in eleven cases. The 8B model produced a summary that was visibly incomplete in nine, which a registrar could see at a glance.

The hospital shipped the 8B QLoRA, unmerged, served with the adapter separate so that turning the fine-tune off is a flag rather than a redeploy. Faiz measured the merged version too, out of discipline, and recorded that merging into the full-precision base cost about one point of field accuracy. That number is written in the model card, and it is the reason the adapter is still unmerged.

Worth arguing about

  1. Full fine-tuning the 8B model was ruled out with arithmetic rather than an experiment. Show the arithmetic, and say why doing it on paper mattered here specifically.

    One answer

    Mixed-precision AdamW holds about sixteen bytes per parameter of persistent state: four bytes of fp32 master weights, four of fp32 gradients, and eight for AdamW’s two moment buffers. Eight billion parameters times sixteen bytes is 128 GB, before activations or the logits tensor, against a 24 GB card and no second card to shard onto. It mattered here because the hospital could not rent its way out of a wrong answer: there was exactly one card in the building, so an option that did not fit was not merely expensive, it was impossible.

  2. The failure that decided the comparison was not the headline metric. What was the mechanism behind it?

    One answer

    A small model has less capacity to represent behaviours outside the narrow one it was trained for, so off-distribution it collapses rather than degrading: it maps an unfamiliar input onto the shape it knows and produces confident, well-formatted output that is wrong. The larger model, with more behaviours available, produced visibly incomplete summaries instead: a failure a registrar could see. On a document a general practitioner will rely on without having seen the patient, a visible failure is far cheaper than a plausible one.

  3. Why did Faiz measure the merged model even though the hospital was going to serve the adapter separately?

    One answer

    Because the adapter was fitted against a four-bit base and merging it into the sixteen-bit base is not the same arithmetic, so merging can move quality by a point or two in either direction. Measuring it produced a number for the model card and made a future decision cheap: if somebody later needs a merged model for a serving engine without adapter support, the cost of that change is already known rather than being discovered under pressure. It is also the general rule of the course: evaluate the exact artefact you would serve, not a related one.

Test yourself6 questions on this modulePractice. Nothing is recorded and no score is kept.
  1. 1

    Mixed-precision full fine-tuning with AdamW costs about 16 bytes per parameter of persistent state. Which four things make up that figure?

  2. 2

    A 3B model is being fine-tuned on a 24 GB card. Why is QLoRA the wrong choice here?

  3. 3

    You have a fixed budget of trainable parameters for a LoRA. Where does the evidence say to spend it?

  4. 4

    Why should alpha be fixed at twice the rank rather than swept alongside the learning rate?

  5. 5

    Your trainable-parameter count prints zero and the loss curve is flat and innocent. What has gone wrong?

  6. 6

    BitFit trains only the bias terms of a model. Why is it close to a no-op on a Llama-style decoder?

Building the dataset

11 lessons · 1 h 41

You will be able toAssemble a training set from named sources with checked licences, convert it to one chat format, filter and deduplicate it, mix in replay data at a stated ratio, and publish a data card that lets a stranger reproduce the set.

  1. 4.1The Dataset Decides Everything11 min
  2. 4.2Where the data legitimately comes from9 min
  3. 4.3The three formats, and the conversion trap8 min
  4. 4.4Cleaning at scale9 min
  5. 4.5Writing the answers, and keeping them consistent9 min
  6. 4.6Generating a dataset from a teacher10 min
  7. 4.7Mixtures and replay9 min
  8. 4.8Packing, document boundaries and long context9 min
  9. 4.9Multi-turn conversations and tool calls9 min
  10. 4.10Memorisation, and what you cannot take back10 min
  11. 4.11The data card8 min
An illustrative case, built from documented patternsNine hundred examples, labelled before the rules existedAn education non-profit in Patna, building a model that replies to parents’ WhatsApp questions about school admissions and scholarships.

The non-profit answered about two thousand messages a month from parents, in Hindi, Bhojpuri-inflected Hindi, and a good deal of transliterated Hinglish. Four field staff answered them between other duties. The plan was a model that drafted the reply, with a person approving it.

Work started in June. Three volunteers wrote gold answers for real parent messages pulled from the archive, at a pace of about sixty a week each. By the third week they had 940 examples and everybody was pleased with the rate.

In the fourth week the project lead, Kavita, did the thing the module asks for and read a hundred of them from beginning to end.

They were not bad answers. That was the difficulty. Each one, taken alone, was something a careful person would have been content to send. Read together, they were four different people.

One volunteer opened every reply with a greeting and the parent’s name. One opened with the answer. One apologised when the news was unwelcome; the others stated the position. Two wrote amounts as “₹1,200” and one wrote “1200 rupees”. When the answer was not known, there were eleven different forms of words across the set, ranging from a promise to find out to a suggestion that the parent visit the office.

Lengths varied from one line to nine. Two volunteers showed their reasoning about eligibility; one gave only the conclusion. And the language mix varied with whoever had answered: one volunteer replied in Devanagari to transliterated questions, the others matched the parent’s script.

None of this was an error by any individual. It was a specification that had never been written down, which meant each volunteer had supplied their own.

Kavita understood what it would do. A model does not learn the right answer; it learns the distribution of the answers in front of it. Trained on that set, it would greet about a third of the time, apologise unpredictably, and produce one of eleven different ways of saying it did not know, which is the same as having no reliable way of declining at all. Every one of those unforced variations would become randomness in production, reproduced faithfully.

The decision was about the 940 examples.

Throwing them out meant losing three weeks of three volunteers’ evenings. The volunteers were unpaid, they had been told their work mattered, and two of them had exams in August. Asking them to redo it was asking for something Kavita was not sure she would get, and a project that loses its annotators in week four does not usually recover.

Keeping them meant training on a coin flip. It also meant that the style guide she was about to write would apply only to whatever came next, so the dataset would be half one thing and half another, which is the mixture that teaches a model that the system prompt is optional and the greeting is a matter of chance.

There was a third option she nearly took, which was to keep the 940 and add two thousand consistent ones on top, on the theory that the consistent majority would win. She talked herself out of it by working out what it actually said: that she would pay for two thousand more examples in order to drown out nine hundred she already had and could simply correct.

How it played out

Kavita wrote the style guide first: eight numbered rules on one page. No greeting, no apology for the scheme’s rules. Amounts as “₹1,200”. Match the parent’s script. One paragraph under sixty words unless listing steps. And rule five, with the exact words to use when the answer was not known, written out in full so that there was one form of decline rather than eleven.

Then she did not throw the 940 away and did not keep them as they were. She put them back in front of the same three volunteers as a rewriting task: the draft is there, apply the eight rules, change nothing else. Rewriting is one to two minutes an example against four to eight for writing from a blank page, so 940 examples came back corrected in nine evenings rather than three weeks. All three volunteers stayed.

Two other things came out of that week. Twelve of the 940 turned out to be genuinely ambiguous (the parent’s question could be read two ways) and those were pulled out of the training set and escalated as product questions rather than resolved by whoever happened to be holding them. And the rewriting surfaced four rules nobody had thought of, which went into the guide as rules nine to twelve.

At 2,400 examples the team ran a fresh batch of fifty. It produced no new rules and no new disagreements, and Kavita stopped hand-writing and moved the effort to varying the inputs instead.

Worth arguing about

  1. Each of the 940 answers was acceptable on its own. Explain precisely why the set was still unusable, in terms of what the training objective does.

    One answer

    Fine-tuning maximises the probability of the written answers given their inputs, so what the model acquires is the distribution of those answers, not their individual correctness. Anything that varies across the set without carrying information becomes noise the model reproduces faithfully: a greeting on roughly a third of replies, an apology at unpredictable moments, eleven different ways of declining. A model with eleven ways of saying it does not know has no reliable way of declining, which is exactly the behaviour the non-profit most needed to be dependable.

  2. Kavita considered keeping the 940 and adding two thousand consistent examples to outweigh them. What is wrong with that plan?

    One answer

    It spends new annotation effort to dilute a problem that correction would remove. The inconsistent examples do not become harmless when outnumbered; they keep contributing gradients that say the greeting is optional and the decline has many forms, so the model learns a mixture rather than a rule. And rewriting an existing draft costs one to two minutes against four to eight for writing a fresh example, so correcting 940 is cheaper than producing two thousand: the plan was both more expensive and worse.

  3. Twelve examples were removed rather than corrected. Why is removing them the right move, and what would including them have taught?

    One answer

    They were genuinely ambiguous: the parent’s question could be read two ways, so any gold answer is an arbitrary choice between readings. An ambiguous item with an arbitrary answer teaches the model to be arbitrary at exactly the point where you most want it to ask a clarifying question. Removing them keeps that randomness out of the weights, and escalating them treats them as what they are (product questions about what the service should do) rather than something for whoever happens to be labelling to decide alone.

Test yourself6 questions on this modulePractice. Nothing is recorded and no score is kept.
  1. 1

    Why must the held-out set be built before the training set rather than carved out of it afterwards?

  2. 2

    Every gold answer in your dataset was written carefully and averages four hundred words. What will the tuned model do with a yes-or-no question?

  3. 3

    You concatenate Alpaca’s instruction and input fields with a newline for training, while your serving code uses the original header format. What is the effect?

  4. 4

    Four per cent of your examples exceed your maximum sequence length and are silently truncated. What specific behaviour does that teach?

  5. 5

    Mixing fifteen to thirty per cent general instruction data into a task set preserves general capability better than lowering the learning rate does. Why?

  6. 6

    In a tool-calling conversation, which message must be masked, and what goes wrong if it is not?

Objectives beyond next-token prediction

9 lessons · 1 h 23

You will be able toChoose between supervised fine-tuning, a preference method such as DPO or KTO, a verifiable-reward method such as GRPO, and continued pretraining, and state the data each needs, the memory each costs, and the way each is gamed.

  1. 5.1What supervised fine-tuning cannot express9 min
  2. 5.2Where preference data comes from9 min
  3. 5.3DPO, from first principles10 min
  4. 5.4KTO, ORPO, SimPO and choosing among them9 min
  5. 5.5RLHF and PPO, honestly9 min
  6. 5.6Verifiable rewards and GRPO10 min
  7. 5.7Reward hacking9 min
  8. 5.8Continued pretraining on raw text9 min
  9. 5.9Training a head instead of generating tokens9 min
An illustrative case, built from documented patternsThe verifier that could be gamed, and the baseline that could notA small education-technology company in Hyderabad, building a model that writes SQL against a school management database for non-technical administrators.

The product let a head teacher type “how many girls in class eight have not paid the second term fee” and get a table. Behind it, a model wrote SQL against a fixed schema of forty tables, the query ran against a read-only replica, and the rows came back.

It worked about seventy-eight per cent of the time. The failures were not syntax (constrained decoding had taken care of that months earlier) but queries that ran cleanly and returned the wrong rows: a join through the wrong key, a term filter omitted, a count of enrolments where a count of pupils was wanted.

The team had something most teams do not: a real verifier. For eleven hundred questions they had a hand-written reference query and its result set on a test database. A generated query could be executed and its rows compared. Correct or not correct, instantly, at no cost, unlimited times.

That made reinforcement learning with a verifiable reward genuinely available, and the engineer leading it, Prakash, wanted to use GRPO. The argument was reasonable. Sampling eight completions per question and scoring them against the reference gives the group its own baseline, removes the value model that makes PPO expensive, and is the method behind the recent open reasoning models.

His colleague Divya proposed the dull alternative first: rejection-sampling fine-tuning. Generate eight completions per question with the existing model, keep only those whose result set matches the reference, train the model on those with ordinary supervised fine-tuning. No reinforcement learning, no reward function to tune, no generation loop inside a training loop.

The cost on each side was concrete. GRPO meant generating eight responses per prompt at every step, inside training, which put the run in GPU-days rather than hours; on a rented A100 that was the best part of a week of compute and, more importantly, two weeks of Prakash’s time on a method neither of them had run before. Rejection sampling meant one generation pass over eleven hundred questions (a few hours) and then a training run they had done ten times.

Divya’s argument was the one the module makes: rejection-sampling fine-tuning on verified outputs is the baseline you should beat before you reach for any of this.

Prakash’s counter was that the interesting failures were the ones the model never got right in eight samples, and rejection sampling learns nothing from those: it simply discards them.

That turned out to be the testable question, and it took an afternoon. They sampled the base model a hundred times on fifty held-out questions and counted how often the correct query appeared at least once. For thirty-nine of the fifty it did. For eleven it never did, across a hundred attempts.

That number decided a great deal. If a method that sharpens a model’s distribution towards paths it can already sometimes find is what reinforcement learning on verifiable rewards mostly does (and whether it teaches new capability or elicits existing capability is genuinely argued, with careful experiments on both sides) then the eleven questions the base model never solved were unlikely to be rescued by it either.

They also wrote down, before running anything, what a reward hack would look like. A query that returns an empty result set matches a reference whose answer is legitimately empty. A query that selects everything and lets the comparison sort it out. A query with the answer hard-coded as a literal, which is the SQL equivalent of returning 4181 when the test asks for the seventeenth term.

How it played out

They ran rejection sampling first. Eight samples per question at temperature 0.7, kept only where the result set matched, which produced 6,400 verified query pairs from the eleven hundred questions. One supervised fine-tuning run of two hours. Accuracy on the held-out set went from 0.78 to 0.89.

Then they ran the GRPO experiment anyway, on a two-week budget agreed in advance with a stated stopping rule. It reached 0.91. The extra two points sat just outside a three-seed noise floor of about 0.8 points, so it was a real effect and a small one.

Two findings made the difference more interesting than the number. The fraction of groups in which all eight sampled responses scored identically (logged from the first step, because Prakash had read that this is the commonest reason a GRPO run does nothing) ran at 41 per cent early on and had to be brought down with a small shaping reward for producing a well-formed query at all. And on the eleven questions the base model had never solved in a hundred attempts, the GRPO model solved none of them either.

The reward hack they had predicted arrived in week two. Queries that returned empty result sets rose from 2 per cent to 9 per cent of outputs, because an empty set matched every reference whose correct answer was also empty. A held-out reward they never trained against (a check that the query touched at least the tables the reference touched) caught it.

They shipped the rejection-sampled model. The GRPO work is in the ablation log, with its two points, its noise floor, and a note that the eleven unsolved questions need a different kind of help.

Worth arguing about

  1. Sampling the base model a hundred times on fifty questions cost an afternoon. What decision did that measurement inform, and why?

    One answer

    Whether reinforcement learning on a verifiable reward could plausibly help. There is an open argument about whether such training teaches new reasoning capability or mostly sharpens the model’s distribution towards paths it could already occasionally produce, and the evidence is genuinely mixed. If it is mostly sharpening, a problem the base model never solves in a hundred attempts is unlikely to be rescued by it. Eleven of fifty were in that category, which capped what the expensive method could deliver before any of it was run.

  2. Forty-one per cent of GRPO groups produced no gradient early in training. What causes that, and what is the standard remedy?

    One answer

    GRPO computes each response’s advantage relative to its own group: the reward minus the group mean, divided by the group standard deviation. If every response in a group scores the same (which happens when a pure correctness reward is zero for all eight early in training) the standard deviation is zero and the advantage is undefined or zero for all of them, so the group contributes nothing. The remedy is a shaping term that is achievable from the start, such as a small reward for producing a well-formed query, which keeps groups differentiated until correctness begins to fire.

  3. The empty-result-set exploit was predicted before training and detected by a reward the team never trained against. Why is a held-out reward the strongest instrument here?

    One answer

    Because optimisation pressure is precisely the process of finding where a proxy and the intent come apart, and the trained-against reward cannot report its own exploitation: by construction it is going up. A second measure of the same intent, never optimised, gives an independent reading: when the trained reward rises while the held-out one is flat or falling, the gap is the hack. It costs one extra scoring function, and here it named the artefact: a query returning nothing satisfies every reference whose correct answer is also nothing.

Test yourself6 questions on this modulePractice. Nothing is recorded and no score is kept.
  1. 1

    Your model has a hedging habit you dislike. Why can supervised fine-tuning only address it indirectly?

  2. 2

    Why must the rejected side of a preference pair come from the model you are about to train?

  3. 3

    During a DPO run, rewards/chosen and rewards/rejected are both falling while the margin widens. What is this?

  4. 4

    Your product collects thumbs-up and thumbs-down on single responses. Which method is built for that data?

  5. 5

    A GRPO run produces almost no gradient. What should you log first?

  6. 6

    You have fifty thousand internal documents, about fifty million tokens, and want the model to write in your domain’s register. What does that volume buy?

The mechanics of a run

10 lessons · 1 h 30

You will be able toConfigure and launch a fine-tuning job with the correct chat template, masking and tokenizer handling, and diagnose from the logs alone whether a run is not learning, diverging, or memorising.

  1. 6.1Chat Templates and Loss Masking9 min
  2. 6.2Running a LoRA, and What It Costs10 min
  3. 6.3The tokenizer is part of the model9 min
  4. 6.4Adding tokens, and initialising them properly8 min
  5. 6.5A working config, line by line10 min
  6. 6.6Debugging a run10 min
  7. 6.7What to log, and how to read it8 min
  8. 6.8Checkpointing and resuming8 min
  9. 6.9Reproducibility, and the noise floor9 min
  10. 6.10Multi-GPU without tears9 min
An illustrative case, built from documented patternsThe model that would not stop talkingA state helpline in Jaipur, three days before a launch, with a model that answers each question and then invents the next one.

The helpline took calls and messages about land record certificates. A model had been fine-tuned to draft the written replies, and it was good: the register was right, the document names were right, the steps were in the order the counter clerks used.

It also, on roughly one reply in three, answered the question, then wrote a new question from the citizen, then answered that one too. Sometimes for four turns. The text was fluent throughout and increasingly invented.

The team had three days. The launch date had been in a press note.

Their first fix took twenty minutes and worked. The serving layer accepted a stop string, so they set it to the sequence that preceded a user turn, and the extra conversation disappeared from every response. They demonstrated it to the programme director on a Tuesday afternoon and she was satisfied.

The engineer, Imran, was not, and he said so in a way that made the next two days awkward. A stop string at the API layer hides a symptom. Whatever had taught the model to continue was still in the weights, and it would surface somewhere else: in a reply that trailed off mid-sentence because the stop string fired early, in a long answer that ran to the token limit, in the next fine-tune built on the same pipeline.

He spent an hour on the four checks the course prescribes before any run, which nobody had done before the original run.

The first check printed one templated example. It looked correct.

The second check was the one that answered it. He decoded the unmasked labels of a real batch (the tokens the model was actually being scored on) and printed them beside the masked ones. The trained region was the assistant’s reply, correctly, and it ended one token early. The end-of-turn token was in the masked region.

The cause was two lines of ordinary setup. The base model shipped without a pad token, as many do, so somebody had written the near-universal workaround of setting the pad token equal to the end-of-sequence token. The collator then built its label mask by matching on the pad id. Every position holding that id was masked, including the real end-of-sequence token at the end of every answer.

The model had therefore never once received a gradient teaching it to stop. It had been trained, thousands of times, on answers that simply ended, with nothing marking the ending as something to produce. At inference it did the only thing it had been shown: it kept going.

The loss curve had been healthy throughout. Nothing in the training logs was wrong. The bug was invisible in every number the run produced and visible in five seconds of decoded labels.

Imran’s proposal was to add a distinct pad token, resize the embeddings, rebuild the mask from the attention mask rather than from the token id, and retrain. The run itself was two and a half hours. The evaluation was another half day. Realistically it put the launch two days late.

Against that, the director’s position was not unreasonable. The stop string worked. The demonstration had been fine. A press note had a date on it, and a delay would have to be explained upwards.

How it played out

They compromised in a way that turned out to be the right shape. The launch went ahead on the announced date with the stop string in place, and the retraining ran the same night with the pad token fixed.

The retrained adapter was evaluated against the same two hundred held-out messages three days later and replaced the first one in a quiet deployment the following week. The stop string stayed, because it costs nothing and a fine-tuned model still occasionally overruns.

Two things came out of the week that outlasted the incident. The four checks went into the repository as a script that the training job runs and prints before it starts: one templated example, the decoded unmasked labels, the trainable parameter count, and the first three token ids. Nobody has to remember to run it.

And when the second model in the same programme was trained two months later, on a different base with a different template, the same script printed a trained region that contained the entire conversation including the citizen’s message. That would have taught the model to write both sides. It was caught before the run, in five seconds, at a cost of nothing.

Worth arguing about

  1. The training loss curve looked healthy throughout. Explain why a masking bug of this kind is invisible in the loss.

    One answer

    Loss is computed only over unmasked positions, so masking the end-of-turn token simply removes it from the average rather than making the average worse. The model was learning the task it was actually given (produce the body of the answer) and doing it well, so the curve fell and flattened normally. Masked positions are not down-weighted, they are absent, which means a wrong mask makes the model learn a different task from the one you think while every number on the dashboard stays reassuring.

  2. Setting the pad token equal to the end-of-sequence token is standard advice. What makes it a trap, and what are the two correct fixes?

    One answer

    It is a trap when the collator builds its label mask by matching on the pad id, because the real end-of-sequence token at the end of each answer carries that same id and is masked with the padding. The model then never receives a gradient teaching it to stop. The two fixes are to add a distinct pad token and resize the embeddings, which costs one embedding row; or to build the mask from the attention mask instead, since the attention mask already records which positions the collator padded.

  3. The stop string worked and cost twenty minutes. Make the case for retraining anyway, and the case against.

    One answer

    For: a stop string hides a symptom without removing its cause, so the same defect surfaces elsewhere: replies truncated when the string fires early, long answers running to the token limit with no learned ending, and the same broken pipeline inherited by the next fine-tune. Against: the launch date was public, the fix was demonstrated and working, and two days of delay has a cost somebody has to explain. The resolution used here takes both seriously: ship on the date with the mitigation, retrain the same night, and replace the artefact quietly once it has been evaluated.

Test yourself6 questions on this modulePractice. Nothing is recorded and no score is kept.
  1. 1

    You decode the unmasked labels of one real batch and nothing prints. What does that mean?

  2. 2

    Before a real run you train on eight examples for a hundred steps and the loss does not approach zero. What have you learned?

  3. 3

    You apply the chat template to get a string, then tokenize that string with default settings. What have you done?

  4. 4

    A run’s gradient norm has been climbing steadily for four hundred steps while the loss still looks fine. What does that tell you?

  5. 5

    You resume a four-GPU run on two GPUs from a complete checkpoint. What happens?

  6. 6

    Three runs of one configuration with seeds 0, 1 and 2 score 0.871, 0.858 and 0.884. A change you made scores 0.879. What can you conclude?

Fine-tuning beyond a chat model

9 lessons · 1 h 21

You will be able toAdapt an embedding model, a reranker, a text classifier, a speech model, a vision-language model or an image generator, and name in each case what differs from fine-tuning a text LM and which cheaper technique should be tried first.

  1. 7.1Fine-tuning an embedding model10 min
  2. 7.2Training a reranker8 min
  3. 7.3Fine-tuning a classifier properly9 min
  4. 7.4Fine-tuning a speech model9 min
  5. 7.5Fine-tuning a vision-language model9 min
  6. 7.6LoRA for image models, and the likeness question10 min
  7. 7.7Getting structure without training for it9 min
  8. 7.8Small models, where fine-tuning matters most9 min
  9. 7.9Tabular and time series: the honest answer8 min
An illustrative case, built from documented patternsThe vision model and the scannerA chartered accountancy practice in Ahmedabad, processing about four thousand supplier invoices a month for forty small-business clients.

The practice had two articled clerks keying invoice data into accounting software: supplier name, GSTIN, invoice number, date, taxable value, tax split, total. Most invoices arrived as PDFs by email, some as photographs of paper taken on a phone, and a few hundred a month as scans of handwritten delivery challans from clients in the textile trade.

The partner who had read about it, Nilesh, wanted to fine-tune a vision-language model. The appeal was obvious: one model, any image, out comes structured data. He had found a recipe, and a rented card for a day was affordable.

The engineer the practice retained, Priya, asked for an afternoon before anything was trained, and ran the comparison the module recommends. Fifty pages, drawn deliberately: thirty machine-printed PDF invoices, ten phone photographs of printed invoices, ten scans of handwritten challans.

Pipeline A was an OCR engine with layout output feeding a text model that had been given five examples in its prompt and a constrained decoder enforcing the schema. Nothing was trained.

Pipeline B was an off-the-shelf vision-language model, prompted, also with a constrained decoder. Nothing was trained.

On the thirty printed PDFs the OCR pipeline extracted all seven fields correctly on twenty-nine. The vision model managed twenty-five, and three of its four failures were the GSTIN: a fifteen-character alphanumeric string where a single wrong character makes the record useless, and where reading is exactly what an OCR specialist is built for.

On the ten phone photographs they were close: OCR eight, vision model eight, failing on different pages.

On the ten handwritten challans the OCR pipeline extracted almost nothing usable. The vision model got six.

Priya also measured something Nilesh had not asked about, and it changed the shape of the decision. She encoded one full-resolution invoice page and printed how many sequence positions it consumed in the vision model. At the resolution needed to read the tax table, the page occupied well over a thousand positions, and the model tiled larger images, multiplying that. Activation memory scales with sequence length, so a training batch of four pages needed more memory than a batch of thirty-two text examples. Her effective batch would be one or two per device with heavy accumulation, and the run Nilesh had budgeted a day for was closer to three.

So the choice was not between two tools. It was between one architecture and two.

Fine-tuning the vision model on everything meant one artefact, one evaluation, one thing to maintain, and worse accuracy on the eighty-five per cent of the volume that was printed, at several times the cost per page, with failures that are hard to inspect because you cannot look at an intermediate output and see where the reading went wrong.

Running both pipelines meant two things to maintain, a router deciding which page goes where, and the clerks seeing two different failure modes. Against that it put a specialist on each job: the OCR engine on printed text, where it is simply better, and the vision model on handwriting, where layout and stroke carry meaning that survives no text extraction.

How it played out

The practice built the router and ran both. The router is not a model: challans arrive from a known set of clients in a known format, so a rule on the sender and the document dimensions sends the right pages to the right pipeline, with a fallback to the vision model when the OCR output has fewer characters than a printed invoice could plausibly contain.

Printed invoices and photographs (about 3,700 a month) go through OCR into a prompted text model with constrained decoding. Nothing in that path was trained at all.

The handwritten challans go to a vision-language model that was fine-tuned, but not the way Nilesh first proposed. The vision encoder was frozen, the projector trained, and the language model adapted with a LoRA, on 900 challan-and-answer pairs the clerks produced over three weeks from their own keying work. Input resolution was set deliberately at the point where the handwritten quantity column was still legible and no higher, because lowering it was the most effective memory lever available and it cost only the detail that had been lowered.

The number the partners care about is that the two clerks now key exceptions rather than invoices, and the exception rate is eleven per cent. The number Priya cares about is that when a field is wrong on a printed invoice, she can open the OCR output and see whether the reading failed or the extraction did, which on the vision path she cannot.

Worth arguing about

  1. Priya ran both pipelines on fifty pages before anything was trained. What made that afternoon decisive rather than merely informative?

    One answer

    It settled an architecture, not a hyperparameter. The comparison showed that the two tools failed on different populations (OCR was better on the 85 per cent of volume that was printed, and unusable on handwriting where the vision model succeeded) which meant the right answer was two pipelines and a router rather than a choice between them. No amount of training either model would have produced that finding, because it is a fact about which specialist suits which input, and it cost an afternoon against a three-day training run aimed at the wrong target.

  2. Why did the GSTIN failures matter more than the raw accuracy gap suggests?

    One answer

    Because a GSTIN is a fifteen-character alphanumeric identifier where one wrong character makes the whole record useless and the error is not self-evident, unlike a slightly mis-read supplier name, which a clerk notices. Reading exact strings is precisely what an OCR engine is specialised for and precisely where a model that has compressed an image into embeddings is weak. Field-level accuracy averaged across seven fields hides the fact that the failures concentrated in the one field whose failure is most expensive.

  3. In the vision path, the encoder was frozen and the input resolution capped. Explain what each choice bought and what it cost.

    One answer

    Freezing the vision encoder keeps the part trained on far more images than the practice has, which reduces memory and reduces the damage a small dataset can do; the cost is that the model cannot adapt how it sees, only how it describes what it sees: acceptable because the challans are ordinary photographs, not a new imaging modality. Capping the resolution reduces the number of sequence positions an image occupies, which is the most effective memory lever in vision-language training since activation memory scales with sequence length; the cost is exactly the detail removed, so the cap was set at the point where the handwritten quantity column was still legible.

Test yourself6 questions on this modulePractice. Nothing is recorded and no score is kept.
  1. 1

    Why is batch size the important hyperparameter when training an embedding model with multiple-negatives ranking loss?

  2. 2

    Why mine hard negatives from ranks ten to fifty rather than from the very top of the retrieved list?

  3. 3

    Why does a cross-encoder rerank fifty candidates rather than search the corpus itself?

  4. 4

    A six-way routing model’s data is 62 per cent one class. Why is accuracy the wrong headline metric?

  5. 5

    Constrained decoding guarantees that your output parses. What does it not guarantee?

  6. 6

    You must predict churn from a table of customer columns. Where does a language model belong?

Did it actually work

9 lessons · 1 h 20

You will be able toCompare a tuned model against a cost-matched baseline on a leak-free held-out set, report the difference with an interval, and demonstrate whether general capability, safety behaviour or calibration regressed.

  1. 8.1Did It Help, and What Did It Break10 min
  2. 8.2The baseline you must beat9 min
  3. 8.3A held-out set that actually holds9 min
  4. 8.4Pairwise human comparison, done properly9 min
  5. 8.5Judging a model you distilled from the judge9 min
  6. 8.6Contamination you can check, and contamination you cannot9 min
  7. 8.7Safety regression, including from benign data9 min
  8. 8.8Calibration after tuning8 min
  9. 8.9Ablations that earn their cost8 min
An illustrative case, built from documented patternsNinety-four, then seventy-nineA three-hospital group in Kochi, one week before launching a model that sorts incoming patient messages into six clinical queues.

The number on the slide was 0.94. Routing accuracy, six queues, on a held-out set of six hundred messages. The base model with the best prompt the team could write had scored 0.86. The project had run for eleven weeks and the figure had been shown to the group’s medical director twice.

Four days before the launch, a data analyst called Meera was asked to write the evaluation section of the model card. She needed to state how the held-out set had been constructed, and discovered that nobody had written it down.

The split had been random. Six thousand messages, shuffled, ninety per cent for training and ten per cent held out.

She ran three checks, each of which took under an hour.

The first was near-duplicate overlap across the split. She built a MinHash index over the training texts and queried every evaluation item against it. Eighty-one of the six hundred evaluation messages had a near-duplicate in the training set: thirteen and a half per cent. Patients ask the same things in the same words, and appointment-rescheduling messages in particular are close to templated.

The second was group leakage. The messages carried a patient identifier. Two hundred and six of the six hundred evaluation messages came from patients who also appeared in training, some of them with a dozen messages each. The model had learned individual patients’ phrasing, their conditions, the department they usually wrote to.

The third was time. The data ran from January to August. A random split had put August in training and February in evaluation, which is the reverse of what production does. In May the group had merged two departments and renamed a queue.

She rebuilt the split properly: grouped by patient, cut at a date so that everything after the first of July was evaluation and everything before was training, and removed evaluation items with a near-duplicate on the other side.

The model scored 0.79.

The prompt baseline, re-run on the same corrected set, scored 0.77.

That is the whole finding. Eleven weeks of work had bought two points, not eight, and on a corrected set of four hundred and eleven items the ninety-five per cent interval on a difference of two points comfortably includes zero.

The decision Meera put in front of the project lead was not whether the model was good. It was what to say, four days before a launch, about a number that had been shown to the medical director twice.

Launching on the old number meant a figure in a model card that the team now knew was inflated by leakage, in a clinical setting, where the queue a message lands in determines how quickly somebody reads it. Correcting it meant explaining that the headline figure had been wrong for eleven weeks, that the honest gap over a prompt was within noise, and that the launch should probably be a pilot rather than a launch.

There was also a third thing, which Meera raised and which nobody had thought about at all. Nobody had run a refusal set. The messages included requests for medical advice that the system was never intended to answer, and no one had measured whether the fine-tuned model still declined them as the base model had.

How it played out

The project lead took the corrected numbers to the medical director himself, with the three leakage measurements attached. The launch became a four-week pilot on one hospital, with every routed message still read by the triage nurse who had been reading them before.

The refusal check was run that week. On a hundred and fifty prompts the base model had declined (requests for a diagnosis, for a medication change, for another patient’s information) the base refused 141 and the tuned model refused 96. Nothing in the training data had been harmful; it was six thousand examples all demonstrating that a message gets answered.

Sixty refusal examples in the hospital’s own wording went into the training set, a replay mixture of fifteen per cent general instruction data went in with them, and the model was retrained. Refusals came back to 138. Routing accuracy on the corrected held-out set moved from 0.79 to 0.78, which was inside the three-seed noise floor of 1.1 points.

The pilot ran. The model is in production now on one queue at a time. The evaluation set has a rule attached to it that Meera wrote: it is grouped by patient, cut by date, checked for thirteen-gram overlap, and every message the system routes wrongly in production is added to it that day.

Worth arguing about

  1. Three separate leaks were found in one random split. Name each and the fix, and say which one inflates a score most invisibly.

    One answer

    Near-duplicate leakage, variations of the same message on both sides, fixed by measuring cross-split overlap with MinHash and removing the matches. Group leakage, the same patients on both sides, fixed by splitting on the patient identifier rather than the row. Temporal leakage, training on August and testing on February, fixed by cutting at a date so evaluation is entirely in the future. The near-duplicate one is the most invisible: it leaves no field to group by and no date to inspect, it is not visible by reading either set, and almost nobody measures it.

  2. On the corrected set the tuned model scored 0.79 and the prompt baseline 0.77. Why is it wrong to call that a two-point improvement?

    One answer

    Because neither number is exact. On four hundred and eleven items the ninety-five per cent interval on a proportion near 0.78 is roughly plus or minus four points, so a two-point gap is well inside it. On top of that sits the training noise floor (the spread across seeds, measured here at about 1.1 points), which is a second, separate uncertainty. A difference smaller than about twice the seed spread, on a set too small to resolve it, is a coin flip that has been given a name.

  3. The refusal regression came from entirely benign data. Explain the mechanism, and why the fix costs an afternoon.

    One answer

    Alignment is a thin, late layer installed on comparatively little data, and every training example in the set demonstrated a request being answered; so the gradient repeatedly taught that the assistant’s job is to produce an answer, and the model generalised that beyond the requests intended. The fix is cheap because it is a data fix: thirty to a hundred examples of the model declining appropriately, in the product’s own wording, plus a replay mixture of general instruction data. It also gives the model a way of declining that suits the hospital rather than a generic refusal from somewhere else.

Test yourself6 questions on this modulePractice. Nothing is recorded and no score is kept.
  1. 1

    A tuned model wins 58 of 100 blind pairwise comparisons against the baseline. What is the honest reading?

  2. 2

    You tuned an 8B model to save money against a hosted frontier model. What is the honest comparison?

  3. 3

    Your random split scores 0.94 and a group-and-time split of the same data scores 0.79. What best explains the gap?

  4. 4

    Your tuned model’s answers are fifty per cent longer and win 60 per cent of comparisons. What do you do next?

  5. 5

    A student distilled from a large teacher beats that teacher on a teacher-judged comparison. What should you conclude first?

  6. 6

    You route to an expensive model whenever confidence falls below 0.7. What does fine-tuning do to that rule?

Shipping it, and living with it

9 lessons · 1 h 19

You will be able toServe a tuned model or adapter at a stated cost and latency, monitor it for drift, reproduce a six-month-old artefact from its recorded version, and plan for the day the base model is replaced.

  1. 9.1Serving the Adapter9 min
  2. 9.2Quantising the model you ship9 min
  3. 9.3Serving many adapters from one base8 min
  4. 9.4The cost at steady state9 min
  5. 9.5Monitoring a model that fails silently9 min
  6. 9.6The day the base model moves9 min
  7. 9.7Versioning so a model can be explained later8 min
  8. 9.8Model cards and disclosure9 min
  9. 9.9Retiring a fine-tune9 min
An illustrative case, built from documented patternsThe fine-tune that the quantiser rounded awayA coaching centre chain in Kota, shipping an offline doubt-solving assistant on low-cost Android tablets to sixty rural study centres with no reliable internet.

The centres had tablets, two gigabytes of usable RAM each, and no connectivity worth depending on. The product was a model that answered physics and chemistry doubts in the chain’s own explanatory style (a fixed structure of restate, principle, working, common mistake) which the teaching staff had spent years standardising and which the students recognised.

The team fine-tuned a 1.5B model. At that size full fine-tuning was affordable and simpler than an adapter, and the results were good. On four hundred held-out doubts the tuned model produced the four-part structure on 96 per cent of answers against 31 per cent for the base model with the best prompt, and two senior teachers preferred its explanations in a blind comparison at better than three to one.

Then it was converted for the tablets: merged, converted to GGUF, quantised to Q4_K_M, which brought the file to about a gigabyte and made it fit.

The first field build came back from two centres with the same complaint. The answers were fine but they were not the chain’s answers. No four-part structure. The common-mistake paragraph, which the teachers considered the most useful part, was simply absent most of the time.

The engineer, Tanvi, assumed a template problem and spent a day on it. The Modelfile template was correct and matched training. The prompt was identical. The tokenizer was the one saved beside the weights.

What she had not done was evaluate the artefact she shipped. Every number in the project came from the fp16 model on the training rig.

She ran the three-way comparison, which took twenty minutes: base quantised, tuned fp16, tuned quantised, on the same four hundred doubts. The tuned fp16 model produced the structure on 96 per cent. The tuned quantised model produced it on 44 per cent. The quantised base produced it on 29 per cent.

The fine-tune had very nearly been rounded away.

The mechanism is unglamorous. Her training had changed the weights by a small amount: full fine-tuning of a small model over four thousand examples is still a modest perturbation. Quantisation error at four bits is roughly constant per weight, and on a 1.5B model there is much less redundancy to absorb it than on an 8B one. When the quantisation error is of comparable size to the change training made, the change is rounded away, and the quantised tuned model behaves substantially like the quantised base.

Her options each cost something the chain would feel.

Ship at Q8_0. About 1.8 GB instead of 1.0, which on a tablet with two gigabytes of usable RAM does not leave room for the application. Some centres had newer tablets; most did not.

Ship a larger model at four bits, where quantisation costs proportionally less. A 3B model at Q4_K_M is around two gigabytes, which is worse on the same tablets, and slower on processors already producing a few tokens a second.

Train harder, so that the delta is larger than the quantisation error. More epochs and a higher learning rate would push the weights further, and on a 1.5B model that also means more memorisation and a sharper collapse on doubts unlike anything in the training set, which in a subject where students ask strange questions is not a small cost.

Accept 44 per cent, and have the application enforce the structure instead.

How it played out

She took the fourth option and a part of the third, and the order in which she tried them is the lesson.

Constrained decoding came first, because it was free and immediate. The four-part structure is a grammar: four labelled sections in a fixed order. Enforced at sampling time, the structure went to 100 per cent on the quantised model, because invalid output was not merely unlikely, it was not available. What the constraint could not fix was the content inside the sections, and the common-mistake paragraph was often thin.

Then she retrained, once, with a modest change: three epochs instead of two, and a larger share of examples whose common-mistake paragraph was the substantial part. The structure was already guaranteed by the constraint, so training could spend its capacity on content rather than on shape.

The quantised model that shipped scores 0.88 on a teacher-rated content rubric against 0.91 for the fp16 version: a real cost, measured, written in the model card, and accepted.

Three things changed in how the team works. The evaluation script now takes a path and a backend, so running it against the final quantised file costs nothing and happens on every build. The build target ends with the evaluation rather than with the conversion. And the constrained decoder was kept after retraining rather than removed, because it costs nothing to keep and a fine-tuned model still produces invalid output occasionally.

Worth arguing about

  1. Explain the mechanism by which four-bit quantisation nearly erased this fine-tune, and why a 1.5B model was especially exposed.

    One answer

    Training moved the weights by a modest amount, and quantisation introduces an error that is roughly constant per weight. When that error is of comparable size to the change training made, the change is rounded away and the quantised tuned model behaves like the quantised base. A small model is more exposed because it has less redundancy to absorb the same per-weight error, so the proportional damage is larger, which is why anything under about 3B is usually better served at eight bits than at four.

  2. Tanvi spent a day on the chat template before finding the real cause. What check, run in twenty minutes, would have pointed at it immediately?

    One answer

    The three-way comparison: quantised base, tuned fp16, and tuned quantised, on the same held-out set. Its shape names the culprit directly: if the tuned fp16 model scores well and the tuned quantised model scores near the quantised base, the loss happened in the conversion rather than in the training or the serving configuration. More generally, the rule it enforces is to evaluate the exact artefact you will serve, since merging, quantising, format conversion and engine choice each change the model and none of them announce it.

  3. Constrained decoding was applied before retraining, and kept afterwards. Justify both decisions.

    One answer

    It was applied first because it is free, immediate and guaranteed: a state machine built from the required structure removes illegal continuations at every step, so invalid output cannot be produced rather than merely being rare. It was kept afterwards because the two are not alternatives: a fine-tuned model still produces invalid output occasionally, the constraint costs nothing per request, and with the shape guaranteed the training run could spend its capacity on the content inside the sections instead of on the format.

Test yourself6 questions on this modulePractice. Nothing is recorded and no score is kept.
  1. 1

    An adapter is loaded against a base model repository that has been updated in place since training. What do you see?

  2. 2

    A tuned 1.5B model scores well in fp16 and behaves like the base model after conversion to four-bit GGUF. What happened?

  3. 3

    You plan fifty per-customer adapters. Which cost do teams usually discover only after the serving layer is built?

  4. 4

    At two million requests a month, a self-hosted tuned 8B on two redundant cards costs about $1,168 and a hosted small model about $720. What does that show?

  5. 5

    Which unlabelled production signal is the strongest indication that an answer was bad?

  6. 6

    A fine-tune still performs well, but nobody can say what it was trained on and the pipeline has not been run in a year. What follows?

What this course is

Fine-tuning is the most over-reached tool in applied machine learning. This course opens with the honest answer (a better prompt or retrieval solves most of what people want fine-tuning for) and then, for the cases that survive that test, teaches the practice end to end: what training actually changes and what it cannot add, LoRA and QLoRA memory arithmetic you can do on paper, building a dataset and the held-out set that has to come before it, chat templates and loss masking, running a job on a free T4 or a rented card for pennies, catching catastrophic forgetting, measuring whether it helped, and serving the adapter. Written for a mid-range laptop as readily as a rented A100.

Who wrote it

Founder and series editor: Dr Mustafa Mun. Written by AI models to a written standard. Exam keys checked blind by a second model: 3,665 of 3,666 agreed. Academic review invited.

More in Go underneath

  1. The Maths You Actually Need76 lessonsEight ideas that carry almost all the weight in machine learning.
  2. The Open Model Ecosystem71 lessonsLlama, Mistral, Qwen, DeepSeek, Gemma, Phi: what is real and what is marketing.
  3. Running Models Yourself82 lessonsLocal and self-hosted LLMs, with the arithmetic instead of the marketing.