Lesson 14 • Intermediate
Model Deployment
Take your ML models from Jupyter notebooks to production — serialisation, API serving, versioning, and monitoring.
✅ What You'll Learn
- • Serialise and load trained models
- • Build prediction APIs with input validation
- • Model versioning and A/B testing
- • Monitor model health and detect data drift
🚀 From Notebook to Production
🎯 Real-World Analogy: Building an ML model in a notebook is like cooking a perfect dish in your kitchen. Deployment is like opening a restaurant — now you need to serve that dish consistently to thousands of customers, handle bad orders gracefully, and notice when ingredient quality drops. The recipe is the easy part; the restaurant operations are the real challenge.
80% of ML projects never make it to production. The gap between "works in a notebook" and "serves predictions reliably" is where most teams struggle. This lesson covers the essential patterns.
🔄 ML Deployment Pipeline
- 1. Train → Build and validate model
- 2. Serialise → Save model to file (pickle/ONNX)
- 3. Package → Container with dependencies (Docker)
- 4. Serve → REST API (FastAPI/Flask)
- 5. Monitor → Track accuracy, latency, drift
Try It: Model Serialisation
Save and load a trained model — the first step to deployment
import json
import numpy as np
# Model Serialization: Saving and Loading Models
# After training, you need to SAVE the model so it can be used later
# Simulate a trained model (weights + config)
class SimpleModel:
def __init__(self, weights, bias, feature_names):
self.weights = weights
self.bias = bias
self.feature_names = feature_names
def predict(self, X):
return X @ self.weights + self.bias
def to_dict(self):
return {
...Try It: Prediction API
Build a model server with input validation and versioning
# Building a Prediction API (FastAPI-style)
# This is the pattern used in production ML systems
class PredictionRequest:
"""Simulated API request validation"""
def __init__(self, data):
self.features = data.get("features", {})
self.model_version = data.get("model_version", "latest")
def validate(self):
required = ["sqft", "bedrooms", "age"]
missing = [f for f in required if f not in self.features]
if missing:
return False, f"M
...⚠️ Common Mistake: Never put model training inside your API endpoint! Train offline, serialise the model, and load it once at startup. Training inside the request path means every API call takes minutes instead of milliseconds.
Try It: Model Monitoring
Detect data drift and model degradation over time
import numpy as np
# Model Monitoring: Detecting when your model goes BAD
# Models degrade over time (data drift, concept drift)
np.random.seed(42)
# Simulate production predictions over 30 days
days = 30
daily_errors = []
daily_latencies = []
print("=== Model Monitoring Dashboard ===")
print()
for day in range(days):
# Simulate gradual model degradation (data drift)
drift_factor = 1 + (day / days) * 0.5 # errors grow over time
n_predictions = 100
errors = np.abs(np.ra
...📋 Quick Reference
| Stage | Tools | Purpose |
|---|---|---|
| Serialisation | joblib, pickle, ONNX | Save/load models |
| API Serving | FastAPI, Flask, TF Serving | HTTP predictions |
| Containerisation | Docker, K8s | Reproducible environments |
| Monitoring | Prometheus, Grafana, Evidently | Track health & drift |
| CI/CD | MLflow, DVC, GitHub Actions | Automated pipelines |
💡 Pro Tip: Start simple. Deploy with FastAPI + Docker first. Add Kubernetes, A/B testing, and shadow deployments only when you have real traffic. Premature infrastructure complexity kills more ML projects than bad models do.
🎉 Lesson Complete!
You can now take models from notebooks to production! Next, dive into Unsupervised Learning — finding hidden patterns in unlabelled data.
Sign up for free to track which lessons you've completed and get learning reminders.