Guide

Ignore the long flag list until these six knobs are right. They control whether the GPU holds enough KV, whether collectives eat your decode, and whether repeated prompts prefill again.

KnobWhat it controlsFailure mode if wrong
tensor_parallel_sizeShards weights across GPUsToo high → communication tax; too low → OOM
max_model_lenMax context; sizes KV poolToo high → fewer concurrent seqs; too low → 400s in prod
gpu_memory_utilizationFraction of VRAM for engineToo high → OOM under fragmentation; too low → idle HBM
QuantizationWeight and KV precisionToo aggressive → quality regressions users notice
Speculative decodingExtra draft computeHelps TPOT when acceptance is high; hurts when low
Prefix cachingKV reuse across requestsOff → repeated prefills; on without routing → uneven hits

Walking through the defaults

Tensor parallel size. For a dense 70B in FP8, 2-way TP on a single node is common; 8-way for larger models or longer contexts. Pipeline parallel appears when the model does not fit in one node's memory even sharded. Expert parallel is for MoE — see MoE serving.

Max model length. Product owners ask for "128k context" by default. Every unused kilotoken of max length reserves KV headroom that could have been concurrency. Set max to the p99 you actually need, and put long-tail jobs on a separate pool.

GPU memory utilization. Start around 0.85–0.90, load a realistic concurrency sweep, watch for OOMs during long-context spikes, then nudge. Leave margin for CUDA graphs, fragmentation and the occasional multimodal activation spike.

Quantization. Weight-only INT4/AWQ/GPTQ and FP8 are table stakes for 70B-class models on 80 GB cards. Quantizing the KV cache further multiplies concurrency. Always keep a quality eval gate — see quantization and evals.

Speculative decoding. Worth enabling when draft acceptance rates stay high on your traffic (code continuation often does; highly creative open-ended chat often does not). Measure TPOT and acceptance together. Speculation that rejects often is pure overhead. See speculative decoding.

Prefix caching. Turn it on for any app with shared system prompts. Then make sure routing sends similar prefixes to the same replica, or the cache hit rate collapses across a horizontally scaled fleet.

Start with one engine (usually vLLM) on a single node. Nail quantization, max length and a concurrency sweep. A/B SGLang if traces show heavy prefix overlap or structured decoding is on the critical path. Evaluate TensorRT-LLM when you are NVIDIA-locked and a few percent of tokens/s pays for the build pipeline.

Export metrics the gateway can use: queue depth, KV utilization, prefix hit rate, active LoRAs. Routing without these signals is round-robin with extra steps.

Warning

Never compare engines with a single concurrency and a fixed 512/128 token synthetic prompt. Engine A may win at concurrency 8 and lose at 64. Prefix caching may look miraculous on repeated prompts and useless on unique ones. Use the benchmarking methodology — same workload file, same SLO, full sweep.

Common mistakes

  • Setting 128k max length for a product whose p99 is 4k.
  • Enabling speculation globally when JSON tool calls reject most drafts.
  • Turning on prefix cache but routing at random, so every replica stays cold.

Check yourself

  1. Why does unused max length cost throughput? Answer: it reserves KV that cannot become concurrent sequences.
  2. Which two signals should the gateway see besides request count? Answer: KV utilization and prefix hit rate (and queue depth).

Key takeaways

  • Six knobs dominate: TP size, max length, memory utilization, quantization, speculation, prefix cache.
  • Set max length from p99, not from a brochure.
  • Prefix cache needs routing affinity or the hit rate dies.
  • Promote engine changes with a concurrency sweep under a real length mix.

Further learning

Back to the serving engines map, then measure with benchmarking.