LearnThatStack Ace your next interview

Fine-Tuning & Model Customization

Hugging Face PEFT and TRL, as of September 2026 Checked Sep 2026 19 code snippets

The model

  • Fine-tuning takes a trained model and keeps training it on your examples, with pretraining's next-token loss and a small learning rate.
  • Fine-tuning changes how a model answers, like its format, tone and tool calls. Use RAG for what it should know.
  • LoRA freezes the base model and trains a small adapter beside it. QLoRA stores that base in 4-bit, so an 8B model fits a 24 GB GPU.
  • Data quality matters more than volume. A few hundred clean rows from real traffic, all in one format, beat thousands of scraped ones.
  • Training loss always falls. Judge a fine-tune on held-out evals against the prompted base model, and check what it forgot.
DatasetJSONL rows, pairsTraining runLoRA on frozen baseEval gateheld-out examplesProductionadapter or mergedTRAINSFT or DPOcheckpointship if it beats baseLOOPretrain if it failslog and curate
A checkpoint ships only if it beats the prompted base model on held-out evals. Real traffic feeds the next round.

When to fine-tune

prompting, RAG, fine-tuning or pretraining

Fine-tuning vs pretraining

Say what fine-tuning starts fromA trained model. Pretraining starts from random weights. Both use next-token loss.
Tell instruction tuning from task tuningBreadth. Instruction tuning spans many tasks. Task tuning trains one narrow job.

TrapA high learning rate or too many epochs erodes what pretraining built.

Good at behavior, bad at facts

Name what fine-tuning is good atFormat, tone, one narrow task, tool-call shapes, and moving work to a smaller model.
Say why it's bad at new factsA small run learns the shape of an answer, then invents the details.
Update a fact that changedRAG needs one document edit. A fine-tune needs a new training run and eval.

TrapTraining on facts the base never saw rewards confident guessing. Hallucination can rise elsewhere too.

Prompt, RAG, fine-tune or pretrain

Pick the first thing to tryPrompting. Stay there while you can put the behavior into words.
Give the model private or fresh factsRAG. It changes the context, not the weights.
Know when to fine-tuneWhen prompts work but are long, slow or unreliable.
Know when to run continued pretrainingFor text the base model barely understands. It takes billions of raw tokens, then SFT again.

TipThese stack. Most systems run prompting plus RAG, and add a fine-tune later for cost or consistency.

Pick a base model

Pick the model sizeThe smallest one that already does the task sometimes, with a good prompt.
Choose the instruct or the base checkpointInstruct for a small style shift. Base for a big dataset or a custom format.
Choose between two or three candidatesTune each on the same 1,000 examples and compare them on your own eval.

TipCheck the license, context length, tokenizer coverage and serving support first.

TrapFine-tuning rarely creates a skill the base model lacks. It sharpens one that's already there.

Supervised fine-tuning

what one step does, and the settings to start with

One SFT step

Say what the loss measuresCross-entropy. It measures how surprised the model was by each of your actual tokens.
Update the weightsout.loss.backward()optimizer.step()Backprop gives each weight a gradient, and the optimizer takes a small step.

TrapFine-tuning stores nothing and looks nothing up. It makes answers like yours more likely.

Mask the loss

Score only the assistant tokenslabels[:len(prompt_ids)] = -100Cross-entropy skips any label set to -100.
Say why masking mattersA 2,000-token prompt would drown the signal from a 50-token answer.
Teach the model to stopKeep the end-of-turn token in the loss. Mask it and the model never learns to stop.

TipMask padding too. Then decode one batch and check which positions are -100.

Match the chat template

See the exact string the model trains ontok.apply_chat_template(messages, tokenize=False)
Catch a doubled BOS tokenThe trainer and the template both add one. It's invisible in the JSONL and costs accuracy.
Check that training matches servingRender a row with the serving tokenizer and diff it against a real request.

TrapA template mismatch between training and serving fails silently. The outputs just get worse.

Starting hyperparameters

Set the learning ratelearning_rate: 2.0e-41e-4 to 2e-4 for LoRA. 1e-5 to 2e-5 for full fine-tuning.
Pick the number of epochsnum_train_epochs: 32 to 3. Small datasets memorize fast after that.
Get an effective batch of 32per_device_train_batch_size: 4gradient_accumulation_steps: 8Aim for 16 to 64 sequences.
Set the max sequence lengthCover your 95th-percentile row, or truncation cuts off answers.

