peterindia.net · Generative AI / MLOps Generative AI · Language Models
Systems & Infrastructure

LLM Training and Inferencing Optimization Techniques

Training and serving a large language model are two different engineering problems that happen to share a GPU. Here's what actually determines cost and speed on each side — and why the techniques that help one side often don't help the other.

Using multiple GPUs to train models or serve production workloads is expensive. There is no single trick that fixes this — the right move depends entirely on which of the two you're doing. A parallelism strategy that speeds up a training run can actively hurt a serving system's latency; a caching trick that makes inference cheap has no equivalent during pretraining. Treating them as the same optimization problem is the most common mistake teams make when their GPU bill doesn't match expectations.

Training optimizes for throughput

A fixed, large compute budget spread across a job that runs for days or weeks. The goal is maximum useful FLOPs per GPU-hour, and the job can tolerate scheduled restarts as long as progress isn't lost.

Inference optimizes for latency and cost per request

Unpredictable, bursty traffic that has to be answered in milliseconds to seconds, one request — or one growing batch of requests — at a time, with no room for a scheduled pause.

Key Considerations for Training

Four decisions shape almost everything else about a training run's cost and reliability.

1

Parallelism Strategy

Choose among data, tensor, pipeline, or a mix, based on model size and hardware topology. Start with data parallelism — each GPU holds a full copy of the model and processes a different slice of the batch — when the model comfortably fits on one GPU. Once memory becomes the constraint, move to sharding or model-splitting:

Frontier-scale runs typically combine all three into 3D parallelism: tensor parallelism inside a node (where bandwidth is highest), pipeline parallelism across a small group of nodes, and data parallelism across the remaining GPUs.

DATA PARALLELISM TENSOR PARALLELISM PIPELINE PARALLELISM GPU 0 GPU 1 full model copy each split the BATCH, sync gradients half of layer N split a LAYER, needs NVLink-class bandwidth layers 1-8 layers 9-16 split by DEPTH, micro-batches flow stage to stage Frontier runs combine all three: tensor parallelism inside a node, pipeline across a few nodes, data parallelism across the rest.

Three parallelism strategies, three different communication patterns — which is why they get mapped onto different tiers of the network hierarchy.

2

Memory Budgeting

Weights, gradients, optimizer states, and activations all compete for the same fixed pool of GPU memory. Know this budget upfront — it's what determines which parallelism strategy is even feasible.

For standard mixed-precision training with the Adam optimizer, a widely cited rule of thumb (from the ZeRO paper) puts the non-activation memory cost at roughly 16 bytes per model parameter: 2 bytes for FP16 weights, 2 bytes for FP16 gradients, and 12 bytes for FP32 optimizer state (master weights, momentum, and variance). Activations add more on top, scaling with batch size and sequence length — which is exactly why activation checkpointing (recomputing activations during the backward pass instead of storing all of them) is a standard technique for fitting larger batches or longer contexts into the same memory budget.

Mixed-precision Adam training: ~16 bytes / parameter (before activations) 2B 2B 12B — Adam optimizer state (FP32 master weights + momentum + variance) FP16 weights FP16 grads Example: a 7B-parameter model needs ~112 GB for weights + gradients + optimizer state alone — before a single activation tensor is stored. This is why the optimizer state, not the weights, usually dominates the memory budget.

The optimizer state — not the model weights — is typically the largest single consumer of training memory, which is exactly what ZeRO/FSDP sharding is built to address.

3

Interconnect Bandwidth

NVLink and NVSwitch deliver very high bandwidth between GPUs within a single node, while InfiniBand connects nodes to each other at a meaningfully lower bandwidth. Communication-heavy strategies — tensor parallelism above all — only make sense inside that high-bandwidth boundary; push them across InfiniBand and the communication overhead can erase the benefit of adding more GPUs entirely.

This is the practical reason 3D parallelism is laid out the way it is: tensor-parallel shards stay inside a node (NVLink), pipeline stages span a handful of nodes (moderate InfiniBand traffic, sent only at stage boundaries), and data-parallel gradient synchronization — the most bandwidth-tolerant of the three — spans the rest of the cluster.

4

Fault Tolerance

Long-running, multi-node jobs will eventually hit hardware failures and stragglers — at cluster scale, over a multi-week run, this isn't an edge case, it's a certainty. A checkpointing strategy and job orchestration layer are what save your progress when something breaks, rather than losing days of compute to a single failed GPU.

Key Considerations for Inference

Once training ends and serving begins, the bottlenecks, and the fixes, change completely. Part one covers the ten mechanics inside the model and serving engine; part two covers the production levers around them that cut cost.

