genaipros← The path
Line B · Build05 · LLM Inference & Serving

LLM inference & serving · stage notebook

Serving, session by session

One tab per session — concepts first, numbers worked by hand, then the production view.

Why this section exists

Getting a model to answer you is a weekend project. Getting it to answer a million people quickly, cheaply, and reliably is a discipline — and it starts with defining "best."

A generative AI model has two phases of life. Training is the one-time, very expensive process of learning the model's weights — the billions of numbers inside it — from data. Inference is everything after: running the trained model in production to answer real requests. Training happens once; inference is the bill and the user experience you live with every day after launch.

Training happens once weights Inference every request, forever users
Fig 1.1 — the two lives of a model. Everything in this stage lives on the right-hand box.

Last decade's machine learning wave made inference look easy: a classic model like a gradient-boosted tree ran happily on a cheap CPU behind a thin web service. Generative models broke that. You cannot take weights, rent a GPU — a graphics processing unit, the massively parallel chip these models run on — and expect production-grade speed and reliability to fall out. The gap between "it responds" and "it serves" is the whole subject of this stage.

And there's a question hiding underneath even that gap: what does fast mean for your product? A live voice agent, a chat app, and an overnight document-crunching job can run the identical model and need three different serving systems, because they optimize different numbers. §0 gives you the map of the discipline (the three layers, next section). §1 gives you the vocabulary for "best" — the metrics — and the checklist of product constraints that make optimization meaningful at all.

Why this discipline exploded now

When ChatGPT launched in late 2022, perhaps a few hundred people in the world did this work, nearly all inside frontier labs and big tech. It looked plausible that training would stay so hard and expensive that everyone else would simply rent intelligence through closed APIs. It didn't play out that way: open-weight models — models whose weights are publicly downloadable, versus closed models whose weights never leave the lab — multiplied into the millions on Hugging Face, and since the DeepSeek releases of late 2024 / early 2025 the intelligence gap between open and closed has effectively closed, with new closed releases matched by open ones within weeks.

That matters for serving because open weights unlock dedicated inference (your GPUs, your rules — defined properly in the Prerequisites section), and dedicated inference lets you optimize on axes the shared APIs can't offer you: latency tuned for real-time products instead of bulk throughput, availability beyond the roughly two-nines uptime typical of public APIs, and cost that can drop dramatically at scale. Which is exactly why "every serious AI product needs an inference strategy" stopped being a niche claim and became the premise of this stage.

Module A — inference is a three-layer discipline

One brilliant cook does not make a restaurant. Serving needs the cook, the kitchens, and the menu — and each is a different engineering problem.

Pass 1 · intuition

Training wrote the cookbook; inference runs the restaurant every night. A restaurant is three problems stacked on each other: a great cook working one station as fast as possible; enough kitchens opening and closing with the dinner rush; and an ordering system so customers can actually reach the food. A world-class cook with no way to take orders serves nobody. Miss any layer and the whole thing fails, but each layer fails differently.

Pass 2 · mechanism

The material names the layers runtime, infrastructure, and tooling, and the entire stage sorts into them:

Tooling APIs, SDKs, deployment workflow — the level of abstraction engineers touch Infrastructure autoscaling, capacity, multi-region and multi-cloud, uptime Runtime one model, one GPU-backed instance, maximum speed batching KV caching quantization speculation parallelism disaggregation
Fig A.1 — the three-layer inference stack. Sessions 2–5 live inside the runtime band; session 6 and much of source 2 live in infrastructure.

Runtime — one model, as fast as possible

