Udostępnij za pośrednictwem


Wdrażanie modelu w usłudze Azure Functions

Dowiedz się, jak wdrożyć wstępnie wytrenowany model uczenia maszynowego ML.NET na potrzeby przewidywań za pośrednictwem protokołu HTTP za pośrednictwem środowiska bezserwerowego usługi Azure Functions.

Wymagania wstępne

  • Program Visual Studio 2022 z zainstalowanymi obciążeniami tworzenia aplikacji klasycznych .NET i tworzenia aplikacji na platformie Azure. Zestaw .NET 6 SDK jest instalowany automatycznie po wybraniu tego obciążenia.
  • Narzędzia usługi Azure Functions
  • PowerShell
  • Wstępnie wytrenowany model. Pobierz ten wstępnie wytrenowany model uczenia maszynowego analizy tonacji lub skorzystaj z samouczka analizy tonacji ML.NET, aby utworzyć własny model.

Omówienie przykładu usługi Azure Functions

Ten przykład to aplikacja wyzwalacza HTTP języka C#, która używa wstępnie wytrenowanego modelu klasyfikacji binarnej do kategoryzowania tonacji tekstu jako pozytywnego lub negatywnego. Usługa Azure Functions umożliwia łatwe uruchamianie małych fragmentów kodu na dużą skalę w zarządzanym środowisku bezserwerowym w chmurze. Kod dla tego przykładu można znaleźć w repozytorium dotnet/machinelearning-samples w witrynie GitHub.

Tworzenie projektu usługi Azure Functions

  1. W programie Visual Studio 2022 otwórz okno dialogowe Tworzenie nowego projektu .

  2. W oknie dialogowym "Tworzenie nowego projektu" wybierz szablon projektu usługi Azure Functions .

  3. W polu tekstowym Nazwa wpisz "SentimentAnalysisFunctionsApp" i wybierz przycisk Dalej .

  4. W oknie dialogowym "Dodatkowe informacje" pozostaw wszystkie wartości domyślne, tak jak i wybierz przycisk Utwórz .

  5. Instalowanie pakietu NuGet Microsoft.ML

    1. W Eksplorator rozwiązań kliknij prawym przyciskiem myszy projekt i wybierz polecenie Zarządzaj pakietami NuGet.
    2. Wybierz pozycję "nuget.org" jako źródło pakietu.
    3. Wybierz kartę "Przeglądaj".
    4. Wyszukaj Microsoft.ML.
    5. Wybierz ten pakiet na liście, a następnie wybierz przycisk Zainstaluj .
    6. Wybierz przycisk OK w oknie dialogowym Podgląd zmian
    7. Wybierz przycisk Akceptuję w oknie dialogowym Akceptacja licencji, jeśli zgadzasz się z postanowieniami licencyjnymi dla wymienionych pakietów.

    Wykonaj te same kroki, aby zainstalować pakiety NuGet Microsoft.Extensions.ML, Microsoft.Extensions.DependencyInjection i Microsoft.Azure.Functions.Extensions .

Dodawanie wstępnie wytrenowanego modelu do projektu

  1. Utwórz katalog o nazwie MLModels w projekcie, aby zapisać model przed kompilacją: w Eksplorator rozwiązań kliknij prawym przyciskiem myszy projekt i wybierz polecenie Dodaj > nowy folder. Wpisz "MLModels" i naciśnij Enter.
  2. Skopiuj wstępnie utworzony model do folderu MLModels .
  3. W Eksplorator rozwiązań kliknij prawym przyciskiem myszy wstępnie utworzony plik modelu i wybierz polecenie Właściwości. W obszarze Zaawansowane zmień wartość kopiuj do katalogu wyjściowego, aby skopiować, jeśli jest nowsza.

Tworzenie funkcji platformy Azure w celu analizowania tonacji

Utwórz klasę do przewidywania tonacji. Dodaj nową klasę do projektu:

  1. W Eksplorator rozwiązań kliknij prawym przyciskiem myszy projekt, a następnie wybierz polecenie Dodaj>nową funkcję platformy Azure.

  2. W oknie dialogowym Dodawanie nowego elementu wybierz pozycję Funkcja platformy Azure i zmień pole Nazwa na AnalyzeSentiment.cs. Następnie wybierz przycisk Dodaj .

  3. W oknie dialogowym Nowa funkcja platformy Azure wybierz pozycję Wyzwalacz HTTP i wybierz pozycję Anonimowe z listy rozwijanej Poziom autoryzacji. Następnie wybierz przycisk OK .

    Plik AnalyzeSentiment.cs zostanie otwarty w edytorze kodu. Dodaj następującą using dyrektywę na początku 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;
    

    Domyślnie klasa AnalyzeSentiment to static. Pamiętaj, aby usunąć static słowo kluczowe z definicji klasy.

    public class AnalyzeSentiment
    {
    
    }
    