Ten Inference Mechanics

From the KV cache to prefill-decode disaggregation: how each technique works, and what it costs.

1

KV Caching

The simplest and most foundational optimization: stop recomputing what you've already computed.

During each step of autoregressive text generation, an LLM compares the last token's Query vector against the Key vectors of every preceding token, including itself. This produces attention weights, which are used to compute a weighted sum over the corresponding Value vectors — the attention output for that token.

For example, when generating the token that follows "The capital of the U.K. is", the model:

This repeats at every step of generation. Recomputing Key and Value vectors for the entire sequence at each step gets expensive fast as the sequence grows — which is exactly the problem a KV cache solves.

Instead of recalculating Key and Value vectors for the whole sequence every time, the KV cache stores each token's K and V vectors once. At each new step, the model only computes (and appends) the new token's Key and Value, reusing everything else from the cache.

WITHOUT KV CACHE — recompute K,V for every token, every step The capital of U.K. is → all 5 recomputed to predict "London" WITH KV CACHE — reuse cached K,V, compute only the new token The capital of U.K. is London ← only the new token is computed

Green/cyan = cached and reused. Red = recomputed. The KV cache trades HBM memory for a large cut in redundant computation.

This massively reduces inference compute — but at the cost of GPU high-bandwidth memory (HBM). There's no free lunch. Still, KV caching is one of the simplest, highest-leverage techniques for improving inference speed.

2

Efficient Attention Mechanisms

Since the KV cache eats into HBM, shrinking it is its own optimization target.

Traditional Multi-Head Attention (MHA) gives every attention head its own Key and Value vectors. Several attention variants reduce the number of K/V vectors in use — and therefore the KV cache size:

MHA MQA GQA MLA 3 heads, 3 full KV sets 3 heads, 1 shared KV 2 groups, 2 shared KV pairs latent compressed KV latent

MHA vs MQA vs GQA vs MLA — fewer distinct Key/Value sets means a smaller KV cache. (Source)

3

Continuous Batching

Processing requests one at a time wastes GPU compute — batching fixes that, but how you batch matters.

Handling LLM requests sequentially is inefficient, since requests arrive at different times and have variable input/output lengths. Batching requests together improves overall throughput and reduces idle GPU compute — but there's more than one way to do it:

In static and dynamic batching, the entire batch must finish before a new request can join. Continuous batching removes that constraint, keeping GPU utilization consistently high.
4

Optimized Kernels

Decode is memory-bound — the bottleneck is moving data, not computing on it.

During inference, the Decode phase is memory-bound: the GPU spends more time moving data from memory (HBM) to its compute cores than actually computing. A kernel is a function that runs on the GPU performing parallel operations, and it can be optimized to keep data in fast on-chip memory (SRAM/registers) rather than repeatedly re-reading it from slow HBM.

Kernel fusion merges multiple individual operations into a single kernel to avoid unnecessary data movement across memory. FlashAttention is the best-known example, fusing the operations of attention computation into one kernel.

Standard attention computation moves data back and forth repeatedly: Query and Key are read from HBM and multiplied to form an attention score matrix, which is written back to HBM, re-read to apply softmax, written back again, then read once more to multiply by the Value matrix — with the final output written back to HBM one last time.

FlashAttention avoids all of this by never materializing the full attention matrix in HBM. It splits the Query, Key, and Value matrices into smaller tiles that fit in on-chip SRAM, and performs attention one tile at a time — computing attention scores and softmax on-chip, and writing only the final output back to HBM.

HBM (slow, large) Q, K, V matrices full Q / K / V final output only On-chip SRAM (fast, small) Q tile K tile V tile attention score + softmax computed on-chip, per tile tile output loop over Q/K/V tile blocks No N×N attention matrix ever touches HBM

FlashAttention tiles Q/K/V into on-chip SRAM, computing attention block by block and writing only the final output back to HBM — minimizing slow memory round-trips.

5

Quantization

Store and compute in fewer bits, and both memory footprint and throughput improve.

Quantization stores and computes LLM parameters, activations, and the KV cache in lower-precision formats such as INT8 (8 bits) or INT4 (4 bits) instead of full-precision FP32 or 16-bit FP16/BF16. This shrinks memory requirements and increases throughput by reducing how much data moves from HBM to the compute cores — at the cost of a slight accuracy drop.

Llama 3 70B memory footprint by precision FP32 280 GB FP16 140 GB INT8 70 GB INT4 35 GB single H100 GPU: 80 GB memory → only INT8 & INT4 fit on one GPU

