What is MLOps?

MLOps (Machine Learning Operations) is the practice of deploying, monitoring, and maintaining machine learning models in production. It combines ML, DevOps, and data engineering to make ML systems reliable, scalable, and reproducible.

A model in a Jupyter notebook isn't delivering value. MLOps bridges the gap between data science and production systems.

The ML Lifecycle

  • Data Collection & Preparation: ETL pipelines, data validation
  • Feature Engineering: Feature stores, transformation pipelines
  • Model Training: Experiment tracking, hyperparameter tuning
  • Model Evaluation: Metrics, validation, testing
  • Deployment: Model serving, API development
  • Monitoring: Performance tracking, drift detection
  • Retraining: Continuous improvement loops

Experiment Tracking with MLflow

import mlflow
import mlflow.sklearn
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, f1_score

# Start MLflow experiment
mlflow.set_experiment("customer_churn")

with mlflow.start_run(run_name="random_forest_v1"):
    # Log parameters
    params = {"n_estimators": 100, "max_depth": 10, "random_state": 42}
    mlflow.log_params(params)

    # Train model
    model = RandomForestClassifier(**params)
    model.fit(X_train, y_train)

    # Evaluate
    predictions = model.predict(X_test)
    accuracy = accuracy_score(y_test, predictions)
    f1 = f1_score(y_test, predictions)

    # Log metrics
    mlflow.log_metrics({"accuracy": accuracy, "f1_score": f1})

    # Log model
    mlflow.sklearn.log_model(model, "model")

    # Log artifacts (plots, data)
    mlflow.log_artifact("confusion_matrix.png")

# View results: mlflow ui

Model Serving with FastAPI

# app.py
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import joblib
import numpy as np

app = FastAPI(title="ML Model API")

# Load model at startup
model = joblib.load("model.pkl")
scaler = joblib.load("scaler.pkl")

class PredictionInput(BaseModel):
    features: list[float]

class PredictionOutput(BaseModel):
    prediction: int
    probability: float

@app.post("/predict", response_model=PredictionOutput)
def predict(input_data: PredictionInput):
    try:
        # Preprocess
        features = np.array(input_data.features).reshape(1, -1)
        features_scaled = scaler.transform(features)

        # Predict
        prediction = model.predict(features_scaled)[0]
        probability = model.predict_proba(features_scaled)[0].max()

        return PredictionOutput(
            prediction=int(prediction),
            probability=float(probability)
        )
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

@app.get("/health")
def health_check():
    return {"status": "healthy"}

# Run: uvicorn app:app --host 0.0.0.0 --port 8000

Containerization with Docker

# Dockerfile
FROM python:3.10-slim

WORKDIR /app

# Install dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copy application
COPY app.py .
COPY model.pkl .
COPY scaler.pkl .

# Expose port
EXPOSE 8000

# Run server
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"]

# Build and run:
# docker build -t ml-api .
# docker run -p 8000:8000 ml-api

Model Monitoring

import pandas as pd
from scipy import stats

def detect_data_drift(reference_data, production_data, threshold=0.05):
    """Detect drift using KS test for numerical features"""
    drift_report = {}

    for column in reference_data.columns:
        if reference_data[column].dtype in ['float64', 'int64']:
            stat, p_value = stats.ks_2samp(
                reference_data[column],
                production_data[column]
            )
            drift_report[column] = {
                'statistic': stat,
                'p_value': p_value,
                'drift_detected': p_value < threshold
            }

    return drift_report

# Monitor prediction distribution
def monitor_predictions(predictions, expected_distribution):
    """Compare prediction distribution to expected"""
    actual_dist = pd.Series(predictions).value_counts(normalize=True)
    # Alert if distribution shifts significantly
    pass

# Log metrics to monitoring system
def log_inference_metrics(prediction_time, input_features, output):
    # Log to Prometheus, CloudWatch, etc.
    pass

CI/CD for ML

# .github/workflows/ml-pipeline.yml
name: ML Pipeline

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '3.10'
      - name: Install dependencies
        run: pip install -r requirements.txt
      - name: Run tests
        run: pytest tests/
      - name: Run model validation
        run: python scripts/validate_model.py

  deploy:
    needs: test
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    steps:
      - name: Deploy to production
        run: |
          # Deploy updated model
          echo "Deploying..."

Best Practices

  • Version everything: Code, data, models, and configs
  • Automate testing: Unit tests, integration tests, model validation
  • Monitor continuously: Track performance, data drift, and system health
  • Use feature stores: Centralize feature computation and serving
  • Implement rollback: Quickly revert to previous model versions
  • Document everything: Model cards, API docs, runbooks

Master MLOps with Expert Mentorship

Our Data Science program covers MLOps from experiment tracking to production deployment. Deploy real models with guidance from industry experts.

Explore Data Science Program

Related Articles