Tworzenie modeli danych

Należy utworzyć kilka klas dla danych wejściowych i przewidywań. Dodaj nową klasę do projektu:

  1. Utwórz katalog o nazwie DataModels w projekcie, aby zapisać modele danych: w Eksplorator rozwiązań kliknij prawym przyciskiem myszy projekt i wybierz polecenie Dodaj > nowy folder. Wpisz ciąg "DataModels" i naciśnij Enter.

  2. W Eksplorator rozwiązań kliknij prawym przyciskiem myszy katalog DataModels, a następnie wybierz polecenie Dodaj > klasę.

  3. W oknie dialogowym Dodawanie nowego elementu wybierz pozycję Klasa i zmień pole Nazwa na SentimentData.cs. Następnie wybierz przycisk Dodaj .

    Plik SentimentData.cs zostanie otwarty w edytorze kodu. Dodaj następującą using dyrektywę na początku SentimentData.cs:

    using Microsoft.ML.Data;
    

    Usuń istniejącą definicję klasy i dodaj następujący kod do pliku SentimentData.cs :

    public class SentimentData
    {
        [LoadColumn(0)]
        public string SentimentText;
    
        [LoadColumn(1)]
        [ColumnName("Label")]
        public bool Sentiment;
    }
    
  4. W Eksplorator rozwiązań kliknij prawym przyciskiem myszy katalog DataModels, a następnie wybierz polecenie Dodaj > klasę.

  5. W oknie dialogowym Dodawanie nowego elementu wybierz pozycję Klasa i zmień pole Nazwa na SentimentPrediction.cs. Następnie wybierz przycisk Dodaj . Plik SentimentPrediction.cs zostanie otwarty w edytorze kodu. Dodaj następującą using dyrektywę na początku SentimentPrediction.cs:

    using Microsoft.ML.Data;
    

    Usuń istniejącą definicję klasy i dodaj następujący kod do pliku SentimentPrediction.cs :

    public class SentimentPrediction : SentimentData
    {
    
        [ColumnName("PredictedLabel")]
        public bool Prediction { get; set; }
    
        public float Probability { get; set; }
    
        public float Score { get; set; }
    }
    

    SentimentPrediction dziedziczy, z SentimentData którego zapewnia dostęp do oryginalnych danych we SentimentText właściwości, a także danych wyjściowych wygenerowanych przez model.

Rejestrowanie usługi PredictionEnginePool

Aby utworzyć pojedyncze przewidywanie, musisz utworzyć element PredictionEngine. PredictionEngine nie jest bezpieczny wątkowo. Ponadto należy utworzyć wystąpienie wszędzie tam, gdzie jest potrzebne w aplikacji. W miarę rozwoju aplikacji ten proces może stać się niezarządzany. W celu zwiększenia wydajności i bezpieczeństwa wątków należy użyć kombinacji wstrzykiwania zależności i PredictionEnginePool usługi, która tworzy ObjectPool PredictionEngine obiekty do użytku w całej aplikacji.

Poniższy link zawiera więcej informacji, jeśli chcesz dowiedzieć się więcej na temat wstrzykiwania zależności.

  1. W Eksplorator rozwiązań kliknij prawym przyciskiem myszy projekt, a następnie wybierz polecenie Dodaj>klasę.

  2. W oknie dialogowym Dodawanie nowego elementu wybierz pozycję Klasa i zmień pole Nazwa na Startup.cs. Następnie wybierz przycisk Dodaj .

  3. Dodaj następujące using dyrektywy na początku 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. Usuń istniejący kod poniżej using dyrektyw i dodaj następujący kod:

    [assembly: FunctionsStartup(typeof(Startup))]
    namespace SentimentAnalysisFunctionsApp
    {
        public class Startup : FunctionsStartup
        {
    
        }
    }
    
  5. Zdefiniuj zmienne do przechowywania środowiska, w którym działa aplikacja, oraz ścieżkę pliku, w której znajduje się model w Startup klasie

    private readonly string _environment;
    private readonly string _modelPath;
    
  6. Poniżej utwórz konstruktor, aby ustawić wartości _environment zmiennych i _modelPath . Gdy aplikacja jest uruchomiona lokalnie, domyślne środowisko to Programowanie.

    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. Następnie dodaj nową metodę o nazwie Configure , aby zarejestrować usługę PredictionEnginePool poniżej konstruktora.

    public override void Configure(IFunctionsHostBuilder builder)
    {
        builder.Services.AddPredictionEnginePool<SentimentData, SentimentPrediction>()
            .FromFile(modelName: "SentimentAnalysisModel", filePath: _modelPath, watchForChanges: true);
    }
    

