Promuovere i flussi di lavoro in un ambiente multi-piattaforma utilizzando Amazon SageMaker Model Registry, HashiCorp Terraform, GitHub e Jenkins CI/CD

Come ottimizzare i flussi di lavoro multi-piattaforma con Amazon SageMaker Model Registry, HashiCorp Terraform, GitHub e Jenkins CI/CD

Costruire una piattaforma di operations di machine learning (MLOps) nel panorama in rapida evoluzione dell’intelligenza artificiale (AI) e del machine learning (ML) è essenziale per colmare in modo fluido il divario tra sperimentazione e distribuzione dei modelli di data science, rispettando nel contempo i requisiti di prestazioni del modello, sicurezza e conformità.

Al fine di soddisfare i requisiti normativi e di conformità, i principali requisiti durante la progettazione di una piattaforma di questo tipo sono:

  • Gestire gli scostamenti dei dati
  • Monitorare le prestazioni del modello
  • Facilitare il riaddestramento automatico del modello
  • Fornire un processo di approvazione del modello
  • Mantenere i modelli in un ambiente sicuro

In questo articolo, mostriamo come creare un framework di MLOps per affrontare queste esigenze utilizzando una combinazione di servizi AWS e strumenti di terze parti. La soluzione prevede una configurazione multi-ambiente con riaddestramento automatico dei modelli, inferenza batch e monitoraggio con Amazon SageMaker Model Monitor, versione del modello con SageMaker Model Registry e un flusso di lavoro di CI/CD per facilitare la promozione del codice e dei flussi di lavoro ML tra gli ambienti utilizzando Amazon SageMaker, Amazon EventBridge, Amazon Simple Notification Service (Amazon S3), HashiCorp Terraform, GitHub e Jenkins CI/CD. Costruiamo un modello per prevedere la gravità (benigna o maligna) di una lesione mammografica formata utilizzando l’algoritmo XGBoost utilizzando il dataset pubblicamente disponibile UCI Mammography Mass e lo distribuiamo utilizzando il framework di MLOps. Le istruzioni complete con il codice sono disponibili nel repository GitHub.

Panoramica della soluzione

Il diagramma di architettura seguente mostra una panoramica del framework di MLOps con i seguenti componenti chiave:

  • Strategia multi-accounts – Vengono configurati due diversi ambienti (dev e prod) in due diversi account AWS seguendo le migliori pratiche di AWS Well-Architected, e viene configurato un terzo account nel registro centrale dei modelli:
    • Ambiente dev – Dove viene configurato un dominio di Amazon SageMaker Studio per consentire lo sviluppo del modello, l’addestramento del modello e il test dei flussi di lavoro ML (train e inference), prima che il modello sia pronto per essere promosso negli ambienti superiori.
    • Ambiente prod – Dove i flussi di lavoro ML da dev sono promossi come primo passo, pianificati e monitorati nel tempo.
    • Registro centrale dei modelliAmazon SageMaker Model Registry viene configurato in un account AWS separato per tracciare le versioni dei modelli generate attraverso gli ambienti dev e prod.
  • CI/CD e controllo del codice sorgente – La distribuzione dei flussi di lavoro ML tra gli ambienti viene gestita attraverso CI/CD configurato con Jenkins, insieme al controllo delle versioni gestito tramite GitHub. Le modifiche al codice unite al ramo git dell’ambiente corrispondente avviano un flusso di lavoro CI/CD per apportare le modifiche appropriate all’ambiente di destinazione specificato.
  • Inferenza batch con monitoraggio del modello – Il flusso di lavoro di inferenza costruito con Amazon SageMaker Pipelines viene eseguito su base programmata per generare previsioni insieme al monitoraggio del modello utilizzando SageMaker Model Monitor per rilevare gli scostamenti dei dati.
  • Mecanismo di riaddestramento automatico – Il flusso di lavoro di addestramento costruito con SageMaker Pipelines viene attivato ogni volta che viene rilevato uno scostamento dei dati nel flusso di lavoro di inferenza. Dopo l’addestramento, il modello viene registrato nel registro centrale dei modelli per essere approvato da un approvatore del modello. Quando viene approvato, la versione del modello aggiornato viene utilizzata per generare previsioni attraverso il flusso di lavoro di inferenza.
  • Infrastruttura come codice – L’infrastruttura come codice (IaC), creata utilizzando HashiCorp Terraform, supporta la pianificazione del flusso di lavoro di inferenza con EventBridge, l’attivazione del flusso di lavoro di addestramento in base a una regola EventBridge e l’invio di notifiche utilizzando Amazon Simple Notification Service (Amazon SNS) topics.
architettura MLOps

