Skip to content

Repository files navigation

Paged Attention Runtime

License: MIT CUDA PyTorch Tests Preemption Batching Async

Custom CUDA implementation of PagedAttention and a full LLM serving runtime stack inspired by vLLM.

This project rebuilds from scratch the core memory and scheduling mechanisms behind high-performance LLM serving engines.


Highlights

  • Custom CUDA PagedAttention kernel
  • Block-based KV cache allocator
  • Continuous (iteration-level) batching
  • Priority-aware scheduling
  • Hybrid preemption (swap + recompute fallback)
  • CPU-side KV swap-out with pinned memory support
  • Cancellation support
  • Streaming API
  • Async submission API
  • Reproducible benchmark infrastructure
  • 80+ tests covering full lifecycle

What This Project Demonstrates

This runtime includes the core architectural ideas behind modern LLM serving systems:

  • Block-based KV allocation (paged memory abstraction)
  • Prefix sharing and reference counting
  • Copy-on-write semantics
  • Continuous dynamic batching
  • Priority-aware admission
  • Preemption under memory pressure
  • Swap-out preemption to CPU
  • Streaming token emission
  • Async request handling

All implemented from scratch with explicit control over memory lifecycle and scheduling behavior.


Architecture Overview

Client Request

Scheduler (Priority + Continuous Admission)

Block Manager (KV Allocation + Ref Counting)

PagedAttention CUDA Kernel

Token Generation

Swap / Preempt / Continue


Core Components

Block Manager

  • Fixed-size KV blocks
  • O(1) allocation via free list
  • Reference counting for prefix sharing
  • Copy-on-write support
  • Fragmentation tracking

Continuous Batching Scheduler

  • Iteration-level admission
  • Priority-aware queue
  • FIFO within same priority
  • Controlled prefill throttling

Preemption

  • Detects memory pressure
  • Selects victim via policy
  • Swap-first strategy
  • Recompute fallback

Swap Manager

  • CPU-side KV storage
  • Optional pinned memory
  • Swap-out on pressure
  • Swap-in on re-admission
  • Preserves generated tokens

Streaming API

Example:

for event in runtime.stream(generator): print(event)

Async API

Example:

future = runtime.submit(generator) result = future.result()


Serving Engine Benchmark

Benchmarks are fully reproducible:

PYTHONPATH=. python benchmarks/compare_serving_modes.py
PYTHONPATH=. python benchmarks/plot_compare.py
PYTHONPATH=. python benchmarks/aggregate_history.py
PYTHONPATH=. python benchmarks/generate_report.py


Configuration

  • Device: CUDA
  • Heads: 4
  • Head size: 8
  • Block size: 16
  • Requests: 32
  • Max new tokens per request: 40

Throughput Comparison

Log Scale Comparison
See: benchmarks/results/compare_serving_modes_log.png

Continuous vs Continuous + Swap
See: benchmarks/results/compare_continuous_only.png


Observations

Static Batching

  • Maximum raw kernel throughput
  • No scheduling overhead
  • Not suitable for heterogeneous workloads

Continuous Batching

  • Enables heterogeneous serving
  • Introduces scheduler overhead
  • Supports dynamic request arrival

Recompute-Based Preemption

  • Discards KV cache
  • Wastes compute under pressure
  • Simple fallback mechanism

Swap-Based Preemption

  • Preserves KV cache in CPU memory
  • Avoids recompute cost
  • Improves throughput under pressure
  • Adds PCIe transfer latency

SLA Behavior

  • High priority requests admitted first
  • Lower priority requests swapped/preempted first
  • Fairness maintained without strict real-time guarantees

Benchmark Infrastructure

Includes:

  • Stress test under memory pressure
  • SLA workload fairness test
  • Throughput benchmark
  • Historical aggregation
  • Auto-generated plots
  • Auto-generated Markdown report

Example stress test:

PYTHONPATH=. python benchmarks/stress_runtime.py

Example SLA test:

PYTHONPATH=. python benchmarks/sla_priority_workload.py



Extreme Preemption Policy Analysis

To evaluate the impact of victim selection strategies under heterogeneous workloads and tight memory constraints, we ran an extreme stress test with:

  • num_blocks = 8 (very constrained GPU memory)
  • max_active_sequences = 6
  • max_swapped_requests = 2
  • Mixed workloads:
    • Large KV requests (prompt_len=64, max_new_tokens=80)
    • Small KV requests (prompt_len=8, max_new_tokens=10)
  • Equal priority across requests

Elapsed Time Comparison

Extreme Policy Elapsed

Throughput Comparison

Extreme Policy Throughput


Results

Under extreme heterogeneity:

Policy Tokens/sec Elapsed (s)
FIFO ~457 ~0.13
COST_BASED ~3232 ~0.019

Interpretation

Under extreme memory constraints and heterogeneous sequence lengths, COST_BASED significantly outperformed FIFO in this synthetic stress scenario.

Although both policies triggered a similar number of swap events, the effective scheduling dynamics differed, leading to a ~7× throughput gap.

This suggests that victim selection policy can materially affect decode parallelism and runtime behavior under tight memory limits.

Further instrumentation (kernel call counts, active batch size evolution, and recompute metrics) is required to fully attribute the performance gap.


Key Insight

Victim selection policy matters significantly under:

  • Heterogeneous sequence lengths
  • Constrained GPU memory
  • Limited swap pool capacity

Simple heuristics (FIFO) are sufficient in homogeneous workloads, but cost-aware scheduling substantially improves performance under real serving pressure.

Testing

Run full test suite:

pytest tests/ -v

Covers:

  • Block allocation
  • Prefix sharing
  • Copy-on-write
  • Continuous batching
  • Preemption
  • Swap-out / swap-in
  • Cancellation
  • Kernel correctness
  • Memory reclamation
  • Priority scheduling

Conclusion

This repository implements a full serving runtime stack comparable to modern LLM serving engines.

It demonstrates:

  • Systems-level understanding
  • GPU memory management
  • Scheduling algorithms
  • Memory pressure handling
  • Hybrid preemption strategies
  • Real-world serving behavior

All built from scratch with explicit control over memory lifecycle and scheduling semantics.


License

MIT João Felipe De Souza

About

Custom CUDA implementation of block-based PagedAttention with prefix sharing, copy-on-write, concurrent batching, and end-to-end Qwen2 integration.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages