Pretraining & Fine-Tuning LLMs
Level: 3 (Production — from-scratch derivations, code-from-memory, explain-out-loud) Time limit: 45 minutes Total marks: 60
Question 1 — LoRA math & memory (12 marks)
A linear layer has weight with , . You apply LoRA with rank , decomposing the update as where , , and scaling .
(a) Write the modified forward pass and state which matrices are trainable. (2)
(b) Compute the number of trainable parameters introduced per layer, and express it as a percentage of the frozen parameters. (4)
(c) LoRA uses effective scaling . Give the numeric value here and explain why is initialised from a random Gaussian while is initialised to zero. (3)
(d) At inference, how can you eliminate the LoRA latency overhead entirely? Show the algebra. (3)
Question 2 — Self-supervised objectives from memory (10 marks)
(a) Write the training objective (loss) for GPT-style causal language modelling over a sequence . (3)
(b) Write BERT's masked language modelling objective and state the classic masking recipe (the 80/10/10 rule). (4)
(c) In one or two sentences each, explain why a causal LM cannot use bidirectional context, and why T5's span-corruption objective is more sample-efficient than single-token masking. (3)
Question 3 — QLoRA memory budget derivation (12 marks)
You fine-tune a 7-billion-parameter model.
(a) Compute the memory (in GB) to store the frozen base weights in FP16 vs INT4. Use bytes. (4)
(b) With full fine-tuning in FP16 using the Adam optimizer, estimate total training memory for weights + gradients + optimizer states (Adam keeps 2 moment buffers). Assume master weights and states in FP32. State your per-parameter byte accounting. (5)
(c) Explain in 2–3 sentences the two key innovations QLoRA adds beyond plain LoRA (name them and say what each does). (3)
Question 4 — Knowledge distillation loss (10 marks)
A teacher produces logits , a student produces logits , over classes, with temperature .
(a) Write the softened probability and the combined distillation loss mixing soft-target KL and hard-label cross-entropy with weight . (4)
(b) Derive for the soft KL term , and explain why the gradient is multiplied by . (4)
(c) State one reason high transfers more "dark knowledge." (2)
Question 5 — Catastrophic forgetting & design (8 marks)
You fine-tune a general instruction-tuned LLM on a narrow medical QA dataset and observe its general reasoning degrades.
(a) Define catastrophic forgetting in the context of sequential fine-tuning. (2)
(b) List and one-line-justify three mitigation strategies, at least one of which must be a PEFT-based approach. (6)
Question 6 — Code from memory: minimal LoRA layer (8 marks)
Write, from memory, a PyTorch nn.Module called LoRALinear that wraps a frozen nn.Linear. It must: freeze the base weight, add trainable low-rank matrices A and B of rank r, apply scaling alpha/r, and implement forward. Initialise correctly. (8)
Answer keyMark scheme & solutions
Question 1 (12)
(a) . Trainable: and only; frozen. (2: forward 1, trainable 1)
(b) Params per LoRA pair . Frozen params . Percentage . (4: formula 1, LoRA count 1, frozen count 1, % 1)
(c) . is initialised to zero so that at the start , meaning the fine-tuned model exactly equals the pretrained model at step 0 (stable start, no shock to activations). is Gaussian so gradients can flow and break symmetry; if both were zero no learning signal would propagate. (3: value 1, B=0 reason 1, A random reason 1)
(d) Since is just another matrix, merge it: . Then is a single matmul with no extra latency; the adapter is folded into the base weight. (3: merge idea 1, algebra 1, zero-overhead statement 1)
Question 2 (10)
(a) (autoregressive negative log-likelihood; each token conditioned only on preceding tokens). (3)
(b) where is the masked set. Recipe: choose ~15% of tokens; of those, 80% → [MASK], 10% → random token, 10% → unchanged. This reduces train/inference mismatch (no [MASK] at inference). (4: loss 2, recipe 2)
(c) Causal LM is trained with a triangular attention mask so position cannot attend to — needed to prevent label leakage during autoregression. T5 span corruption masks contiguous spans replaced by a single sentinel, so one forward pass predicts multiple tokens per example (more supervised signal per token/step) → higher sample efficiency. (3: causal 1.5, span 1.5)
Question 3 (12)
(a) FP16 = 2 bytes/param: B GB. INT4 = 0.5 bytes/param: B GB. (4: FP16 2, INT4 2)
(b) Per-parameter FP32 (4 bytes) accounting for full FT + Adam:
- weights (master) FP32: 4 B
- gradients FP32: 4 B
- Adam : 4 B
- Adam : 4 B Total = 16 B/param. B GB. (Accept ~112 GB; if FP16 weights+grads + FP32 states counted as 2+2+4+4+4=16 with FP32 master copy, still ≈112 GB.) (5: byte accounting 3, arithmetic 2)
(c) (1) 4-bit NormalFloat (NF4) quantization of the frozen base weights — information-theoretically optimal for normally-distributed weights, cutting base memory ~4×. (2) Double quantization — quantizing the quantization constants themselves to save further memory; plus paged optimizers to handle memory spikes. LoRA adapters are trained in FP16/BF16 on top of the frozen NF4 base. (3: NF4 1.5, double-quant/paged 1.5)
Question 4 (10)
(a) . . (4: softmax 2, combined loss 2)
(b) For KL with soft targets the well-known result: Because differentiating softmax w.r.t. logits brings a factor, and the leading cancels one power → net . The multiplier is included so that gradient magnitudes stay comparable to the hard-label CE term (whose gradients scale as ), keeping the two losses balanced as changes. (4: derivative 2, τ² rationale 2)
(c) High softens the distribution so relative probabilities of incorrect classes (the "dark knowledge" about class similarity) become non-negligible and are transferred to the student. (2)
Question 5 (8)
(a) Catastrophic forgetting: when a neural network trained sequentially on a new task overwrites weights important for previously learned tasks, causing sharp performance loss on the old task/distribution. (2)
(b) Any three (2 each = 6):
- PEFT (LoRA/adapters) — freeze base weights, so original knowledge in is preserved; only small modules change.
- Rehearsal / data mixing — mix general-instruction data into the medical fine-tuning set so gradients don't drift entirely.
- Lower LR + fewer epochs / early stopping — smaller weight movement reduces overwriting.
- Regularisation (EWC / L2-to-pretrained) — penalise moving weights important to old tasks.
- Knowledge distillation from the original model — keep student close to teacher's general behaviour. (≥1 must be PEFT-based.) (6)
Question 6 (8)
import torch
import torch.nn as nn
import math
class LoRALinear(nn.Module):
def __init__(self, base: nn.Linear, r=8, alpha=16):
super().__init__()
self.base = base
for p in self.base.parameters(): # freeze base
p.requires_grad = False
in_f, out_f = base.in_features, base.out_features
self.r = r
self.scaling = alpha / r
# A: (r, in), B: (out, r)
self.A = nn.Parameter(torch.randn(r, in_f) / math.sqrt(in_f))
self.B = nn.Parameter(torch.zeros(out_f, r)) # zero init
def forward(self, x):
base_out = self.base(x)
lora_out = (x @ self.A.t()) @ self.B.t()
return base_out + self.scaling * lora_outMark scheme: freeze base 2; A random init 1; B zero init 1; correct shapes 2; forward with scaling 2. (8)
[
{"claim":"LoRA trainable params r(d+k)=131072","code":"r,d,k=16,4096,4096; result = (r*(d+k)==131072)"},
{"claim":"LoRA percentage of frozen ~0.78125%","code":"r,d,k=16,4096,4096; result = (Rational(r*(d+k),d*k)*100 == Rational(78125,100000))"},
{"claim":"7B FP16 = 14GB and INT4 = 3.5GB","code":"n=7*10**9; result = (n*2==14*10**9 and n*Rational(1,2)==Rational(35,10)*10**9)"},
{"claim":"Full FT Adam FP32 memory 16 bytes/param = 112GB for 7B","code":"n=7*10**9; result = (n*16==112*10**9)"},
{"claim":"LoRA effective scaling alpha/r=2","code":"result = (Rational(32,16)==2)"}
]