At FP32, a 70B-parameter model needs 280 GB — more than a single 80 GB H100 GPU. Quantizing to INT4 brings that down to 35 GB, small enough to fit on one GPU.

Quantized models are commonly labeled using the convention W(x)A(y), describing how much the weights (W) and activations (A) have been quantized:

W4A16W8A8W4A4

You'll also see model names suffixed with -GPTQ or -AWQ — the two most common quantization techniques:

6

Prefix / Prompt Caching & RadixAttention

Many requests share the same opening tokens — compute that shared prefix once.

LLM inference has two distinct phases:

Prefix (or prompt) caching reuses the computed KV cache for a shared prefix of the input prompt across multiple requests, cutting redundant Prefill computation and shortening TTFT. Consider a long system prompt like "System: You are a helpful assistant..." — without prefix caching, every request recomputes Prefill for the entire system prompt plus the user's question. With it, the system prompt's KV cache is computed once and reused; each request only computes Prefill for its own unique question.

RadixAttention, introduced with the SGLang serving framework, implements prefix caching efficiently using a radix tree: each path from the root represents a token sequence, and shared prefixes across requests become shared branches. For a new request, the algorithm walks the tree, matching tokens as far as possible and reusing the KV cache along that path — computing Prefill only for the tokens unique to that request.

7

Pruning

Not every parameter earns its keep — pruning removes the ones that don't.

Pruning removes parts of a model that contribute little to its accuracy, making it smaller and cheaper to run inference on. It comes in three flavors:

  1. Unstructured pruning — sets low-magnitude individual parameters to zero.
  2. Structured pruning — removes entire sections of the model, such as neurons, attention heads, or fully-connected layers.
  3. Semi-structured (N:M) pruning — sets N of every M consecutive weights to zero. NVIDIA GPUs from Ampere onward have hardware support for 2:4 sparsity, giving roughly a 2x boost in matrix multiplication throughput.
8

PagedAttention

Borrowed from operating systems: don't demand one giant contiguous block of memory.

PagedAttention, introduced in the vLLM serving framework, manages the KV cache's memory more efficiently by borrowing an idea from how operating systems handle memory paging.

Instead of reserving one large contiguous chunk of GPU memory for the KV cache upfront, PagedAttention stores it dynamically across many small, fixed-size, non-contiguous blocks called pages. A per-sequence block table maps logical token positions to their physical memory blocks, and the attention kernel consults this table to locate the right KV pairs on demand.

Logical sequence tok 0-3 tok 4-7 tok 8-11 tok 12-15 Block table Physical GPU memory (non-contiguous pages) page page page free page

A block table maps each logical chunk of the sequence to a physical page, which can live anywhere in GPU memory — just like OS virtual memory paging.

9

Speculative Decoding

Use a fast, small model to guess ahead — then let the big model verify the guesses in one pass.

Speculative decoding accelerates inference with large LLMs by pairing them with a smaller model from the same family, sharing the same tokenizer and vocabulary. The smaller model — the Draft model — runs faster than the larger Target model simply because it has fewer parameters. The process works like this:

  1. Drafting — for a given prompt, the Draft model generates K tokens ahead of time.
  2. Target forward pass — those K draft tokens, plus the original prompt, are fed to the Target model. In a single forward pass, it produces a probability distribution for the next token at every drafted position, plus one more beyond it (K + 1 predictions total). Because Decode is memory-bound, this single pass costs about as much as generating just one token normally would.
  3. Verification — each drafted token is checked against the Target model's prediction at that position. It's accepted if they match (under greedy decoding) or if the Target model finds it likely enough via rejection sampling (under probabilistic decoding). At the first token where verification fails, that token and every token after it are discarded, the Target model supplies a replacement, and drafting resumes from that position.
Example: 5 drafted tokens, verified against the target model ✓ D1 ✓ D2 ✓ D3 ✗ D4 D5 (discarded) replacement Result: 3 accepted draft tokens + 1 resampled replacement = 4 tokens from one target pass, instead of 4 separate memory-bound decode steps.

If all K draft tokens are accepted, the output is K+1 tokens in one pass (best case). If the very first draft token is rejected, the result is just 1 resampled token — identical to normal decoding (worst case, no loss).

10

Prefill-Decode Disaggregation

Prefill and Decode want different things from hardware — so give them different hardware.

Prefill is compute-bound and determines TTFT; Decode is memory-bound and determines TPOT (also called inter-token latency). These are fundamentally different problems, and optimizing both on the same GPU is difficult — especially for prefill-heavy requests where long prompts produce short outputs, and low TTFT and low TPOT are both required at once.

