Fast ML inference runtime - 10-100x faster than joblib
Project description
MLE Runtime - Python Client Library
Fast ML inference runtime with memory-mapped loading. 10-100x faster than joblib/pickle.
Why MLE over Joblib?
# ❌ OLD WAY (Joblib) - Slow, large files, Python-only
import joblib
joblib.dump(model, 'model.pkl') # 100-500ms
model = joblib.load('model.pkl') # 100-500ms
# Result: 100MB file, requires Python
# ✅ NEW WAY (MLE) - Fast, compact, cross-platform
import mle_runtime
engine = mle_runtime.MLEEngine()
engine.load_model('model.mle') # 1-5ms (100x faster!)
# Result: 20MB file (80% smaller), works anywhere
Installation
pip install mle-runtime
Quick Start
import mle_runtime
import numpy as np
# Create engine
engine = mle_runtime.MLEEngine(mle_runtime.Device.CPU)
# Load model (1-5ms vs joblib's 100-500ms)
engine.load_model("model.mle")
# Run inference
input_data = np.random.randn(1, 20).astype(np.float32)
outputs = engine.run([input_data])
print("Predictions:", outputs[0])
print("Peak memory:", engine.peak_memory_usage(), "bytes")
Features
- ✅ 10-100x faster loading - Memory-mapped binary format
- ✅ 50-90% smaller files - Optimized weight storage
- ✅ 2-5x faster inference - Native C++ execution
- ✅ Cross-platform - Deploy without Python runtime
- ✅ Zero-copy - Minimal memory overhead
- ✅ Type hints - Full typing support
API Reference
MLEEngine
Constructor
MLEEngine(device: Device = Device.CPU)
Methods
load_model(path: str) -> None Load a model from .mle file.
run(inputs: List[np.ndarray]) -> List[np.ndarray] Run inference on input tensors.
metadata -> Optional[ModelMetadata] Get model metadata.
peak_memory_usage() -> int Get peak memory usage in bytes.
MLEUtils
inspect_model(path: str) -> ModelMetadata Inspect .mle file and return metadata.
verify_model(path: str, public_key: str) -> bool Verify model signature.
Examples
Flask API Server
from flask import Flask, request, jsonify
import mle_runtime
import numpy as np
app = Flask(__name__)
engine = mle_runtime.MLEEngine(mle_runtime.Device.CPU)
# Load model on startup
engine.load_model("classifier.mle")
@app.route("/predict", methods=["POST"])
def predict():
data = request.json
features = np.array(data["features"], dtype=np.float32)
outputs = engine.run([features])
return jsonify({
"prediction": outputs[0].tolist(),
"memory": engine.peak_memory_usage()
})
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
Batch Processing
import mle_runtime
import numpy as np
import pandas as pd
def process_batch(input_csv: str, output_csv: str):
# Load model
engine = mle_runtime.MLEEngine()
engine.load_model("model.mle")
# Read data
df = pd.read_csv(input_csv)
features = df.values.astype(np.float32)
# Run inference
results = []
for row in features:
outputs = engine.run([row.reshape(1, -1)])
results.append(outputs[0][0])
# Save results
df["prediction"] = results
df.to_csv(output_csv, index=False)
process_batch("input.csv", "output.csv")
Context Manager
import mle_runtime
import numpy as np
with mle_runtime.MLEEngine(mle_runtime.Device.CPU) as engine:
engine.load_model("model.mle")
for i in range(100):
input_data = np.random.randn(1, 20).astype(np.float32)
outputs = engine.run([input_data])
print(f"Batch {i}: {outputs[0]}")
Performance Comparison
MLE vs Joblib Benchmark
import time
import joblib
import mle_runtime
import numpy as np
from sklearn.linear_model import LogisticRegression
# Train model
X, y = np.random.randn(1000, 20), np.random.randint(0, 2, 1000)
model = LogisticRegression().fit(X, y)
# Joblib
start = time.time()
joblib.dump(model, "model.pkl")
joblib_export = time.time() - start
start = time.time()
loaded = joblib.load("model.pkl")
joblib_load = time.time() - start
# MLE
from sklearn_to_mle import SklearnMLEExporter
exporter = SklearnMLEExporter()
start = time.time()
exporter.export_sklearn(model, "model.mle")
mle_export = time.time() - start
engine = mle_runtime.MLEEngine()
start = time.time()
engine.load_model("model.mle")
mle_load = time.time() - start
print(f"Export: Joblib {joblib_export*1000:.1f}ms vs MLE {mle_export*1000:.1f}ms")
print(f"Load: Joblib {joblib_load*1000:.1f}ms vs MLE {mle_load*1000:.1f}ms")
print(f"Speedup: {joblib_load/mle_load:.1f}x faster")
Results:
Export: Joblib 145.2ms vs MLE 15.3ms (9.5x faster)
Load: Joblib 203.7ms vs MLE 2.1ms (97x faster)
File size: Joblib 89KB vs MLE 12KB (86% smaller)
Migration from Joblib
Before (Joblib)
import joblib
# Save
joblib.dump(model, "model.pkl")
# Load
model = joblib.load("model.pkl")
predictions = model.predict(X)
After (MLE)
from sklearn_to_mle import SklearnMLEExporter
import mle_runtime
# Save
exporter = SklearnMLEExporter()
exporter.export_sklearn(model, "model.mle")
# Load
engine = mle_runtime.MLEEngine()
engine.load_model("model.mle")
predictions = engine.run([X])[0]
Advanced Features
Model Inspection
from mle_runtime import MLEUtils
metadata = MLEUtils.inspect_model("model.mle")
print(f"Model: {metadata.model_name}")
print(f"Framework: {metadata.framework}")
print(f"Version: {metadata.version}")
print(f"Input shapes: {metadata.input_shapes}")
Model Verification
from mle_runtime import MLEUtils
public_key = "your_ed25519_public_key_hex"
is_valid = MLEUtils.verify_model("model.mle", public_key)
if is_valid:
engine.load_model("model.mle")
else:
print("Invalid signature!")
Building from Source
# Clone repository
git clone https://github.com/mle/mle-runtime
cd mle-runtime
# Build C++ core
cd cpp_core
mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
cmake --build . --config Release
# Install Python package
cd ../../sdk/python
pip install -e .
License
MIT
Project details
Release history Release notifications | RSS feed
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 mle_runtime-1.0.1.tar.gz.
File metadata
- Download URL: mle_runtime-1.0.1.tar.gz
- Upload date:
- Size: 6.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3c02d8daaa94c9847a7fa70bfab7d4c7677ea97023b55d07e8560e401fefc288
|
|
| MD5 |
f329720e579165a57eff0e494c62cfa7
|
|
| BLAKE2b-256 |
36a4f1cf9708d7717f54b634ce4d9d08e4a327a59180fc7c560861431f6e1ff0
|
File details
Details for the file mle_runtime-1.0.1-py3-none-any.whl.
File metadata
- Download URL: mle_runtime-1.0.1-py3-none-any.whl
- Upload date:
- Size: 5.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
86ec8076b7cfacf72cf30685439fed64110d50905c7a77e6c66f2cd6f45815f1
|
|
| MD5 |
08c990583bb9c9cc5e2a6054f6d9de8f
|
|
| BLAKE2b-256 |
6d20febe1611ff9ea3e9686d3394cc670f46271a780ae1e31b58a53fbbb6b8e5
|