Na wysokim poziomie ten kod inicjuje obiekty i usługi automatycznie do późniejszego użycia w przypadku żądania przez aplikację zamiast konieczności ręcznego wykonania.

Modele uczenia maszynowego nie są statyczne. Gdy nowe dane szkoleniowe staną się dostępne, model jest ponownie trenowany i wdrażany ponownie. Jednym ze sposobów pobrania najnowszej wersji modelu do aplikacji jest ponowne uruchomienie lub ponowne wdrożenie aplikacji. Jednak powoduje to przestój aplikacji. Usługa PredictionEnginePool udostępnia mechanizm ponownego ładowania zaktualizowanego modelu bez ponownego uruchamiania lub ponownego wdrażania aplikacji.

watchForChanges Ustaw parametr na truewartość , a PredictionEnginePool parametr uruchamia FileSystemWatcher element , który nasłuchuje powiadomień o zmianie systemu plików i zgłasza zdarzenia w przypadku zmiany pliku. Spowoduje to wyświetlenie monitu o PredictionEnginePool automatyczne ponowne załadowanie modelu.

Model jest identyfikowany przez modelName parametr, aby można było ponownie załadować więcej niż jeden model na aplikację po zmianie.

Napiwek

Alternatywnie można użyć FromUri metody podczas pracy z modelami przechowywanymi zdalnie. Zamiast obserwować zdarzenia zmienionego pliku, FromUri sonduje zdalną lokalizację pod kątem zmian. Interwał sondowania domyślnie to 5 minut. Możesz zwiększyć lub zmniejszyć interwał sondowania na podstawie wymagań aplikacji. W poniższym PredictionEnginePool przykładzie kodu sonduje model przechowywany w określonym identyfikatorze URI co 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));

Ładowanie modelu do funkcji

Wstaw następujący kod w klasie AnalyzeSentiment :

public AnalyzeSentiment(PredictionEnginePool<SentimentData, SentimentPrediction> predictionEnginePool)
{
    _predictionEnginePool = predictionEnginePool;
}

Ten kod przypisuje element PredictionEnginePool , przekazując go do konstruktora funkcji, który uzyskuje się za pośrednictwem wstrzykiwania zależności.

Korzystanie z modelu do przewidywania

Zastąp istniejącą implementację metody Run w klasie AnalyzeSentiment następującym kodem:

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);
}

Po wykonaniu Run metody dane przychodzące z żądania HTTP są deserializowane i używane jako dane wejściowe dla elementu PredictionEnginePool. Predict Następnie metoda jest wywoływana w celu przewidywania przy użyciu zarejestrowanego SentimentAnalysisModel Startup w klasie klasy i zwraca wyniki z powrotem do użytkownika, jeśli zakończy się to pomyślnie.

Testowanie lokalne

Teraz, gdy wszystko jest skonfigurowane, nadszedł czas na przetestowanie aplikacji:

  1. Uruchamianie aplikacji

  2. Otwórz program PowerShell i wprowadź kod w wierszu polecenia, w którym port jest portem, na którym działa aplikacja. Zazwyczaj port to 7071.

    Invoke-RestMethod "http://localhost:<PORT>/api/AnalyzeSentiment" -Method Post -Body (@{SentimentText="This is a very bad steak"} | ConvertTo-Json) -ContentType "application/json"
    

    W przypadku powodzenia dane wyjściowe powinny wyglądać podobnie do poniższego tekstu:

    Negative
    

Gratulacje! Model został pomyślnie obsłużyny w celu przewidywania za pośrednictwem Internetu przy użyciu funkcji platformy Azure.

Następne kroki