Skip to main content

Prerequisites

Before you begin, confirm that you have:
  • Python 3.11 (exactly — >=3.11, <3.12 is required)
  • A CUDA-capable GPU (required for Triton kernels and torch CUDA ops)
  • Git to clone the repository

Installation

1

Install uv

miniVLLM uses uv for dependency management. Install it with:
2

Clone the repository

3

Sync dependencies

uv sync reads pyproject.toml and installs all dependencies into an isolated virtual environment. No manual pip install is needed.

Run the inference demo

The main demo runs end-to-end inference through the custom engine:
This script:
  1. Loads the Qwen/Qwen3-0.6B tokenizer
  2. Initializes LLMEngine with a small Qwen3 model (random weights for speed)
  3. Creates chat prompts and tokenizes them using the model’s chat template
  4. Processes them through the engine using paged attention and KV cache management
  5. Generates up to 256 new tokens per prompt with temperature sampling
  6. Prints each prompt alongside its completion

Configuration

The demo is configured by the config dict at the top of main.py. The engine requires both scheduling/memory keys and model architecture keys:

Multi-GPU setup

To run with multiple GPUs, set world_size in the config dict to the number of GPUs you want to use:
The engine uses tensor parallelism and spawns one worker process per additional GPU rank.

Run benchmarks

The prefill benchmark compares three attention implementations during the prompt-processing phase:
  1. PyTorch standard attention (O(N²) memory)
  2. Naive Triton kernel (O(N²) memory, limited to ≤128 tokens)
  3. Flash attention Triton kernel (O(N) memory)
The decode benchmark compares three paged attention implementations during token generation:
  1. Naive PyTorch loop over paged KV cache
  2. Optimized PyTorch with vectorized gathering and masking
  3. Custom Triton paged attention kernel

Use the API directly

You can use LLMEngine and SamplingParams directly in your own scripts:

SamplingParams fields

Understanding the output

During a generate() call, the engine prints throughput statistics for each scheduling step:
  • Prefilling processes all input prompt tokens in parallel — throughput is high.
  • Decoding generates one token per active sequence per step — throughput reflects the cost of paged attention over the growing KV cache.
The final outputs dict contains:
  • outputs["text"] — list of decoded completion strings, one per prompt
  • outputs["token_ids"] — list of token ID lists for each completion