Prefill-decode disaggregation is a serving architecture that solves this by moving the two inference stages onto separate, dedicated GPU pools: one pool optimized for high compute (e.g. the H100) handles Prefill, while a pool optimized for high memory throughput (e.g. the H200, which offers much faster and larger memory at similar core compute) handles Decode.

The main overhead in this architecture is transferring the KV cache between the Prefill pool and the Decode pool — a cost that can be reduced with faster interconnects such as NVLink or InfiniBand.
Latency vs. throughput. Serving optimizes for responsiveness under concurrent load, not raw throughput in isolation. That changes which parallelism strategies make sense: pipeline parallelism adds latency per token as a request moves stage to stage, so it is often avoided in serving even though it is a mainstay of training. Systems track two separate metrics, Time-to-First-Token (TTFT) and Time Per Output Token (TPOT), because a fix that improves one can quietly hurt the other.

Measuring Inference in Production

Inference engineering is the discipline of keeping a model fast, stable and affordable once real traffic arrives. A LinkedIn commentary by Progressive Thinker argues it is underrated compared with training, because serving adds queueing, batching, KV-cache pressure, GPU memory limits, scheduling, communication and tail-latency problems.

⏱

Metrics that matter

MetricWhat it tells you
TTFT (time to first token)How long a user waits before output starts; driven mainly by queueing and prefill.
ITL / TPOT (inter-token latency)How smoothly tokens stream after the first; driven mainly by decode.
Throughput and concurrencyAggregate tokens per second and simultaneous requests served.
Queueing delay and tail latencyWhat the slowest requests experience; averages hide it.
KV-cache occupancy and GPU utilizationHow close the server is to its memory and compute ceilings.
GoodputThe share of requests that still meet the latency objective, not just raw volume.
Tokens per second alone is misleading. A server can post strong aggregate throughput while users wait too long for the first token. Larger batches raise utilization but can increase queueing and decode latency, so scheduling matters as much as kernel optimization.
⚙

Where each technique fits

Prefill vs. decode. Prefill processes the prompt and builds the KV cache; it parallelizes well and is usually compute-bound. Decode generates one token at a time and is often limited by memory bandwidth at practical batch sizes. Most techniques below target one phase or the other.

Beyond performance, production serving also needs access control, cost tracking, token budgets and guardrails; avoiding a request altogether through caching and routing can be cheaper than optimizing GPU throughput.

Cutting Inference Cost in Production

Most enterprise AI budgets don't blow up because the model is expensive per token. They blow up because every request pays the full price of a frontier model, a cold context window, and an unbatched GPU — regardless of whether the request actually needed any of that. The fix isn't a cheaper model; it's an inference layer that only spends what a given request genuinely requires. That layer is built from a dozen or so techniques that work at different points in the request path — before the model is even called, inside the serving engine, inside the model itself, and after the response ships. Seven levers follow, grouped by where in the stack they operate.

INCOMING REQUEST Context Window Audit trim to relevant context only Semantic + Prefix Cache Check embedding match · exact KV prefix match Cache Hit → Return skips model call entirely miss Complexity-Aware Router classify task; estimate cost/quality trade-off Small / On-Prem Model routine · sensitive/local data Mid-Tier Model moderate reasoning, most traffic Frontier Model complex · ~10-15% of traffic Quantized Weights (AWQ / GPTQ / FP8) + Fine-Tuned / Distilled Variants smaller memory footprint, same or narrower task scope Serving Engine Continuous batching + PagedAttention Speculative decoding · Compressed KV cache (GQA/MLA/FP8) Async queue for latency-tolerant workloads Streamed, Length-Capped Response max_tokens / stop sequences enforced Governance & Observability quotas · budgets · rate limits spend tagged by team / app / model feeds router thresholds back Observability watches every stage and continuously retunes routing and quota thresholds — it never serves a token itself request path feedback loop — tunes, doesn't serve

A request first checks the cache layer, then a router picks the cheapest model tier capable of handling it, that model's quantized or distilled weights run through a serving engine doing continuous batching and speculative decoding, and the response streams back under a token cap. Observability watches spend at every stage and continuously retunes the router and the governance guardrails — it sits outside the request path entirely.

1

Model Right-Sizing and Intelligent Routing

The single highest-leverage decision in the whole pipeline happens before a single token is generated: which model handles this request at all. Frontier models are priced for the hardest 10-15% of tasks a system will ever see, but most production traffic is routine — classification, extraction, short summarization, templated drafting — and never needed frontier-level reasoning in the first place. A router that estimates request complexity and dispatches accordingly turns that observation into savings without touching output quality on the requests that actually matter.

