AppliedAIPrep logoAppliedAI/Prep
ML Infrastructure & GPUs / 01
hard★ EssentialNVIDIAOpenAIAnthropic

Serve a 70B-parameter model with high throughput. Do the memory math and name the optimizations.

The interviewer wants real numbers, not 'use a big GPU.' Weights are fixed, the KV cache grows with load, and the lever order decides everything. Here is the back-of-envelope and the serving stack.

Updated Aug 2026 · Grounded in real Applied AI Engineer interview loops and written to a senior-engineer editorial bar.

TL;DR: A 70B model is ~140GB in FP16, so it does not fit on one 80GB GPU; shard with tensor parallelism across 2+ GPUs, or quantize to INT8/INT4 (~70GB / ~35GB) to fit on one. Then the live constraint is the KV cache, which grows with batch × sequence length and is what actually caps concurrency. Serve with continuous batching and PagedAttention (vLLM), MQA/GQA, and quantization.

KV CACHE (drag through decoding)
Themodelwritesonetokenatatime
without cache10 ops
with cache4 ops
With the cache, each token's keys and values are computed once and reused. Without it, every step recomputes them for all prior tokens, so total work grows with the square of the sequence. At step 4 that is 2.5x more compute wasted.

How to approach it

Do the arithmetic out loud, separating weights (fixed) from KV cache (grows with load). State the lever order: fit the weights first (quantization or tensor parallelism), then maximize throughput (continuous batching, paged KV cache), then trim tail latency. Most candidates skip the KV cache and quote only weight memory, which is the part that actually limits batch size.

A strong answer

Weights. Parameters × bytes-per-param. FP16/BF16 is 2 bytes, so 70B is about 140GB. That exceeds an 80GB H100/A100, so either tensor-parallel shard across at least 2 GPUs (split each layer's matrices column/row-wise, sync with all-reduce over NVLink) or quantize: INT8 lands near 70GB (fits one 80GB card with room for cache), INT4 near 35GB. Training is a different beast: weights plus gradients plus FP32 Adam states run about 16 bytes/param, roughly 1.1TB, which is why training shards with FSDP/ZeRO. Inference only carries the weights plus the KV cache.

KV cache, the real limiter. Each generated token caches a key and value per layer per head, roughly 2 × layers × hidden × seq_len × batch × bytes. For a 70B model that is on the order of hundreds of KB per token, so a few thousand tokens across a moderate batch is tens of GB, often dwarfing leftover weight headroom. KV cache, not weights, is what caps concurrency.

LeverWhat it buysWhen it bites back
INT8/INT4 quantizationFit on one GPU, faster decodeSmall quality hit at INT4; validate on tasks
Tensor parallelismFit when one GPU is too smallAll-reduce per layer needs NVLink, not PCIe
Continuous batchingBiggest throughput winLarger batch raises time-to-first-token
PagedAttentionKills KV fragmentation, raises batchNeeds a paged-aware kernel (vLLM)
MQA/GQAShrinks KV cache several-foldMust be in the model architecture

Throughput versus latency is the central tradeoff: larger batches raise tokens/sec but raise per-request time-to-first-token, so set the batch policy to the SLO rather than maxing one number.

Key takeaways

  • Weights are fixed (2 bytes/param at FP16); the KV cache grows with batch × sequence and is the true concurrency ceiling.
  • Lever order: fit weights (quantize or TP), then throughput (continuous batching, PagedAttention), then latency.
  • Quantize before reaching for tensor parallelism if a single quantized GPU fits; TP pays interconnect tax.
  • Decode is memory-bandwidth-bound, so fewer bytes per weight and a smaller KV cache directly speed generation.

What interviewers probe next

  • "Prefill vs decode?" Prefill processes the whole prompt in parallel (compute-bound); decode is one token at a time (memory-bandwidth-bound), which is why KV cache and bandwidth dominate steady-state cost.
  • "INT4 quality risk?" Usually a small perplexity hit with AWQ/GPTQ; validate on your eval set, and keep sensitive layers higher precision if a regression shows up.
  • "Speculative decoding?" A small draft model proposes tokens the big model verifies in parallel, cutting latency when acceptance is high.

Common mistakes

  • Quoting only weight memory and forgetting the KV cache, which is what actually limits batch size.
  • Using FP32 numbers for inference; inference runs in FP16/BF16 or lower.
  • Reaching for tensor parallelism before quantization when a single quantized GPU would do, paying needless interconnect overhead.
  • Conflating training memory (16 bytes/param with optimizer states) with inference memory (weights plus cache).
HOW DID IT GO?
0
UP NEXT ON YOUR JOURNEY
DISCUSSION · 0

No comments yet — be the first to share your approach.