High-performance LLM inference engine with paged KV cache, continuous batching, and custom attention kernels.
Python
5
21 commits
updated Sep 23, 2026
PagedServe is an experimental LLM inference runtime built from scratch to explore paged KV memory, continuous batching, direct blockwise attention, and custom GPU kernels.
LLM inference engines like vLLM popularized PagedAttention to eliminate KV cache fragmentation and enable high-throughput continuous batching. However, understanding the intricate systems interactions between block tables, physical memory pools, continuous iteration scheduling, streaming engines, and custom hardware kernels requires building these components ground-up. PagedServe was engineered as a transparent, modular runtime to measure, benchmark, and evaluate each component independently.
flowchart TD
Client["HTTP Client / SDK"] -->|OpenAI REST / Streaming| API["FastAPI Server (api.py)"]
API --> Engine["PagedServeEngine"]
Engine --> Scheduler["Continuous Batching Scheduler"]
Engine --> ModelRunner["ModelRunner (Hugging Face PyTorch)"]
Scheduler -->|Block Allocation & Claims| KVManager["KVCacheManager"]
KVManager --> BlockPool["BlockPool"]
KVManager --> PrefixCache["PrefixCache (SHA-256)"]
KVManager --> BlockTable["BlockTable (Logical -> Physical Mapping)"]
BlockTable --> TensorBlockStore["TensorBlockStore (Unified 5D Physical Storage)"]
TensorBlockStore --> AttentionBackend{"PagedAttention Backend"}
AttentionBackend -->|PyTorch Fallback| PyTorchBackend["PyTorch Blockwise (Online Softmax)"]
AttentionBackend -->|Apple Metal GPU| MetalBackend["Fused Apple Metal MSL Kernel"]
PagedServe is an experimental LLM inference runtime engineered to measure, evaluate, and benchmark inference subsystems.
Scheduler), request state machine (InferenceRequest), memory pressure admission control, block allocation pool (BlockPool), prefix cache (PrefixCache), FastAPI REST & SSE streaming server (api.py), and metrics telemetry (metrics.py).ModelRunner / ModelLoader) executes Hugging Face PyTorch models (distilgpt2, TinyLlama-1.1B) using standard Hugging Face transformer cache state where applicable.TensorBlockStore), PyTorch online-softmax blockwise attention (paged_attention_blockwise), and fused Apple Metal MSL GPU kernel (paged_attention_decode_kernel) exist as modular, independent subsystems with dedicated unit tests and microbenchmarks.Iterates sequence generation token-by-token across active requests. Interleaves prefill chunks with decode steps (FCFSPolicy, token budgets, memory-aware pressure control).
Virtualizes KV cache into fixed-size physical blocks (block_size=16 or 32), eliminating external memory fragmentation.
Allocates physical Key and Value tensors in pre-allocated unified 5D PyTorch tensors (TensorBlockStore) of shape [num_layers, num_blocks, block_size, num_kv_heads, head_dim]. Identical prompt prefixes share physical block IDs with Copy-on-Write (CoW) protection.
Iterates directly over non-contiguous physical blocks using numerically stable online softmax ($m, l, \text{acc}$), maintaining $O(\text{block_size})$ temporary memory overhead per block ($128\times$ memory reduction at $S=2048$) without constructing a full contiguous KV sequence tensor.
Provides a custom GPU compute shader in Metal Shading Language (MSL) (paged_attention_decode_kernel) that executes single-token decode attention directly on Apple Silicon GPUs (M1/M2/M3/M4).
Results measured on Apple M-series (arm64, CPU, float32). Run with python benchmarks/benchmark_throughput.py.
| Model | Mode | Requests/sec | Output tokens/sec | Mean latency (s) |
|---|---|---|---|---|
| distilgpt2 (82M) | PagedServe (c=8) | 3.39 | 27.15 | 1.165 |
| distilgpt2 (82M) | Sequential baseline | 0.86 | 6.87 | 1.165 |
| TinyLlama-1.1B-Chat-v1.0 (1.1B) | PagedServe (c=4) | 0.41 | 13.2 | 4.87 |
| TinyLlama-1.1B-Chat-v1.0 (1.1B) | Sequential baseline | 0.12 | 3.78 | 8.23 |
TinyLlama numbers measured on Apple M3 Pro (36 GB), 8 requests, 64-token prompts, 32 output tokens, 3 trials, float32 CPU.
Run with:python benchmarks/benchmark_throughput.py --run-tinyllama
Requires ~6 GB RAM and ~2.2 GB model download from HuggingFace.
Throughput improvement under continuous batching:
FCFSPolicy vs MemoryAwarePolicy under simulated sequence load without model execution overhead.768 KB vs Blockwise = 96 KB ($8\times$ reduction)3,072 KB vs Blockwise = 96 KB ($32\times$ reduction)12,288 KB vs Blockwise = 96 KB ($128\times$ reduction)0.605 ms | Metal Direct = 3.570 ms (5.90x higher latency)2.111 ms | Metal Direct = 13.146 ms (6.23x higher latency)19.284 ms | Metal Direct = 46.935 ms (2.43x higher latency)newBufferWithBytes) and Command Buffer encoding costs in Python.283 passing tests (0 failed, 0 skipped). Tested across 2 complete test suite iterations.
Coverage includes:
1 to 256)# Clone the repository
git clone https://github.com/your-username/pagedserve.git
cd pagedserve
# Create and activate Python virtual environment
python3 -m venv .venv
source .venv/bin/activate
# Install PagedServe package in editable mode
pip install -e .
pytest -v tests/
uvicorn pagedserve.server.api:app --host 127.0.0.1 --port 8000
# Run Direct Blockwise Attention Microbenchmark
python benchmarks/benchmark_blockwise_attention.py
# Run Apple Metal Paged Attention Microbenchmark
python benchmarks/benchmark_metal_attention.py
PagedServe provides an OpenAI-compatible REST API:
GET /health: Health status endpoint.GET /metrics: Telemetry endpoint reporting uptime, request counts, throughput, latency distributions (TTFT, TPOT, E2E), KV block utilization, and prefix cache hit rate.POST /v1/completions: Text completion endpoint (supports "stream": true).POST /v1/chat/completions: Chat completion endpoint (supports "stream": true).python -m pagedserve.experiments.fragmentation --workload bimodal: Allocator memory fragmentation simulation.python benchmarks/benchmark_scheduler.py: Continuous batching scheduler policy benchmark.pagedserve/
├── baseline/ # Sequential single-request baseline
├── engine/ # Continuous batching engine & request state
├── experiments/ # Allocator fragmentation & overhead experiments
├── kernels/ # Backend abstraction (PyTorch & Fused Apple Metal MSL)
├── memory/ # BlockPool, BlockTable, TensorBlockStore, PrefixCache, Attention
├── model/ # ModelLoader, ModelRunner, Sampler, CacheAdapter
├── server/ # FastAPI HTTP server endpoints
├── config.py # EngineConfig & model parameters
├── errors.py # Custom exception hierarchy
└── metrics.py # Internal telemetry & latency distribution tracking
benchmarks/ # Reproducible performance benchmark suite
docs/ # In-depth technical architecture documentation
examples/ # Runnable usage examples
tests/ # 283 unit and integration tests
DynamicCache).query_seq_len == 1) in float32 precision.PagedServe is an original, independent educational codebase built from scratch for learning and research purposes.
21 commits
Python
98.9%
Metal
1.1%
High-performance LLM inference engine with paged KV cache, continuous batching, and custom attention kernels.
Python
5
21 commits
updated Sep 23, 2026
PagedServe is an experimental LLM inference runtime built from scratch to explore paged KV memory, continuous batching, direct blockwise attention, and custom GPU kernels.
LLM inference engines like vLLM popularized PagedAttention to eliminate KV cache fragmentation and enable high-throughput continuous batching. However, understanding the intricate systems interactions between block tables, physical memory pools, continuous iteration scheduling, streaming engines, and custom hardware kernels requires building these components ground-up. PagedServe was engineered as a transparent, modular runtime to measure, benchmark, and evaluate each component independently.
flowchart TD
Client["HTTP Client / SDK"] -->|OpenAI REST / Streaming| API["FastAPI Server (api.py)"]
API --> Engine["PagedServeEngine"]
Engine --> Scheduler["Continuous Batching Scheduler"]
Engine --> ModelRunner["ModelRunner (Hugging Face PyTorch)"]
Scheduler -->|Block Allocation & Claims| KVManager["KVCacheManager"]
KVManager --> BlockPool["BlockPool"]
KVManager --> PrefixCache["PrefixCache (SHA-256)"]
KVManager --> BlockTable["BlockTable (Logical -> Physical Mapping)"]
BlockTable --> TensorBlockStore["TensorBlockStore (Unified 5D Physical Storage)"]
TensorBlockStore --> AttentionBackend{"PagedAttention Backend"}
AttentionBackend -->|PyTorch Fallback| PyTorchBackend["PyTorch Blockwise (Online Softmax)"]
AttentionBackend -->|Apple Metal GPU| MetalBackend["Fused Apple Metal MSL Kernel"]
PagedServe is an experimental LLM inference runtime engineered to measure, evaluate, and benchmark inference subsystems.
Scheduler), request state machine (InferenceRequest), memory pressure admission control, block allocation pool (BlockPool), prefix cache (PrefixCache), FastAPI REST & SSE streaming server (api.py), and metrics telemetry (metrics.py).ModelRunner / ModelLoader) executes Hugging Face PyTorch models (distilgpt2, TinyLlama-1.1B) using standard Hugging Face transformer cache state where applicable.TensorBlockStore), PyTorch online-softmax blockwise attention (paged_attention_blockwise), and fused Apple Metal MSL GPU kernel (paged_attention_decode_kernel) exist as modular, independent subsystems with dedicated unit tests and microbenchmarks.Iterates sequence generation token-by-token across active requests. Interleaves prefill chunks with decode steps (FCFSPolicy, token budgets, memory-aware pressure control).
Virtualizes KV cache into fixed-size physical blocks (block_size=16 or 32), eliminating external memory fragmentation.
Allocates physical Key and Value tensors in pre-allocated unified 5D PyTorch tensors (TensorBlockStore) of shape [num_layers, num_blocks, block_size, num_kv_heads, head_dim]. Identical prompt prefixes share physical block IDs with Copy-on-Write (CoW) protection.
Iterates directly over non-contiguous physical blocks using numerically stable online softmax ($m, l, \text{acc}$), maintaining $O(\text{block_size})$ temporary memory overhead per block ($128\times$ memory reduction at $S=2048$) without constructing a full contiguous KV sequence tensor.
Provides a custom GPU compute shader in Metal Shading Language (MSL) (paged_attention_decode_kernel) that executes single-token decode attention directly on Apple Silicon GPUs (M1/M2/M3/M4).
Results measured on Apple M-series (arm64, CPU, float32). Run with python benchmarks/benchmark_throughput.py.
| Model | Mode | Requests/sec | Output tokens/sec | Mean latency (s) |
|---|---|---|---|---|
| distilgpt2 (82M) | PagedServe (c=8) | 3.39 | 27.15 | 1.165 |
| distilgpt2 (82M) | Sequential baseline | 0.86 | 6.87 | 1.165 |
| TinyLlama-1.1B-Chat-v1.0 (1.1B) | PagedServe (c=4) | 0.41 | 13.2 | 4.87 |
| TinyLlama-1.1B-Chat-v1.0 (1.1B) | Sequential baseline | 0.12 | 3.78 | 8.23 |
TinyLlama numbers measured on Apple M3 Pro (36 GB), 8 requests, 64-token prompts, 32 output tokens, 3 trials, float32 CPU.
Run with:python benchmarks/benchmark_throughput.py --run-tinyllama
Requires ~6 GB RAM and ~2.2 GB model download from HuggingFace.
Throughput improvement under continuous batching:
FCFSPolicy vs MemoryAwarePolicy under simulated sequence load without model execution overhead.768 KB vs Blockwise = 96 KB ($8\times$ reduction)3,072 KB vs Blockwise = 96 KB ($32\times$ reduction)12,288 KB vs Blockwise = 96 KB ($128\times$ reduction)0.605 ms | Metal Direct = 3.570 ms (5.90x higher latency)2.111 ms | Metal Direct = 13.146 ms (6.23x higher latency)19.284 ms | Metal Direct = 46.935 ms (2.43x higher latency)newBufferWithBytes) and Command Buffer encoding costs in Python.283 passing tests (0 failed, 0 skipped). Tested across 2 complete test suite iterations.
Coverage includes:
1 to 256)# Clone the repository
git clone https://github.com/your-username/pagedserve.git
cd pagedserve
# Create and activate Python virtual environment
python3 -m venv .venv
source .venv/bin/activate
# Install PagedServe package in editable mode
pip install -e .
pytest -v tests/
uvicorn pagedserve.server.api:app --host 127.0.0.1 --port 8000
# Run Direct Blockwise Attention Microbenchmark
python benchmarks/benchmark_blockwise_attention.py
# Run Apple Metal Paged Attention Microbenchmark
python benchmarks/benchmark_metal_attention.py
PagedServe provides an OpenAI-compatible REST API:
GET /health: Health status endpoint.GET /metrics: Telemetry endpoint reporting uptime, request counts, throughput, latency distributions (TTFT, TPOT, E2E), KV block utilization, and prefix cache hit rate.POST /v1/completions: Text completion endpoint (supports "stream": true).POST /v1/chat/completions: Chat completion endpoint (supports "stream": true).python -m pagedserve.experiments.fragmentation --workload bimodal: Allocator memory fragmentation simulation.python benchmarks/benchmark_scheduler.py: Continuous batching scheduler policy benchmark.pagedserve/
├── baseline/ # Sequential single-request baseline
├── engine/ # Continuous batching engine & request state
├── experiments/ # Allocator fragmentation & overhead experiments
├── kernels/ # Backend abstraction (PyTorch & Fused Apple Metal MSL)
├── memory/ # BlockPool, BlockTable, TensorBlockStore, PrefixCache, Attention
├── model/ # ModelLoader, ModelRunner, Sampler, CacheAdapter
├── server/ # FastAPI HTTP server endpoints
├── config.py # EngineConfig & model parameters
├── errors.py # Custom exception hierarchy
└── metrics.py # Internal telemetry & latency distribution tracking
benchmarks/ # Reproducible performance benchmark suite
docs/ # In-depth technical architecture documentation
examples/ # Runnable usage examples
tests/ # 283 unit and integration tests
DynamicCache).query_seq_len == 1) in float32 precision.PagedServe is an original, independent educational codebase built from scratch for learning and research purposes.
21 commits
Python
98.9%
Metal
1.1%