This isn't theoretical. RouteLLM, a widely cited open routing framework, reported 85% cost savings while retaining 95% of GPT-4-level quality on MT-Bench, sending only 14% of queries to the stronger model. Field reports from teams running tuned routers in production land in a broad 40-85% bill-reduction range, and the math is intuitive once you model it as a traffic split: routing 70% of volume to a cheap model and 30% to a frontier model (say, Haiku-class to Opus-class) nets roughly 67% savings versus sending everything to the frontier tier; an 80/20 split nets closer to 79%. The savings compound sharply once the cheap-model share crosses 50% of total volume — which is exactly where most real workloads sit once you actually measure them.

Hybrid cloud/on-prem routing is the same idea applied to a different axis: instead of routing by model size, route by data sensitivity and predictability. Workloads with stable, well-understood shapes — and anything where sending data off-premises is itself the cost (compliance risk, egress fees, latency to a regulated data residency zone) — stay on local or on-prem inference. Genuinely open-ended reasoning still goes to a cloud frontier model when the task warrants it. Both forms of routing rest on the same principle: complexity and sensitivity, not habit, should decide where a request lands.

2

Serving-Layer Efficiency

Routing picks the model; the serving engine underneath still decides how much of a GPU's capacity a request wastes. Continuous batching and PagedAttention, covered above as techniques 3 and 8, are the two changes that matter most here.

3

Caching Strategy: Prefix, Semantic, and KV Cache

Caching shows up at three different layers of the stack, and conflating them is the most common mistake in a cost-optimization plan. Each one catches a different kind of repetition.

Prefix (prompt) caching

Prefix caching operates inside the model's attention mechanism: it stores KV-cache entries for a prompt's beginning and reuses them when a new request's prefix matches exactly, token for token. It only reduces time-to-first-token — output generation still runs, and still costs, at full price. But the TTFT effect scales with prefix length: roughly 7% improvement at a 1,024-token shared prefix, climbing to 67% at 150,000+ tokens, and around 79% TTFT reduction with a 90% cost cut on the cached portion at a 100,000-token cached prefix in benchmark testing. This is the mechanism behind the "prompt caching" discounts offered by Anthropic, OpenAI, Google, and AWS Bedrock.

Semantic caching

Semantic caching sits a layer above the model entirely. Incoming queries are converted to embeddings and compared against cached queries by cosine similarity against a configurable threshold; on a hit, the LLM is never called at all — both input and output tokens are fully saved, not just discounted. Because it matches on meaning rather than exact text, it catches paraphrased and reworded repeats that prefix caching can't touch, which is why teams report meaningfully higher hit rates and total savings in the range of 30-40%+ of LLM spend when it's tuned well. The trade-off is a small risk of a false-positive match returning a stale or subtly wrong cached answer, which is why threshold tuning and cache invalidation policy matter more here than in exact-match caching.

The two are complementary, not competing — a layered strategy runs exact-match caching first, semantic caching second, and prefix caching for whatever's left that still has to reach the model.

KV cache compression

Independent of caching strategy, the KV cache itself can be shrunk architecturally. Grouped-Query Attention (GQA) delivers 4-8x compression and is the default in Llama 3.x and Mistral; Multi-Query Attention (MQA) pushes to 32x compression at a noticeable 1-3 point quality cost; Multi-head Latent Attention (MLA), used in DeepSeek's V2 through V4 models, achieves 7-14x compression with under 0.2 points of regression. Layered on top, FP8 KV-cache quantization halves memory again for a modest 0.3-0.7 point hit. Stacked together, these compound multiplicatively — a 70B model at 1M-token context can go from 135GB of KV cache at FP16 baseline down to roughly 8GB with MLA plus FP8, a documented 4-40x reduction on long-context inference depending on which techniques are combined.

Cache layerWhat it matchesSaves
Exact-match cacheIdentical repeated queriesInput + output tokens
Semantic cacheParaphrased / similar queries (embeddings)Input + output tokens
Prefix / prompt cacheExact shared prompt prefixInput tokens (TTFT) only
KV cache compressionN/A — architectural, not query-levelGPU memory for any request
4

Compressing the Model: Quantization and Distillation

Routing and caching reduce how often and how much of the model runs. Quantization and distillation reduce the cost of running the model itself.

