Skip to content

End-to-End ML Workflow: Train → Deploy → Test

Date: 2025-11-08
Status: ✅ Complete
Notebook: https://github.com/tosin2013/jupyter-notebook-validator-test-notebooks/blob/main/model-training/train-sentiment-model.ipynb


Overview

The training notebook now supports a complete end-to-end ML workflow in a single notebook:

  1. Train - Train sentiment analysis model
  2. Save - Persist model artifacts
  3. Deploy - Automatically deploy to KServe/OpenShift AI
  4. Test - Validate deployed model using model discovery

This eliminates manual steps and creates a fully automated ML pipeline!

Workflow Steps

Step 1-6: Training (Always Executed)

These steps always run: 1. Create training data 2. Prepare data (train/test split, vectorization) 3. Train model (Logistic Regression) 4. Evaluate model (accuracy, classification report) 5. Save model (model.pkl, vectorizer.pkl, metadata.json) 6. Test saved model (verify it loads and works)

Step 7: Deploy Model (Optional)

Controlled by: DEPLOY_MODEL environment variable

When enabled (DEPLOY_MODEL=true): - Checks if running in Kubernetes - Creates InferenceService manifest - Deploys model to KServe/OpenShift AI - Configures resources, runtime, storage URI - Adds labels for tracking

InferenceService created:

apiVersion: serving.kserve.io/v1beta1
kind: InferenceService
metadata:
  name: trained-sentiment-model  # from MODEL_NAME
  namespace: mlops  # from NAMESPACE
  labels:
    trained-by: jupyter-notebook-validator
    model-type: sklearn
    training-notebook: train-sentiment-model
spec:
  predictor:
    model:
      modelFormat:
        name: sklearn
        version: "1"
      runtime: mlserver-sklearn
      storageUri: pvc://model-storage/sentiment-model  # from MODEL_STORAGE_URI

Step 8: Test Deployed Model (Optional)

Controlled by: DEPLOY_MODEL environment variable

When enabled: - Uses model_discovery.py library - Discovers deployed model - Waits for model to be Ready - Makes test predictions - Validates responses

Environment Variables

Training Variables (Always Used)

Variable Default Description
TRAINING_MODE true Enable training mode
MODEL_OUTPUT_DIR /tmp/sentiment-model Where to save model files
TRAINING_SAMPLES 20 Number of training samples

Deployment Variables (Optional)

Variable Default Description
DEPLOY_MODEL false Enable automatic deployment
NAMESPACE mlops Target Kubernetes namespace
MODEL_NAME trained-sentiment-model Name for InferenceService
MODEL_STORAGE_URI pvc://model-storage/sentiment-model Model storage location

Usage Examples

Example 1: Training Only (No Deployment)

apiVersion: mlops.mlops.dev/v1alpha1
kind: NotebookValidationJob
metadata:
  name: train-sentiment-model
  namespace: mlops
spec:
  notebook:
    git:
      url: https://github.com/tosin2013/jupyter-notebook-validator-test-notebooks.git
      ref: main
    path: model-training/train-sentiment-model.ipynb

  podConfig:
    containerImage: quay.io/jupyter/scipy-notebook:latest
    serviceAccountName: model-validator-sa
    env:
      - name: DEPLOY_MODEL
        value: "false"  # Deployment disabled

Result: - ✅ Model trained - ✅ Model saved to /tmp/sentiment-model/ - ⏭️ Deployment skipped - ⏭️ Testing skipped

Example 2: Training + Deployment

apiVersion: mlops.mlops.dev/v1alpha1
kind: NotebookValidationJob
metadata:
  name: train-and-deploy-sentiment
  namespace: mlops
spec:
  notebook:
    git:
      url: https://github.com/tosin2013/jupyter-notebook-validator-test-notebooks.git
      ref: main
    path: model-training/train-sentiment-model.ipynb

  podConfig:
    containerImage: quay.io/jupyter/scipy-notebook:latest
    serviceAccountName: model-validator-sa
    env:
      - name: DEPLOY_MODEL
        value: "true"  # Deployment enabled!
      - name: NAMESPACE
        value: "mlops"
      - name: MODEL_NAME
        value: "trained-sentiment-model"
      - name: MODEL_STORAGE_URI
        value: "pvc://model-storage/sentiment-model"

Result: - ✅ Model trained - ✅ Model saved to /tmp/sentiment-model/ - ✅ InferenceService created - ✅ Model discovered and tested

Example 3: Training + S3 Deployment

apiVersion: mlops.mlops.dev/v1alpha1
kind: NotebookValidationJob
metadata:
  name: train-deploy-s3
  namespace: mlops
