Most of this book has followed capability. Larger models, longer contexts, better scores.
There is a second axis, and outside research it is usually the binding one. A model that cannot run within your budget, memory or latency is not available to you at any quality.
This chapter is about that axis. It divides cleanly into three questions.
How do I adapt a model without paying for full fine-tuning? How do I make the model smaller? How do I make it answer faster?
Full fine-tuning updates every weight, and the memory cost is worse than the parameter count suggests.
For a billion parameter model in half precision:
| what must be held | memory |
|---|---|
| weights, fp16 | 14 GB |
| gradients, fp16 | 14 GB |
| Adam states, fp32 master and two moments | 56 GB |
| total, before activations | 84 GB |
That is several high-end accelerators to fine-tune a model that fits on one for inference. And the result is a whole new GB of weights per task.
Low-rank adaptation rests on one observation. The change a fine-tune makes to a weight matrix has low intrinsic rank, even though the matrix does not.
So do not learn the change directly. Factor it:
Freeze entirely. Train only and .
The arithmetic is the argument. A full matrix has parameters. The adapter has .
| rank | full matrix | adapter | share |
|---|---|---|---|
| 1 | 16,777,216 | 8,192 | 0.05% |
| 4 | 16,777,216 | 32,768 | 0.20% |
| 8 | 16,777,216 | 65,536 | 0.39% |
| 16 | 16,777,216 | 131,072 | 0.78% |
| 64 | 16,777,216 | 524,288 | 3.13% |
Those figures are for , a typical attention projection.
At you train four tenths of one per cent of the weights. The optimiser state shrinks in the same proportion, which is where most of the GB went.
Three practical consequences follow, and the third is the one people underrate.
You can fine-tune a large model on one accelerator.
An adapter is megabytes rather than gigabytes, so you can keep hundreds of them.
And because Equation (23.1) is an addition to a frozen , adapters can be swapped at serving time without reloading the base model. One model in memory, many behaviours.
QLoRA combines the idea with a quantised base model, and puts fine-tuning a billion parameter model within reach of a single accelerator.
Weights are usually trained in bits. They rarely need bits to be used.
| precision | bytes per parameter | a 7B model |
|---|---|---|
| fp32 | 4 | 28.0 GB |
| fp16 | 2 | 14.0 GB |
| int8 | 1 | 7.0 GB |
| int4 | 0.5 | 3.5 GB |
The int4 row is the interesting one. A model that needed a data-centre card at fp16 now fits on a consumer GPU.
Quality loss at int8 is usually indistinguishable in practice.
At int4 the loss is measurable but often acceptable. It is almost always a better trade than moving to a genuinely smaller model.
Distillation trains a small student to match a large teacher’s output distribution. The teacher’s full distribution carries more information than a hard label does, because it says which wrong answers were nearly right.
Pruning removes weights or whole structures that contribute little. Unstructured pruning gives better compression ratios; structured pruning gives speedups on real hardware, because it removes shapes rather than scattered entries.
The general finding across all three techniques is the same. Models are substantially over-parameterised for inference, and most of that slack can be recovered without retraining from scratch.
Generation has two phases with completely different cost profiles, and conflating them causes most confusion about latency.
Prefill processes the whole prompt in parallel. It is compute-bound, and it is fast per token.
Decoding produces one token at a time, each depending on the last. It is memory-bound, because every step reads the entire weight matrix to produce one token.
So the second phase dominates wall-clock time on any answer of reasonable length, and it is the one worth optimising.
Each decoding step recomputes attention over the whole prefix. Caching the keys and values avoids that, and it is the single most important inference optimisation there is.
It also becomes the memory problem. For and layers, in fp16:
| context length | KV cache |
|---|---|
| 2,048 | 1.07 GB |
| 32,768 | 17.18 GB |
At long context the cache can exceed the weights.
That is why grouped-query attention exists, sharing key and value projections across heads. It is one of the few architecture changes since the original transformer driven purely by serving cost.
Throughput comes from batching. Because decoding is memory-bound, processing many sequences at once costs little more than one.
So serving systems batch aggressively, and schedule continuously rather than waiting for a batch to fill.
Underneath all of it sits the of Chapter 16. Quadrupling the context multiplies the attention cost sixteen-fold, and every long-context technique is an attempt to pay less than that.
FlashAttention does not change the complexity. It changes the memory traffic, computing attention in tiles that fit in fast on-chip memory. That is a large practical speedup for no change in the result.
Two effects that only appear after shipping, and neither is a modelling problem.
Drift. The world changes and the training data does not. A model’s accuracy on live traffic decays even though the model has not changed. The response is monitoring, not retraining on a schedule.
Feedback loops. A deployed model influences the data it will later be trained on. A recommender changes what people read; a text model changes what people write. That loop is now measurable in web corpora.
The engineering discipline here is the empirical method of Chapter 14, applied to a system rather than an experiment. State the metric, hold out the evaluation, log the failures, and look at them.
introduce LoRA and its rank ablations are worth reading for the intuition about intrinsic dimension. combine it with quantisation. explain why memory traffic rather than arithmetic is the bottleneck.
Count the adapter. For , compute the LoRA parameter count at and express each as a share of the full matrix. Then repeat for . Why is the share so much larger on the smaller matrix, and what does that imply about where LoRA pays best?
The memory budget. Work out the full fine-tuning memory for a billion parameter model in fp16 with Adam, then the same figure with LoRA at applied to attention projections only. State every assumption you made.
Choose a precision. A B model must run on a card with GB of memory, leaving GB for activations and the KV cache. Which precision can you use? Now the context must be tokens. Recompute and say what has to give.
Prefill against decode. Explain why the first phase is compute-bound and the second memory-bound. Then predict which phase dominates for a token prompt with a token answer, and for a token prompt with a token answer.
Size the cache. For , and fp16, compute the KV cache at and tokens. At which length does it exceed the weights of a B model? Name one architectural change that reduces it.
Pick the technique. For each constraint, choose one method from this chapter and justify it: (a) one accelerator, must serve forty customer- specific behaviours; (b) model must run on a phone; (c) latency is fine but throughput is a tenth of what is needed; (d) context must grow from 4k to 64k.