Quantization lowers the numeric precision of model weights (and optionally activations and the KV cache) from 16-bit down to 8-bit or 4-bit representations. The two dominant post-training methods differ in how they decide what to protect: GPTQ relies on layer-wise second-order weight optimization, which is computationally expensive and less targeted; AWQ (Activation-Aware Weight Quantization) instead profiles activation magnitudes during calibration to identify the roughly 1% of "salient" weight channels that matter most, scales those channels to preserve precision, and quantizes the rest aggressively — and it consistently outperforms GPTQ by 1-2 quality points at the same bit-width. The economics are substantial: a 70B model drops from roughly 140GB in BF16 to 35-40GB in AWQ INT4, a ~71% memory reduction, which in one benchmark comparison took serving cost from $0.757 per million tokens on dual A100s down to $0.253 per million tokens on a single A100 — a ~67% cost reduction — with throughput improving roughly 1.5x on top of that.

Distillation and task-specific fine-tuning attack the same problem from a different angle: instead of shrinking a general-purpose model's weights, train a much smaller student model to reproduce a larger teacher's behavior on a narrower task. This is the right call precisely when prompts are long, repetitive, and narrow in scope — sending the same lengthy context and instructions on every call is often more expensive over time than the one-time cost of fine-tuning a small model to do that one job without the context at all. The trade-off is scope: a distilled or fine-tuned model is deliberately worse at everything outside its training distribution, which is why it belongs behind a router, not in front of general traffic.

Compression needs an eval gate, not just a benchmark run. Quality regressions from quantization and distillation are measured in fractions of a point on public benchmarks, but those benchmarks rarely match a specific production task's distribution. Before shipping a quantized or distilled model into the routing tier, run it against a held-out sample of your own real traffic — not just MMLU or MT-Bench — and set an explicit tolerance for acceptable degradation before it goes live.
5

Accelerating Decode: Speculative Decoding, Async, and Streaming

Everything above reduces how much compute a request costs. This section is about latency — and, indirectly, cost, since lower latency means fewer retries and less GPU time held open per request.

Speculative decoding is covered above (technique 9): a small draft model proposes tokens that the full model verifies in one pass.

Asynchronous inference is the simpler lever: not every workload needs a synchronous, sub-second response. Batch scoring, overnight report generation, and background enrichment jobs can be queued and processed during off-peak capacity, which both improves GPU utilization and often qualifies for lower off-peak or batch API pricing where providers offer it.

Streaming responses address perceived latency rather than actual compute cost: delivering tokens as they're generated, rather than waiting for the full response, keeps a user or downstream system engaged instead of timing out or retrying — and retries are pure wasted spend, since a timed-out request that gets resent pays for the discarded generation too.

6

Context Engineering: Auditing What You Actually Send

Every token in the context window is compute you're paying for whether or not it helps the answer — and, on current transformer architectures, attention cost scales with context length, so a bloated context window is a compounding cost, not a flat one. Context window auditing means treating retrieval and prompt assembly as a relevance-filtering problem: pull in what a request needs, not everything a retrieval system could plausibly return. This isn't only a cost argument — models are also demonstrably worse at using information buried in the middle of an very long context than information near the start or end, so an aggressively padded prompt can simultaneously cost more and perform worse.

Output token controls close the other end of the same problem. An unbounded max_tokens setting, combined with a model that tends to over-explain, restate, or hedge, can quietly become one of the largest line items in an inference bill — and it's one of the cheapest to fix, since explicit output limits and stop sequences cost nothing to implement and directly cap the most expensive part of a request (output tokens are typically priced several times higher than input tokens across most providers).

7

Governance and Observability: Guardrails Before the Bill Arrives

Every technique above is a lever inside the request path. This last pair operates outside it, and it's the layer that keeps the others from silently drifting back toward waste.

Usage governance — quotas, per-team and per-application budgets, rate limits, and hard guardrails on which model tiers a given caller can even reach — has to exist before a runaway integration or an unbounded agent loop turns into a five-figure surprise, not after. A router that's technically capable of sending everything to a frontier model will do exactly that if nothing stops it, whether the cause is a misconfigured default or a legitimate but unbounded batch job.

Cost and usage observability is what makes every other technique in this piece measurable rather than assumed. Tracking spend by application, feature, team, workflow, model, and user segment turns "our AI costs went up" into "feature X's fallback path is calling the frontier model on cache misses at 3x the volume we expected" — an actionable finding instead of a vague budget alarm. This is also the feedback loop that closes back into routing and caching: a router's complexity thresholds and a semantic cache's similarity threshold are not "set once" parameters — they need retuning as traffic mix shifts, and that retuning is only possible with granular, current cost data to look at.

Optimization without measurement is guesswork. It's tempting to treat this list as a one-time implementation checklist. In practice, routing thresholds, cache hit rates, and quantization quality all drift as traffic composition and model versions change. Observability isn't the twelfth technique on the list — it's the mechanism that tells you whether the others are still working six months from now.
Putting it together