spec:
  notebook:
    git:
      url: https://github.com/tosin2013/jupyter-notebook-validator-test-notebooks.git
      ref: main
    path: model-training/train-sentiment-model.ipynb

  podConfig:
    containerImage: quay.io/jupyter/scipy-notebook:latest
    serviceAccountName: model-validator-sa
    env:
      # AWS credentials (from ESO)
      - name: AWS_ACCESS_KEY_ID
        valueFrom:
          secretKeyRef:
            name: aws-credentials
            key: access-key-id
      - name: AWS_SECRET_ACCESS_KEY
        valueFrom:
          secretKeyRef:
            name: aws-credentials
            key: secret-access-key

      # Deployment with S3
      - name: DEPLOY_MODEL
        value: "true"
      - name: MODEL_STORAGE_URI
        value: "s3://my-bucket/models/sentiment-v1/"

Complete Workflow Commands

1. Train and Deploy

# Apply training + deployment job
oc apply -f config/samples/model-training-with-deployment.yaml

# Watch progress
oc get notebookvalidationjob train-and-deploy-sentiment -n mlops -w

# Check logs
oc logs -n mlops -l job-name=train-and-deploy-sentiment-validation -f

2. Verify Deployment

# Check InferenceService
oc get inferenceservice trained-sentiment-model -n mlops

# Wait for Ready
oc wait --for=condition=Ready inferenceservice/trained-sentiment-model -n mlops --timeout=5m

# Get endpoint
oc get inferenceservice trained-sentiment-model -n mlops -o jsonpath='{.status.url}'

3. Test Deployed Model

# Get model URL
MODEL_URL=$(oc get inferenceservice trained-sentiment-model -n mlops -o jsonpath='{.status.url}')

# Test prediction
curl -X POST $MODEL_URL/v1/models/:predict \
  -H "Content-Type: application/json" \
  -d '{"instances": [[0.1, 0.2, 0.3, 0.4]]}'

Architecture Benefits

1. Single Notebook Workflow

  • No manual steps - Everything automated
  • Reproducible - Same notebook, same results
  • Version controlled - Notebook in Git
  • Testable - Operator validates execution

2. Flexible Deployment

  • Optional - Can train without deploying
  • Configurable - Environment variables control behavior
  • Multiple storage - Supports PVC, S3, GCS
  • Graceful fallback - Continues if deployment fails

3. Integration with Model Discovery

  • Dynamic discovery - No hardcoded endpoints
  • Health checking - Validates model is Ready
  • Automatic testing - Tests deployed model
  • Library reuse - Uses model_discovery.py

4. Production Ready

  • Resource management - Configurable CPU/memory
  • RBAC - Proper permissions for deployment
  • Labeling - Tracks training source
  • Error handling - Graceful failure modes

Files Created/Updated

In Operator Repository

  • test/generate-test-notebooks.py - Updated with deployment steps
  • config/samples/model-training-job.yaml - Training only (DEPLOY_MODEL=false)
  • config/samples/model-training-with-deployment.yaml - Training + deployment (DEPLOY_MODEL=true)
  • docs/tutorials/END_TO_END_ML_WORKFLOW.md - This document

In Test Notebooks Repository

  • model-training/train-sentiment-model.ipynb - Updated with Steps 7-8
  • Step 7: Deploy Model (Optional)
  • Step 8: Test Deployed Model (Optional)

Comparison: Before vs After

Before (Manual Process)

  1. Run training notebook
  2. Extract model from pod: oc cp ...
  3. Upload to S3: aws s3 cp ...
  4. Create InferenceService YAML
  5. Apply manifest: oc apply -f ...
  6. Wait for Ready: oc wait ...
  7. Get endpoint: oc get ...
  8. Test manually: curl ...

Total: 8 manual steps, error-prone

After (Automated Process)

  1. Set DEPLOY_MODEL=true
  2. Run notebook

Total: 2 steps, fully automated! 🎉

Next Steps

Immediate

  1. ✅ Training notebook with deployment created
  2. ✅ NotebookValidationJob configurations created
  3. ✅ Documentation completed
  4. 📝 Test end-to-end workflow on OpenShift
  5. 📝 Validate deployed model works

Future Enhancements

  1. Model Registry Integration
  2. Register models in MLflow
  3. Track model versions
  4. Compare model performance

  5. Advanced Deployment

  6. Canary deployments
  7. A/B testing
  8. Traffic splitting

  9. Monitoring

  10. Model performance metrics
  11. Prediction logging
  12. Drift detection

  13. CI/CD Integration

  14. Automated retraining
  15. Model promotion
  16. Rollback capabilities

Summary

Complete End-to-End Workflow - Train → Deploy → Test in one notebook
Flexible Configuration - Optional deployment via environment variables
Model Discovery Integration - Automatic testing of deployed models
Production Ready - Proper RBAC, resources, error handling
Fully Automated - No manual extraction or deployment steps

Status: Ready for testing! The complete workflow is now available at: https://github.com/tosin2013/jupyter-notebook-validator-test-notebooks/blob/main/model-training/train-sentiment-model.ipynb

Next Action: Test the complete workflow with DEPLOY_MODEL=true!