Monitorowanie modelu¶
Kiedy model działa już produkcyjnie jako usługa, trzeba wiedzieć, jak jest używany i czy nadal działa poprawnie. Azure Machine Learning daje na to dwa uzupełniające się sposoby dla zarządzanego punktu końcowego online (ang. managed online endpoint):
- Integracja z Application Insights - ustawienie na poziomie wdrożenia, które wysyła wbudowaną telemetrię (liczba żądań, czasy odpowiedzi), a także wszystko, co skrypt oceniający wypisze na standardowe wyjście, do zasobu Application Insights powiązanego z obszarem roboczym.
- Monitorowanie modelu w Azure Machine Learning - bogatsza funkcja zbudowana na zbieraniu danych (ang. data collection) z punktu końcowego. Śledzi w czasie dryf danych, dryf predykcji i jakość danych. Jest ona tematem następnego ćwiczenia (ćwiczenie 10B), ale to ćwiczenie włącza zbieranie danych, od którego tamta funkcja zależy.
W tym ćwiczeniu wytrenujesz i wdrożysz model klasyfikacji cukrzycy na punkcie końcowym diabetes-endpoint (tym samym, co w ćwiczeniu 7A) z włączoną diagnostyką Application Insights oraz zbieraniem danych. Potem wywołasz punkt końcowy i obejrzysz powstałą telemetrię.
Po co to robimy: model, który dobrze wypadł na danych testowych, nie jest modelem sprawdzonym na zawsze. Dane w produkcji zmieniają się same z siebie - zmienia się populacja pacjentów, zmieniają się procedury pomiarowe. Bez monitorowania dowiesz się o tym dopiero wtedy, gdy ktoś zauważy złe decyzje.
Połączenie z obszarem roboczym¶
Zacznij od połączenia z obszarem roboczym (ang. workspace).
Uwaga: jeśli od poprzedniego ćwiczenia wygasła sesja uwierzytelniania z subskrypcją Azure, zobaczysz prośbę o ponowne zalogowanie.
from azure.ai.ml import MLClient
from azure.identity import DefaultAzureCredential
credential = DefaultAzureCredential()
ml_client = MLClient.from_config(credential=credential)
print(f"Gotowe do pracy z obszarem roboczym {ml_client.workspace_name}")
Przygotowanie modelu do wdrożenia¶
Potrzebujesz teraz modelu, który wdrożysz. Uruchom poniższą komórkę, aby wczytać dane o cukrzycy, wytrenować prosty model drzewa decyzyjnego i zarejestrować go jako zasób modelu diabetes_model (jeśli rejestrowałeś ten model we wcześniejszym ćwiczeniu, powstanie jego nowa wersja).
import pandas as pd
import numpy as np
import joblib
import mlflow
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import roc_auc_score
from azure.ai.ml.entities import Model
from azure.ai.ml.constants import AssetTypes
# Wczytujemy dane o cukrzycy (zarejestrowane jako zasob diabetes_dataset - patrz cwiczenie 1A)
diabetes = pd.read_csv('data/diabetes.csv')
# Rozdzielamy cechy i etykiety
X, y = diabetes[['Pregnancies','PlasmaGlucose','DiastolicBloodPressure','TricepsThickness',
'SerumInsulin','BMI','DiabetesPedigree','Age']].values, diabetes['Diabetic'].values
# Dzielimy dane na zbior treningowy i testowy
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.30, random_state=0)
# Trenujemy model drzewa decyzyjnego, sledzac metryki przy uzyciu MLflow
mlflow.start_run()
print('Trenowanie modelu drzewa decyzyjnego')
model = DecisionTreeClassifier().fit(X_train, y_train)
y_hat = model.predict(X_test)
acc = np.average(y_hat == y_test)
mlflow.log_metric('Accuracy', acc)
print('Skutecznosc:', acc)
y_scores = model.predict_proba(X_test)
auc = roc_auc_score(y_test, y_scores[:, 1])
mlflow.log_metric('AUC', auc)
print('AUC:', auc)
mlflow.end_run()
# Zapisujemy plik wytrenowanego modelu, zeby dalo sie go zarejestrowac
# i spakowac do wdrozenia
model_file = 'diabetes_model.pkl'
joblib.dump(value=model, filename=model_file)
# Rejestrujemy model jako zasob w obszarze roboczym
registered_model = Model(
path=model_file,
type=AssetTypes.CUSTOM_MODEL,
name="diabetes_model",
description="A decision tree model that predicts diabetes",
)
model = ml_client.models.create_or_update(registered_model)
print(f"Model wytrenowany i zarejestrowany: {model.name}, wersja {model.version}")
Wdrożenie modelu jako zarządzanego punktu końcowego online¶
Możesz teraz wdrożyć zarejestrowany model jako zarządzany punkt końcowy online.
Najpierw utwórz folder na pliki wdrożenia.
import os
folder_name = 'diabetes_service'
os.makedirs(folder_name, exist_ok=True)
print(folder_name)
Potrzebujesz jeszcze skryptu wejściowego (oceniającego, ang. scoring script), którego wdrożenie użyje do wczytania modelu i obsługi przychodzących żądań. Poniższy skrypt wypisuje dane każdego żądania wraz z predykcjami - dzięki temu zobaczysz je w Application Insights - a przy użyciu klasy Collector z pakietu azureml-ai-monitoring zapisuje wejścia i wyjścia modelu. To właśnie te zapisy posłużą jako dane produkcyjne monitorowi, który utworzysz w ćwiczeniu 10B.
Zwróć uwagę na nazwy
initirun: to nie są dowolne nazwy. Azure ML wywołuje te dwie funkcje po nazwie -init()raz, przy uruchamianiu usługi, arun()przy każdym żądaniu. Zmiana nazwy zepsuje wdrożenie.
%%writefile $folder_name/score_diabetes.py
import os
import json
import joblib
import numpy as np
import pandas as pd
from azureml.ai.monitoring import Collector
# Wywolywane raz, przy uruchamianiu uslugi
def init():
global model, inputs_collector, outputs_collector
# Ustalamy sciezke do wdrozonego pliku modelu i wczytujemy go
model_path = os.path.join(os.getenv('AZUREML_MODEL_DIR'), 'diabetes_model.pkl')
model = joblib.load(model_path)
# Kolektory zapisuja wejscia i wyjscia modelu na potrzeby zbierania danych
# i monitorowania modelu
inputs_collector = Collector(name='model_inputs')
outputs_collector = Collector(name='model_outputs')
# Wywolywane przy kazdym przychodzacym zadaniu
def run(raw_data):
# Odczytujemy dane wejsciowe jako tablice numpy
data = json.loads(raw_data)['data']
np_data = np.array(data)
input_df = pd.DataFrame(np_data)
# Pobieramy predykcje z modelu
predictions = model.predict(np_data)
# Wypisujemy dane i predykcje - dzieki temu trafia do Application Insights
log_text = 'Data:' + str(data) + ' - Predictions:' + str(predictions)
print(log_text)
# Zamieniamy kazda predykcje (0 lub 1) na nazwe klasy
classnames = ['zdrowy', 'chory']
predicted_classes = [classnames[prediction] for prediction in predictions]
# Zapisujemy wejscia i wyjscia na potrzeby zbierania danych i monitorowania
context = inputs_collector.collect(input_df)
outputs_collector.collect(pd.DataFrame({'predicted_classes': predicted_classes}), context)
# Zwracamy listę predykcji - serwer inferencyjny sam zamieni ją na JSON
return predicted_classes
Potrzebne będzie też środowisko (ang. environment) określające pakiety Pythona wymagane przez wdrożenie.
%%writefile $folder_name/diabetes_env.yml
name: diabetes-service-env
dependencies:
- python=3.10
- pip
- pip:
- scikit-learn
- joblib
- pandas
- numpy
- azureml-ai-monitoring
Teraz możesz wdrożyć model na zarządzanym punkcie końcowym diabetes-endpoint. Wdrożenie o nazwie blue skonfigurujesz jednocześnie pod diagnostykę Application Insights (app_insights_enabled=True) i zbieranie danych (data_collector).
Uwaga: potrwa to kilka minut - tworzenie wdrożenia czeka, aż zgłosi ono gotowość.
from azure.ai.ml.entities import (
ManagedOnlineEndpoint,
ManagedOnlineDeployment,
Environment,
CodeConfiguration,
DataCollector,
DeploymentCollection,
)
endpoint_name = "diabetes-endpoint"
deployment_name = "blue"
# Tworzymy punkt koncowy, jesli jeszcze nie istnieje (np. z cwiczenia 7A)
endpoint = ManagedOnlineEndpoint(name=endpoint_name, auth_mode="key")
ml_client.online_endpoints.begin_create_or_update(endpoint).result()
registered_model = ml_client.models.get(name="diabetes_model", label="latest")
diabetes_env = Environment(
name="diabetes-service-env",
description="Environment for the diabetes scoring service",
conda_file=f"{folder_name}/diabetes_env.yml",
image="mcr.microsoft.com/azureml/openmpi5.0-ubuntu24.04",
)
data_collector = DataCollector(
collections={
"model_inputs": DeploymentCollection(enabled="true"),
"model_outputs": DeploymentCollection(enabled="true"),
}
)
blue_deployment = ManagedOnlineDeployment(
name=deployment_name,
endpoint_name=endpoint_name,
model=registered_model,
environment=diabetes_env,
code_configuration=CodeConfiguration(code=folder_name, scoring_script="score_diabetes.py"),
instance_type="Standard_DS2_v2",
instance_count=1,
app_insights_enabled=True,
data_collector=data_collector,
)
ml_client.online_deployments.begin_create_or_update(blue_deployment).result()
# Kierujemy caly ruch na to wdrozenie
endpoint.traffic = {deployment_name: 100}
ml_client.online_endpoints.begin_create_or_update(endpoint).result()
print(f"Wdrozono diabetes_model na {endpoint_name} z wlaczona diagnostyka Application Insights i zbieraniem danych.")
Korzystanie z usługi¶
Wdrożenie jest gotowe, więc możesz wysłać dane do oceny i sprawdzić, czy wracają predykcje.
Wskazówka: jeśli pojawi się błąd, bo wdrożenie nie jest jeszcze gotowe, odczekaj kilka sekund i spróbuj ponownie.
import json
# Przygotowujemy nowe dane do oceny
x_new = [[2,180,74,24,21,23.9091702,1.488172308,22],
[0,148,58,11,179,39.19207553,0.160829008,45]]
request_data = {"data": x_new}
with open("sample-data.json", "w") as f:
json.dump(request_data, f)
response = ml_client.online_endpoints.invoke(
endpoint_name=endpoint_name,
deployment_name=deployment_name,
request_file="sample-data.json",
)
predicted_classes = json.loads(response)
for i in range(len(x_new)):
print("Pacjent {}".format(x_new[i]), predicted_classes[i])
Przegląd telemetrii w Application Insights¶
Możesz teraz obejrzeć dane zapisane dla punktu końcowego:
W Azure Machine Learning studio otwórz stronę punktu końcowego diabetes-endpoint i przejdź na kartę Monitoring. Zobaczysz wbudowane wykresy żądań i czasów odpowiedzi - to najszybszy sposób na potwierdzenie, że Application Insights odbiera telemetrię.
W portalu Azure otwórz swój obszar roboczy Machine Learning i na stronie Overview wybierz powiązany zasób Application Insights.
W zasobie Application Insights wybierz Logs.
Uwaga: jeśli otwierasz Log Analytics po raz pierwszy, może być potrzebne kliknięcie Get Started, aby przejść do edytora zapytań.
Uruchom zapytanie podobne do poniższego (dokładne nazwy pól w
customDimensionszależą od obrazu bazowego użytego przez środowisko, więc jeśli nic nie wróci, obejrzyj strukturę tabeli traces):traces |where message == "STDOUT" |project timestamp, message, customDimensionsTelemetria potrzebuje kilku minut, żeby dotrzeć do Application Insights - odczekaj i uruchom zapytanie ponownie, aż zobaczysz zapisane dane i predykcje.
Dlaczego to nie pojawia się od razu: telemetria jest buforowana i wysyłana partiami. Pusty wynik tuż po wywołaniu punktu końcowego nie oznacza, że coś nie działa.
Więcej informacji: o monitorowaniu zarządzanych punktów końcowych online przy użyciu Application Insights przeczytasz w artykule Monitor online endpoints w dokumentacji Azure Machine Learning. Pełniejsze monitorowanie modelu - dryf danych, dryf predykcji i jakość danych - jest tematem ćwiczenia 10B: Monitorowanie dryfu danych, które opiera się na wdrożeniu diabetes-endpoint i zbieraniu danych skonfigurowanych przed chwilą.