Book Deep-Read · Generative AI System Design Interview · Chapter 10
Generative AI System Design Interview · Ch 10 · Ali Aminian, Hao Sheng & Alex Xu · 2024
You upload a dozen phone selfies, pick a "professional headshot" style, wait a few minutes, and get back dozens of studio-lit portraits in a suit — with your face still being your face. This chapter is about how that pipeline is built.
Last chapter's model was already very good at drawing. Tell it "a professional headshot of a woman in her thirties" and it produces something fast and beautiful — but it is a stranger. Add details: monolid eyes, a high nose bridge, a mole on the left cheek… by the twentieth adjective it is still somebody else.
Think about it and you already know why: could you describe your mother in words well enough that a stranger could pick her out of a crowd? The words simply do not exist. What makes a face recognizable lives in millimetre-scale geometry, and adjectives are a very blunt instrument.
If it can't be said, teach it differently: put a handful of your photos in front of the model, let it take a short class, and give you a brand-new name that means only you. Afterwards you say "draw that name standing on a snowy mountain" and it knows who to draw.
There are two ways to run that class. One is to let it relearn everything: the memory sticks best, but every single user then needs their own full copy of the retrained "brain", several gigabytes each — and it easily overdoes it, getting so absorbed in you that afterwards everyone it draws looks like you.
The other is what nearly every product picks: leave the original skills completely untouched and pin a tiny badge beside them. A few dozen megabytes, clipped on when you want a picture and taken off afterwards — so one brain can serve thousands of people in turn.
Overdo the class and what it learned is not "your face" but those dozen photos memorized whole. Ask for you on a snowy mountain and you get the same white study wall as before, just with a more accurate face.
So "does it look like me" cannot be read alone — while it climbs, "does it do what I asked" is falling. What you want is where the two cross. It is also why a dozen photos from different places and different angles beat forty taken in front of the same wall.
Earlier chapters generated fictional people; this one generates a real person. So a whole set of things the earlier chapters never needed has to be built into the flow: confirming on upload that the face really is yours, blocking what shouldn't be produced, leaving a traceable mark on the image, and — when someone deletes their account — destroying that badge along with the photos, because it amounts to a standing ability to recreate that person.
The cost is concrete too: every user needs their own training run, a per-head compute bill none of the earlier chapters had.
Identity is the one condition you cannot talk your way into, so it has to be taught with samples; the winning way to teach is not "relearn everything" but "pin on a few-dozen-megabyte badge", because that lets one brain be shared by everyone and lets the memory be deleted cleanly; and "does it look like me" must always be read alongside "does it do what I asked", or you end up with a model that only recites its training photos.
Want the mechanisms, the notation and the diagrams? → Switch to the deep read
Last chapter's condition was a sentence; this chapter's is a handful of photos — identity is the one condition that cannot be encoded into a prompt. The fix is to write it into the model from few samples: learn a single word vector (Textual Inversion), fine-tune the whole network with a built-in antidote (DreamBooth's prior preservation), or hang a low-rank bypass (LoRA). But the real systems problem sits outside the model: storing and hot-swapping one artifact per user, an evaluation where "looks like me" and "does what I asked" pull against each other, and likeness rights — the one chapter in the book where abuse prevention is not a bonus but the requirement itself.
Question 9 of the ten in Part II. Ch9 wired text into a diffusion model; this chapter swaps in images, and the next one adds time — one more dimension of conditioning per chapter is the quiet thread running through the book's second half. It maps onto AI headshot apps and the "reference portrait / character consistency" features in mainstream image tools.
Pin the scenario down first: a user uploads 10–20 selfies, picks a style pack, and the system returns dozens of professional headshots within a few minutes — an inherently asynchronous product shape, not Ch9's second-scale synchronous generation.
Why isn't Ch9's machinery enough? Because 77 tokens cannot hold a face. Text conditioning has been discretized by language; it can only express things language has words for. What makes a face recognizable sits in millimetre-scale geometry — inter-eye distance, nasolabial folds, cheekbone projection — and a face-recognition model needs a 512-dimensional continuous vector to hold it. Language has no words along those dimensions.
What happens if you don't solve it? There is no "fluently wrong" escape hatch here, unlike last chapter: however polished the headshot, if it isn't you the product value is zero — users reject it at a glance.
Two more constraints all but single-handedly determine the technical choices below:
Since identity can't be described, it has to be taught with samples. The training objective never changes — it is still Ch8's denoising loss: add noise to your photo, have the model restore it. Exactly one thing varies: which parameters this round is allowed to change. That is the entire difference between the three mainstream routes: a single new slot in the token-embedding table, the whole denoising network, or a very narrow bypass beside the attention layers.
The lightest route. The diffusion model and the text encoder are entirely frozen; you open one pseudo-word S* in the vocabulary and take gradients only on that single embedding vector — so that shown "a photo of S*", the model can restore your photo out of noise.
In plain terms: none of the model's skill moved, you only added an entry to its dictionary. From then on S* enters prompts like any noun: "S* in a spacesuit, oil painting".
The upside is seductive: the artifact is one vector, a few KB, entries compose freely, and it cannot possibly contaminate the base — you changed nothing.
The cost is equally plain: expressiveness is capped by what one vector can hold. Likeness is the lowest of the three, and precisely the identifying details — a mole, a hairline — tend to disappear. With so few trainable parameters the gradient signal is weak, so it actually trains slower than LoRA, often needing thousands of steps. It suits a style or an object — and what this chapter needs is a face.
The other extreme. A prompt built from a rare identifier plus a class word (shaped like "a sks person") fine-tunes the entire denoising network, often the text encoder with it.
Why must the identifier be rare? Because you need a symbol the model has almost no prior for to hang this face on. Use "john" and you fight the john it already knows, ending up half you and half its imagined john. A meaningless short string like sks is an empty lot in the vocabulary.
But it has two unavoidable side effects:
The antidote is the prior preservation loss: during training you also feed a batch of the model's own generated images of the same class ("a photo of a person" — implementations commonly use a couple of hundred), and require its output on that batch to stay essentially unchanged. In plain terms, you teach it "sks is you" while constantly reminding it what an ordinary person looks like — regularizing the model with its own prior knowledge.
It reveals a general rule: whenever you change a large model with a small amount of data, you must simultaneously arrange to preserve what it already knew, or you get a model that is stronger in a narrow domain and dumber everywhere else.
Likeness and controllability are the best of the three, but the artifact is a full copy of the weights (Stable Diffusion-family snapshots run 2–4 GB), one per user — a storage dead end that keeps it out of consumer products.
The engineering landing point of the chapter. LoRA's observation: what fine-tuning wants to do — move the weight matrix W a little — does not need a full-rank move. So freeze W and wire a narrow channel alongside it:
output = W·x + B·A·x, where A is r×d, B is d×r, and the rank r is typically 4–32
What that formula is saying in plain terms: constrain "how much you may move" into a very narrow shape. Parameters drop from d×d to 2×d×r — about 1/64 when d=1024 and r=8. Only A and B train; not a byte of the original weights changes. It hangs on the attention layers' projection matrices — exactly where conditioning entered in Ch9. To change "how the model gets steered by its condition", those layers are the best value.
The artifact lands at a few MB to a bit over a hundred MB, two to three orders of magnitude below a full model. But storage is only the paper win; the real dividend is the serving shape: the base model stays resident in GPU memory, and at inference you stack the adapter on by user_id and peel it off afterwards, so one GPU can serve thousands of users in turn. Full fine-tuning cannot do this — each user occupies their own copy of GPU memory, and utilization is doomed by design. Being a standalone file, the adapter can also enter a user's deletion pipeline, which matters below.
Quality is close to DreamBooth, so the most common practice combines them: DreamBooth's recipe (rare identifier plus prior preservation), with the artifact emitted as a LoRA.
There is also a route with no training at all: train an identity encoder, pull an identity vector from an off-the-shelf face-recognition model, and inject it through a separate cross-attention path decoupled from text — the user arrives and you simply run inference, no training, seconds to an image, at the price of a personalization ceiling fixed once and for all by that encoder. The book was written in 2024, when per-user fine-tuning was still the mainline.
Three yardsticks, pulling against each other:
CLIP score — did it actually deliver the suit, the mountain, the lighting.FID plus human review.The chapter's most counter-intuitive point: a monotonically rising identity similarity is not good news. Push the step count and similarity does keep climbing — but the later gains come from the model starting to copy the training photos: ask for "on a snowy mountain" and you still get that white study wall, only with a more accurate face. Fidelity collapses, diversity implodes, and the primary metric glows green.
So plot two curves: training intensity (steps, learning rate, rank r) on the x-axis, identity similarity and prompt fidelity on the y-axis, and stop early where they cross. This is the same disease as FID and CLIP score moving against each other along w in Ch9 — the dial just moved from sampling time to training time. Add one yardstick unique to this chapter: "is it copying" — run near-duplicate detection between generated images and training photos, and a hit is hard proof of overfitting.
Training is an async job, not a synchronous request. Training one user's LoRA on a single mainstream training card takes minutes (commonly five to twenty), far beyond any HTTP timeout. The shape is therefore fixed: upload → verify → enqueue → GPU worker → artifact to object storage → callback. That is why these products all say "we'll notify you" instead of spinning.
Inference shares the base and hot-swaps the adapter. The first image for a given user pulls tens of MB from object storage — hundreds of milliseconds in-region; an LRU cache keyed on activity makes the cold start effectively invisible.
Deletion is a hard requirement here. On account closure you must delete not just the original photos but the adapter itself — it is data derived from biometrics, and keeping it means keeping a standing ability to recreate that person. That yields one hard architectural constraint: never merge the adapter into shared weights. Once baked into the base it cannot be separated out or cleanly deleted; stacking at runtime and peeling off afterwards is the deletable shape.
The same capability, pointed at someone else's photos, is a deepfake. So protection has to be designed into the flow, not bolted on as a filter afterwards:
Table 1 · Choosing among the four personalization routes
| Route | What changes | Artifact / training | Cost | When to pick it |
|---|---|---|---|---|
| Textual Inversion | One new word's embedding vector | A few KB; trains slowly | Lowest likeness, details lost | Styles or objects; faces are a stretch |
| DreamBooth, full | Whole denoiser (often the text encoder too) | 2–4 GB; minutes | One full model per person, no shared GPU memory | Quality ceiling reference; unviable for consumer scale |
| LoRA (+ DreamBooth recipe) | Low-rank bypass B·A beside attention | A few MB–100+ MB; minutes | Slightly below full; rank r needs tuning | The default: shared base, hot-swap, deletable |
| Identity encoder (zero-shot) | No per-user training; inject a face vector at inference | No per-user artifact; seconds | Likeness and personalization ceiling fixed by the encoder | Where a few minutes' wait is unacceptable |
Table 2 · Setting training intensity (steps / rank r / learning rate)
| Setting | You get | You pay | How to spot it |
|---|---|---|---|
| Too weak | Prompts obeyed in full, background and pose freely changeable | Not you — more like a distant relative | Cosine similarity clearly below the same-person baseline |
| Sweet spot | Recognizably you, and the requested setting / outfit / lighting mostly lands | You must sweep the intensity to find it | Where the two curves cross; keep several snapshots and pick by hand |
| Too strong | Highest identity similarity, best-looking primary metric | Copies the training photos: background and pose memorized too, prompt ignored | Near-duplicate detection hits; CLIP score drops |
One lever fits in no table and is the cheapest of all: how you collect the photos. A dozen selfies across different settings, angles and lighting clearly beat forty taken in front of one wall — what overfitting feeds on is exactly the shared background and pose. That lever lives in your onboarding copy and costs no compute at all.
Asked in an interview how you'd do personalization, "fine-tune it" is a non-answer. This chapter gives three separately actionable layers: what changes (word vector / full model / low-rank bypass), where you train (once per user / one encoder once) and how you serve (dedicated GPU memory / shared base with hot-swap). Keeping those three apart already beats most answers.
LoRA's significance also long ago outgrew this chapter: it is today the default shape of all large-model customization — domain adaptation for language models, style packs for image models, the same "freeze the trunk, hang a low-rank bypass".
125M trainable parameters down to 0.8M. That ratio, not image quality, is the decisive variable in this chapter's technical choice.Microsoft · LoRA repo (2021) · github.com/microsoft/LoRAsks is just an empty lot in the vocabulary where the prior is weakest; a common first name fights the semantics already there.① The core claim: identity is the one condition you cannot write into a prompt — 77 tokens cannot hold a face, whose recognizability needs a 512-dimensional continuous vector. It can only be taught with samples.
② The three routes differ in exactly one respect: which parameters this round may change — one new slot in the embedding table (Textual Inversion), the whole denoiser (DreamBooth), a low-rank bypass beside attention (LoRA). A fourth trains nothing: an identity encoder injecting a face vector at inference, seconds fast but ceilinged.
③ DreamBooth must carry a prior preservation loss: teach "sks is you" while reminding it with its own generated class images what an ordinary person looks like, or language drift makes everyone look like you.
④ LoRA is the product default: W·x + B·A·x, rank r of 4–32, artifact tens of MB. The real dividend is not storage but hot-swapping on a shared base (GPU utilization) and deletability (never merge it into the base).
⑤ The most counter-intuitive evaluation point: monotonically rising identity similarity is not good — the later gains are bought by copying the training photos. Plot two curves, stop early where they cross, and add near-duplicate detection.
⑥ Training duration dictates the serving shape: minutes means an async queue plus callback; inference shares the base and hot-swaps the adapter by user_id.
⑦ The cheapest lever is on the product side: ask users for photos across different settings, angles and lighting — a dozen of those beat forty from the same wall.
⑧ Abuse prevention is a requirement, not an appendix: liveness on upload, celebrity blocking at training, one-notch-stricter output filtering, watermarks as evidence only, and faces as special-category data requiring explicit consent.