TipCosine decay with 3 to 5% warmup rarely needs tuning. Change one setting at a time.

LoRA & QLoRA

train a small adapter, freeze the rest

How LoRA works

xW frozenAB+h
LoRA layerx runs through frozen W and through A then B. The sum is output h. Only A and B train.
Write the LoRA forward passh = x @ W.T + (alpha / r) * (x @ A.T) @ B.TW stays frozen. The rank r is often 8 to 64.
Say why training starts at the base modelB starts at zero, so the update BA is zero on step one.
Say why LoRA became the defaultOne mid-range GPU, megabyte adapters, and near full quality on narrow tasks.

Set rank, alpha and targets

Start with a standard configLoraConfig(r=16, lora_alpha=32, target_modules="all-linear")
Say what rank and alpha controlRank sets capacity. Alpha only scales the update, by alpha / r.
Add capacity for a new skillRaise rank to 32 or 64 and keep alpha at 2r, so the step size stays the same.
Choose which layers to adaptEvery linear layer, in attention and the MLP. The MLP holds most of the weights.

TipCoverage beats rank. In QLoRA's tests, LoRA matched full fine-tuning only on all linear layers.

TrapLeave the embeddings and lm_head out unless you add new tokens. Those matrices are huge.

QLoRA

Say what QLoRA changesThe frozen base is stored in 4-bit NF4. The adapters stay in bf16.
Name QLoRA's three innovationsNF4 for normally distributed weights, double quantization, and paged optimizers.
Choose QLoRA over LoRAWhen the model won't fit otherwise. Dequantizing makes every step slower.

TrapDon't merge the adapter into 4-bit weights. Merge it into the 16-bit base, or serve it separately.

Full fine-tuning and other PEFT methods

Know when full fine-tuning is worth itA new language or domain, a very large dataset, a small model, or one model to ship.
Name PEFT methods besides LoRABottleneck adapters, prompt tuning, IA3, BitFit and DoRA.
Get closer to full quality at low rankDoRA. It learns a magnitude per weight and uses LoRA for the direction.

TrapBottleneck adapter layers never merge into the weights, so they add latency forever.

Training data

rows, size, mix, splits and cleaning

Write the training rows

{"messages": [ {"role": "system", "content": "Reply in JSON."}, {"role": "user", "content": "Charged twice."}, {"role": "assistant", "content": "{\"type\": \"billing\"}"}]}one line in the real file
Keep every row consistentSame system prompt and output shape on every line. The model copies sloppiness too.
Pick where the inputs come fromReal traffic, so training inputs match production.

TipShip two files, one for training and one for validation.

Split and deduplicate

Hold out a validation split5 to 10% after dedupe, split by document, customer or template.
Remove near-duplicatesMinHashLSH(threshold=0.8, num_perm=128)Run it after an exact pass that hashes normalized text.
Dedupe on the prompt tooTwo answers to one prompt conflict, and the model learns to hedge.
Keep eval items out of trainingMatch 13-word n-grams and embedding neighbors. Keep a private holdout nothing touches.

TrapDuplicates act as extra epochs. The model memorizes them and repeats them word for word.

Distillation

a bigger model writes the training data

Distill a big model into a small one

Say what distillation isA large teacher writes answers for your task, and you fine-tune a small student on them.
Tell hard labels from soft labelsHard labels are the teacher's text. Soft labels match its token probabilities and need its logits.
Stop the student drifting at inferenceOn-policy distillation. The student samples, and the teacher scores those samples.
Replace a frontier model with a small oneOnly for a narrow, stable task. Shadow it, canary 1 to 5%, and route rare inputs back.

TrapThe student copies the teacher's mistakes. Judge it on real ground truth, and check the license.

Generate synthetic data

Pick the safest way to generate rowsA stronger model answers real production prompts. Invented prompts drift.
Filter what the model wroteKeep rows that pass a verifier, like a unit test, a schema check or human review.
Avoid model collapse at scaleKeep real data in every mix, and a human-written holdout you never generate from.

TrapNever verify with the model that wrote the data. Its own mistakes pass its own check.

Evaluate & debug

prove it's better and find what broke