None of these techniques is a substitute for the others, and the diagram earlier in this piece is really the argument in full: a request should be checked against a cache before it ever reaches a model, routed to the cheapest tier actually capable of handling it, served by an engine that keeps the GPU saturated and the KV cache compressed, generated by weights that are no larger or slower than the task requires, and capped and streamed back efficiently — all while an observability layer watches spend closely enough to keep tightening every threshold in that chain. Skip any one layer and the others compensate for it by burning more of the layers around them; a brilliant router sending every request to an unquantized model on a statically-batched server still wastes most of its GPU capacity, just as the best serving engine in the world can't fix a context window stuffed with irrelevant retrieval results.

The framing this piece opened with is worth repeating as the close, because the techniques above are really just its implementation: LLM cost optimization is an architecture problem, not a model-pricing problem. The goal was never simply cheaper inference — it's intelligent routing, efficient context, appropriately sized models, strong observability, and predictable economics, working together so that AI systems can scale without their infrastructure cost scaling uncontrollably alongside them.

Training vs. Inference, Side by Side

DimensionTrainingInference
Primary objectiveMaximize useful FLOPs per GPU-hour over a fixed compute budgetMinimize latency and cost per request under live, variable traffic
Time horizonOne long batch job — days to weeksMilliseconds to seconds, continuously, forever
Main bottleneckInterconnect bandwidth + optimizer-state memoryKV-cache HBM footprint + memory bandwidth during decode
Parallelism favoredData, tensor, pipeline, and ZeRO/FSDP sharding, often combined (3D parallelism)Tensor parallelism plus batching; pipeline parallelism is usually avoided (adds per-token latency)
Typical hardware patternLarge homogeneous GPU clusters, NVLink intra-node + InfiniBand inter-nodeSometimes split pools — compute-optimized for prefill, memory-bandwidth-optimized for decode
Failure mode to guard againstMid-run hardware failure losing unsaved progress → checkpointingTraffic spikes and idle GPU cycles → continuous batching, autoscaling

A Practical Decision Framework

  1. Training — does the model fit on one GPU? If yes, start with plain data parallelism. If no, add ZeRO/FSDP sharding first (simplest to operate); reach for tensor parallelism only inside a high-bandwidth NVLink domain, and pipeline parallelism only once you're spanning multiple nodes.
  2. Training — is the run long and multi-node? If it spans more than a handful of nodes for more than a few hours, invest in checkpointing and orchestration before optimizing throughput further — an unrecoverable failure costs more than a suboptimal parallelism choice.
  3. Inference — are you serving concurrent users? Continuous batching and prefix caching are almost always the first, cheapest wins — they require no model changes and directly attack idle GPU time.
  4. Inference — is memory the ceiling, not compute? Reach for KV-cache-focused techniques (efficient attention variants, PagedAttention) and quantization before adding more GPUs; see the ten inference mechanics above for how each works.
  5. Inference — is the bill the problem rather than latency? Start with routing each request to the smallest capable model and layering caches (exact, semantic, prefix); then add compression and context trimming. See cutting inference cost in production.
  6. Either side — measure before you optimize. Training bottlenecks show up as low GPU utilization or communication-bound step times; inference bottlenecks show up as TTFT/TPOT regressions or falling requests-per-GPU. Instrument both before reaching for a specific technique — see the LLM observability tools directory for tooling.

Frequently Asked Questions

What is the single highest-leverage optimization for LLM training?

Matching your parallelism strategy to your memory budget. Most wasted training spend comes from either over-parallelizing a model that fits on one GPU (adding needless communication overhead) or under-parallelizing one that doesn't (forcing painful gradient accumulation or out-of-memory crashes).

What is the single highest-leverage optimization for LLM inference?

Continuous batching. Moving from static or dynamic batching to continuous (in-flight) batching is usually the cheapest, highest-impact change a serving stack can make, since it keeps GPUs busy under unpredictable, bursty traffic without any change to the model itself.

Do the same techniques apply to both training and inference?

Some cross over — mixed-precision arithmetic and interconnect-aware placement, for example — but most do not. Training optimizes throughput on a large, fixed compute budget over days or weeks; inference optimizes latency and cost per request in real time. That difference in objective drives largely different tooling on each side.

How much does quantization affect model accuracy?

It depends on the technique and bit width. Well-tuned INT8 quantization is often near-lossless on standard benchmarks, while aggressive INT4 quantization (via methods like GPTQ or AWQ) typically costs a small, measurable amount of accuracy in exchange for roughly a 4x reduction in memory footprint versus FP32.

