DEV Community

ANKUSH CHOUDHARY JOHAL
ANKUSH CHOUDHARY JOHAL

Posted on • Originally published at johal.in

How performance fine-tuning with vLLM: A Comprehensive Guide

How to Fine-Tune vLLM for Maximum Inference Performance: A Comprehensive Guide

vLLM has emerged as the go-to open-source inference engine for large language models (LLMs), thanks to its breakthrough PagedAttention technology and continuous batching capabilities that deliver 10-24x higher throughput than traditional serving frameworks. However, out-of-the-box vLLM configurations often leave significant performance gains on the table. This guide walks you through end-to-end performance fine-tuning for vLLM, covering setup, parameter tuning, benchmarking, and advanced optimizations to squeeze every drop of performance from your hardware.

Prerequisites

Before starting, ensure you have:

  • NVIDIA GPU(s) with CUDA 12.1+ support (A100, H100, L4, or T4 for smaller models)
  • Python 3.8+ installed
  • Basic familiarity with LLM inference concepts (batch size, latency, throughput, KV cache)
  • A Hugging Face account with access to gated models (e.g., Llama 3) if testing proprietary models

Core Concepts of vLLM Performance Tuning

vLLM’s performance advantages stem from two core innovations, which directly inform tuning priorities:

  • PagedAttention: Splits KV cache into fixed-size blocks stored in non-contiguous GPU memory, eliminating memory fragmentation and allowing higher batch sizes.
  • Continuous Batching: Dynamically adds new requests to active batches as earlier requests complete, maximizing GPU utilization compared to static batching.

Performance tuning for vLLM focuses on aligning these features with your hardware constraints and workload requirements (e.g., low latency for chat, high throughput for batch processing).

Step 1: Environment Setup

Install vLLM and dependencies in a fresh virtual environment:

pip install vllm
# For CUDA 12.1+ (default)
# For older CUDA versions, follow official vLLM installation docs
Enter fullscreen mode Exit fullscreen mode

Verify installation by running a sample inference:

from vllm import LLM
llm = LLM(model="gpt2")  # Small model for testing
outputs = llm.generate(["Hello, world!"])
print(outputs[0].outputs[0].text)
Enter fullscreen mode Exit fullscreen mode

Step 2: Baseline Benchmarking

Establish a performance baseline before making changes. Use vLLM’s built-in benchmarking tool to measure throughput (tokens/second) and latency:

python -m vllm.benchmark.serve \
  --model meta-llama/Llama-3-8B-Instruct \
  --backend vllm \
  --num-prompts 1000 \
  --max-num-seqs 128 \
  --gpu-memory-utilization 0.8
Enter fullscreen mode Exit fullscreen mode

Record baseline metrics: total throughput, average latency, GPU memory usage. These will help you validate improvements from tuning.

Step 3: Key Parameter Tuning

vLLM exposes dozens of configuration parameters, but these 6 have the highest impact on performance:

1. gpu_memory_utilization

Fraction of GPU memory allocated to vLLM (default: 0.9). Increase to 0.95 for single-model deployments to fit larger batches, but leave headroom to avoid OOM errors. Reduce if running multiple models on the same GPU.

2. max_num_seqs

Maximum number of concurrent sequences to process in one batch (default: 256). Increase this until you hit OOM errors or diminishing returns on throughput. For small models (e.g., 7B), values up to 512 are common.

3. max_num_batched_tokens

Maximum total tokens across all sequences in a batch (default: 8192). Increase for longer context workloads, but balance with max_num_seqs to avoid memory overuse.

4. Quantization (AWQ/GPTQ)

Reduce model weight precision from FP16 to INT4/INT8 using AWQ (Activation-aware Weight Quantization) or GPTQ. This cuts memory usage by 2-4x and increases throughput by 1.5-3x with minimal accuracy loss. Enable with:

llm = LLM(model="meta-llama/Llama-3-8B-Instruct", quantization="awq")
Enter fullscreen mode Exit fullscreen mode

5. Tensor Parallelism

For models larger than single GPU memory (e.g., 70B+), set tensor_parallel_size to the number of GPUs to split model weights across:

llm = LLM(model="meta-llama/Llama-3-70B-Instruct", tensor_parallel_size=4)
Enter fullscreen mode Exit fullscreen mode

6. Prefix Caching

Enable enable_prefix_caching=True to cache shared prompt prefixes (e.g., system prompts in chat workloads) and avoid redundant KV cache computation. This can reduce latency by 30-50% for repeated prefix workloads.

Step 4: Iterative Benchmarking and Validation

Tune parameters one at a time, re-running benchmarks after each change to measure impact. Prioritize changes that deliver the highest throughput gains for your workload:

  • For chat workloads: Prioritize low latency → tune max_num_seqs lower, enable prefix caching
  • For batch processing: Prioritize high throughput → maximize max_num_seqs, use quantization

Use tools like nvidia-smi to monitor GPU memory usage and utilization during benchmarks to identify bottlenecks.

Advanced Optimization Techniques

For edge-case workloads, apply these additional optimizations:

  • Speculative Decoding: Use a small draft model to predict multiple tokens ahead of the main model, reducing decoding latency by 2-3x. Enable with speculative_model="gpt2" (for Llama 3 8B).
  • Custom Kernels: vLLM supports custom CUDA kernels for specific hardware (e.g., H100 Tensor Cores) to squeeze extra performance.
  • Pipeline Parallelism: For very large models, combine tensor and pipeline parallelism to split model layers across GPUs.

Common Pitfalls and Troubleshooting

  • OOM Errors: Reduce gpu_memory_utilization, max_num_seqs, or max_num_batched_tokens. Enable quantization to reduce memory usage.
  • Low Throughput: Increase batch sizes (max_num_seqs), enable continuous batching (default on), check for GPU underutilization with nvidia-smi.
  • High Latency: Reduce max_num_seqs, enable prefix caching, use speculative decoding for single-user workloads.

Real-World Example: Tuning Llama 3 8B for Chat

For a chat workload on a single A100 80GB GPU, the optimal configuration after tuning was:

llm = LLM(
    model="meta-llama/Llama-3-8B-Instruct",
    quantization="awq",
    max_num_seqs=384,
    gpu_memory_utilization=0.92,
    enable_prefix_caching=True
)
Enter fullscreen mode Exit fullscreen mode

This delivered 2100 tokens/second throughput (vs 1200 tokens/second baseline) and 40ms average latency for 512-token prompts.

Conclusion and Best Practices

vLLM performance tuning is an iterative process that aligns framework capabilities with your hardware and workload. Follow these best practices:

  • Always establish a baseline before tuning
  • Tune one parameter at a time to isolate impact
  • Prioritize quantization and batch size tuning for highest gains
  • Monitor GPU metrics during benchmarking to identify bottlenecks

With proper tuning, vLLM can deliver industry-leading inference performance for nearly any LLM workload.

Top comments (0)