Skip to main content

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mle_runtime-1.0.1.tar.gz (6.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mle_runtime-1.0.1-py3-none-any.whl (5.4 kB view details)

Uploaded Python 3

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

Hashes for mle_runtime-1.0.1.tar.gz
Algorithm Hash digest
SHA256 3c02d8daaa94c9847a7fa70bfab7d4c7677ea97023b55d07e8560e401fefc288
MD5 f329720e579165a57eff0e494c62cfa7
BLAKE2b-256 36a4f1cf9708d7717f54b634ce4d9d08e4a327a59180fc7c560861431f6e1ff0

See more details on using hashes here.

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

Hashes for mle_runtime-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 86ec8076b7cfacf72cf30685439fed64110d50905c7a77e6c66f2cd6f45815f1
MD5 08c990583bb9c9cc5e2a6054f6d9de8f
BLAKE2b-256 6d20febe1611ff9ea3e9686d3394cc670f46271a780ae1e31b58a53fbbb6b8e5

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page