The runtime layer makes a single model on a single GPU-backed instance as performant and efficient as it can be. It rests on a deep software stack: CUDA (NVIDIA's GPU programming platform) at the bottom, frameworks like PyTorch above it, and inference engines — vLLM, SGLang, TensorRT-LLM — on top. Low-level work matters enormously here: a single well-designed GPU kernel such as FlashAttention can move performance by large margins. Session 4 walks this stack bottom to top.

The six runtime levers

Batching runs many requests through the GPU together, interleaving them token by token, so the expensive hardware is never waiting on one slow customer — the single biggest throughput lever. KV caching re-uses stored attention results (the KV cache, defined properly in Module B) across requests that share the same opening text — think of a system prompt every request begins with. Quantization stores selected parts of the model in lower-precision number formats, cutting memory traffic and unlocking faster math at a small, measurable quality risk. Speculation (speculative decoding) drafts several cheap guess-tokens and verifies them in one model pass, yielding more than one token per step when the guesses land. Parallelism splits a model too big for one GPU across several without letting the communication between them become the new bottleneck. Disaggregation separates the two phases of a request — prefill and decode, Module B's subject — onto independently scaling pools of machines. All six apply beyond text: vision-language, embedding, speech-recognition, speech-synthesis, image and video models ride the same machinery with their own twists.

Infrastructure — many copies, without silos

No matter how fast one instance is, it eventually receives more traffic than it can handle. That is not a CUDA problem or a PyTorch problem; it is a systems problem, and its shape changes with scale. At first the problem is autoscaling: knowing when to add and remove replicas, and doing it fast enough to matter. Past a few hundred GPUs the problem becomes capacity: you physically cannot get enough GPUs in one place, so workloads spread across regions and cloud providers. Spreading creates silos — one cluster starving while another idles — so the endgame is treating all resources everywhere as one unified pool of compute. Done well, multi-cloud also buys reliability (no single region can take you down) and lower latency for global users (inference runs near them).

Tooling — the right amount of abstraction

Once runtime and infrastructure exist, someone has to decide how much of the machinery engineers see. One extreme is the black box: hand over weights, receive an API. The other is raw primitives: compute, network, disk, good luck. The productive answer sits in the middle — enough control to run mission-critical inference confidently, enough abstraction to stay productive. Whether you buy a platform or build one internally, this layer is a real product decision, not an afterthought.

Pass 3 · trade-offs

The instinct to carry out of this module: different layer, different fix. Runtime optimizations cannot save you from capacity problems; more replicas cannot fix a slow kernel; and beautiful tooling over a slow, siloed system is lipstick. When a number looks bad later in this stage, the first diagnostic question is always which layer owns this number? Module C sharpens that question into an actual routing rule.

Module B — the life of one request

An LLM reads your whole question in one gulp, then writes its answer one word at a time. Those two behaviors are so different they get their own names, bottlenecks, and metrics.

Pass 1 · intuition

Imagine answering an essay question under a strange rule: you may read the entire question at once, but you must write your answer one word at a time, re-reading everything written so far before each new word. Reading is a single parallel gulp; writing is a strict sequential loop. Every performance property of LLM serving flows from that asymmetry.

Pass 2 · mechanism

Vocabulary first. A token is the atomic unit of an LLM: a number standing for a chunk of text, usually a whole common word or a fragment of a rarer one — roughly 1,000 tokens per 750 English words. The tokenizer converts text to tokens and back. Generation is autoregressive: each new token is predicted from all previous tokens, appended, and fed back in. Reading the prompt is the prefill phase; the write-one-token loop is the decode phase. Prefill also produces the KV cache — stored intermediate results of the attention computation (the mechanism that lets tokens relate to each other; session 2 opens it up) — so decode never re-derives the past from scratch. Streaming means sending each token to the user the moment it exists rather than waiting for the full answer.

tok queue prefill — whole prompt, one pass end to end — what the user feels (network + queue + GPU) TTFT ITL gray = off-GPU · purple = prefill · teal = decode
Fig B.1 — one streamed request end to end. The first-token dot separates the two phases.

The six beats, in order

  1. Tokenize. The prompt is split into tokens. Cheap, fast, CPU-side — never your bottleneck, but it defines the units everything else is measured in.
  2. Queue. The request waits for the scheduler to slot it into GPU work. Zero GPU effort happens here, but the user's clock is running — queue time is invisible on the GPU and very visible to the person.
  3. Prefill. The entire prompt is processed in one parallel pass — heavy arithmetic across thousands of tokens at once. It emits two things: the first output token, and the KV cache the decode loop will re-use.
  4. First token. The elapsed time from send to here is TTFT (defined in Module C). On a streamed interface, this is the instant the reply starts appearing.
  5. Decode. Tokens arrive one per step, each appended and fed back in. The gap between steps is ITL; 25 ms per token means the user watches text arrive at 40 tokens/second.
  6. Zoom out. Wrap network hops and the queue around the GPU work and you get end-to-end latency; strip them off and you have on-GPU (inference-only) time. Module C turns that split into a diagnostic rule.
Pass 3 · trade-offs

Prefill and decode stress the GPU in opposite ways, and the material plants the flag in §1 because everything downstream grows from it. Prefill is compute-bound: the limit is how fast the chip does arithmetic, because a whole prompt's tokens are crunched in parallel — plenty of math per byte fetched. Decode is memory-bandwidth-bound: each step does comparatively little math but must re-read enormous amounts of data — the weights plus the growing KV cache — from GPU memory, so the limit is how fast bytes move, not how fast the chip multiplies. One request, two different physics.

Consequences worth memorizing now: a single knob rarely improves TTFT and token speed together, because they answer to different bottlenecks; long prompts punish TTFT specifically (more prefill work) while long outputs punish total time through ITL; and the industry's eventual answer to the mismatch — run the two phases on different, separately-scaled machines — is exactly the disaggregation chip from Module A. Sessions 2 and 3 make this quantitative with the ops:byte ratio (how many math operations a workload performs per byte it moves); for now, hold the asymmetry.

One boundary note: everything above assumes streamed output. When output is not streamed — a tool call inside an agent, where half an answer is useless — token-by-token metrics stop mattering and you measure plain total response time instead.

Module C — the four numbers that describe "fast"

"Is the restaurant fast?" is two questions: how long until my food arrives, and how many meals leave the kitchen per hour. Confusing them is the classic serving mistake.

Pass 1 · intuition

Latency is the wait for one request — your food. Throughput is total work per unit time — meals per hour across all tables. A packed kitchen maximizes meals per hour while each diner waits a little longer; an empty kitchen serves you instantly and wastes the stoves. Every serving configuration in this stage is a chosen point on that curve, and "optimize" without naming the axis is meaningless.

Pass 2 · mechanism

For streamed LLM output, latency splits along Module B's two phases. TTFT — time to first token — is the wait until output begins: queue time plus the prefill pass, so it scales with prompt length. After the first token, the felt speed is ITL — inter-token latency, the gap between successive tokens; its reciprocal is per-user token speed, so 10 ms ITL ⇔ 100 tokens/second for that user.

Then comes the trap the material flags explicitly: people say "TPS" (tokens per second) for two different quantities. Perceived TPS is tokens/second a single user receives after the first token — a latency metric. Total TPS is tokens/second the whole service produces across all users — a throughput metric. Batching typically lowers each user's perceived TPS a little while multiplying total TPS a lot, which is precisely why the two must never share a name in your dashboards. And for non-streamed calls, the right latency metric is simply total response time, first byte sent to last byte received.

Percentiles: one number is never the truth

Inference times form a right-skewed distribution: most requests cluster near a typical value, a minority take far longer, and those outliers drag the mean above the median. So engineers report percentiles — P50 is the median, and P90/P95/P99 mark the values that 1 in 10 / 20 / 100 requests exceed. Targets you formally commit to on these numbers are SLOs — service-level objectives — and they are written against tails, never averages, because a product where most replies feel snappy but one in ten hangs still bleeds user trust.

p50 mean p95 p99 response time →
Fig C.1 — the right-skewed reality. Outliers pull the mean right of p50; SLOs live out at p95/p99.
PercentileMeaningPlain reading
P50median latency1 in every 2 requests is slower
P9090th percentile1 in every 10 requests is slower
P9595th percentile1 in every 20 requests is slower
P9999th percentile1 in every 100 requests is slower

End-to-end vs inference-only: the routing rule

Every latency also has two frames. Inference-only time is the on-GPU portion — prefill plus decode — and it tells you whether your model-performance work is working. End-to-end latency adds queue time and network on both sides, and it tells you what users actually feel. The diagnostic rule that falls out is the most practical sentence in the section: when inference-only is fast but end-to-end is slow, stop tuning the model — the problem lives in the infrastructure layer.

Pass 3 · trade-offs

Three sharp edges. First, averages actively lie — the histogram above is why; chase P90/P99, and treat a drifting p99 under a steady p50 as an early warning of queue buildup or memory pressure. Second, measure at realistic concurrency: TTFT with one user in the system is mostly network plus a single forward pass and says almost nothing about production behavior. Third, tighter tails are a provisioning cost before they are an engineering achievement — every notch of TTFT-p99 you promise forces lower peak utilization and therefore more replicas; the Reality-check section prices this with 2026 numbers.

Module D — before optimizing anything, constrain everything

NFL players aren't the biggest, fastest, or strongest humans — they're optimized for a position. So is a good serving system. "Best" only exists relative to a use case.

Pass 1 · intuition

Sumo wrestlers out-mass them, sprinters out-run them, powerlifters out-lift them — yet NFL players dominate their own game, because their bodies are tuned for its specific demands. Same for a recruiting coach at a school: the basketball coach wants the tallest kids, the gymnastics coach the shortest. Your inference system is the athlete; your product is the sport. Every constraint you pin down — traffic shape, latency budget, economics — shrinks the search space and makes genuinely better outcomes reachable. Optimization without constraints is just motion.

Pass 2 · mechanism

The five questions to answer first

§1 opens with a checklist; if you cannot answer these, you are not ready to optimize. Model requirements — which model or models must run? Application interface — how do inputs arrive and how must output be shaped (streamed text, JSON, audio)? Latency budget — end to end, how fast must the product respond to a user action? Unit economics — what is worth spending per request, per user, per month? Usage patterns — how many concurrent users, and with what rhythm (business hours, launches, seasonality)? Early products often can't answer these yet — which is itself the signal to stay on off-the-shelf APIs until the answers firm up.

Decision one: who runs the GPUs

Shared inference means sending traffic to a public pay-per-token API endpoint. A dedicated deployment means renting GPUs by the hour (or owning them) and running an inference service exclusively for your application. This is not identical to closed vs open models — shared endpoints for open models exist, and big customers sometimes get dedicated capacity for closed ones — but open weights are what make unrestricted dedicated serving possible, which is a key reason teams adopt them.

Shared inference — pay per tokenDedicated deployment — pay per GPU-hour
Zero setup — an API key and goYou tune latency, uptime, everything
Always warm — no cold starts (the spin-up delay when a model isn't loaded anywhere)Runs custom and fine-tuned models
Cost tracks usage exactly; no floorCheaper per token past a volume threshold
Bill grows linearly with usage, foreverReal engineering surface area
Provider uptime caps yours; noisy neighbors (other tenants' spikes degrading your latency)Monthly cost floor, even when idle
No control over latency, quality, or rate limitsReliability becomes your pager

Most products should start on the left and move right only on a clear, immediate business need. The material names exactly three such needs, which read as a guard-clause tree — follow each "no" down, exit right on any "yes", and the bottom-left box is the default:

Scale?token bill rivals GPU rental yes Go dedicatedeconomics favor GPU-hours no Specialization?custom model, strict latency/uptime yes Go dedicatedyou need the control no Orchestration?multi-model pipeline, hops hurt yes Go dedicatedkeep hops in-cluster no Stay on shared APIs pay per token, revisit at scale
Fig D.1 — dedicated or shared, as a guard-clause tree. Scale = it's cheaper; specialization = you need control (custom models, strict latency or uptime, compliance); orchestration = multi-model pipelines where network hops between hosted APIs add latency and complexity.

Decision two: the shape of the workload

Online vs offline. Online workloads — chat, code completion, voice — have an impatient human on every call: optimize latency. Offline workloads — transcribing a podcast back-catalog, embedding a document corpus on a schedule, cleaning massive datasets for training — have nobody watching: optimize throughput, because more work per GPU-hour means fewer GPUs. The elegant trick: one model can get two deployments. A speech-to-text model like Whisper can run latency-tuned inside a live dictation app and, separately, throughput-tuned inside a batch transcription job — if both have volume, two specialized deployments beat one compromise.

Consumer vs B2B. Consumer apps are cost-sensitive with spiky, virality-driven traffic — one launch can multiply load overnight — so prioritize marginal cost and elastic scaling, keeping latency and availability merely decent. B2B products sit in someone's revenue path and are held to a higher bar: prioritize latency and uptime, with cost an important second. In both, compliance can veto infrastructure outright: data sovereignty (are your GPUs in a region legally allowed to see this data?), user privacy, and sector regulation all constrain where and how you serve — work with security and legal, not around them.

Generality is the exception. Two builders must stay general: labs selling their own foundation model through a public API, and teams building an inference platform that must host any model for any use case. Everyone else — the vertical apps that dominate the field — should do the opposite and add every constraint they can.

What each application category actually optimizes

CategoryExampleDominant considerationOptimize
Chatcustomer-support chat with RAG (retrieval-augmented generation — fetching relevant documents into the prompt to ground answers)a fast first word makes the whole product feel fastTTFT, then perceived TPS
Agentssales prospecting agentone user action fans out into many chained model calls; per-call latency compoundswhole-chain E2E + throughput
Voicelive speech translationthe whole turn must fit a natural conversational pauseend-to-end p99
Mediavirtual try-on for clothingusers trade a short wait for a better imagetotal latency vs quality
Searchlegal document discoverybulk offline corpus prep plus snappy online queries — often two deploymentsthroughput offline · latency online
RecSyse-commerce recommendationsconsistency at very high request volumep99 latency + total TPS
Completiontab completion in an IDEthe whole chunk must land at typing speed; nobody streams a tab-completetotal response time
Moderationscanning user content for safetynobody is watching an individual check; cost per item dominatestotal TPS (throughput)
Pass 3 · trade-offs — the model is the biggest knob

The section's punchline: the largest performance decision is not a flag or an algorithm — it is which model you run. All else equal, fewer parameters means faster and cheaper, so the job is finding, or making, the smallest model that is smart enough. Sometimes that is still a trillion-parameter frontier model; it is always worth checking whether it isn't.

"Smart enough" is measured by evals — systematic, product-specific tests of model quality — as opposed to public benchmarks (standardized tests like MMLU or SWE-bench), which are useful for shortlisting but increasingly saturated and gamed. Goodhart's law — when a measure becomes a target, it stops being a good measure — applies squarely to leaderboard-chasing releases; head-to-head preference ratings gauge general intelligence better, but nothing substitutes for measuring the model on your own task. Evals also protect you later: several optimizations in this stage can nibble at quality, and you cannot detect nibbling without a baseline. Practical habits: look at your data (check results against your intuition), be precise (focus evaluation on the hardest problems the product must solve), and use existing tooling rather than reinventing it.

Two tools shrink the model you need. Fine-tuning continues training a pre-trained model on domain data, changing the weights while keeping the architecture. The canonical win is text-to-SQL: SQL is so constrained that a fine-tuned model of a few billion parameters can match general coding models a hundred times its size on that one task — an extreme case, but it shows what a cleanly scoped domain, strong evals, and good labeled data can buy. Distillation trains a small "student" model to imitate a large "teacher," learning from the teacher's full output probability distributions rather than just final answers — so the student inherits behavior, good and bad. It is rarer in practice: when labs ship model families, the small ones are usually trained independently so the big model's biases don't cap them. But when a lab ships only a giant — DeepSeek-R1 at 671B parameters in early 2025 — distills onto popular architectures like Llama 3 and Qwen 2.5 make the behavior accessible, and inherit all the performance tooling those architectures already enjoy.

Which is the final selection criterion: prefer popular architectures. Inference engines optimize the common paths first; an exotic architecture can lock you out of the very techniques the rest of this stage teaches.

Reality check — arithmetic, then the wild

One worked napkin problem to make the trade-off concrete, then three field reports from the last few months showing §1's concepts running in production.

The napkin: one request, two ways to serve it

A chat product. Prompt: 1,200 tokens; reply: 300 tokens. Config A is latency-tuned, config B throughput-tuned. GPU cost: $2/hour = $0.000556 per second. Each request's cost is its share of GPU time.

Config A — latency-tuned TTFT 300 ms · ITL 25 ms · 4 concurrent users per GPU
E2E = 0.3 + 300 × 0.025 = 7.8 s
GPU-time/request = 7.8 / 4 = 1.95 s → $0.00108

Config B — throughput-tuned TTFT 900 ms · ITL 45 ms · 64 concurrent users per GPU
E2E = 0.9 + 300 × 0.045 = 14.4 s
GPU-time/request = 14.4 / 64 = 0.225 s → $0.000125

Verdict B is ≈ 8.7× cheaper per request for being ≈ 1.8× slower.

Is slower even bad here? Roughly 6 tokens/second matches typical human reading speed (see the serving-metrics survey linked below) — config B still streams at 22 tok/s, nearly four times faster than anyone reads. For chat, B is probably the right answer; for a voice agent or a chained agent workflow, A is. That is §1 compressed into one arithmetic problem: the product picks the metric; the metric picks the config.

Field report 1 — throughput under a latency floor (disaggregation, grown up)

NVIDIA's Dynamo 1.0 announcement (April 2026) reports about 7× more performance from disaggregated serving combined with wide expert parallelism on GB200 NVL72 racks — measured on DeepSeek R1-0528 at an interactivity target of roughly 50 tokens/sec/user, per SemiAnalysis InferenceX benchmarks updated March 3, 2026. Read the phrasing carefully: throughput gains at a fixed per-user token speed. That is Module C's perceived-vs-total TPS distinction as a production headline — real systems maximize total TPS under a floor on perceived TPS. It is also Module A's disaggregation chip at datacenter scale: prefill workers (compute-bound) and decode workers (memory-bound) scaled independently, with the KV cache shipped between them.
NVIDIA dev blog: Dynamo 1.0 github.com/ai-dynamo/dynamo product page

Field report 2 — what a tail costs in dollars

A May 2026 capacity-planning guide works the SLO economics: tightening a TTFT-p99 target from 500 ms to 200 ms raises infrastructure spend by roughly 35% at the same request rate, because tighter tails force lower peak utilization — more replicas for the same traffic. Voice pipelines get the tightest budgets of all, around 400 ms end-to-end to first speech. Meanwhile the tail hides from averages: a system with a 200 ms average TTFT can simultaneously run a p99 over 3 seconds, and because TTFT grows roughly linearly with uncached prompt tokens, a 32,000-token context can cost ~100× the TTFT of a 320-token one — context-length heterogeneity is a primary driver of heavy tails in real traffic. This is Fig C.1, priced.
SLO engineering guide (May 2026) latency decomposition tail latency deep-dive serving-metrics survey (TTFT/TBT/TPOT)

Field report 3 — the aging check

The material states its own knowledge cutoff: January 2026. In engine terms that was vLLM v0.12.0 (mid-January). Six months later vLLM sits at v0.26.0 (released July 25, 2026) on a two-week cadence, merging 1,918 commits in June 2026 alone — guarded by nightly performance benchmarks and accuracy evaluations, because "did throughput regress?" and "did quality regress?" are separate questions. Two lessons: the runtime layer moves faster than any source can freeze, so always cross-check versions and defaults; and even the engine builders practice Module D's discipline — evals as the baseline that licenses optimization.
vLLM: keeping production quality (Jul 2026) vLLM on PyPI docs.vllm.ai

Ecosystem mappingThe same concepts wear three uniforms. Open source: vLLM / SGLang engines, Dynamo for disaggregated multi-node orchestration. NVIDIA stack: TensorRT-LLM as the engine, Dynamo + NIM microservices packaging it. Clouds: AWS and GCP expose the pattern through managed endpoints (SageMaker, Vertex) or raw GPU instances (EC2 G/P families, GCE A/L families) where you run the open stack yourself — which is what your Modal setup emulates on a per-container basis.

Apply to your code

Your PROFILE ladder in gemma_modal.py is §1 turned into a switch statement: same model, same L4, seven points on the latency–throughput curve.

ProfileKey changeConcept exercisedMetric it moves
worstmax_num_seqs=1 · max_inputs=1 · enforce_eagerthe no-batching floor — perceived TPS equals total TPS because one user owns the GPUqueue owns p99 TTFT under any concurrency
baseline64 seqs · max_model_len 32768→16384continuous batching (Module A's token-by-token weaving); shrinking unused context frees KV-cache room for concurrencytotal TPS ↑ sharply; per-user ITL slightly ↑ under load
bestenforce_eager=False · async_scheduling · 256 seqs · 0.92 utilCUDA graphs (pre-recorded GPU launch sequences cutting per-step overhead) + preparing the next batch while the current one runsITL ↓ · concurrency ↑ — throughput under a latency floor
prefixenable_prefix_caching=TrueKV re-use across shared prompt openings — skips compute-bound prefill workTTFT ↓ for repeated prefixes (your gain = prefix − best)
tunedmax_num_batched_tokens=8192the per-step token budget: how much prefill may ride each engine step alongside decodeTTFT vs ITL tension (yours no-ops: seqs already capped at 256)
quantfp8 weights + fp8 KV cachequantization relieving memory-bandwidth-bound decode — fewer bytes read per step, smaller KV per sequenceITL ↓ · max concurrency ↑ · re-run evals (Module D)
fp8-ckptpre-quantized checkpoint (modelopt)same physics as quant; isolates load-time and boot reliabilitycold-start time, not steady-state speed

Your tutorial repo speaks the same vocabulary: the Prometheus p95/p99 panels are Module C's percentile discipline; the 22.5× batch-32-vs-1 benchmark is the perceived-vs-total-TPS distinction measured; and the IntelligentRouter — classifying request complexity and routing to the cheapest adequate model under budget and latency constraints — is Module D's "smallest model that passes" applied per request instead of once at design time.

One experimentBenchmark worst vs baseline at concurrency 1 and concurrency 16, recording TTFT p50/p99, ITL, and total TPS. Prediction: near-identical at concurrency 1; at 16, baseline's total TPS lands roughly an order of magnitude higher with only modest ITL degradation, while worst's p99 TTFT explodes — queueing made visible in your own logs, the end-to-end vs on-GPU split of Module C, live.

Next session: the serving text, Models — tokens, transformers, attention, and the ops:byte arithmetic that proves why prefill saturates compute while decode starves on memory bandwidth.

Glossary

Every term this session defined, alphabetized. If a word isn't here, session 1 hasn't earned it yet.

autoregressive
Generation where each new token is predicted from all previous tokens, appended, and fed back in.
batching
Running many requests through the GPU together, interleaved token by token, to raise throughput. Continuous batching is the scheduler admitting and retiring requests mid-flight rather than waiting for a fixed group.
benchmark
A standardized public test of model capability (MMLU, SWE-bench). Useful for shortlisting; increasingly saturated and gamed.
closed / open model
Closed: weights never leave the lab; you rent access. Open: weights are publicly downloadable, enabling unrestricted dedicated serving (license terms vary — check them).
cold start
The spin-up delay when a model isn't loaded anywhere and must boot before serving.
compute-bound
Limited by how fast the chip does arithmetic. Prefill's regime — abundant math per byte fetched.
concurrency
The number of simultaneous in-flight requests a system is handling.
CUDA
NVIDIA's GPU programming platform; the bottom of the runtime software stack. CUDA graphs are pre-recorded launch sequences that cut per-step CPU overhead.
data sovereignty
The legal constraint on which geographic regions may process a given user's data.
decode
The sequential phase generating one token per step, re-reading weights and KV cache each time. Memory-bandwidth-bound.
dedicated deployment
An inference service run exclusively for your application on GPUs you rent or own; pay per GPU-hour.
disaggregation
Serving prefill and decode on separate, independently scaled machine pools, shipping the KV cache between them.
distillation
Training a small student model to imitate a large teacher, learning from the teacher's output probability distributions rather than only final answers.
end-to-end (E2E) latency
Total wall-clock time the user experiences: network + queue + on-GPU work.
evals
Systematic, product-specific measurements of model quality; the baseline that licenses optimization.
fine-tuning
Continuing training of a pre-trained model on domain data — weights change, architecture stays.
GPU
Graphics processing unit; the massively parallel accelerator generative models run on.
inference
Serving a trained generative model in production; the second and permanent phase of a model's life.
inference-only time
The on-GPU portion of latency: prefill + decode, excluding queue and network.
ITL — inter-token latency
The gap between successive output tokens during decode. Reciprocal of per-user token speed: 10 ms ⇔ 100 tok/s.
KV cache
Stored intermediate results of the attention computation, produced during prefill and re-read every decode step so the past is never recomputed.
latency
The wait for one request; for streamed output it decomposes into TTFT and ITL.
memory-bandwidth-bound
Limited by how fast bytes move from GPU memory, not by arithmetic speed. Decode's regime.
noisy neighbors
Other tenants on a shared endpoint whose traffic spikes degrade your latency.
P50 / P90 / P95 / P99
Latency percentiles: the value that 1 in 2 / 10 / 20 / 100 requests exceeds. P50 is the median.
parallelism
Splitting a model across multiple GPUs without letting inter-GPU communication become the new bottleneck.
perceived TPS
Tokens per second one user receives after the first token — a latency metric.
prefill
The parallel phase processing the entire prompt in one pass; emits the first token and the KV cache. Compute-bound.
prefix caching
Re-using the KV cache across requests that share the same opening tokens, skipping that portion of prefill.
quantization
Storing selected parts of the model (weights, KV cache) in lower-precision formats to cut memory traffic and unlock faster math.
queue time
Time a request waits before the GPU begins work on it; invisible on-GPU, fully visible to the user.
RAG
Retrieval-augmented generation — fetching relevant documents into the prompt to ground the model's answer.
shared inference
Sending traffic to a public pay-per-token API endpoint.
SLO — service-level objective
A formal target on a metric, written against tail percentiles, that you commit to and provision for.
speculation (speculative decoding)
Drafting cheap guess-tokens and verifying them in one model pass, yielding more than one token per step when guesses land.
streaming
Sending each token to the user as it is produced rather than waiting for the full response.
throughput
Total work per unit time across all requests — for LLMs, total TPS or requests/second.
token / tokenizer
The atomic unit of an LLM — a number standing for a word or word-fragment (~1,000 tokens per 750 English words) — and the component converting text to tokens and back.
total response time
First byte sent to last byte received; the right latency metric when output isn't streamed.
total TPS
Tokens per second the whole service produces across all users — a throughput metric.
training
The one-time process of learning a model's weights from data.
TTFT — time to first token
Elapsed time from request send to first output token: queue + prefill. Scales with (uncached) prompt length.
weights
The learned numbers inside a model; set during training, read constantly during inference.
← 04The path
Next stage · 06 →genaipros · 05 · LLM Inference & ServingAI for Everyone ↗