Skip to content
MLOpsJanuary 22, 20266 min read

MLOps in 2026: Taking ML Models From Jupyter Notebook to Production

Most ML projects stall at the notebook stage not because the model is bad but because the infrastructure to serve, monitor, and retrain it does not exist. Here is how to build it.

The model works in the notebook. It has good metrics on the validation set. The data scientists are confident. And then it sits there for three months because nobody knows how to put it into production.

This is the most common failure mode in enterprise ML projects. The gap between a working Jupyter notebook and a reliable production ML service is not a modelling problem - it is an infrastructure problem.

Here is what that infrastructure looks like in practice.

Why Notebooks Are Not Production

A Jupyter notebook is a great research tool. It is not a deployment artifact.

The problems with shipping notebook code directly:

  • No versioning of inputs: the model was trained on data that may change. If the data pipeline changes, you cannot reproduce the model.
  • No dependency management: the notebook runs on a specific machine with specific package versions. Reproducing that environment is manual.
  • No serving infrastructure: notebooks produce a model file. Something has to load that file and serve predictions via an API.
  • No monitoring: you cannot tell if model performance is degrading on live traffic.
  • No retraining trigger: when do you retrain? On a schedule? When accuracy drops? There is no mechanism.

The goal of MLOps is to solve all of these systematically.

The Core MLOps Stack

A production ML system needs these components:

1. Feature Store

Features used in training must be the same features available at inference time. Without a feature store, you get training-serving skew - the model trained on one representation of the data but serves predictions against a different one. This silently degrades model quality.

Tools: Feast (open source), AWS SageMaker Feature Store, Tecton

For most startups, a simple pattern works: compute features as SQL transformations in a data warehouse, materialize them to a feature table, and use that table for both training and online serving. A full feature store is overkill until you have 20+ features or multiple models sharing features.

2. Experiment Tracking

Every training run should log: the dataset version used, hyperparameters, metrics, and the model artifact. Without this, you cannot compare experiments, reproduce a model, or explain why Model v3 was better than Model v2.

Tools: MLflow (self-hosted or managed), Weights & Biases, Neptune

MLflow is the most common choice - open source, simple to self-host on Kubernetes, and has wide framework support (sklearn, PyTorch, TensorFlow, XGBoost).

python
import mlflow with mlflow.start_run(): mlflow.log_param("learning_rate", 0.01) mlflow.log_param("max_depth", 6) mlflow.log_metric("accuracy", 0.94) mlflow.log_metric("f1", 0.91) mlflow.sklearn.log_model(model, "model")

3. Model Registry

The model registry is where trained models are stored, versioned, and promoted through stages (Staging → Production → Archived). It answers the question: "which model artifact is currently serving production traffic?"

MLflow has a built-in model registry. For teams on AWS, SageMaker Model Registry integrates naturally with SageMaker deployment.

4. Model Serving

A trained model needs to be loaded and exposed as an API endpoint. The serving layer handles batching, scaling, and latency requirements.

Options:

  • BentoML - framework-agnostic, good developer experience, deploys to Kubernetes
  • Triton Inference Server - high-performance, designed for GPU serving, complex to configure
  • AWS SageMaker Endpoints - managed, auto-scaling, but vendor-locked and expensive at scale
  • FastAPI + custom container - simple for low-traffic models, requires you to build the scaling layer

For most production ML APIs serving under 1,000 requests/second, a FastAPI wrapper around a BentoML-packaged model on Kubernetes is a practical starting point.

5. Training Pipelines

Model training should be reproducible and automatable. A training pipeline defines the steps (data ingestion → preprocessing → training → evaluation → registration) as code.

Tools: Kubeflow Pipelines, Apache Airflow (with ML operators), Metaflow, ZenML

Kubeflow Pipelines is the most complete solution for teams already on Kubernetes. Each pipeline step runs as a container - reproducible, versioned, and parallelizable.

6. Model Monitoring

Models degrade in production because real-world data changes. A model trained 6 months ago on payment fraud patterns may miss new fraud patterns that emerged since training.

You need to monitor:

  • Data drift: has the distribution of input features changed?
  • Prediction drift: has the distribution of model outputs changed?
  • Outcome monitoring: when you can measure actual outcomes (a fraud prediction followed by a confirmed fraud), track model accuracy on live data

Tools: Evidently AI, WhyLogs, Arize

A Practical Path From Notebook to Production

If you are starting from a working notebook, here is the sequence:

Week 1–2: Packaging and serving

  • Refactor notebook code into a Python module with a clear train() and predict() function
  • Add MLflow experiment tracking
  • Containerize the serving logic with FastAPI
  • Deploy to Kubernetes behind an internal endpoint

Week 3–4: Pipeline automation

  • Build a training pipeline (Kubeflow or Airflow) that retrains on a schedule
  • Connect it to the model registry - new models are registered automatically, promoted manually
  • Add data validation checks before training starts

Week 5–6: Monitoring and retraining triggers

  • Deploy Evidently for drift detection on live predictions
  • Set up alerts when drift exceeds a threshold
  • Define the retraining policy: scheduled weekly, or triggered by drift detection

After six weeks, you have a system where: data scientists work in notebooks and MLflow tracks their experiments → the best experiment is registered in the model registry → the serving API pulls the registered model → monitoring detects degradation → retraining pipeline runs automatically or on alert.

Common Pitfalls

Overbuilding too early. You do not need Kubeflow Pipelines for one model. A scheduled script that runs python train.py and logs to MLflow is sufficient until you have multiple models or training pipelines that need dependencies between steps.

Ignoring feature consistency. Training-serving skew is the most common silent failure. Even if you do not implement a full feature store, make sure training features are computed with the same logic as serving features - ideally from the same code path.

No rollback mechanism. The model registry should store the previous production model. When a new model underperforms, rolling back should be a single command.


We build MLOps infrastructure for teams that have working models but cannot get them into production reliably. Book a free audit if you are stuck at the notebook stage.

RK
RKSSH LLP
DevOps Engineer · rkssh.com

I help funded startups fix their CI/CD pipelines and Kubernetes infrastructure. If this post was useful and you want to talk through your specific situation, book a free 30-minute audit.

Related Articles