Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

JohnScheuer/decode-batching-profiler

Open more actions menu

Repository files navigation

decode-batching-profiler

Author: João Felipe De Souza

Python PyTorch Transformers CUDA Platform GPU License

Overview

Empirical profiling of decode-path batching in autoregressive transformers.

Measures how batch size affects throughput, per-step latency, GPU memory, and batching efficiency during the decode (token generation) phase — the dominant cost in LLM serving.

For detailed architecture and design rationale, see DESIGN.md.


Why This Matters

In LLM serving, the decode phase generates tokens one at a time per request. But multiple requests can share a single forward pass. The key tradeoffs:

  • Small batch: GPU underutilized, low throughput, low latency
  • Large batch: high throughput, but latency per step increases
  • Too large: memory-bandwidth bound, throughput saturates or drops

Finding the sweet spot is critical for production serving systems.


Models and Hardware

Models

Model Params Layers Heads
gpt2 117M 12 12
gpt2-medium 345M 24 16

Hardware

Spec Value
GPU NVIDIA RTX 2070
VRAM 8.6 GB
Framework PyTorch 2.13
Library Transformers 5.13

Methodology

Benchmark Design

For each (model, context_length, batch_size):

  1. Prefill: process the full prompt in one forward pass, producing KV-cache
  2. Decode: generate 64 tokens autoregressively using cached KV
  3. Measure: prefill time, per-step decode latency, total throughput, peak memory

Configuration Space

  • Context lengths: 128, 512, 960
  • Batch sizes: 1, 2, 4, 8, 16, 32, 64
  • Total: 42 benchmark runs (21 per model)
  • Key points repeated 3x for statistical confidence

Timing

  • CUDA events for precise GPU timing
  • 16 warmup steps before measurement
  • 64 measured decode steps per configuration

See DESIGN.md for detailed rationale on timing, warmup, position limits, and OOM handling.


Key Findings

Finding 1 — Batching gives near-free throughput at small batch

GPT-2, ctx=128:

Batch Throughput (tok/s) Step latency (ms) Gain vs bs=1
1 200 5.0 1.0x
8 1332 6.0 6.7x
32 5816 ± 248 5.5 ± 0.2 29.1x
64 7649 ± 63 8.4 ± 0.1 38.2x

Step latency stays nearly flat from bs=1 to bs=32. The GPU has spare compute capacity that batching fills for free.

Finding 2 — Context length determines the saturation point

ctx Sweet spot batch Peak throughput
128 64 7649 ± 63 tok/s
512 32 2657 ± 17 tok/s
960 16 1446 ± 7 tok/s

Longer context means larger KV-cache per request, which fills memory bandwidth earlier and forces the sweet spot to a smaller batch.

Finding 3 — Larger models saturate earlier and harder

GPT-2-medium, ctx=960:

Batch Throughput (tok/s) Step latency (ms) Peak mem (GB)
1 99 10.1 0.20
16 548 ± 2 29.2 ± 0.1 3.19
32 362 ± 6 88.4 ± 1.4 6.38
64 90 709.8 12.76

At bs=64, throughput drops below bs=1 because peak memory (12.76 GB) exceeds physical VRAM (8.6 GB), causing implicit swapping.

Finding 4 — Compute-to-memory-bandwidth crossover

The crossover point where step latency begins rising sharply:

Model ctx=128 ctx=512 ctx=960
gpt2 bs=4 bs=16 bs=8
gpt2-medium bs=32 bs=16 bs=8

This crossover is reproducible — repeated measurements show coefficient of variation below 5% at all key points.

Finding 5 — Batching efficiency collapses at large batch

Efficiency = actual throughput / (batch_size x bs=1 throughput):

Model ctx bs=4 bs=16 bs=32 bs=64
gpt2 128 85% 87% 85% 57%
gpt2 960 94% 44% 23% 11%
gpt2-medium 512 97% 58% 32% 11%
gpt2-medium 960 97% 35% 12% 1.4%

At gpt2-medium ctx=960 bs=64, each request gets only 1.4% of its solo throughput — the GPU is completely memory-bound.

