Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.
Modelli di test con varianti di produzione
I data scientist e i tecnici spesso cercano di migliorare le prestazioni nei flussi di lavoro di ML di produzione utilizzando vari modi, ad esempio Ottimizzazione automatica dei modelli con AI SageMaker , eseguendo l’addestramento con dati aggiuntivi o più recenti, migliorando la selezione delle funzionalità, utilizzando istanze meglio aggiornate e container di distribuzione. Puoi utilizzare le varianti di produzione per confrontare modelli, istanze e container e scegliere il candidato con le migliori prestazioni per rispondere alle richieste di inferenza.
Gli endpoint multi-variante di SageMaker AI consentono di ripartire le richieste di invocazione di endpoint tra più varianti di produzione ricorrendo alla distribuzione del traffico per ogni variante oppure di invocare direttamente una variante specifica per ogni richiesta. In questo argomento esaminiamo entrambi i metodi di test dei modelli ML.
Argomenti
Test dei modelli con la distribuzione del traffico
Per testare più modelli con la distribuzione del traffico, occorre specificare la percentuale di traffico che viene instradato a ciascun modello, indicando il peso per ogni variante di produzione nella configurazione dell'endpoint. Per ulteriori informazioni, consulta CreateEndpointConfig. Il diagramma seguente ne mostra il funzionamento in modo più dettagliato.
Test dei modelli con l'invocazione di varianti specifiche
Per testare più modelli con l'invocazione di modelli specifici per ogni richiesta, occorre indicare la versione del modello che vuoi invocare fornendo un valore per il parametro TargetVariant quando chiami InvokeEndpoint. SageMaker AI garantisce che la richiesta venga elaborata dalla variante di produzione specificata. Se con la distribuzione del traffico già applicata specifichi un valore per il parametro TargetVariant, il routing di destinazione sostituisce la distribuzione casuale del traffico. Il diagramma seguente ne mostra il funzionamento in modo più dettagliato.
Esempio di test A/B del modello
L'esecuzione di test A/B tra un nuovo modello e un modello precedente con traffico di produzione può essere una scelta efficace per concludere il processo di convalida di un nuovo modello. Con i test A/B puoi verificare diverse varianti dei modelli e confrontare le prestazioni di ciascuna variante. Se la versione più recente del modello offre prestazioni migliori rispetto alla versione già esistente, sostituisci la versione precedente del modello con la nuova versione in produzione.
Nell'esempio seguente viene illustrato come eseguire il test A/B del modello. Un notebook che implementa questo esempio è disponibile nell'argomento relativo ai test A/B dei modelli ML in produzione
Fase 1: creazione e distribuzione di modelli
Definisci innanzitutto dove si trovano i modelli Amazon S3. Queste posizioni verranno utilizzate quando implementi i modelli nelle fasi successive:
model_url = f"s3://{path_to_model_1}" model_url2 = f"s3://{path_to_model_2}"
Quindi, crei gli oggetti del modello con i dati dell'immagine e del modello. Questi oggetti del modello vengono utilizzati per distribuire le varianti di produzione in un endpoint. I modelli sono sviluppati tramite l’addestramento dei modelli ML con diversi set di dati, algoritmi o framework ML e diversi iperparametri:
from sagemaker.amazon.amazon_estimator import get_image_uri model_name = f"DEMO-xgb-churn-pred-{datetime.now():%Y-%m-%d-%H-%M-%S}" model_name2 = f"DEMO-xgb-churn-pred2-{datetime.now():%Y-%m-%d-%H-%M-%S}" image_uri = get_image_uri(boto3.Session().region_name, 'xgboost', '0.90-1') image_uri2 = get_image_uri(boto3.Session().region_name, 'xgboost', '0.90-2') sm_session.create_model( name=model_name, role=role, container_defs={ 'Image': image_uri, 'ModelDataUrl': model_url } ) sm_session.create_model( name=model_name2, role=role, container_defs={ 'Image': image_uri2, 'ModelDataUrl': model_url2 } )
Ora crei due varianti di produzione, ognuna con propri requisiti di modello e risorse (tipo di istanza e conteggi). In tal modo puoi testare anche i modelli in diversi tipi di istanza.
Imposta un peso iniziale pari a 1 per entrambe le varianti. Ciò significa che il 50% delle richieste va a Variant1 e il restante 50% delle richieste va a Variant2. La somma dei pesi di entrambe le varianti è 2 e ogni variante ha un'assegnazione di peso pari a 1. Ciò significa che ogni variante riceve 1/2 (o il 50%) del traffico totale.
from sagemaker.session import production_variant variant1 = production_variant( model_name=model_name, instance_type="ml.m5.xlarge", initial_instance_count=1, variant_name='Variant1', initial_weight=1, ) variant2 = production_variant( model_name=model_name2, instance_type="ml.m5.xlarge", initial_instance_count=1, variant_name='Variant2', initial_weight=1, )
A questo punto, puoi implementare le varianti di produzione in un endpoint di SageMaker AI.
endpoint_name = f"DEMO-xgb-churn-pred-{datetime.now():%Y-%m-%d-%H-%M-%S}" print(f"EndpointName={endpoint_name}") sm_session.endpoint_from_production_variants( name=endpoint_name, production_variants=[variant1, variant2] )
Fase 2: invocazione dei modelli distribuiti
A questo punto puoi inviare le richieste all'endpoint per ottenere le inferenze in tempo reale. Utilizzi sia la distribuzione del traffico che l'indirizzamento diretto.
Per prima cosa usi la distribuzione del traffico configurata nella fase precedente. Ogni risposta di inferenza contiene il nome della variante di produzione che elabora la richiesta e pertanto puoi osservare che il traffico verso le due varianti di produzione è approssimativamente uguale.
# get a subset of test data for a quick test !tail -120 test_data/test-dataset-input-cols.csv > test_data/test_sample_tail_input_cols.csv print(f"Sending test traffic to the endpoint {endpoint_name}. \nPlease wait...") with open('test_data/test_sample_tail_input_cols.csv', 'r') as f: for row in f: print(".", end="", flush=True) payload = row.rstrip('\n') sm_runtime.invoke_endpoint( EndpointName=endpoint_name, ContentType="text/csv", Body=payload ) time.sleep(0.5) print("Done!")
SageMaker AI emette metriche come Latency e Invocations per ogni variante in Amazon CloudWatch. Per l’elenco completo delle metriche generate da SageMaker AI, consulta Metriche di Amazon SageMaker AI in Amazon CloudWatch. Esegui una query su CloudWatch per ottenere il numero di invocazioni di ogni variante e per mostrare come le invocazioni vengono divise tra le varianti per impostazione predefinita:
Ora invochi una versione specifica del modello definendo Variant1 come TargetVariant nella chiamata a invoke_endpoint.
print(f"Sending test traffic to the endpoint {endpoint_name}. \nPlease wait...") with open('test_data/test_sample_tail_input_cols.csv', 'r') as f: for row in f: print(".", end="", flush=True) payload = row.rstrip('\n') sm_runtime.invoke_endpoint( EndpointName=endpoint_name, ContentType="text/csv", Body=payload, TargetVariant="Variant1" ) time.sleep(0.5)
Per verificare che tutte le nuove chiamate siano effettivamente state elaborate da Variant1, puoi eseguire una query su CloudWatch per ottenere il numero di invocazioni per ogni variante. Puoi notare che per le invocazioni più recenti (con l'ultimo timestamp), tutte le richieste sono state elaborate da Variant1, come avevi specificato. Non sono presenti invocazioni eseguite per Variant2.
Fase 3: valutazione delle prestazioni del modello
Per vedere qual è la versione ottimale del modello, si valuta l'accuratezza, la precisione, la richiamata, il punteggio F1 e il ROC o l'area sottesa alla curva per ogni variante. Per prima cosa, osserva i parametri per Variant1:
Ora osserva i parametri per Variant2:
Per la maggior parte dei parametri definiti, Variant2 ha le prestazioni migliori e pertanto è la versione ottimale da utilizzare in produzione.
Fase 4: incremento del traffico verso il modello migliore
Ora che hai determinato che Variant2 funziona meglio di Variant1, puoi indirizzarvi più traffico. Puoi continuare a utilizzare TargetVariant per invocare una variante del modello specifico, ma un approccio più semplice consiste nell'aggiornare i pesi assegnati a ciascuna variante con la chiamata a UpdateEndpointWeightsAndCapacities. In questo modo la distribuzione del traffico alle varianti di produzione viene modificata senza richiedere aggiornamenti per l'endpoint. Tieni presente che nella sezione di configurazione hai impostato i pesi di variante in modo da dividere il traffico 50/50. I parametri CloudWatch per le invocazioni totali di ciascuna variante riportate di seguito mostrano i modelli di invocazione di ogni variante:
Ora spostiamo il 75% del traffico su Variant2 assegnando nuovi pesi a ciascuna variante che utilizza UpdateEndpointWeightsAndCapacities. SageMaker AI ora invia il 75% delle richieste di inferenza a Variant2 e il restante 25% delle richieste a Variant1.
sm.update_endpoint_weights_and_capacities( EndpointName=endpoint_name, DesiredWeightsAndCapacities=[ { "DesiredWeight": 25, "VariantName": variant1["VariantName"] }, { "DesiredWeight": 75, "VariantName": variant2["VariantName"] } ] )
I parametri CloudWatch per le invocazioni totali di ogni variante evidenziano un numero maggiore di invocazioni per Variant2 rispetto a Variant1:
Continua a monitorare i parametri e quando ritieni che le prestazioni di una variante siano soddisfacenti, instrada il 100% del traffico verso quella variante. Puoi utilizzare UpdateEndpointWeightsAndCapacities per aggiornare le assegnazioni del traffico alle varianti. Il peso per Variant1 è impostato su 0 e il peso per Variant2 è impostato su 1. SageMaker AI ora invia il 100% di tutte le richieste di inferenza a Variant2.
sm.update_endpoint_weights_and_capacities( EndpointName=endpoint_name, DesiredWeightsAndCapacities=[ { "DesiredWeight": 0, "VariantName": variant1["VariantName"] }, { "DesiredWeight": 1, "VariantName": variant2["VariantName"] } ] )
I parametri CloudWatch per le invocazioni totali di ogni variante evidenziano che tutte le richieste di inferenza vengono elaborate da Variant2 e che non sono state elaborate richieste di inferenza da Variant1.
A questo punto puoi aggiornare in modo sicuro l'endpoint ed eliminare Variant1 dall'endpoint. Inoltre puoi continuare a testare i nuovi modelli in produzione aggiungendo nuove varianti all'endpoint e ripetendo le fasi da 2 a 4.