Topic 12 / 12

Shipping Models: MLOps Fundamentals

~10 min read  //  AI & ML Series  //  Coding India

A Model in a Notebook Earns Nothing

Production ML means a model that answers requests reliably, gets monitored, and gets retrained when the world drifts. The gap between “works in Jupyter” and “runs in prod” is where most ML projects die — this topic closes it.

Step 1: Make Preprocessing Part of the Model

The #1 production bug is training/serving skew — preprocessing in the notebook differing from preprocessing at inference. scikit-learn pipelines eliminate it by bundling the steps into the model object:

from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import StandardScaler, OneHotEncoder

pre = ColumnTransformer([
    ("num", StandardScaler(), ["area", "age"]),
    ("cat", OneHotEncoder(handle_unknown="ignore"), ["city"]),
])
pipe = Pipeline([("pre", pre), ("model", Ridge(alpha=10))])
pipe.fit(X_train, y_train)        # scaler fitted on train only — leakage impossible

Step 2: Serialize

import joblib
joblib.dump(pipe, "model_v3.joblib")
pipe = joblib.load("model_v3.joblib")

Version the artefact (model_v3), and pin library versions in requirements.txt — a pickle saved under scikit-learn 1.4 may not load under 1.6.

Step 3: Serve Behind an API

from fastapi import FastAPI
from pydantic import BaseModel
import joblib, pandas as pd

app = FastAPI()
model = joblib.load("model_v3.joblib")   # load once at startup

class House(BaseModel):
    area: float
    age: float
    city: str

@app.post("/predict")
def predict(h: House):
    X = pd.DataFrame([h.model_dump()])
    return {"price": float(model.predict(X)[0]), "model_version": "v3"}
uvicorn serve:app --host 0.0.0.0 --port 8000

Pydantic validates every request — bad inputs get a clean 422 instead of a crash deep inside NumPy. Containerise with Docker and this deploys anywhere.

Step 4: Monitor, Because Models Rot

  • System metrics — latency, error rate, throughput (same as any service).
  • Data drift — log incoming features; alert when their distribution shifts from training (a price model trained pre-inflation quietly goes stale).
  • Outcome metrics — when true labels arrive later (did the user churn?), join them back and track live accuracy.

Log every prediction with its inputs and model version — that log is both your debugging tool and your next training set.

Step 5: Retrain on a Schedule, Not a Panic

Automate: pull fresh data → retrain pipeline → evaluate against the current model on a held-out window → promote only if better → keep the old artefact for instant rollback. Tools like MLflow track experiments and model registries; start simple with a cron job and a metrics table.

Series Wrap-Up

You can now frame ML problems, build and evaluate models honestly, beat overfitting, train neural networks, and ship the result behind an API. The best next step: pick a real dataset you care about and run the entire workflow end to end — nothing teaches like shipping.