Full Fine-Tuning vs PEFT
Introduction
Last lesson cut memory with fewer bits per weight (quantization). This one cuts it with fewer trainable weights — the second great lever of fine-tuning mechanics, and the one that put fine-tuning in everyone's hands: PEFT (Parameter-Efficient Fine-Tuning).
The question is simple: when you adapt a model, do you update all its weights (full fine-tuning) or just a tiny sliver (PEFT)? The answer, for ~80% of real work, is the sliver — and not because it's a cheap compromise. PEFT trains <1% of the parameters yet reaches 95–99% of full fine-tuning's quality, while also being modular, forget-proof, and small enough to fine-tune a 70B on a single GPU. This lesson is why, and when full fine-tuning still earns its cost.

Full Fine-Tuning: All Weights, Maximum Cost
Full fine-tuning does exactly what L189's loop describes, on every weight: a gradient and an optimizer state for all of them. It gives the model maximum flexibility to change — and pays for it three times over:
- Memory — the full ~16 bytes/parameter from L190 (a 7B needs ~112 GB to train).
- Catastrophic forgetting — moving every weight toward your task moves them away from everything else (the L186 trap; full FT forgets ~20%).
- A full copy per task — each fine-tune is a complete new model. Need 5 specialized models? That's 5 full checkpoints (e.g. 5 × 40 GB).
Full FT is the sledgehammer: powerful, but expensive, forgetful, and unwieldy if you need more than one specialized model.
PEFT: Freeze the Base, Train a Sliver
PEFT flips the default: freeze the entire pre-trained base and train only a small set of new or selected parameters — typically under 1%. On a 7B model that's a few million trainable parameters instead of seven billion.
The magic is in what frozen buys you. A frozen weight needs no gradient and no optimizer state (recall L190 — those were 5/6 of the memory), and it can't be forgotten because it never moves. The few trainable parameters live in a tiny adapter that you can save separately and snap onto the shared base at run time. From this one idea — train little, freeze the rest — flow four wins.
The Four Wins of PEFT
1) Memory — 10–20× less. Only the tiny adapter carries gradients and optimizer state, so a fine-tune that needed a cluster now fits a single consumer GPU. (This, plus QLoRA's 4-bit base, is why a 7B trains in ~6 GB.)
2) Modularity — one base, many tasks. Because the base is untouched, each task's adapter is an independent, few-MB file. You store one base + N tiny adapters and hot-swap the right one per request — instead of loading a different full model. The classic example: a model whose full checkpoint is 40 GB would cost 40 GB per task with full FT, but a few MB per task with PEFT.
3) No catastrophic forgetting. The frozen base keeps all its general knowledge and safety — you're adding a skill, not overwriting the model (the L186 fix, by construction).
4) Quality parity. For most tasks, a well-configured PEFT method reaches 95–99% of full fine-tuning's score while training <1% of the weights. The gap is usually too small to matter.
The PEFT Family
PEFT is a family of methods that differ in where they put the trainable parameters:
- LoRA (Low-Rank Adaptation) — injects tiny low-rank matrices beside the frozen weights. The dominant method (next lesson, in depth).
- Adapters — small bottleneck layers inserted between the model's layers (the original PEFT, ~0.5% params).
- Prefix / Prompt / P-tuning — learn a handful of soft "virtual token" vectors that condition the frozen model (you tune the input, not the weights).
- BitFit — train only the bias terms (a fraction of a percent).
- (IA)³ — learn to scale activations.
In practice the library does the wiring — wrapping a model in PEFT is a few lines, and it tells you exactly how little you're training:
from peft import LoraConfig, get_peft_model
from transformers import AutoModelForCausalLM
base = AutoModelForCausalLM.from_pretrained('meta-llama/Llama-3.2-3B') # the FROZEN base
config = LoraConfig(r=16, lora_alpha=32, target_modules='all-linear') # a tiny low-rank adapter
model = get_peft_model(base, config)
model.print_trainable_parameters()
# trainable params: 12,156,928 || all params: 3,224,906,752 || trainable%: 0.38
# You train 0.38% of the weights. The other 99.62% are FROZEN -> no gradients,
# no optimizer state, no catastrophic forgetting. The trained adapter saves as a ~24 MB
# file you hot-swap onto the shared base at serve time (model.save_pretrained('support-adapter')).When Full Fine-Tuning Still Wins
PEFT isn't always the answer — it wins about 80% of production fine-tuning; full FT owns the other 20%. And the deciding line isn't cost — it's the depth of behavioral change you need:
- Infusing substantial new behavior/capability — if you need to fundamentally change how the model reasons or operates (not just add a format/skill), updating all the weights has more capacity to do it. PEFT is constrained by the frozen base.
- Some simpler classification tasks — where more trainable parameters and longer training reliably help, full FT can edge out PEFT.
- You have the data and compute — and the marginal last few % of quality is worth the full bill.
But notice the default has flipped: the question used to be "can we afford to fine-tune?"; now it's "is this change deep enough to justify full fine-tuning over a LoRA?" For most teams, the honest answer is no — use PEFT.
See It: The PEFT vs Full Fine-Tuning Lab
Watch the two diverge. Pick a base model, choose PEFT or full FT, then drag the number of tasks you need. The pipeline shows PEFT as one frozen base + swappable adapters and full FT as N separate copies — and the storage bar makes the modularity win unmissable: full FT explodes by a whole model per task, while PEFT grows by a few MB.