Where should I start when trying to cut LLM inference cost?

Start with routing and caching. Send each request to the smallest model that can handle it, and layer exact-match, semantic and prefix caching so repeated work never reaches the model. Then add quantization or distillation, trim the context you send, and put usage governance and cost observability around all of it.

What is the difference between prefix caching and semantic caching?

Prefix caching reuses the model's stored attention state for an identical prompt beginning, inside the serving engine. Semantic caching sits above the model and returns a stored answer when a new query is similar enough in meaning to an earlier one. They are complementary.

What is the difference between prefill and decode?

Prefill processes the prompt and builds the KV cache; it parallelizes well and is usually compute-bound. Decode generates tokens one at a time and is often limited by memory bandwidth at practical batch sizes.

Why is tokens per second a misleading inference metric?

Aggregate throughput can look strong while individual users wait too long for the first token. TTFT, inter-token latency, tail latency and goodput show whether requests actually meet the latency target.

Match the Optimization to the Bottleneck

A LinkedIn post by AI Mill (30 October 2026) makes the point that production LLM performance depends on more than model size or GPU count: it depends on how efficiently memory, compute, batching, parallelism and scheduling are managed, and the goal is more tokens per GPU-second, lower latency, higher throughput and lower cost per token. It names seven key inference optimizations and a simple bottleneck-to-technique mapping, summarized here in our own words and consistent with the mechanics above.

  1. Model too large for the memory you have? Quantization: lower precision means lower memory use and more efficient inference.
  2. Generation feels slow? KV caching, which reuses computed key-value states instead of recalculating them, and speculative decoding, where a smaller model drafts tokens that a larger model verifies.
  3. High concurrency? Continuous batching, which schedules requests dynamically to keep GPUs well utilized.
  4. Model too large for one GPU? Parallelism: tensor parallelism splits computation across GPUs, and pipeline parallelism distributes layers across GPUs for large-scale inference.
  5. Serving cost is the problem? Knowledge distillation transfers capabilities into a smaller model to reduce inference cost, a technique covered under compression above.

The post asks which optimization to prioritize first: KV caching, continuous batching, quantization or speculative decoding. There is no universal answer; the framework above suggests continuous batching and prefix caching as the cheapest first wins for concurrent serving, and measuring TTFT, TPOT and requests per GPU before choosing. See the post for the original.


Frequently Asked Questions

What does this guide cover?

Training optimization (parallelism, memory budgeting, interconnect bandwidth, fault tolerance) and ten inference mechanics, including KV cache, GQA/MLA, continuous batching, FlashAttention, quantization, PagedAttention and speculative decoding.

What is a KV cache?

A store of attention keys and values from earlier tokens, which avoids recomputing them for each new token during generation.

How do I cut inference cost?

The guide describes the production levers, such as batching, quantization and speculative decoding.

Where are inference platforms listed?

See the LLM Inference Platforms page on this site.

What is the difference between prefill and decode?

Prefill processes the prompt and builds the KV cache; it parallelizes well and is usually compute-bound. Decode generates tokens one at a time and is often limited by memory bandwidth at practical batch sizes.

Why is tokens per second a misleading inference metric?

Aggregate throughput can look strong while individual users wait too long for the first token. TTFT, inter-token latency, tail latency and goodput show whether requests actually meet the latency target.

Which LLM inference optimization should I prioritize first?

Match the technique to the bottleneck. A LinkedIn post by AI Mill suggests quantization when the model is too large, KV caching or speculative decoding when generation is slow, continuous batching under high concurrency, and parallelism when the model does not fit on one GPU. For concurrent serving, continuous batching and prefix caching are usually the cheapest first wins, and you should measure before optimizing.

What are the seven key LLM inference optimizations?

The post lists quantization, KV caching, continuous batching, speculative decoding, knowledge distillation, tensor parallelism and pipeline parallelism. This guide covers each of them, along with efficient attention, FlashAttention, PagedAttention, prefix caching and prefill-decode disaggregation.

Do I need more GPUs to speed up an LLM?

Not necessarily. Better memory management, batching and scheduling can increase tokens per GPU-second and lower cost per token before you add hardware, which is the point the post makes. Measure TTFT, inter-token latency and throughput to find the real bottleneck.

How current is this guide?

Links were checked on 1 November 2026, and the RadixAttention link was replaced with the LMSYS SGLang blog post after the previous link returned 404. The LinkedIn post may ask visitors to sign in. Techniques are described conceptually and are not benchmarks.