Distribuire un modello in un'API Web ASP.NET Core
Informazioni su come rendere disponibile un modello di Machine Learning ML.NET con training preliminare sul Web usando un'API Web ASP.NET Core. La disponibilità di un modello su un'API Web consente previsioni tramite metodi HTTP standard.
Prerequisiti
- Visual Studio 2022 con il carico di lavoro Sviluppo ASP.NET e Web.
- PowerShell.
- Modello con training preliminare. Usare l'esercitazione di analisi del sentiment in ML.NET per creare un modello personalizzato oppure scaricare questo modello di Machine Learning di analisi del sentiment con training preliminare
Creare un progetto API Web ASP.NET Core
Avviare Visual Studio 2022 e selezionare Crea un nuovo progetto.
Nella finestra di dialogo Crea un nuovo progetto:
- Immettere
Web API
nella casella di ricerca. - Selezionare il modello API Web ASP.NET Core e selezionare Avanti.
- Immettere
Nella finestra di dialogo Configura il progetto:
- Denominare il progetto SentimentAnalysisWebAPI.
- Selezionare Avanti.
Nella finestra di dialogo Informazioni aggiuntive:
- Deselezionare Non usare istruzioni di primo livello.
- Seleziona Crea.
Installare i pacchetti NuGet seguenti:
Per altre informazioni sull'installazione di pacchetti NuGet in Visual Studio, vedere la guida Installare e usare un pacchetto NuGet in Visual Studio.
Aggiungere il modello al progetto API Web ASP.NET Core
Copiare il modello predefinito nella directory del progetto SentimentAnalysisWebAPI.
Configurare il progetto per copiare il file del modello nella directory di output. In Esplora soluzioni:
- Fare clic con il pulsante destro del mouse sul file ZIP del modello e scegliere Proprietà.
- In Avanzate, impostare il valore di Copia nella directory di output su Copia se più recente.
Creare i modelli di dati
È necessario creare alcune classi per definire lo schema dell'input e dell'output del modello.
Nota
Le proprietà delle classi dello schema di input e output dipendono dalle colonne del set di dati usate per eseguire il training del modello e dall'attività di Machine Learning (regressione, classificazione e così via).
Nel file Program.cs:
Aggiungere le direttive
using
seguenti:using Microsoft.ML.Data; using Microsoft.Extensions.ML;
Nella parte inferiore del file aggiungere le classi seguenti:
Input del modello
Per questo modello, l'input contiene una singola proprietà
SentimentText
che è una stringa che rappresenta un commento utente.public class ModelInput { public string SentimentText; }
Output del modello
Dopo aver valutato l'input, il modello restituisce una stima con tre proprietà:
Sentiment
,Probability
eScore
. In questo caso,Sentiment
è il sentiment stimato del commento dell'utente, eProbability
eScore
sono misure di attendibilità per la stima.public class ModelOutput { [ColumnName("PredictedLabel")] public bool Sentiment { get; set; } public float Probability { get; set; } public float Score { get; set; } }
Registrare PredictionEnginePool per l'uso nell'applicazione
Per eseguire una singola stima, è necessario creare un oggetto PredictionEngine
. PredictionEngine
non è thread-safe. Inoltre, è necessario crearne un'istanza ovunque sia necessaria all'interno dell'applicazione. Man mano che l'applicazione cresce, la gestione di questo processo può rivelarsi difficile. Per migliorare le prestazioni e la sicurezza dei thread, usare una combinazione di inserimento delle dipendenze e del servizio PredictionEnginePool
, che crea un ObjectPool
di oggetti PredictionEngine
da usare in tutta l'applicazione.
Per ulteriori informazioni su questo argomento, vedere Inserimento delle dipendenze in ASP.NET Core.
Aggiungere il codice seguente al file Program.cs:
builder.Services.AddPredictionEnginePool<ModelInput, ModelOutput>()
.FromFile(modelName: "SentimentAnalysisModel", filePath: "sentiment_model.zip", watchForChanges: true);
A livello generale, questo codice inizializza automaticamente gli oggetti e i servizi per usarli in un secondo momento quando richiesto dall'applicazione anziché dover eseguire manualmente questa operazione.
I modelli di Machine Learning non sono statici. Man mano che diventano disponibili nuovi dati di training, il modello viene nuovamente sottoposto a training e ridistribuito. Un modo per ottenere la versione più recente del modello nell'applicazione consiste nel riavviare o ridistribuire l'applicazione. Tuttavia, ciò comporta tempi di inattività dell'applicazione. Il servizio PredictionEnginePool
fornisce un meccanismo per ricaricare un modello aggiornato senza riavviare o ridistribuire l'applicazione.
Impostare il parametro watchForChanges
su true
, e PredictionEnginePool
avvia FileSystemWatcher
in ascolto delle notifiche di modifica del file system e genera eventi quando viene apportata una modifica al file. In questo modo viene richiesto a PredictionEnginePool
di ricaricare automaticamente il modello.
Il modello viene identificato dal parametro modelName
in modo che sia possibile ricaricare più di un modello per applicazione al momento della modifica.
Suggerimento
In alternativa, è possibile usare il metodo FromUri
quando si usano i modelli archiviati in modalità remota. Invece di cercare gli eventi modificati dei file, FromUri
esegue il polling della posizione remota per individuare le modifiche. Per impostazione predefinita, l'intervallo di polling è 5 minuti. È possibile aumentare o ridurre l'intervallo di polling in base ai requisiti dell'applicazione. Nell'esempio di codice seguente, PredictionEnginePool
esegue il polling del modello archiviato all'URI specificato ogni minuto.
services.AddPredictionEnginePool<SentimentData, SentimentPrediction>()
.FromUri(
modelName: "SentimentAnalysisModel",
uri:"https://github.com/dotnet/samples/raw/main/machine-learning/models/sentimentanalysis/sentiment_model.zip",
period: TimeSpan.FromMinutes(1));
Eseguire il mapping dell'endpoint di stima
Per elaborare le richieste HTTP in ingresso, creare un endpoint.
Sostituire l'endpoint /
con il codice seguente:
var predictionHandler =
async (PredictionEnginePool<ModelInput, ModelOutput> predictionEnginePool, ModelInput input) =>
await Task.FromResult(predictionEnginePool.Predict(modelName: "SentimentAnalysisModel", input));
app.MapPost("/predict", predictionHandler);
L'endpoint /predict
accetta le richieste HTTP POST e usa il pool del motore di stima per restituire una stima usando l'input fornito.
Al termine, il Program.cs dovrebbe essere simile al seguente:
using Microsoft.ML.Data;
using Microsoft.Extensions.ML;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddPredictionEnginePool<ModelInput, ModelOutput>()
.FromFile(modelName: "SentimentAnalysisModel", filePath: "sentiment_model.zip", watchForChanges: true);
var app = builder.Build();
var predictionHandler =
async (PredictionEnginePool<ModelInput, ModelOutput> predictionEnginePool, ModelInput input) =>
await Task.FromResult(predictionEnginePool.Predict(modelName: "SentimentAnalysisModel", input));
app.MapPost("/predict", predictionHandler);
app.Run();
public class ModelInput
{
public string SentimentText;
}
public class ModelOutput
{
[ColumnName("PredictedLabel")]
public bool Sentiment { get; set; }
public float Probability { get; set; }
public float Score { get; set; }
}
Testare l'API Web in locale
Dopo aver completato la configurazione, è possibile testare l'applicazione.
Eseguire l'applicazione.
Aprire PowerShell e immettere il codice seguente, dove PORT è la porta su cui l'applicazione è in ascolto.
Invoke-RestMethod "https://localhost:<PORT>/predict" -Method Post -Body (@{SentimentText="This was a very bad steak"} | ConvertTo-Json) -ContentType "application/json"
In caso di esito positivo, l'output sarà simile al testo seguente:
sentiment probability score --------- ----------- ----- False 0.5 0
Complimenti. Il modello per effettuare previsioni in Internet usando un'API Web ASP.NET Core è stato reso disponibile.