Crank the task count to 8 and the picture is decisive: full fine-tuning ships eight full models; PEFT ships one base + eight tiny adapters — same quality, a fraction of the footprint, and you can hot-swap between them on a single server.
Why This Matters
PEFT is the reason a solo developer can fine-tune a frontier-class open model on a rented GPU, and the reason a company can serve dozens of customer-specific models from one base without a storage bill that scales with customers. Knowing the full-vs-PEFT trade — and that the line is depth of change, not money — means you default to the cheap, modular, forget-proof option and only spend on full fine-tuning when the task genuinely demands it. It's the single highest-leverage architectural decision in a fine-tuning project, and it leads directly into the method you'll actually use: LoRA.
🧪 Try It Yourself
Make the storage case. Imagine your team needs 6 task-specific variants of an 8B model. Estimate, for each approach: (1) training memory (full ≈ 8B × 16 vs PEFT ≈ 8B × 2.4), (2) storage to deploy all 6 (full = 6 × the ~16 GB checkpoint vs PEFT = one base + 6 tiny adapters), and (3) whether you'd suffer catastrophic forgetting. Then open the Lab, set 8B + 6 tasks, and check your storage numbers. Finally, name one scenario from your own work where you'd actually choose full FT — and justify it by depth of change, not cost.
Mental-Model Corrections
- "PEFT is a cheaper, lower-quality compromise." It trains <1% of weights yet hits 95–99% of full quality — for most tasks the difference is noise.
- "PEFT makes the model smaller." No — the base is the same size (and still loaded). PEFT trains a tiny adapter on top of a frozen base.
- "Each PEFT task still needs its own full copy." The opposite — that's PEFT's superpower: one shared base + tiny swappable adapters. Full FT is the one that needs N copies.
- "Full fine-tuning is always more thorough, so it's safer." It also forgets more and costs ~20× the memory/storage. Use it only for deep behavioral change.
- "LoRA is PEFT." LoRA is the most popular PEFT method; PEFT also includes adapters, prefix/prompt tuning, BitFit, and more.
Key Takeaways
- Full fine-tuning updates all weights → max flexibility, but ~16 B/param memory, catastrophic forgetting, and a full copy per task.
- PEFT freezes the base and trains <1% of the weights (a tiny adapter) → 10–20× less memory, no forgetting, and 95–99% of full-FT quality.
- Modularity is the killer win: one shared base + few-MB swappable adapters (one model serves many tasks) instead of N full checkpoints.
- The family: LoRA (dominant), adapters, prefix/prompt tuning, BitFit, (IA)³ — they differ in where the trainable parameters go.
- Default to PEFT (~80% of cases). Reach for full FT only for deep behavioral change (lots of new capability), where the line is depth, not cost.
Next: L193 — LoRA & QLoRA Explained — exactly how the dominant PEFT method works (low-rank adapters), and how QLoRA's 4-bit base brings it all together.