Distribuera en modell till Azure Functions
Lär dig hur du distribuerar en förtränad ML.NET maskininlärningsmodell för förutsägelser via HTTP via en serverlös Azure Functions-miljö.
Förutsättningar
- Visual Studio 2022 med arbetsbelastningarna .NET Desktop Development och Azure Development installerat. .NET 6 SDK installeras automatiskt när du väljer den här arbetsbelastningen.
- Azure Functions-verktyg
- PowerShell
- Förtränad modell. Ladda ned den här förtränade maskininlärningsmodellen för attitydanalys eller använd självstudien ML.NET Attitydanalys för att skapa en egen modell.
Översikt över Azure Functions-exempel
Det här exemplet är ett C# HTTP Trigger Azure Functions-program som använder en förtränad binär klassificeringsmodell för att kategorisera attityden för text som positiv eller negativ. Azure Functions är ett enkelt sätt att köra små delar av kod i stor skala i en hanterad serverlös miljö i molnet. Koden för det här exemplet finns på lagringsplatsen dotnet/machinelearning-samples på GitHub.
Skapa Azure Functions-projekt
Öppna dialogrutan Skapa ett nytt projekt i Visual Studio 2022.
I dialogrutan "Skapa ett nytt projekt" väljer du projektmallen Azure Functions .
I textrutan Namn skriver du "SentimentAnalysisFunctionsApp" och väljer knappen Nästa.
I dialogrutan "Ytterligare information" lämnar du alla standardvärden som är och väljer knappen Skapa .
Installera Microsoft.ML NuGet-paketet
- Högerklicka på projektet i Solution Explorer och välj Hantera NuGet-paket.
- Välj "nuget.org" som paketkälla.
- Välj fliken "Bläddra".
- Sök efter Microsoft.ML.
- Välj paketet i listan och välj knappen Installera .
- Välj knappen OK i dialogrutan Förhandsgranska ändringar
- Välj knappen Jag accepterar i dialogrutan Licensgodkännande om du godkänner licensvillkoren för de paket som anges.
Följ samma steg för att installera nuget-paketen Microsoft.Extensions.ML, Microsoft.Extensions.DependencyInjection och Microsoft.Azure.Functions.Extensions .
Lägga till förtränad modell i projektet
- Skapa en katalog med namnet MLModels i projektet för att spara din förhandsversionsmodell: Högerklicka på projektet i Solution Explorer och välj Lägg till > ny mapp. Skriv "MLModels" och tryck på Retur.
- Kopiera din färdiga modell till mappen MLModels .
- Högerklicka på den färdiga modellfilen i Solution Explorer och välj Egenskaper. Under Avancerat ändrar du värdet för Kopiera till utdatakatalog till Kopiera om det är nyare.
Skapa Azure-funktion för att analysera sentiment
Skapa en klass för att förutsäga sentiment. Lägg till en ny klass i projektet:
Högerklicka på projektet i Solution Explorer och välj sedan Lägg till>ny Azure-funktion.
I dialogrutan Lägg till nytt objekt väljer du Azure-funktion och ändrar fältet Namn till AnalyzeSentiment.cs. Välj sedan knappen Lägg till .
I dialogrutan Ny Azure-funktion väljer du Http-utlösare och väljer Anonym i listrutan auktoriseringsnivå. Välj sedan ok-knappen .
Filen AnalyzeSentiment.cs öppnas i kodredigeraren. Lägg till följande
using
direktiv överst i AnalyzeSentiment.cs:using System; using System.IO; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.Azure.WebJobs; using Microsoft.Azure.WebJobs.Extensions.Http; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using Microsoft.Extensions.ML; using SentimentAnalysisFunctionsApp.DataModels;
Som standard
AnalyzeSentiment
ärstatic
klassen . Se till att ta bort nyckelordetstatic
från klassdefinitionen.public class AnalyzeSentiment { }
Skapa datamodeller
Du måste skapa några klasser för dina indata och förutsägelser. Lägg till en ny klass i projektet:
Skapa en katalog med namnet DataModels i projektet för att spara dina datamodeller: Högerklicka på projektet i Solution Explorer och välj Lägg till > ny mapp. Skriv "DataModels" och tryck på Retur.
Högerklicka på katalogen DataModels i Solution Explorer och välj sedan Lägg till > klass.
I dialogrutan Lägg till nytt objekt väljer du Klass och ändrar fältet Namn till SentimentData.cs. Välj sedan knappen Lägg till .
Filen SentimentData.cs öppnas i kodredigeraren. Lägg till följande
using
direktiv överst i SentimentData.cs:using Microsoft.ML.Data;
Ta bort den befintliga klassdefinitionen och lägg till följande kod i filen SentimentData.cs :
public class SentimentData { [LoadColumn(0)] public string SentimentText; [LoadColumn(1)] [ColumnName("Label")] public bool Sentiment; }
Högerklicka på katalogen DataModels i Solution Explorer och välj sedan Lägg till > klass.
I dialogrutan Lägg till nytt objekt väljer du Klass och ändrar fältet Namn till SentimentPrediction.cs. Välj sedan knappen Lägg till . Filen SentimentPrediction.cs öppnas i kodredigeraren. Lägg till följande
using
direktiv överst i SentimentPrediction.cs:using Microsoft.ML.Data;
Ta bort den befintliga klassdefinitionen och lägg till följande kod i filen SentimentPrediction.cs :
public class SentimentPrediction : SentimentData { [ColumnName("PredictedLabel")] public bool Prediction { get; set; } public float Probability { get; set; } public float Score { get; set; } }
SentimentPrediction
ärver somSentimentData
ger åtkomst till de ursprungliga data iSentimentText
egenskapen samt utdata som genereras av modellen.
Registrera PredictionEnginePool-tjänsten
Om du vill göra en enda förutsägelse måste du skapa en PredictionEngine
. PredictionEngine
är inte trådsäker. Dessutom måste du skapa en instans av den överallt där den behövs i ditt program. När programmet växer kan den här processen bli ohanterlig. För bättre prestanda och trådsäkerhet använder du en kombination av beroendeinmatning och PredictionEnginePool
tjänsten, som skapar en ObjectPool
av PredictionEngine
objekt som kan användas i hela programmet.
Följande länk innehåller mer information om du vill veta mer om beroendeinmatning.
Högerklicka på projektet i Solution Explorer och välj sedan Lägg till>klass.
I dialogrutan Lägg till nytt objekt väljer du Klass och ändrar fältet Namn till Startup.cs. Välj sedan knappen Lägg till .
Lägg till följande
using
direktiv överst i Startup.cs:using Microsoft.Azure.Functions.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.ML; using SentimentAnalysisFunctionsApp; using SentimentAnalysisFunctionsApp.DataModels; using System.IO; using System;
Ta bort den befintliga koden under direktiven
using
och lägg till följande kod:[assembly: FunctionsStartup(typeof(Startup))] namespace SentimentAnalysisFunctionsApp { public class Startup : FunctionsStartup { } }
Definiera variabler för att lagra miljön som appen körs i och filsökvägen där modellen finns i
Startup
klassenprivate readonly string _environment; private readonly string _modelPath;
Under det skapar du en konstruktor för att ange värdena för variablerna
_environment
och_modelPath
. När programmet körs lokalt är standardmiljön Utveckling.public Startup() { _environment = Environment.GetEnvironmentVariable("AZURE_FUNCTIONS_ENVIRONMENT"); if (_environment == "Development") { _modelPath = Path.Combine("MLModels", "sentiment_model.zip"); } else { string deploymentPath = @"D:\home\site\wwwroot\"; _modelPath = Path.Combine(deploymentPath, "MLModels", "sentiment_model.zip"); } }
Lägg sedan till en ny metod med namnet
Configure
för att registreraPredictionEnginePool
tjänsten under konstruktorn.public override void Configure(IFunctionsHostBuilder builder) { builder.Services.AddPredictionEnginePool<SentimentData, SentimentPrediction>() .FromFile(modelName: "SentimentAnalysisModel", filePath: _modelPath, watchForChanges: true); }
På hög nivå initierar den här koden objekten och tjänsterna automatiskt för senare användning när programmet begär det i stället för att behöva göra det manuellt.
Maskininlärningsmodeller är inte statiska. När nya träningsdata blir tillgängliga tränas modellen om och distribueras om. Ett sätt att hämta den senaste versionen av modellen i ditt program är att starta om eller distribuera om programmet. Detta medför dock programavbrott. Tjänsten PredictionEnginePool
tillhandahåller en mekanism för att läsa in en uppdaterad modell igen utan att starta om eller distribuera om programmet.
Ange parametern watchForChanges
till true
, och PredictionEnginePool
startar en FileSystemWatcher
som lyssnar på meddelanden om filsystemets ändring och genererar händelser när filen ändras. Detta uppmanar PredictionEnginePool
till att automatiskt läsa in modellen igen.
Modellen identifieras av parametern modelName
så att fler än en modell per program kan läsas in igen vid ändring.
Dricks
Du kan också använda FromUri
metoden när du arbetar med modeller som lagras på distans. I stället för att titta efter ändrade filhändelser avsöker FromUri
du fjärrplatsen efter ändringar. Avsökningsintervallet är som standard 5 minuter. Du kan öka eller minska avsökningsintervallet baserat på programmets krav. I kodexemplet nedan PredictionEnginePool
avsöker modellen som lagras vid den angivna URI:n varje minut.
builder.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));
Läs in modellen i funktionen
Infoga följande kod i klassen AnalyzeSentiment :
public AnalyzeSentiment(PredictionEnginePool<SentimentData, SentimentPrediction> predictionEnginePool)
{
_predictionEnginePool = predictionEnginePool;
}
Den här koden tilldelar PredictionEnginePool
genom att skicka den till funktionens konstruktor som du får via beroendeinmatning.
Använda modellen för att göra förutsägelser
Ersätt den befintliga implementeringen av Kör-metoden i klassen AnalyzeSentiment med följande kod:
public async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequest req,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
// Parse HTTP Request Body
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
SentimentData data = JsonConvert.DeserializeObject<SentimentData>(requestBody);
//Make Prediction
SentimentPrediction prediction = _predictionEnginePool.Predict(modelName: "SentimentAnalysisModel", example: data);
//Convert prediction to string
string sentiment = Convert.ToBoolean(prediction.Prediction) ? "Positive" : "Negative";
//Return Prediction
return new OkObjectResult(sentiment);
}
Run
När metoden körs deserialiseras inkommande data från HTTP-begäran och används som indata för PredictionEnginePool
. Metoden Predict
anropas sedan för att göra förutsägelser med hjälp av den SentimentAnalysisModel
registrerade i Startup
klassen och returnerar resultatet tillbaka till användaren om det lyckas.
Testa lokalt
Nu när allt har konfigurerats är det dags att testa programmet:
Kör appen
Öppna PowerShell och ange koden i kommandotolken där PORT är den port som programmet körs på. Vanligtvis är porten 7071.
Invoke-RestMethod "http://localhost:<PORT>/api/AnalyzeSentiment" -Method Post -Body (@{SentimentText="This is a very bad steak"} | ConvertTo-Json) -ContentType "application/json"
Om det lyckas bör utdata se ut ungefär som texten nedan:
Negative
Grattis! Du har hanterat din modell för att göra förutsägelser via Internet med hjälp av en Azure-funktion.