Finding 6 — KV-cache memory model

Measured peak memory vs analytical KV-cache estimate:

Model Measured / Estimated ratio
gpt2 3.7 - 3.9x
gpt2-medium 2.0 - 2.1x

The analytical estimate underpredicts by 2-4x because it does not account for activation memory, framework overhead, and temporary buffers.

Finding 7 — Peak throughput is often not the best operating point

Latency-aware sweet spots deliver 90-97% of peak throughput at roughly half the per-step latency:

Model ctx Peak batch Recommended batch % of peak Latency reduction
gpt2 512 64 32 96.8% 48% less
gpt2 960 32 16 95.2% 47% less
gpt2-medium 512 32 16 90.0% 44% less
gpt2-medium 960 16 16 100%

Statistical Confidence

Key benchmark points were repeated 3x. Run-to-run variance:

Metric Typical CV Worst CV
Step latency 0.2 - 1.6% 4.9%
Throughput 0.2 - 2.2% 4.8%
Peak memory 0.0% 0.0%

Single-run vs repeated mean difference: within ±5% for all points, majority within ±2%.


Results Files

File Description
results/decode_batching_results.csv Full benchmark (42 runs)
results/decode_batching_summary.csv Sweet spot per model/ctx
results/repeated_key_points_raw.csv 3x repeated raw measurements (63 rows)
results/repeated_key_points_agg.csv Aggregated mean/std/min/max (21 configs)
results/pareto_points.csv Pareto-optimal configurations
results/regime_transitions.csv Latency growth between batch sizes
results/memory_model_validation.csv Estimated vs measured memory
results/metadata.json Run configuration

Plots

File Description
plots/gpt2_decode_batching_dashboard.png 4-panel GPT-2 dashboard
plots/gpt2-medium_decode_batching_dashboard.png 4-panel GPT-2-medium dashboard
plots/cross_model_ctx*.png Model comparison at each ctx
plots/pareto_throughput_vs_latency.png Throughput-latency Pareto frontier
plots/regime_detection.png Compute vs memory-bandwidth crossover
plots/memory_model_validation.png Estimated vs measured KV memory
plots/roofline_throughput.png Roofline-style throughput analysis

Repository Structure

decode-batching-profiler/
├── decode_benchmark.py          # Main benchmark sweep
├── plot_decode_benchmark.py     # Basic plots and summary
├── advanced_analysis.py         # Pareto, regime, memory, roofline
├── repeat_key_points.py         # Statistical confidence (3x repeats)
├── README.md
├── DESIGN.md
├── LICENSE
├── requirements.txt
├── results/
└── plots/

How to Run

1. Setup

python3 -m venv venv && source venv/bin/activate
pip install -r requirements.txt

2. Main benchmark

python3 decode_benchmark.py \
    --models gpt2 \
    --ctx-lens 128 512 960 \
    --batch-sizes 1 2 4 8 16 32 64

python3 decode_benchmark.py \
    --models gpt2-medium \
    --ctx-lens 128 512 960 \
    --batch-sizes 1 2 4 8 16 32 64

3. Plots and summary

python3 plot_decode_benchmark.py

4. Advanced analysis

python3 advanced_analysis.py

5. Statistical confidence

python3 repeat_key_points.py

Limitations

  • GPT-2 max_positions=1024; context capped at 960 to fit 64 decode steps
  • Single-prompt workload; real serving has variable prompt lengths
  • Results specific to RTX 2070; different GPUs have different crossover points
  • No continuous batching; all requests start and end together
  • Same prompt replicated across batch; real workloads have heterogeneous lengths

References

  • Yu et al., Orca: A Distributed Serving System for Transformer-Based Generative Models (2022)
  • Kwon et al., Efficient Memory Management for Large Language Model Serving with PagedAttention (2023)

About

Empirical profiling of decode-path batching in GPT-2 and GPT-2-medium: throughput, step latency, memory, Pareto frontier, compute-vs-memory-bandwidth regime detection, and 3x repeated measurements for statistical confidence.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages

Morty Proxy This is a proxified and sanitized view of the page, visit original site.