High-throughput ML inference middleware with dynamic batching
Project description
SmartBatch: High-Throughput Async Inference Middleware
SmartBatch is a production-grade inference serving system designed to maximize GPU utilization and throughput for PyTorch models. It implements Dynamic Batching to group incoming requests on-the-fly, significantly reducing overhead compared to naive request-per-inference processing.
🚀 Key Features
- Dynamic Batching: Automatically groups requests into batches (up to
MAX_BATCH_SIZE) or processes them after a timeout (MAX_WAIT_TIME), striking the perfect balance between throughput and latency. - Asynchronous API: Built on
FastAPIandasyncioto handle thousands of concurrent connections efficiently. - Production Robustness: Includes graceful shutdown, proper error handling, and thread-safe metrics.
- Real-World Load Testing: Benchmarking suite included to simulate high-concurrency traffic with realistic payloads.
- Observability:
/metricsendpoint for real-time monitoring of latency, batch sizes, and throughput.
📊 Benchmark Results (Stress Test)
We conducted a rigorous 1-hour stress test comparing SmartBatch against a Baseline (no batching) implementation.
Hardware: Single Node (Simulated Production Environment) Load: 200-1000 Concurrent Users Payload: Real-world images (ResNet18 inputs)
| Metric | Baseline (Sequential) | SmartBatch (Batched) | Improvement |
|---|---|---|---|
| Throughput (RPS) | ~0.67 req/s | ~2.22 req/s | 3.3x Higher |
| Median Latency (p50) | > 1000s (Collapsed) | ~13s (Stable) | ~99% Reduction |
| Tail Latency (p95) | Unstable / Timeouts | Controlled by Batching | Stabilized |
🛠️ Installation
-
Clone the repository:
git clone https://github.com/yourusername/SmartBatch.git cd SmartBatch
-
Create a virtual environment:
python3.12 -m venv venv source venv/bin/activate
-
Install dependencies:
pip install .
🏃 Usage
1. The Decorator Pattern (Recommended)
Add @batch to any async function to automatically group requests.
from smartbatch import batch
from typing import List
# 1. Define your batched function (List -> List)
@batch(max_batch_size=32, max_wait_time=0.01)
async def run_model(batch_inputs: List[float]) -> List[float]:
# This runs ONLY when a batch is full or timeout matches
return model.predict(batch_inputs)
# 2. Call it normally (Single Item -> Single Item)
# The decorator handles queueing and waiting!
result = await run_model(single_input)
2. Binary Transport (MsgPack)
For high-performance clients, send binary packed data instead of JSON to reduce payload size.
Header: Content-Type: application/msgpack
Body: MsgPack encoded dict (e.g., {"data": [...]}) or raw list [...].
import msgpack, requests
payload = msgpack.packb([0.1, 0.2, 0.3])
requests.post("http://localhost:8000/predict", data=payload, headers={"Content-Type": "application/msgpack"})
3. Multi-Model Registry
To serve multiple models on dynamic routes (/models/{name}/predict), use @register:
from smartbatch import batch, register
@register(name="yolo")
@batch(max_batch_size=8)
async def run_yolo(batch: List):
return yolo_model(batch)
# Now available at: POST /models/yolo/predict
4. Input Schema Validation (Recommended)
Protect your workers by enforcing Pydantic schemas. Invalid requests (e.g. string instead of int) will raise an error before queueing.
from pydantic import BaseModel
class ImageInput(BaseModel):
data: List[float]
threshold: float = 0.5
@batch(max_batch_size=32, input_schema=ImageInput)
async def safe_inference(batch: List[ImageInput]):
# 'batch' contains valid Pydantic objects now!
inputs = [item.data for item in batch]
return model.predict(inputs)
5. Multi-GPU / Multi-Worker Support
Scale verticaly by running multiple worker loops. Use worker_id to select devices.
# Models loaded on different GPUs
models = {
0: load_model("cuda:0"),
1: load_model("cuda:1")
}
@batch(max_batch_size=32, workers=2)
async def infer(batch, worker_id=0):
# SmartBatch injects 'worker_id' (0 or 1) automatically
model = models[worker_id]
return model(batch)
🧪 Benchmarking
Reproduce the performance results yourself using the included benchmark suite.
1. Run the Comparison Benchark This script runs both Baseline and SmartBatch scenarios sequentially and generates plots.
# usage: --users [NUM] --duration [TIME]
venv/bin/python scripts/production_benchmark.py --users 200 --duration 1h
2. View Results The script will generate these files in your root directory:
production_throughput.pngproduction_latency_p50.pngproduction_latency_p95.png
📂 Project Structure
SmartBatch/
├── smartbatch/ # Core Package
│ ├── main.py # Entry point & App lifecycle
│ ├── api.py # FastAPI endpoints
│ ├── batching.py # Batch logic & Queue management
│ ├── model.py # PyTorch Model Wrapper
│ └── metrics.py # Thread-safe metrics collection
├── scripts/ # Utilities
│ ├── production_benchmark.py # A/B Stress Test Script
│ └── study_params.py # Hyperparameter optimization
├── tests/ # Testing
│ ├── locustfile.py # Load generator
│ └── data/ # Test images (for realistic load)
└── README.md # Documentation
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file smartbatch-0.1.0.tar.gz.
File metadata
- Download URL: smartbatch-0.1.0.tar.gz
- Upload date:
- Size: 12.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
38257d8a443394788b00715b10d1d64e8eac47b4d21a8c70c445c63b61cd50ab
|
|
| MD5 |
dcca2150b50533565eae4895a68d8e1b
|
|
| BLAKE2b-256 |
4e0a6d39ea57364f59355af0b02aefc8cafce8d44a92106df232c96094dea289
|
Provenance
The following attestation bundles were made for smartbatch-0.1.0.tar.gz:
Publisher:
publish.yml on VeeraKarthick609/SmartBatch
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
smartbatch-0.1.0.tar.gz -
Subject digest:
38257d8a443394788b00715b10d1d64e8eac47b4d21a8c70c445c63b61cd50ab - Sigstore transparency entry: 855392320
- Sigstore integration time:
-
Permalink:
VeeraKarthick609/SmartBatch@72f52150c75ff85209d9380a77580d8b33e6e80d -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/VeeraKarthick609
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@72f52150c75ff85209d9380a77580d8b33e6e80d -
Trigger Event:
release
-
Statement type:
File details
Details for the file smartbatch-0.1.0-py3-none-any.whl.
File metadata
- Download URL: smartbatch-0.1.0-py3-none-any.whl
- Upload date:
- Size: 11.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bb9d25de380441bf5d611131ab5cc79d1690d876724764115683c11c6e3eac69
|
|
| MD5 |
9a3a399fc499d87e25aa784ca4b90101
|
|
| BLAKE2b-256 |
9a232d2004feef5dc7a89a095f3f9d56fb3904da3fab5a0a35b4eef0c672e67c
|
Provenance
The following attestation bundles were made for smartbatch-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on VeeraKarthick609/SmartBatch
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
smartbatch-0.1.0-py3-none-any.whl -
Subject digest:
bb9d25de380441bf5d611131ab5cc79d1690d876724764115683c11c6e3eac69 - Sigstore transparency entry: 855392348
- Sigstore integration time:
-
Permalink:
VeeraKarthick609/SmartBatch@72f52150c75ff85209d9380a77580d8b33e6e80d -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/VeeraKarthick609
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@72f52150c75ff85209d9380a77580d8b33e6e80d -
Trigger Event:
release
-
Statement type: