Contents

Chapter 1

Getting Started

Prerequisites

  • Python 3.10+
  • pip

Installation

bash
pip install -r requirements.txt

Your First Pipeline Run

Run the included classification pipeline:

bash
python -m src.pipeline_runner --config pipelines/classification_pipeline.yaml --verbose

This will:

1. Generate a demo dataset (2000 rows with age, income, region, etc.)

2. Apply feature engineering (scaling, encoding, imputation)

3. Train a Random Forest classifier

4. Evaluate with accuracy, F1, and AUC threshold gates

5. Attempt a canary deployment (dry-run — no actual infrastructure)

6. Save all artifacts to ./artifacts//

Inspect the Output

After the run completes, check:

  • ./artifacts//run_summary.json — full run metadata
  • ./artifacts//snapshot.json — reproducibility snapshot

Customize for Your Data

1. Copy pipelines/classification_pipeline.yaml to pipelines/my_pipeline.yaml

2. Update the feature_engineering stage to match your columns

3. Adjust the training hyperparameters

4. Set meaningful threshold_gates in the evaluation stage

5. Configure your deployment endpoint in the deployment stage

Adding Custom Stages

Create a function with this signature and register it:

python
from src.pipeline_runner import register_stage

def my_custom_stage(params: dict, context: dict) -> dict:
    # Do your work here
    result = {"my_output": "some_value"}
    return result

register_stage("my_custom_stage", my_custom_stage)

Then reference it in your pipeline YAML:

yaml
stages:
  - name: my_custom_stage
    depends_on: [feature_engineering]
    params:
      my_param: my_value
Chapter 2

Pipeline Patterns

Architectural patterns and best practices for building ML pipelines with this framework.

Pattern 1: Fan-Out / Fan-In

Train multiple models in parallel, pick the best one:

yaml
stages:
  - name: feature_engineering
    depends_on: []
  - name: train_rf
    depends_on: [feature_engineering]
    params:
      framework: sklearn
      model_type: random_forest
  - name: train_gb
    depends_on: [feature_engineering]
    params:
      framework: sklearn
      model_type: gradient_boosting
  - name: model_selection
    depends_on: [train_rf, train_gb]

The DAG runner executes train_rf and train_gb in parallel (same wave), then model_selection runs after both complete.

Pattern 2: Champion/Challenger

Compare new model against the current production model:

yaml
stages:
  - name: training
    depends_on: [feature_engineering]
  - name: evaluation
    depends_on: [training]
    params:
      comparison_run_path: ./artifacts/production_baseline/eval_results.json
      threshold_gates:
        accuracy: 0.85

The evaluation stage loads the baseline metrics and computes deltas, so you can see exactly how the new model compares.

Pattern 3: Staged Rollout

Deploy to staging first, then production:

yaml
stages:
  - name: deploy_staging
    depends_on: [evaluation]
    params:
      strategy: blue_green
      endpoint_url: https://staging.example.com/v1/models/churn
  - name: deploy_production
    depends_on: [deploy_staging]
    params:
      strategy: canary
      canary_percentage: 5
      endpoint_url: https://api.example.com/v1/models/churn

Pattern 4: Feature Store Integration

Load features from your feature store instead of raw data:

python
from src.pipeline_runner import register_stage

def load_from_feature_store(params, context):
    # Your feature store client here
    import pandas as pd
    entity_df = pd.read_csv(params["entity_source"])
    # features = feast_client.get_historical_features(...)
    return {"dataframe": entity_df}

register_stage("load_features", load_from_feature_store)

Use environment overrides for grid search in CI:

bash
for lr in 0.01 0.05 0.1; do
  for depth in 4 6 8; do
    MLOPS_PIPELINE__STAGES__1__PARAMS__HYPERPARAMETERS__LEARNING_RATE=$lr \
    MLOPS_PIPELINE__STAGES__1__PARAMS__HYPERPARAMETERS__MAX_DEPTH=$depth \
    python -m src.pipeline_runner --config pipelines/regression_pipeline.yaml
  done
done

Each run gets its own run_id and snapshot, so you can compare results after.

Anti-Patterns to Avoid

Anti-PatternWhy It's BadWhat to Do Instead
Hardcoded file pathsBreaks in CI, other machinesUse config params
No threshold gatesBad models reach productionAlways set minimum thresholds
Skipping reproducibilityCan't debug regressionsAlways capture snapshots
One giant stageCan't retry/parallelizeBreak into focused stages
No artifact versioningOverwrite previous resultsUse run_id-based paths
MLOps Pipeline Templates v1.0.0 — Free Preview