C3 - building a complete pipeline

src/
├── preprocess.py
├── train.py
└── evaluate.py
PREPROCESS COMPONENT

Input:
    raw_data

Output:
    clean_data
preprocess_component = command(
    name="preprocess",
    code="./src",
    command="""
        python preprocess.py
        --raw-data ${{inputs.raw_data}}
        --clean-data ${{outputs.clean_data}}
    """,
    inputs={
        "raw_data": Input(...)
    },
    outputs={
        "clean_data": Output(...)
    },
    environment="azureml:preprocess-env:3"
)
TRAIN COMPONENT

Inputs:
    clean_data
    max_depth
    learning_rate
    n_estimators

Output:
    model

EVALUATE COMPONENT

Inputs:
    model
    test_data

Outputs:
    metrics
@pipeline()
def detector_training_pipeline(raw_data):

    prep = preprocess_component(
        raw_data=raw_data
    )

    train = training_component(
        clean_data=prep.outputs.clean_data
    )

    evaluate = evaluation_component(
        model=train.outputs.model
    )
PIPELINE

Inputs:
├── raw_training_data
├── test_data
├── min_f1
└── min_recall
raw_training_data
       │
       ▼
   PREPROCESS

test_data ───────────────┐
	                      EVALUATE

min_f1  ────────────────┐
min_recall ──────────────┤
                    QUALITY GATE
mlflow.log_metric("f1", f1)
TRAINING DATA
     ↓
SWEEP
     │
uses validation information
     ↓
BEST CONFIGURATION
     ↓
FINAL EVALUATION
     │
uses held-out test data
     ↓
production decision
pipeline_job = detector_training_pipeline(...)

ml_client.jobs.create_or_update(pipeline_job)
PIPELINE JOB 872
│
├── preprocess job
├── sweep job
│   ├── trial job 1
│   ├── trial job 2
│   └── ...
├── evaluation job
└── registration step
GitHub Actions
      ↓
authenticate with Entra
      ↓
Azure CLI / SDK
      ↓
submit pipeline
      ↓
Azure ML
      ↓
PREPROCESS
      ↓
SWEEP
      ↓
EVALUATE
      ↓
QUALITY GATE
      ↓
REGISTER