Il processo MLOps include i seguenti passaggi:

  1. Accedere al dominio di SageMaker Studio nell’account di sviluppo, clonare il repository GitHub, seguire il processo di sviluppo del modello utilizzando il modello di esempio fornito e generare le pipeline di addestramento e inferenza.
  2. Eseguire la pipeline di addestramento nell’account di sviluppo, che genera gli artefatti del modello per la versione del modello addestrato e registra il modello nel Registro dei modelli di SageMaker nell’account del registro dei modelli centralizzato.
  3. Approvare il modello nel Registro dei modelli di SageMaker nell’account del registro dei modelli centralizzato.
  4. Pubblicare il codice (pipelines di addestramento e inferenza e il codice Terraform IaC per creare la pianificazione di EventBridge, la regola di EventBridge e l’argomento di SNS) in un ramo del repository GitHub. Creare una richiesta di pull per fondere il codice nel ramo principale del repository GitHub.
  5. Avviare la pipeline CI/CD Jenkins, che è configurata con il repository GitHub. La pipeline CI/CD distribuisce il codice nell’account di produzione per creare le pipeline di addestramento e inferenza insieme al codice Terraform per la creazione della pianificazione di EventBridge, la regola di EventBridge e l’argomento di SNS.
  6. La pipeline di inferenza è pianificata per essere eseguita quotidianamente, mentre la pipeline di addestramento è configurata per essere eseguita ogni volta che viene rilevata una variazione nei dati dalla pipeline di inferenza.
  7. Vengono inviate notifiche tramite l’argomento di SNS ogni volta che si verifica un errore con la pipeline di addestramento o di inferenza.

Prerequisiti

Per questa soluzione, è necessario avere i seguenti prerequisiti:

  • Tre account AWS (account di sviluppo, di produzione e account centrale del registro dei modelli)
  • Un dominio di SageMaker Studio configurato in ciascuno dei tre account AWS (vedi Accedi a Amazon SageMaker Studio o guarda il video Accedi rapidamente ad Amazon SageMaker Studio per istruzioni di configurazione)
  • Jenkins (utilizziamo Jenkins 2.401.1) con privilegi amministrativi installato su AWS
  • Versione 1.5.5 o successiva di Terraform installata sul server Jenkins

In questo post, lavoriamo nella regione us-east-1 per distribuire la soluzione.

Provisione delle chiavi KMS negli account di sviluppo e di produzione

Il nostro primo passaggio è creare le chiavi del servizio di gestione delle chiavi AWS (AWS KMS) negli account di sviluppo e di produzione.

Creare una chiave KMS nell’account di sviluppo e concedere accesso all’account di produzione

Seguire i seguenti passaggi per creare una chiave KMS nell’account di sviluppo:

  • Nella console di AWS KMS, scegliere Chiavi gestite dal cliente nel riquadro di navigazione.
  • Scegliere Crea una chiave.
  • Per il Tipo di chiave, selezionare Simmetrica.
  • Per l’Utilizzo della chiave, selezionare Crittografa e decrittografa.
  • Scegliere Avanti. configura chiave kms
  • Inserire il numero dell’account di produzione per concedere all’account di produzione l’accesso alla chiave KMS provisionata nell’account di sviluppo. Questo è un passaggio obbligatorio perché la prima volta che il modello viene addestrato nell’account di sviluppo, gli artefatti del modello vengono crittografati con la chiave KMS prima di essere scritti nel bucket S3 nell’account centrale del registro dei modelli. L’account di produzione ha bisogno dell’accesso alla chiave KMS per decrittografare gli artefatti del modello ed eseguire la pipeline di inferenza.
  • Scegliere Avanti e completare la creazione della chiave. completare la creazione della chiave

Dopo che la chiave è stata fornita, dovrebbe essere visibile sulla console AWS KMS.

chiave kms sulla console

Crea una chiave KMS nell’account prod

Seguire gli stessi passaggi nella sezione precedente per creare una chiave KMS gestita dal cliente nell’account prod. È possibile saltare il passaggio per condividere la chiave KMS con un altro account.

Imposta un bucket S3 per gli artefatti del modello nell’account centrale del registro modello

Crea un bucket S3 a tua scelta con la parola “sagemaker” nella convenzione di denominazione come parte del nome del bucket nell’account centrale del registro modello e aggiorna la policy del bucket S3 per concedere autorizzazioni sia agli account dev che prod per leggere e scrivere gli artefatti del modello nel bucket S3.

Il codice seguente rappresenta la policy del bucket da aggiornare:

{    "Version": "2012-10-17",    "Statement": [        {            "Sid": "AddPerm",            "Effect": "Allow",            "Principal": {                "AWS": "arn:aws:iam::<ID-account-dev>:root"            },            "Action": [                "s3:PutObject",                "s3:PutObjectAcl",                "s3:GetObject",                "s3:GetObjectVersion"            ],            "Resource": "arn:aws:s3:::<nome-bucket-s3-account-centrale>/*"        },        {            "Sid": "AddPerm1",            "Effect": "Allow",            "Principal": {                "AWS": "arn:aws:iam::<ID-account-dev>:root"            },            "Action": "s3:ListBucket",            "Resource": [                "arn:aws:s3:::<nome-bucket-s3-account-centrale>",                "arn:aws:s3:::<nome-bucket-s3-account-centrale>/*"            ]        },        {            "Sid": "AddPerm2",            "Effect": "Allow",            "Principal": {                "AWS": "arn:aws:iam::<ID-account-prod>:root"            },            "Action": [                "s3:PutObject",                "s3:PutObjectAcl",                "s3:GetObject",                "s3:GetObjectVersion"            ],            "Resource": "arn:aws:s3:::<nome-bucket-s3-account-centrale>/*"        },        {            "Sid": "AddPerm3",            "Effect": "Allow",            "Principal": {                "AWS": "arn:aws:iam::<ID-account-prod>:root"            },            "Action": "s3:ListBucket",            "Resource": [                "arn:aws:s3:::<nome-bucket-s3-account-centrale>",                "arn:aws:s3:::<nome-bucket-s3-account-centrale>/*"            ]        }    ]}

