ML Pipeline Architecture
A Jupyter Notebook is not software. An ML Pipeline turns a messy, manual research script into a repeatable, automated factory that ingests data and produces deployable models.
Why Does This Exist?
In the beginning, a Data Scientist writes a Jupyter Notebook. They download a CSV, clean the null values, train an XGBoost model, print the accuracy, and save the model file to their desktop.
This works for a hackathon, but it is a disaster for a company. What happens next month when the data changes and the model needs retraining? Does the Data Scientist just run the notebook again? What if they left the company? What if the notebook only runs on their specific laptop because of a weird dependency?
An ML Pipeline solves this by converting the machine learning process from a manual craft into an automated factory. It breaks the notebook into distinct, repeatable code steps that run on a schedule in the cloud.
Think of It Like This
Think of It Like This
Imagine a master chef baking a cake. They taste the batter, add a little extra sugar intuitively, and bake it until it "looks right." That is a Jupyter Notebook. It produces a great cake once, but nobody else can replicate it.
Now imagine a commercial bakery. There are separate, automated stations: Station 1 measures exact flour. Station 2 mixes for exactly 4 minutes. Station 3 bakes at exactly 350°F. If the cake comes out bad, you know exactly which station failed. That is an ML Pipeline.
How It Actually Works
An ML Pipeline is structurally a Directed Acyclic Graph (DAG). It is a sequence of isolated scripts (Nodes) connected by data dependencies (Edges). It typically consists of 5 core stages:
1. Data Ingestion
The pipeline wakes up (e.g., triggered by a cron job every Sunday at midnight). It reaches into the data warehouse (Snowflake, BigQuery), runs a SQL query to pull the last 30 days of user behavior, and saves it to cloud storage (S3).
2. Feature Engineering & Preprocessing
The pipeline reads the raw data from S3. It imputes missing values, normalizes numerical columns, and one-hot encodes categorical variables. Crucially, it saves these preprocessing parameters (like the mean and variance used for scaling) so they can be reused at inference time.
3. Model Training
The pipeline spins up a GPU machine. It downloads the preprocessed data and trains the model (e.g., a PyTorch network). It tracks hyperparameters and loss curves using an Experiment Tracker (like MLflow or Weights & Biases).
4. Model Evaluation
Before anyone uses the model, the pipeline tests it against a holdout validation set. It calculates metrics (Accuracy, F1-Score, RMSE). If the new model performs worse than the model currently in production, the pipeline halts immediately.
5. Model Registration
If the model passes evaluation, the pipeline packages the model weights, the preprocessing parameters, and the dependencies into a single artifact and uploads it to a Model Registry. It is now ready for deployment.
Show Me the Code
In modern ML engineering, pipelines are written using orchestration frameworks like Airflow, Kubeflow, or Prefect. Here is a conceptual example using a Python-based orchestrator (similar to Prefect).
from prefect import task, flowimport pandas as pd
# Define the isolated steps (Tasks)@taskdef extract_data(): return pd.read_csv("s3://bucket/raw_data.csv")
@taskdef clean_data(df): return df.fillna(0)
@taskdef train_model(df): from sklearn.ensemble import RandomForestClassifier model = RandomForestClassifier().fit(df[['X']], df['y']) return model
@taskdef evaluate_and_register(model, df): score = model.score(df[['X']], df['y']) if score > 0.85: print(f"Model passed with {score}. Registering!") # mlflow.register_model(...) else: raise ValueError("Model degraded. Halting pipeline.")
# Define the DAG (Flow)@flow(name="Weekly-Churn-Model-Pipeline")def ml_pipeline(): # The pipeline logic explicitly defines the Directed Acyclic Graph (DAG) raw_data = extract_data() clean_data = clean_data(raw_data) model = train_model(clean_data) evaluate_and_register(model, clean_data)
# Run the pipelineif __name__ == "__main__": ml_pipeline()Watch Out For
Watch Out For
The "Hidden State" Trap. The most common mistake when converting a notebook to a pipeline is leaving "hidden state." In a notebook, if you run Cell 4, then Cell 2, then Cell 5, your model depends on that exact, invisible execution order. In a pipeline, every single step must be perfectly isolated and stateless. A step should only know about the data passed directly into it via its function arguments.
The Quick Version
- A Jupyter Notebook is manual and unrepeatable. An ML Pipeline is automated and repeatable.
- Pipelines are modeled as DAGs (Directed Acyclic Graphs) running on orchestrators like Airflow or Kubeflow.
- The standard pipeline stages are: Ingest Preprocess Train Evaluate Register.
- If a pipeline fails at the Evaluation stage, it halts to prevent a degraded model from reaching production.
What to Read Next
experiment-tracking— How step 3 (Training) logs its metrics and hyperparameters to a central dashboard.model-registry— Where step 5 (Registration) actually puts the final model artifact.cicd-for-ml— How software engineering practices (like GitHub Actions) are used to trigger these pipelines automatically.