Prove the fine-tune is better

Pick the baselineWhat you run today, usually the prompted base model, on held-out examples.
Score the outputsTask metrics, blind pairwise wins for open-ended answers, and a regression set.
Size the comparisonHundreds of examples, with a confidence interval. A 3-point gain on 50 examples is noise.
Test format adherenceOne validator per constraint, each with its own pass rate. Score the worst of several samples.

TrapOffline wins that don't move real user metrics aren't wins. Ship behind a shadow or A/B test.

Spot overfitting

Read the loss curvesTraining loss falls while validation loss rises. Stop at the best checkpoint.
Fix outputs that quote training rowsDedupe, then add more varied prompts.
Fix answers that collapse to one templateLower the learning rate and the LoRA rank or alpha, and add dropout.

TipIf held-out evals drop but validation loss looks fine, suspect leakage across the split.

TrapRising validation loss alone doesn't prove a worse model. Gate on task evals.

Forgetting and lost safety

Define catastrophic forgettingA narrow fine-tune degrades skills the model had, because the loss rewards only your data.
Prevent forgettingReplay 5 to 30% general data. Use low-rank LoRA, a low learning rate and 1 to 3 epochs.
Say why fine-tuning can break safetyAlignment is shallow. Ten harmful examples jailbroke GPT-3.5 Turbo.
Keep refusals workingMix in 2 to 5% refusals, keep the template unchanged, and gate on a harmful-prompt set.

TipKeep a retention eval beside the task eval, and gate releases on both.

TrapBenign data weakens safety too, and LoRA doesn't protect it.

Debug a model that got worse

Check which tokens get trainedtok.decode(labels[labels != -100])It should show assistant text plus EOS.
Fix a model that never stopsEOS is missing from the targets, or masked out of the loss.
Fix a model that ignores instructionsThe training and serving templates differ. Compare them byte for byte.
Fix a model that's fluent but dumberThe learning rate was too high, or the run had too many epochs.

TipCheck formatting before hyperparameters. Endless rambling almost always means broken formatting.

TrapA misnamed adapter fails silently, and you serve the base model. Check that it loaded.

Preference tuning & RL

teach the model which answer is better

RLHF and DPO

Name the three stages of RLHFSFT on demos, a reward model trained on ranked pairs, then RL against it with a KL penalty.
Name RLHF's costsSlow labels, four models in memory, an unstable loop, reward hacking and an alignment tax.
Say what DPO removesThe reward model and the RL loop. It trains straight on chosen and rejected pairs.
Write the DPO loss-logsigmoid(beta * (chosen_logratio - rejected_logratio))Each log-ratio is the policy's log-prob minus the frozen reference's.

TipDPO runs like SFT, with two models in memory, not four. It learns only from the pairs you collected.

Build preference pairs

Pick where the answers come fromSample both from the model you're about to train, on real production prompts.
Stop DPO learning that longer winsMatch length and format across the pair, and track the length ratio.
Keep the judge honestUse a different model family, recalibrated on human labels each round.

TipRelease on a held-out human comparison, never on training loss or judge score alone.

TrapPairs from a much stronger model teach a gap your policy can't close.

DPO's successors and GRPO

Name DPO's failure modesThe chosen answer's likelihood drops too, longer answers win, and the policy drifts.
Match IPO, KTO, ORPO and SimPO to their fixIPO curbs overfitting, KTO needs no pairs, ORPO folds in SFT, and SimPO fixes length bias.
Say what GRPO drops from PPOThe critic. The mean reward of a group of sampled answers becomes the baseline.
Reward answers a program can checkRLVR. Unit tests, exact match or schema checks replace a learned reward model.

TipRun SFT first, then GRPO with verifiable rewards for math and code. Keep DPO for open-ended taste.

GPUs, tools & cost

memory, multiple GPUs, where to train, and the budget

GPU memory for an 8B model

Estimate full fine-tuningAbout 130 to 150 GB before activations, on several 80 GB GPUs.
Estimate LoRA and QLoRALoRA needs 20 to 30 GB, on one 40 to 80 GB GPU. QLoRA fits 8 to 12 GB, on one 24 GB GPU.
Break down full fine-tuning per parameter2 bytes for bf16 weights, 2 for gradients, 4 for an fp32 copy and 8 for Adam. About 16.
Cut activation memorygradient_checkpointing=TrueIt recomputes activations in the backward pass. Training runs about 20% slower.