Imposta i ruoli IAM nei tuoi account AWS

Il passaggio successivo consiste nell’installare AWS Identity and Access Management (IAM) nei tuoi account AWS con le autorizzazioni per AWS Lambda, SageMaker e Jenkins.

Ruolo di esecuzione Lambda

Imposta ruoli di esecuzione Lambda negli account dev e prod, che verranno utilizzati dalla funzione Lambda eseguita come parte del passaggio Lambda delle SageMaker pipelines. Questo passaggio viene eseguito dal pipeline di inferenza per recuperare il modello approvato più recente, che viene utilizzato per generare le inferenze. Crea ruoli IAM negli account dev e prod con la seguente convenzione di denominazione arn:aws:iam::<ID-account>:role/lambda-sagemaker-role e collega le seguenti policy IAM:

  • Policy 1 – Crea una policy inline chiamata cross-account-model-registry-access, che fornisce accesso al pacchetto del modello configurato nel registro dei modelli nel conto centrale:

    { "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": "sagemaker:ListModelPackages", "Resource": "arn:aws:sagemaker:us-east-1:<central-model-registry-account-id>:model-package/mammo-severity-model-package/*" }, { "Sid": "VisualEditor1", "Effect": "Allow", "Action": "sagemaker:DescribeModelPackageGroup", "Resource": "arn:aws:sagemaker:us-east-1:<central-model-registry-account-id>:model-package-group/mammo-severity-model-package" } ]}
  • Policy 2 – Collega AmazonSageMakerFullAccess, che è una policy gestita da AWS che concede accesso completo a SageMaker. Fornisce inoltre accesso selezionato a servizi correlati, come AWS Application Auto Scaling, Amazon S3, Amazon Elastic Container Registry (Amazon ECR) e Amazon CloudWatch Logs.

  • Policy 3 – Collega AWSLambda_FullAccess, che è una policy gestita da AWS che concede accesso completo a Lambda, alle funzionalità della console di Lambda e ad altri servizi correlati di AWS.

  • Policy 4 – Utilizza la seguente policy di fiducia IAM per il ruolo IAM:

    { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": [ "lambda.amazonaws.com", "sagemaker.amazonaws.com" ] }, "Action": "sts:AssumeRole" } ]}

Ruolo di esecuzione di SageMaker

I domini di SageMaker Studio configurati nei conti dev e prod devono avere ciascuno un ruolo di esecuzione associato, che può essere trovato nella scheda Impostazioni del dominio nella pagina dei dettagli del dominio, come mostrato nello screenshot seguente. Questo ruolo viene utilizzato per eseguire lavori di addestramento, lavori di elaborazione e altro all’interno del dominio di SageMaker Studio.

sagemaker studio domain

Aggiungi le seguenti policy al ruolo di esecuzione di SageMaker in entrambi i conti:

  • Policy 1 – Crea una policy inline chiamata cross-account-model-artifacts-s3-bucket-access, che fornisce accesso al bucket S3 nel conto centrale del registro dei modelli, in cui sono archiviati gli artefatti del modello:

    { "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "s3:PutObject", "s3:GetObject", "s3:GetObjectVersion" ], "Resource": "arn:aws:s3:::<s3-bucket-in-central-model-registry-account>/*" }, { "Sid": "VisualEditor1", "Effect": "Allow", "Action": [ "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::<s3-bucket-in-central-model-registry-account>", "arn:aws:s3:::<s3-bucket-in-central-model-registry-account>/*" ] } ]}
  • Policy 2 – Crea una policy inline chiamata cross-account-model-registry-access, che fornisce accesso al pacchetto del modello nel registro dei modelli nel conto centrale del registro dei modelli:

    { "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": "sagemaker:CreateModelPackageGroup", "Resource": "arn:aws:sagemaker:us-east-1:<central-model-registry-account-id>:model-package-group/mammo-severity-model-package" } ]}
  • Policy 3 – Crea una policy inline chiamata kms-key-access-policy, che fornisce accesso alla chiave KMS creata nel passaggio precedente. Fornire l’ID dell’account in cui viene creata la policy e l’ID della chiave KMS creata in tale account.

    { "Version": "2012-10-17", "Statement": [ { "Sid": "AllowUseOfKeyInThisAccount", "Effect": "Allow", "Action": [ "kms:Encrypt", "kms:Decrypt", "kms:ReEncrypt*", "kms:GenerateDataKey*", "kms:DescribeKey" ], "Resource": "arn:aws:kms:us-east-1:<account-id>:key/<kms-key-id>" } ]}
  • Policy 4 – Collega AmazonSageMakerFullAccess, che è una policy gestita da AWS che concede accesso completo a SageMaker e accesso selezionato a servizi correlati.

  • Policy 5 – Collega AWSLambda_FullAccess, che è una policy gestita da AWS che concede accesso completo a Lambda, alle funzionalità della console di Lambda e ad altri servizi correlati di AWS.

  • Policy 6 – Collega CloudWatchEventsFullAccess, che è una policy gestita da AWS che concede accesso completo a CloudWatch Events.

  • Policy 7 – Aggiungi la seguente policy di fiducia IAM per il ruolo IAM di esecuzione di SageMaker:

    { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": [ "events.amazonaws.com", "sagemaker.amazonaws.com" ] }, "Action": "sts:AssumeRole" } ]}
  • Policy 8 (specifica per il ruolo di esecuzione di SageMaker nel conto prod) – Crea una policy inline chiamata cross-account-kms-key-access-policy, che fornisce accesso alla chiave KMS creata nel conto dev. Questo è necessario affinché il flusso di inferenza possa leggere gli artefatti del modello archiviati nel conto centrale del registro dei modelli, dove gli artefatti del modello vengono crittografati utilizzando la chiave KMS dal conto dev quando la prima versione del modello viene creata dal conto dev.

    { "Version": "2012-10-17", "Statement": [ { "Sid": "AllowUseOfKeyInDevAccount", "Effect": "Allow", "Action": [ "kms:Encrypt", "kms:Decrypt", "kms:ReEncrypt*", "kms:GenerateDataKey*", "kms:DescribeKey" ], "Resource": "arn:aws:kms:us-east-1:<dev-account-id>:key/<dev-kms-key-id

    Ruolo Jenkins inter-account

    Configurare un ruolo IAM chiamato cross-account-jenkins-role nell'account di produzione, che Jenkins assumerà per distribuire le pipeline dell'apprendimento automatico e l'infrastruttura corrispondente nell'account di produzione.

    Aggiungere le seguenti politiche gestite IAM al ruolo:

    • CloudWatchFullAccess
    • AmazonS3FullAccess
    • AmazonSNSFullAccess
    • AmazonSageMakerFullAccess
    • AmazonEventBridgeFullAccess
    • AWSLambda_FullAccess

    Aggiornare la relazione di fiducia del ruolo per concedere le autorizzazioni all'account AWS che ospita il server Jenkins:

    {    "Version": "2012-10-17",    "Statement": [        {            "Effect": "Allow",            "Principal": {                "Service": "events.amazonaws.com",                "AWS": "arn:aws:iam::<jenkins-account-id>:root"            },            "Action": "sts:AssumeRole",            "Condition": {}        }    ]}

    Aggiornare le autorizzazioni sul ruolo IAM associato al server Jenkins

    Premettendo che Jenkins sia stato configurato su AWS, aggiornare il ruolo IAM associato a Jenkins per aggiungere le seguenti politiche, che forniranno a Jenkins l'accesso per distribuire le risorse nell'account di produzione:

    • Politica 1 - Creare la seguente politica incorporata denominata assume-production-role-policy:

      {    "Version": "2012-10-17",    "Statement": [        {            "Sid": "VisualEditor0",            "Effect": "Allow",            "Action": "sts:AssumeRole",            "Resource": "arn:aws:iam::<prod-account-id>:role/cross-account-jenkins-role"        }    ]}
    • Politica 2 - Allegare la politica gestita CloudWatchFullAccess.

    Configurare il gruppo dei pacchetti di modelli nell'account del registro dei modelli centralizzato

    Dal dominio di SageMaker Studio nell'account del registro dei modelli centralizzato, creare un gruppo di pacchetti di modelli chiamato mammo-severity-model-package utilizzando il seguente frammento di codice (che è possibile eseguire utilizzando un notebook Jupyter):

    import boto3 model_package_group_name = "mammo-severity-model-package"sm_client = boto3.Session().client("sagemaker")create_model_package_group_response = sm_client.create_model_package_group(    ModelPackageGroupName=model_package_group_name,    ModelPackageGroupDescription="Gruppo di pacchetti di modelli inter-account per il modello di gravità del mammogramma",)print('ModelPackageGroup Arn : {}'.format(create_model_package_group_response['ModelPackageGroupArn']))

    Configurare l'accesso al pacchetto di modelli per i ruoli IAM negli account dev e prod

    Garantire l'accesso ai ruoli di esecuzione di SageMaker creati negli account dev e prod in modo da poter registrare le versioni dei modelli all'interno del pacchetto di modelli mammo-severity-model-package nel registro dei modelli centralizzato da entrambi gli account. Dal dominio di SageMaker Studio nell'account del registro dei modelli centralizzato, eseguire il seguente codice in un notebook Jupyter:

    import json import boto3 model_package_group_name = "mammo-severity-model-package"# Convertire la politica da dizionario JSON a stringamodel_package_group_policy = dict({  "Version": "2012-10-17",  "Statement": [    {      "Sid": "AddPermModelPackageGroupCrossAccount",      "Effect": "Allow",      "Principal": {        "AWS": ["arn:aws:iam::<dev-account-id>:root", "arn:aws:iam::<prod-account-id>:root"]      },      "Action": [        "sagemaker:DescribeModelPackageGroup"              ],      "Resource": "arn:aws:sagemaker:us-east-1:<central-model-registry-account>:model-package-group/mammo-severity-model-package"        },    {      "Sid": "AddPermModelPackageVersionCrossAccount",      "Effect": "Allow",      "Principal": {        "AWS": ["arn:aws:iam::<dev-account-id>:root", "arn:aws:iam::<prod-account-id>:root"]       },      "Action": [        "sagemaker:DescribeModelPackage",        "sagemaker:ListModelPackages",        "sagemaker:UpdateModelPackage",        "sagemaker:CreateModelPackage",        "sagemaker:CreateModel"            ],      "Resource": "arn:aws:sagemaker:us-east-1:<central-model-registry-account>:model-package/mammo-severity-model-package/*"    }  ]})model_package_group_policy = json.dumps(model_package_group_policy)# Aggiungere la politica al gruppo dei pacchetti di modellism_client = boto3.Session().client("sagemaker")response = sm_client.put_model_package_group_policy(    ModelPackageGroupName = model_package_group_name,    ResourcePolicy = model_package_group_policy)

    Configurazione di Jenkins

    In questa sezione, configuriamo Jenkins per creare i pipeline di apprendimento automatico (ML) e l'infrastruttura di Terraform corrispondente nell'account prod tramite il pipeline di Jenkins CI/CD.

    • Nella console di CloudWatch, crea un gruppo di log chiamato jenkins-log all'interno dell'account prod a cui Jenkins invierà i log dal pipeline CI/CD. Il gruppo di log deve essere creato nella stessa regione in cui è stato configurato il server Jenkins.
    • Installa i seguenti plugin sul tuo server Jenkins:
      1. Job DSL
      2. Git
      3. Pipeline
      4. Pipeline: AWS Steps
      5. Pipeline Utility Steps
    • Configura le credenziali AWS in Jenkins utilizzando il ruolo IAM tra account (cross-account-jenkins-role) fornito nell'account prod.
    • Per la Configurazione di sistema, scegli AWS.
    • Fornisci le credenziali e il gruppo di log di CloudWatch creati in precedenza.
    • Configura le credenziali di GitHub all'interno di Jenkins.
    • Crea un nuovo progetto in Jenkins.
    • Inserisci un nome di progetto e scegli Pipeline.
    • Nella scheda Generale, seleziona Progetto di GitHub e inserisci l'URL del repository di GitHub forkato GitHub.
    • Seleziona Questo progetto ha un parametro.
    • Nel menu Aggiungi Parametro, scegli Parametro di Testo.
    • Per Nome, inserisci prodAccount.
    • Per Valore predefinito, inserisci l'ID dell'account prod.
    • In Opzioni avanzate del progetto, per Definizione, seleziona Script del pipeline da SCM.
    • Per SCM, scegli Git.
    • Per URL del repository, inserisci l'URL del repository di GitHub forkato GitHub.
    • Per Credenziali, inserisci le credenziali di GitHub salvate in Jenkins.
    • Inserisci main nella sezione Branches da compilare, in base al quale sarà attivato il pipeline CI/CD.
    • Per Percorso dello script, inserisci Jenkinsfile.
    • Scegli Salva.

    Il pipeline di Jenkins dovrebbe essere creato e visibile nella tua dashboard.

    Provvedi ai bucket S3, raccogli e prepara i dati

    Completa i seguenti passaggi per configurare i tuoi bucket S3 e i dati:

    • Crea un bucket S3 a tua scelta con la stringa sagemaker nella convenzione di denominazione come parte del nome del bucket sia nei account dev che prod per archiviare dataset e artefatti del modello.

    • Configura un bucket S3 per mantenere lo stato di Terraform nell'account prod.

    • Scarica e salva il dataset pubblicamente disponibileUCI Mammography Mass nel bucket S3 che hai creato in precedenza nell'account dev.

    • Fai il fork e clona il repository GitHub all'interno del dominio SageMaker Studio nell'account dev. Il repository ha la seguente struttura delle cartelle:

      • /environments – Script di configurazione per l'ambiente prod
      • /mlops-infra – Codice per il deployment di servizi AWS utilizzando il codice Terraform
      • /pipelines – Codice per i componenti della pipeline SageMaker
      • Jenkinsfile – Script per il deployment tramite pipeline Jenkins CI/CD
      • setup.py – Necessario per installare i moduli Python richiesti e creare il comando run-pipeline
      • mammography-severity-modeling.ipynb – Consente di creare ed eseguire il workflow di ML
    • Crea una cartella chiamata data all'interno della cartella del repository GitHub clonato e salva una copia del dataset pubblicamente disponibile UCI Mammography Mass.

    • Segui il notebook Jupyter mammography-severity-modeling.ipynb.

    • Esegui il seguente codice nel notebook per preprocessare il dataset e caricarlo nel bucket S3 nell'account dev:

      import boto3import sagemakerimport numpy as npimport pandas as pdfrom sklearn.compose import ColumnTransformerfrom sklearn.impute import SimpleImputerfrom sklearn.pipeline import Pipelinefrom sklearn.preprocessing import StandardScaler, OneHotEncoder#Sostituisci i valori in base alle risorse createdefault_bucket = "<s3-bucket-in-dev-account>"model_artifacts_bucket = "<s3-bucket-in-central-model-registry-account>"region = "us-east-1"model_name = "mammography-severity-model"role = sagemaker.get_execution_role()lambda_role = "arn:aws:iam::<dev-account-id>:role/lambda-sagemaker-role"kms_key = "arn:aws:kms:us-east-1:<dev-account-id>:key/<kms-key-id-in-dev-account>"model_package_group_name="arn:aws:sagemaker:us-east-1:<central-model-registry-account-id>:model-package-group/mammo-severity-model-package"feature_columns_names = [    'BIRADS',    'Age',    'Shape',    'Margin',    'Density',]feature_columns_dtype = {    'BIRADS': np.float64,    'Age': np.float64,    'Shape': np.float64,    'Margin': np.float64,    'Density': np.float64,}# leggi il dataset grezzo iniziale mappographic_data = pd.read_csv("data/mammographic_masses.data",header=None)# suddividi i dati in batch e datasets grezzi batch_df =mammographic_data.sample(frac=0.05,random_state=200)raw_df =mammographic_data.drop(batch_df.index)# Separa i datasets grezzi in due parti, una sarà utilizzata per addestrare# il modello inizialmente e l'altro dataset verrà utilizzato quando #si ritrainerà il modellotrain_dataset_part2 =raw_df.sample(frac=0.1,random_state=200)train_dataset_part1 =raw_df.drop(train_dataset_part2.index)# salva i datasets train_dataset_part1.to_csv("data/mammo-train-dataset-part1.csv",index=False)train_dataset_part2.to_csv("data/mammo-train-dataset-part2.csv",index=False)# rimuovi la colonna dell'etichetta dal dataset batch che verrà utilizzata per generare inferenzebatch_df.drop(5,axis=1,inplace=True)# crea una copia del dataset batch batch_modified_df = batch_dfdef preprocess_batch_data(feature_columns_names,feature_columns_dtype,batch_df):    batch_df.replace("?", "NaN", inplace = True)    batch_df.columns = feature_columns_names    batch_df = batch_df.astype(feature_columns_dtype)    numeric_transformer = Pipeline(         steps=[("imputer", SimpleImputer(strategy="median"))]        )    numeric_features = list(feature_columns_names)    preprocess = ColumnTransformer(        transformers=[            ("num", numeric_transformer, numeric_features)        ]    )    batch_df = preprocess.fit_transform(batch_df)    return batch_df# salva il file del dataset batchbatch_df = preprocess_batch_data(feature_columns_names,feature_columns_dtype,batch_df)pd.DataFrame(batch_df).to_csv("data/mammo-batch-dataset.csv", header=False, index=False)# modifica il dataset batch per introdurre valori mancantibatch_modified_df.replace("?", "NaN", inplace = True)batch_modified_df.columns = feature_columns_namesbatch_modified_df = batch_modified_df.astype(feature_columns_dtype)# salva il file del dataset batch con outlierbatch_modified_df.to_csv("data/mammo-batch-dataset-outliers.csv",index=False)

    Il codice genererà i seguenti set di dati:

      • data/ mammo-train-dataset-part1.csv - Verrà utilizzato per addestrare la prima versione del modello.
      • data/ mammo-train-dataset-part2.csv  - Verrà utilizzato per addestrare la seconda versione del modello insieme al dataset mammo-train-dataset-part1.csv.
      • data/mammo-batch-dataset.csv - Verrà utilizzato per generare inferenze.
      • data/mammo-batch-dataset-outliers.csv - Introdurrà outlier nel set di dati per interrompere il flusso delle inferenze. Ciò ci permetterà di testare il modello automatico di apprendimento.
    • Carica il dataset mammo-train-dataset-part1.csv con il prefisso mammography-severity-model/train-dataset, e carica i dataset mammo-batch-dataset.csv e mammo-batch-dataset-outliers.csv con il prefisso mammography-severity-model/batch-dataset nel bucket S3 creato nell'account dev:

      import boto3
      s3_client = boto3.resource('s3')
      s3_client.Bucket(default_bucket).upload_file("data/mammo-train-dataset-part1.csv","mammography-severity-model/data/train-dataset/mammo-train-dataset-part1.csv")
      s3_client.Bucket(default_bucket).upload_file("data/mammo-batch-dataset.csv","mammography-severity-model/data/batch-dataset/mammo-batch-dataset.csv")
      s3_client.Bucket(default_bucket).upload_file("data/mammo-batch-dataset-outliers.csv","mammography-severity-model/data/batch-dataset/mammo-batch-dataset-outliers.csv")
      
    • Carica i dataset mammo-train-dataset-part1.csv e mammo-train-dataset-part2.csv con il prefisso mammography-severity-model/train-dataset nel bucket S3 creato nell'account prod tramite la console di Amazon S3.

    • Carica i dataset mammo-batch-dataset.csv e mammo-batch-dataset-outliers.csv con il prefisso mammography-severity-model/batch-dataset nel bucket S3 nell'account prod.

    Esegui la pipeline di addestramento

    Sotto <project-name>/pipelines/train, puoi vedere i seguenti script Python:

    • scripts/raw_preprocess.py - Si integra con SageMaker Processing per l'ingegneria delle caratteristiche
    • scripts/evaluate_model.py - Consente il calcolo delle metriche del modello, in questo caso auc_score
    • train_pipeline.py - Contiene il codice per la pipeline di addestramento del modello

    Completa i seguenti passaggi:

    • Carica gli script in Amazon S3:

      import boto3
      s3_client = boto3.resource('s3')
      s3_client.Bucket(default_bucket).upload_file("pipelines/train/scripts/raw_preprocess.py","mammography-severity-model/scripts/raw_preprocess.py")
      s3_client.Bucket(default_bucket).upload_file("pipelines/train/scripts/evaluate_model.py","mammography-severity-model/scripts/evaluate_model.py")
      
    • Ottieni l'istanza della pipeline di addestramento:

      from pipelines.train.train_pipeline import get_pipeline
      train_pipeline = get_pipeline(
                              region=region,
                              role=role,
                              default_bucket=default_bucket,
                              model_artifacts_bucket=model_artifacts_bucket,
                              model_name = model_name,
                              kms_key = kms_key,
                              model_package_group_name= model_package_group_name,
                              pipeline_name="mammo-severity-train-pipeline",
                              base_job_prefix="mammo-severity",
                          )
      train_pipeline.definition()
      
    • Invia la pipeline di addestramento e avviala:

      train_pipeline.upsert(role_arn=role)
      train_execution = train_pipeline.start()
      

    La figura seguente mostra una esecuzione di successo del pipeline di addestramento. L'ultimo passaggio nel pipeline registra il modello nell'account del registro centrale dei modelli.

    Approvare il modello nel registro centrale dei modelli

    Accedi all'account del registro centrale dei modelli e accedi al registro dei modelli SageMaker all'interno del dominio di SageMaker Studio. Cambia lo stato della versione del modello in Approvato.

    Una volta approvato, lo stato dovrebbe cambiare sulla versione del modello.

    Esegui il pipeline di inferenza (Opzionale)

    Questo passaggio non è obbligatorio, ma è comunque possibile eseguire il pipeline di inferenza per generare previsioni nell'account di sviluppo.

    Sotto <nome-progetto>/pipelines/inference, è possibile vedere i seguenti script Python:

    • scripts/lambda_helper.py - Prende l'ultima versione approvata del modello dall'account del registro centrale dei modelli utilizzando un passaggio di Lambda di SageMaker Pipelines
    • inference_pipeline.py - Contiene il codice per il pipeline di inferenza del modello

    Completa i seguenti passaggi:

    • Carica lo script nel bucket S3:

      import boto3s3_client = boto3.resource('s3')s3_client.Bucket(default_bucket).upload_file("pipelines/inference/scripts/lambda_helper.py","mammography-severity-model/scripts/lambda_helper.py")
    • Ottieni l'istanza del pipeline di inferenza utilizzando il dataset batch normale:

      from pipelines.inference.inference_pipeline import get_pipelineinference_pipeline = get_pipeline(                        region=region,                        role=role,                        lambda_role = lambda_role,                        default_bucket=default_bucket,                        kms_key=kms_key,                        model_name = model_name,                        model_package_group_name= model_package_group_name,                        pipeline_name="mammo-severity-inference-pipeline",                        batch_dataset_filename = "mammo-batch-dataset"                    )
    • Invia il pipeline di inferenza e avvialo:

      inference_pipeline.upsert(role_arn=role)inference_execution = inference_pipeline.start()

    La figura seguente mostra una esecuzione di successo del pipeline di inferenza. L'ultimo passaggio nel pipeline genera le previsioni e le memorizza nel bucket S3. Utilizziamo MonitorBatchTransformStep per monitorare gli input nel job di trasformazione batch. Se ci sono degli outlier, il pipeline di inferenza passa allo stato di errore.

    Esegui il pipeline di Jenkins

    La cartella environment/ all'interno del repository GitHub contiene lo script di configurazione per l'account di produzione. Completa i seguenti passaggi per avviare il pipeline di Jenkins:

    • Aggiorna lo script di configurazione prod.tfvars.json in base alle risorse create nei passaggi precedenti:

      {    "env_group": "prod",    "aws_region": "us-east-1",    "event_bus_name": "default",    "pipelines_alert_topic_name": "mammography-model-notification",    "email":"[email protected]",    "lambda_role":"arn:aws:iam::<prod-account-id>:role/lambda-sagemaker-role",    "default_bucket":"<s3-bucket-in-prod-account>",    "model_artifacts_bucket": "<s3-bucket-in-central-model-registry-account>",    "kms_key": "arn:aws:kms:us-east-1:<prod-account-id>:key/<kms-key-id-in-prod-account>",    "model_name": "mammography-severity-model",    "model_package_group_name":"arn:aws:sagemaker:us-east-1:<central-model-registry-account-id>:model-package-group/mammo-severity-model-package",    "train_pipeline_name":"mammo-severity-train-pipeline",    "inference_pipeline_name":"mammo-severity-inference-pipeline",    "batch_dataset_filename":"mammo-batch-dataset",    "terraform_state_bucket":"<s3-bucket-terraform-state-in-prod-account>",    "train_pipeline": {            "name": "mammo-severity-train-pipeline",            "arn": "arn:aws:sagemaker:us-east-1:<prod-account-id>:pipeline/mammo-severity-train-pipeline",            "role_arn": "arn:aws:iam::<prod-account-id>:role/service-role/<sagemaker-execution-role-in-prod-account>"        },    "inference_pipeline": {            "name": "mammo-severity-inference-pipeline",            "arn": "arn:aws:sagemaker:us-east-1:<prod-account-id>:pipeline/mammo-severity-inference-pipeline",            "cron_schedule": "cron(0 23 * * ? *)",            "role_arn": "arn:aws:iam::<prod-account-id>:role/service-role/<sagemaker-execution-role-in-prod-account>"        }}
    • Una volta aggiornato, pusha il codice nel repository GitHub forkato e unisci il codice nel ramo principale.

    • Vai all'interfaccia utente di Jenkins, scegli Build con parametri e avvia il pipeline CI/CD creato nei passaggi precedenti.

    Quando la compilazione è completa e avviene con successo, puoi accedere all'account prod e visualizzare le pipeline di train e inferenza all'interno del dominio di SageMaker Studio.

    Inoltre, vedrai tre regole EventBridge nella console EventBridge dell'account prod:

    • Pianifica la pipeline di inferenza
    • Invia una notifica di errore sulla pipeline di train
    • Quando la pipeline di inferenza non riesce a attivare la pipeline di train, invia una notifica

    Infine, vedrai un argomento di notifica SNS nella console di Amazon SNS che invia notifiche tramite email. Riceverai un'email che ti chiederà di confermare l'accettazione di queste email di notifica.

    Testa la pipeline di inferenza utilizzando un dataset batch senza outliers

    Per testare se la pipeline di inferenza funziona come previsto nell'account prod, puoi accedere all'account prod e attivare la pipeline di inferenza utilizzando il dataset batch senza outliers.

    Esegui la pipeline tramite la console delle SageMaker Pipelines nel dominio di SageMaker Studio dell'account prod, dove transform_input sarà l'URI S3 del dataset senza outliers (s3://<s3-bucket-in-prod-account>/mammography-severity-model/data/mammo-batch-dataset.csv).

    La pipeline di inferenza ha successo e scrive le previsioni nel bucket S3.

    Testa la pipeline di inferenza utilizzando un dataset batch con outliers

    Puoi eseguire la pipeline di inferenza utilizzando il dataset batch con outliers per verificare se il meccanismo di riaddestramento automatico funziona come previsto.

    Esegui la pipeline tramite la console delle SageMaker Pipelines nel dominio di SageMaker Studio dell'account prod, dove transform_input sarà l'URI S3 del dataset con outliers (s3://<s3-bucket-in-prod-account>/mammography-severity-model/data/mammo-batch-dataset-outliers.csv).

    La pipeline di inferenza fallisce come previsto, il che attiva la regola EventBridge, che a sua volta attiva la pipeline di train.

    Dopo alcuni istanti, dovresti vedere una nuova esecuzione del pipeline di addestramento sulla console SageMaker Pipelines, che recupera i due diversi set di dati di addestramento (mammo-train-dataset-part1.csv e mammo-train-dataset-part2.csv) caricati nel bucket S3 per riaddestrare il modello.

    Vedrai anche una notifica inviata all'email sottoscritta al topic SNS.

    Per utilizzare la versione aggiornata del modello, accedi all'account del registro centrale dei modelli e approva la versione del modello, che verrà acquisita durante la successiva esecuzione del pipeline di inferenza scatenato mediante la regola di EventBridge pianificata.

    Sebbene i pipeline di addestramento e di inferenza utilizzino un URL di dataset statico, è possibile far passare l'URL del dataset ai pipeline di addestramento e di inferenza come variabili dinamiche al fine di utilizzare dataset aggiornati per riaddestrare il modello e generare previsioni in uno scenario del mondo reale.

    Ripulire

    Per evitare future spese, completa i seguenti passaggi:

    • Rimuovi il dominio di SageMaker Studio in tutti gli account AWS.
    • Elimina tutte le risorse create al di fuori di SageMaker, inclusi i bucket S3, i ruoli IAM, le regole EventBridge e il topic SNS configurato tramite Terraform nell'account prod.
    • Elimina i pipeline di SageMaker creati tra gli account utilizzando l'AWS Command Line Interface (AWS CLI).

    Conclusioni

    Le organizzazioni spesso hanno bisogno di allinearsi con set di strumenti a livello aziendale per consentire la collaborazione tra diverse aree funzionali e team. Questa collaborazione garantisce che la piattaforma MLOps possa adattarsi alle mutevoli esigenze aziendali e accelera l'adozione di ML tra i team. In questo articolo è stato spiegato come creare un framework MLOps in un ambiente multi-ambiente per consentire l'aggiornamento automatico del modello, l'inferenza batch e il monitoraggio con Amazon SageMaker Model Monitor, la versione del modello con SageMaker Model Registry e la promozione del codice e dei pipeline di ML tra gli ambienti con una pipeline CI/CD. Abbiamo presentato questa soluzione utilizzando una combinazione di servizi AWS e set di strumenti di terze parti. Per istruzioni su come implementare questa soluzione, consulta il repository GitHub. È inoltre possibile estendere questa soluzione integrando le proprie origini dati e framework di modellazione.