| name | deploy-ml-model-serving |
| description | Deploy machine learning models to production serving infrastructure using MLflow, BentoML, or Seldon Core with REST/gRPC endpoints, implement autoscaling, monitoring, and A/B testing capabilities for high-performance model inference at scale. Use when deploying trained models for real-time inference, setting up REST or gRPC prediction APIs, implementing autoscaling for variable load, running A/B tests between model versions, or migrating from batch to real-time inference.
|
| license | MIT |
| allowed-tools | Read Write Edit Bash Grep Glob |
| metadata | {"author":"Philipp Thoss","version":"1.1","domain":"mlops","complexity":"advanced","language":"multi","tags":"model-serving, bentoml, seldon, rest-api, grpc"} |
Deploy ML Model Serving
See Extended Examples for complete configuration files and templates.
Deploy machine learning models to production with scalable serving infrastructure, monitoring, and A/B testing.
When to Use
- Deploying trained models to production for real-time inference
- Setting up REST or gRPC APIs for model predictions
- Implementing autoscaling for variable load patterns
- Running A/B tests between model versions
- Migrating from batch to real-time inference
- Building low-latency prediction services
- Managing multiple model versions in production
Inputs
- Required: Registered model in MLflow Model Registry or trained model artifact
- Required: Kubernetes cluster or container orchestration platform
- Required: Serving framework choice (MLflow, BentoML, Seldon Core, TorchServe)
- Optional: GPU resources for deep learning models
- Optional: Monitoring infrastructure (Prometheus, Grafana)
- Optional: Load balancer and ingress controller
Procedure
Step 1: Deploy with MLflow Models Serving
Use MLflow's built-in serving for quick deployment of scikit-learn, PyTorch, and TensorFlow models.
mlflow models serve \
--model-uri models:/customer-churn-classifier/Production \
--port 5001 \
--host 0.0.0.0
curl -X POST http://localhost:5001/invocations \
-H 'Content-Type: application/json' \
-d '{
"dataframe_records": [
{"feature1": 1.0, "feature2": 2.0, "feature3": 3.0}
]
}'
Docker deployment:
# Dockerfile.mlflow-serving
FROM python:3.9-slim
# Install MLflow and dependencies
RUN pip install mlflow boto3 scikit-learn
# Set environment variables
ENV MLFLOW_TRACKING_URI=http://mlflow-server:5000
# ... (see EXAMPLES.md for complete implementation)
Docker Compose for local testing:
version: '3.8'
services:
model-server:
build:
context: .
dockerfile: Dockerfile.mlflow-serving
Test the deployment:
import requests
import json
def test_prediction():
url = "http://localhost:8080/invocations"
Expected: Model server starts successfully, responds to HTTP POST requests, returns predictions in JSON format, Docker container runs without errors.
On failure: Check model URI is valid (mlflow models list), verify MLflow tracking server accessibility, ensure all model dependencies installed in container, check port availability (netstat -tulpn | grep 8080), verify model flavor compatibility, inspect container logs (docker logs <container-id>).
Step 2: Deploy with BentoML for Production Scale
Use BentoML for advanced serving with better performance and features.
import bentoml
from bentoml.io import JSON, NumpyNdarray
import numpy as np
import pandas as pd
import mlflow
Build and containerize:
bentoml build
bentoml containerize customer_churn_classifier:latest \
--image-tag customer-churn:v1.0
docker run -p 3000:3000 customer-churn:v1.0
BentoML configuration:
service: "bentoml_service:ChurnPredictionService"
include:
- "bentoml_service.py"
- "preprocessing.py"
python:
packages:
- scikit-learn==1.0.2
- pandas==1.4.0
- numpy==1.22.0
- mlflow==2.0.1
docker:
distro: debian
python_version: "3.9"
cuda_version: null
Kubernetes deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: churn-prediction
labels:
app: churn-prediction
spec:
Deploy to Kubernetes:
kubectl apply -f k8s/deployment.yaml
kubectl get deployments
kubectl get pods
kubectl get services
EXTERNAL_IP=$(kubectl get svc churn-prediction-service -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
curl -X POST http://$EXTERNAL_IP/predict \
-H 'Content-Type: application/json' \
-d '{"instances": [{"tenure": 12, "monthly_charges": 70.35}]}'
Expected: BentoML service builds successfully, container runs and serves predictions, Kubernetes deployment creates 3 replicas, load balancer exposes external endpoint, health checks pass.
On failure: Verify BentoML installation (bentoml --version), check model exists in BentoML store (bentoml models list), ensure Docker daemon running, verify Kubernetes cluster access (kubectl cluster-info), check resource limits not exceeded, inspect pod logs (kubectl logs <pod-name>), verify service selector matches pod labels, confirm liveness/readiness probes are defined — without a readiness probe Kubernetes does not wait for model loading and routes traffic to pods that are not ready — and confirm pod anti-affinity is configured — multiple replicas alone do not guarantee availability, since without anti-affinity all replicas can be scheduled onto the same node.
Step 3: Implement Seldon Core for Advanced Features
Use Seldon Core for multi-model serving, A/B testing, and explainability.
import logging
from typing import Dict, List, Union
import numpy as np
import mlflow
logger = logging.getLogger(__name__)
Seldon deployment configuration:
apiVersion: machinelearning.seldon.io/v1
kind: SeldonDeployment
metadata:
name: churn-classifier
namespace: seldon
spec:
name: churn-classifier
A/B testing configuration:
apiVersion: machinelearning.seldon.io/v1
kind: SeldonDeployment
metadata:
name: churn-classifier-ab
spec:
name: churn-classifier-ab
predictors:
Deploy to Kubernetes:
kubectl create namespace seldon-system
helm install seldon-core seldon-core-operator \
--repo https://storage.googleapis.com/seldon-charts \
--namespace seldon-system \
--set usageMetrics.enabled=true
Expected: Seldon Core operator installed successfully, model deployment creates pods, REST endpoint responds to predictions, A/B test splits traffic correctly, Seldon Analytics records metrics.
On failure: Verify Seldon Core operator running (kubectl get pods -n seldon-system), check SeldonDeployment status (kubectl describe seldondeployment), ensure image registry accessible from cluster, verify model URI resolution, check RBAC permissions for Seldon operator, inspect model container logs.
Step 4: Implement Monitoring and Observability
Add comprehensive monitoring for model serving infrastructure.
from prometheus_client import Counter, Histogram, Gauge, start_http_server
import time
import logging
logger = logging.getLogger(__name__)
Prometheus configuration:
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'model-serving'
kubernetes_sd_configs:
Grafana dashboard JSON:
{
"dashboard": {
"title": "ML Model Serving Metrics",
"panels": [
{
"title": "Predictions Per Second",
"targets": [
{
# ... (see EXAMPLES.md for complete implementation)
Expected: Prometheus scrapes metrics successfully, Grafana dashboards display prediction throughput, latency percentiles, error rates, and active requests in real-time.
On failure: Verify Prometheus scrape targets are UP (http://prometheus:9090/targets), check metrics endpoint accessibility (curl http://model-pod:8000/metrics), ensure Kubernetes service discovery configured, verify Grafana data source connection, check firewall rules for metrics port.
Step 5: Implement Autoscaling
Configure horizontal pod autoscaling based on request load.
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: churn-prediction-hpa
namespace: seldon
spec:
scaleTargetRef:
Apply autoscaling:
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
kubectl apply -f hpa.yaml
kubectl get hpa -n seldon
kubectl describe hpa churn-prediction-hpa -n seldon
kubectl run -it --rm load-generator --image=busybox --restart=Never -- /bin/sh -c "while sleep 0.01; do wget -q -O- http://churn-prediction-service/predict; done"
kubectl get hpa -n seldon --watch
Expected: HPA monitors CPU/memory/custom metrics, scales replicas up under load, scales down after stabilization period, min/max replica limits respected.
On failure: Verify metrics-server running (kubectl get deployment metrics-server -n kube-system), check pod resource requests defined (HPA requires requests), ensure custom metrics available if used, verify RBAC permissions for HPA controller, check stabilization windows not too restrictive.
Step 6: Implement Canary Deployment Strategy
Gradually roll out new model versions with traffic shifting.
apiVersion: machinelearning.seldon.io/v1
kind: SeldonDeployment
metadata:
name: churn-classifier-canary
spec:
name: churn-classifier-canary
predictors:
Gradual rollout script:
import time
import subprocess
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
Expected: Canary deployment starts with 0% traffic, gradual traffic shift occurs automatically, health checks pass at each stage, rollback triggered if metrics degrade, complete rollout after all stages pass.
On failure: Verify Seldon deployment has multiple predictors, check traffic percentages sum to 100, ensure canary image exists and is pullable, verify Prometheus metrics available for health checks, check rollback logic executes correctly, inspect pod logs for both versions.
Validation
Common Pitfalls
- Cold start latency: First request slow due to model loading - use readiness probes with adequate delay, implement model caching
- Memory leaks: Long-running servers accumulate memory - monitor memory usage, implement periodic restarts, profile code
- Dependency conflicts: Model dependencies incompatible with serving framework - use exact pinned versions, test in Docker before deployment
- Resource limits too low: Pods OOMKilled or CPU throttled - profile resource usage, set appropriate limits based on load testing
- Ignoring latency: Focusing only on accuracy, not inference speed - benchmark latency, optimize model/code, use batching
- GPU not utilized: GPU available but not used - set CUDA visible devices, verify GPU allocation in Kubernetes
Related Skills
register-ml-model - Register models before deploying them
run-ab-test-models - Implement A/B testing between model versions
deploy-to-kubernetes - General Kubernetes deployment patterns
monitor-ml-model-performance - Monitor model drift and degradation
orchestrate-ml-pipeline - Automate model retraining and deployment