A common misconception among software engineers entering the AI infrastructure space is that Large Language Model text generation is bottlenecked by the computational power (FLOPs) of the GPU. In reality, during the autoregressive token generation phase (decoding), the vast majority of the GPU's Tensor Cores sit over 80% to 90% idle.
The true, inescapable physical bottleneck of single-user LLM inference is Memory Bandwidth—the rate at which parameters and Key-Value cache tensors can be transferred from High Bandwidth Memory (HBM) into on-chip Static RAM (SRAM) and registers.
1. The Physics of Autoregressive Decoding: The Weight Streaming Problem
To understand why memory bandwidth is the bottleneck, examine what happens when an LLM generates a single token.
In an autoregressive transformer:
- The user provides a prompt, which generates a hidden state vector representing the current token (with batch size ).
- To compute the next token, that single vector must be multiplied by every weight matrix in the model:
- Attention projections:
- Feed-forward projections:
- Layer normalization and LM head projection:
- Every single parameter of the neural network must be loaded from HBM into the SM registers exactly once per generated token.
GEMM vs GEMV: The Matrix-Vector Arithmetic Trap
- In Matrix-Matrix Multiplication (GEMM) (used during training and prompt prefill), a matrix of shape multiplies a weight matrix . Each weight loaded from memory is reused across input tokens. The arithmetic intensity is high:
- In Matrix-Vector Multiplication (GEMV) (used during single-token decoding with ), the input is a single row vector multiplying weight matrix . Each weight loaded from VRAM is used exactly once for a single multiply-accumulate operation!
- The arithmetic intensity collapses:
Since an NVIDIA H100 requires an arithmetic intensity of to saturate its Tensor Cores, running at means the GPU is running at less than 0.35% of its peak computational capability.
2. Deriving the Theoretical Maximum Generation Speed
Because every parameter must be read from VRAM for each token generated, we can derive the hard physical upper bound for token generation speed.
Concrete Calculations Across Hardware and Models
Let us calculate the absolute theoretical limits across industry-standard GPUs and model configurations:
Case 1: Llama 3 70B (FP16: 140 GB) on 2x NVIDIA H100 SXM5 (Tensor Parallelism = 2)
- Total Weights =
- Combined Memory Bandwidth of 2x H100 =
- Assuming 80% memory bus efficiency ():
It is physically impossible for a single user to receive more than ~38 tokens/sec for unquantized Llama 3 70B on 2x H100s without batching or speculative decoding!
Case 2: Llama 3 70B (4-bit AWQ: 35 GB) on 1x NVIDIA H100 SXM5
- Total Weights =
- Memory Bandwidth of 1x H100 =
- Assuming 80% efficiency:
By quantizing weights from 16-bit to 4-bit, we reduced the bytes read per token by , which directly translates to a boost in token generation speed.
3. Theoretical Peak Throughput Comparison Matrix
| Model Parameter Count | Precision / Quantization | Model VRAM Size | Hardware Platform | Total Peak Bandwidth | Max Theoretical Single-Stream TPS |
|---|---|---|---|---|---|
| 8B (Llama 3) | FP16 (16-bit) | 16 GB | 1x NVIDIA A100 (80GB) | 2,039 GB/s | 102 TPS |
| 8B (Llama 3) | FP16 (16-bit) | 16 GB | 1x NVIDIA H100 (80GB) | 3,350 GB/s | 167 TPS |
| 8B (Llama 3) | INT4 / AWQ (4-bit) | 4 GB | 1x NVIDIA H100 (80GB) | 3,350 GB/s | 670 TPS |
| 70B (Llama 3) | FP16 (16-bit) | 140 GB | 2x NVIDIA H100 (TP=2) | 6,700 GB/s | 38 TPS |
| 70B (Llama 3) | FP8 (8-bit) | 70 GB | 1x NVIDIA H200 (141GB) | 4,800 GB/s | 55 TPS |
| 70B (Llama 3) | INT4 / AWQ (4-bit) | 35 GB | 1x NVIDIA H100 (80GB) | 3,350 GB/s | 76 TPS |
| 405B (Llama 3.1) | FP8 (8-bit) | 405 GB | 8x NVIDIA H100 (TP=8) | 26,800 GB/s | 53 TPS |
| 405B (Llama 3.1) | FP16 (16-bit) | 810 GB | 8x NVIDIA H200 (TP=8) | 38,400 GB/s | 38 TPS |
4. Overcoming the Memory Wall: Three Architectural Solutions
Since physical memory bandwidth is bounded by silicon manufacturing and thermal limits, how do modern LLM serving engines achieve high throughput?
A. Amortization via Batching
When batch size , the GPU reads the weight matrix from HBM once, but multiplies it against independent token vectors simultaneously.
- Memory bandwidth spent loading weights: (constant regardless of batch size).
- Number of tokens generated: .
- Effective memory cost per token: .
- At , system throughput increases by nearly , moving the workload into the compute-bound regime.
5. Memory Bandwidth Benchmarking Tool
Below is an automated diagnostic script in Python that measures actual sustainable PyTorch GPU memory bandwidth and compares empirical performance against the theoretical hardware ceiling.
6. Production Failure Modes and Engineering Runbook
Failure Mode: SLA Violations Due to Misconfigured Batching Timeouts
- Symptom: An inference cluster serving Llama 3 70B experiences Time to First Token (TTFT) spikes exceeding 4,000ms while GPU utilization sits at only 15%.
- Root Cause: The dynamic batching scheduler is configured with a high
max_batch_delay_ms = 500msattempting to aggregate requests for compute efficiency, but traffic volume is low. Requests sit waiting in the queue to form batches that never fill, while decoding remains memory-bandwidth starved. - Resolution: In low-concurrency environments, switch to Continuous Batching (Iteration-Level Scheduling) with zero batch timeout (
max_batch_delay = 0). Immediately begin prefill on arriving requests while interleaving active decoding iterations.
7. Summary & Key Takeaways
- Decode is Memory-Bound, Prefill is Compute-Bound: Single-token generation is governed by matrix-vector operations (), meaning performance is dictated purely by HBM bandwidth.
- Single-Stream TPS Has a Strict Physical Limit: . No software optimization can exceed this limit without reducing precision (quantization) or reducing forward passes (speculative decoding).
- Weight Quantization Unlocks Linear Speedups: Compressing 16-bit weights to 4-bit cuts memory bus transfers by , directly boosting single-user generation speed by up to .
- Concurrency Amortizes the Memory Penalty: High-concurrency continuous batching shares weight memory transfers across dozens of concurrent requests, shifting the GPU from idle memory-wait states into high-efficiency Tensor Core execution.