TrapLoRA saves on gradients and optimizer states. The frozen base still takes 2 bytes per parameter.

Train across several GPUs

zero_stage: 1For when the weights fit but Adam's states don't.Shard the optimizer states
zero_stage: 2For one more step of headroom.Shard the gradients too
zero_stage: 3For when the weights alone don't fit. FSDP's FULL_SHARD does the same.Shard the weights too
split across the GPUsa full copy on every GPU

TrapStage 3 gathers each layer in both passes. On slow links between GPUs, stage 2 often trains faster.

Estimate the cost

Size the training billExamples x tokens x epochs, so 5,000 x 600 x 3 is 9M tokens. Multiply by the price per 1M.
Count the runsFive to ten, with sweeps and reruns. Nobody ships the first one.
Price the restHuman hours for data and evals, plus serving surcharges or idle dedicated capacity.

TipTraining compute is usually the smallest cost. Compare the total with just using a bigger model.

Hosted fine-tuning APIs

Say what a hosted API does for youYou upload JSONL and start a job. It runs the GPUs and serves the model, billed per token.
Tune Gemini or GPTGemini Enterprise Agent Platform, formerly Vertex AI, or Azure OpenAI. The weights never leave.
Tune Nova or Llama on AWSBedrock. The result runs only inside Bedrock.
Download the LoRA adapterTogether AI or Fireworks usually allow it, for open models like Llama and Qwen.

TrapOpenAI is winding down its fine-tuning platform. No new users, and no new jobs from January 2027.

Tool calling & RAG

fine-tunes with their own data and evals

Fine-tune for tool calling

Pick the training dataWhole multi-turn runs, keeping only the ones that passed a programmatic check.
Mask the tool resultsThey're environment output. Training on them teaches the model to invent results.
Stop it calling tools for everythingInclude rows where the right move is no tool call, and track the false-call rate.
Evaluate a tool-calling modelTask success in a sandbox with mocked tools, plus checks on arguments and tool choice.

TipKeep the serving stack's exact tool-call format and chat template.

Fine-tune for RAG and retrieval

Train a generator for RAGThe real serving prompt with retrieved chunks, plus distractors and rows with no answer.
Train an embedding modelContrastive loss on query, positive and negative triples. Judge it by Recall@k, not loss.
Mine hard negativesYour retriever's top hits that nobody clicked. Random negatives teach almost nothing.
Know what a retriever change costsA new embedding model means re-embedding the corpus. A new reranker needs no reindex.

TrapFine-tune the generator only after retrieval works. It can't answer from chunks it never gets.

Serve & roll back

deploy adapters, version them, keep improving

Merge the adapter or serve it

Merge an adapter into the basemerged = model.merge_and_unload()For one variant, at base speed.
Serve many variants on shared GPUsKeep adapters separate, 10 to 200 MB each. A new version is a pointer change.
Batch requests for different adaptersThe base matmul runs once. A grouped kernel like SGMV applies each request's adapter.

TipKeep adapters in CPU RAM and page them in with an LRU cache. A cold adapter slows its first request.

TrapEvery adapter must share the same base model. A merged variant is a full copy, one per GPU.

Version, release and roll back

Version a fine-tuneKeep weights, data hash, template hash, config and eval report as one immutable version.
Roll back in secondsServe through an alias like prod. Keep the previous version loaded and flip the pointer.
Turn production traffic into training dataLog with consent, scrub personal data, and curate from ratings, edits and abandons.
Release a retrained modelPass a fixed and a fresh eval suite, then go shadow, a 5% canary, and full traffic.

TrapRoll back the prompt template with the weights. A new prompt on old weights is an untested pair.

Found this useful? Pass it on.
Pro · $10/mo

This sheet stays free. With Pro, you can:

  • Every answer on this sheet. Read the full answer to all 56 questions it links, not just the 7 free ones.
  • My sheet. The cards you star and the ones you miss in Quiz me, from every sheet, on one page to quiz and print.
  • PDFs. Download this sheet and My sheet, laid out for A4, with every question a link to its answer.
  • The rest of Pro. Every answer in the question library, and 1,000 AI credits a month.