Dela via


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

  1. Öppna dialogrutan Skapa ett nytt projekt i Visual Studio 2022.

  2. I dialogrutan "Skapa ett nytt projekt" väljer du projektmallen Azure Functions .

  3. I textrutan Namn skriver du "SentimentAnalysisFunctionsApp" och väljer knappen Nästa.

  4. I dialogrutan "Ytterligare information" lämnar du alla standardvärden som är och väljer knappen Skapa .

  5. Installera Microsoft.ML NuGet-paketet

    1. Högerklicka på projektet i Solution Explorer och välj Hantera NuGet-paket.
    2. Välj "nuget.org" som paketkälla.
    3. Välj fliken "Bläddra".
    4. Sök efter Microsoft.ML.
    5. Välj paketet i listan och välj knappen Installera .
    6. Välj knappen OK i dialogrutan Förhandsgranska ändringar
    7. 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

  1. 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.
  2. Kopiera din färdiga modell till mappen MLModels .
  3. 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:

  1. Högerklicka på projektet i Solution Explorer och välj sedan Lägg till>ny Azure-funktion.

  2. 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 .

  3. 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 är staticklassen . Se till att ta bort nyckelordet static 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:

  1. 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.

  2. Högerklicka på katalogen DataModels i Solution Explorer och välj sedan Lägg till > klass.

  3. 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;
    }
    
  4. Högerklicka på katalogen DataModels i Solution Explorer och välj sedan Lägg till > klass.

  5. 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 som SentimentData ger åtkomst till de ursprungliga data i SentimentText 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.

  1. Högerklicka på projektet i Solution Explorer och välj sedan Lägg till>klass.

  2. 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 .

  3. 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;
    
  4. 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
        {
    
        }
    }
    
  5. Definiera variabler för att lagra miljön som appen körs i och filsökvägen där modellen finns i Startup klassen

    private readonly string _environment;
    private readonly string _modelPath;
    
  6. 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");
        }
    }
    
  7. Lägg sedan till en ny metod med namnet Configure för att registrera PredictionEnginePool 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:

  1. Kör appen

  2. Ö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.

Nästa steg