Chapter 6 · Bonus — Additional experiments
What Actually Matters in Fine-tuning
The main chapter made a dozen choices — classify the last token, unfreeze the last block, pad to 120. This bonus notebook re-runs the classifier 19 ways to find out which of those choices carried the result.
Adapted from the original notebook by Sebastian Raschka · the Python shown is the book's; the demos run a faithful JavaScript port in your browser
What-if · Ablation experiments
test accuracy · axis from 60%
The bonus notebook re-runs the classifier 19 ways to test the choices we made. The baseline — last token, last block, 124M — hits 95% test accuracy. Everything else is measured against it.
The lab
All nineteen runs, sortable. Click a column to rank by it — accuracy or training time — and read off the trade-offs yourself.
Ablation table
19 classifier variants; published A100 results. Click a numeric header to sort.
| model | weights | token | trained | context | |||||
|---|---|---|---|---|---|---|---|---|---|
| 1● | 124M | pretrained | last | last block | longest (120) | 96.6 | 99.3 | 95.0 | 0.28 |
| 2 | 124M | pretrained | first | last block | longest (120) | 78.5 | 80.5 | 75.0 | 0.28 |
| 3 | 124M | pretrained | last | last layer | longest (120) | 78.7 | 79.9 | 72.0 | 0.25 |
| 4 | 124M | pretrained | last | last two blocks | longest (120) | 98.8 | 98.7 | 98.3 | 0.33 |
| 5 | 124M | pretrained | last | all | longest (120) | 99.6 | 96.6 | 96.7 | 0.69 |
| 6 | 355M | pretrained | last | last block | longest (120) | 87.5 | 91.3 | 84.7 | 0.75 |
| 7 | 774M | pretrained | last | last block | longest (120) | 99.5 | 98.7 | 96.7 | 1.50 |
| 8 | 1558M | pretrained | last | last block | longest (120) | 99.8 | 99.8 | 98.3 | 2.83 |
| 9 | 1558M | pretrained | last | all | longest (120) | 100.0 | 98.7 | 98.7 | 8.12 |
| 10 | 124M | random | last | all | longest (120) | 100.0 | 96.6 | 93.7 | 0.69 |
| 11 | 124M | pretrained | last | LoRA | longest (120) | 100.0 | 97.3 | 96.7 | 0.75 |
| 12 | 1558M | pretrained | last | LoRA | longest (120) | 100.0 | 98.7 | 98.3 | 5.79 |
| 13 | 124M | pretrained | last | last block | full 1024 | 83.1 | 87.9 | 78.3 | 2.46 |
| 14 | 124M | pretrained | last | last block | no padding (bs 1) | 100.0 | 98.7 | 98.0 | 1.75 |
| 15 | 124M | pretrained | last | last block | no padding (bs 1, accum 8) | 99.3 | 98.7 | 98.3 | 1.70 |
| 16 | 124M | pretrained | last (flexible) | last block | last non-pad token | 99.4 | 98.7 | 98.3 | 0.30 |
| 17 | 124M | pretrained | last | last block | no causal mask | 99.2 | 98.7 | 95.3 | 0.29 |
| 18 | 124M | pretrained | last | last block | ignore_index padding | 96.6 | 99.3 | 95.0 | 0.28 |
| 19 | 124M | pretrained | last + pooled | last block | longest (120) | 97.8 | 99.3 | 96.3 | 0.32 |
Published results on an A100 GPU (ch06/02 bonus). Row 1 (●) is the main-chapter configuration; accuracies are percentages. Attributed data — these runs aren't reproduced in the browser.
The real code
Every row is one command-line flag on the same script:
python additional_experiments.py # row 1 (baseline)
python additional_experiments.py --trainable_token_pos first # row 2
python additional_experiments.py --trainable_layers last_two_blocks # row 4
python additional_experiments.py --trainable_layers all # row 5
python additional_experiments.py --model_size "gpt2-large (774M)" # row 7
python additional_experiments.py --trainable_layers lora --lora_rank 16 --lora_alpha 16 # row 11
python additional_experiments.py --context_length "model_context_length" # row 13
python additional_experiments.py --disable_causal_mask # row 17Three things to remember
- Ablations turn choices into evidence. Change one knob, hold the rest, re-measure — the only honest way to know which decision mattered.
- The causal mask dictates the token position. Classifying the last token isn't arbitrary; it's the only position with full context, and the 20-point gap versus the first token proves it.
- More capacity has diminishing — sometimes negative — returns. Bigger models and more trainable layers don't monotonically help; the last two blocks of a 124M model are a sweet spot.
Adapted from Build a Large Language Model (From Scratch) by Sebastian Raschka — additional experiments (Apache 2.0). The results shown are its published A100 benchmarks, quoted as attributed data.