Implantar um modelo no Azure Functions

Saiba como implantar um modelo de aprendizado de máquina ML.NET pré-treinado para previsões sobre HTTP por meio de um ambiente sem servidor do Azure Functions.

Pré-requisitos

  • Visual Studio 2022 com as cargas de trabalho de desenvolvimento de área de trabalho .NET e desenvolvimento do Azure instaladas. O SDK do .NET 6 é instalado automaticamente quando você seleciona essa carga de trabalho.
  • Ferramentas do Azure Functions
  • PowerShell
  • Modelo pré-treinado. Transfira este modelo de aprendizagem automática de análise de sentimento pré-treinado ou utilize o tutorial de Análise de Sentimento ML.NET para criar o seu próprio modelo.

Visão geral do exemplo do Azure Functions

Este exemplo é um aplicativo C# HTTP Trigger Azure Functions que usa um modelo de classificação binária pré-treinado para categorizar o sentimento do texto como positivo ou negativo. O Azure Functions fornece uma maneira fácil de executar pequenos pedaços de código em escala em um ambiente gerenciado sem servidor na nuvem. O código para este exemplo pode ser encontrado no repositório dotnet/machinelearning-samples no GitHub.

Criar projeto do Azure Functions

  1. No Visual Studio 2022, abra a caixa de diálogo Criar um novo projeto .

  2. Na caixa de diálogo "Criar um novo projeto", selecione o modelo de projeto do Azure Functions .

  3. Na caixa de texto Nome , digite "SentimentAnalysisFunctionsApp" e selecione o botão Avançar .

  4. Na caixa de diálogo "Informações adicionais", deixe todos os padrões como estão e selecione o botão Criar .

  5. Instalar o Microsoft.ML pacote NuGet

    1. No Gerenciador de Soluções, clique com o botão direito do mouse em seu projeto e selecione Gerenciar Pacotes NuGet.
    2. Escolha "nuget.org" como a fonte do pacote.
    3. Selecione a guia "Procurar".
    4. Pesquise Microsoft.ML.
    5. Selecione esse pacote na lista e selecione o botão Instalar .
    6. Selecione o botão OK na caixa de diálogo Visualizar alterações
    7. Selecione o botão Aceito na caixa de diálogo Aceitação de licença se concordar com os termos de licença para os pacotes listados.

    Siga as mesmas etapas para instalar os pacotes NuGet Microsoft.Extensions.ML, Microsoft.Extensions.DependencyInjection e Microsoft.Azure.Functions.Extensions .

Adicionar modelo pré-treinado ao projeto

  1. Crie um diretório chamado MLModels em seu projeto para salvar seu modelo de pré-compilação: No Gerenciador de Soluções, clique com o botão direito do mouse em seu projeto e selecione Adicionar > Nova Pasta. Digite "MLModels" e pressione Enter.
  2. Copie seu modelo pré-criado para a pasta MLModels .
  3. No Gerenciador de Soluções, clique com o botão direito do mouse no arquivo de modelo pré-criado e selecione Propriedades. Em Avançado, altere o valor de Copiar para Diretório de Saída para Copiar se for mais recente.

Criar a Função do Azure para analisar o sentimento

Crie uma classe para prever o sentimento. Adicione uma nova classe ao seu projeto:

  1. No Gerenciador de Soluções, clique com o botão direito do mouse no projeto e selecione Adicionar>Nova Função do Azure.

  2. Na caixa de diálogo Adicionar Novo Item, selecione Função do Azure e altere o campo Nome para AnalyzeSentiment.cs. Em seguida, selecione o botão Adicionar .

  3. Na caixa de diálogo Nova Função do Azure, selecione Gatilho Http e escolha Anônimo na lista suspensa Nível de autorização. Em seguida, selecione o botão OK .

    O arquivo AnalyzeSentiment.cs é aberto no editor de códigos. Adicione a seguinte using instrução ao topo da 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;
    

    Por padrão, a AnalyzeSentiment classe é static. Certifique-se de remover a static palavra-chave da definição de classe.

    public class AnalyzeSentiment
    {
    
    }
    

Criar modelos de dados

Você precisa criar algumas classes para seus dados de entrada e previsões. Adicione uma nova classe ao seu projeto:

  1. Crie um diretório chamado DataModels em seu projeto para salvar seus modelos de dados: No Gerenciador de Soluções , clique com o botão direito do mouse em seu projeto e selecione Adicionar > Nova Pasta. Digite "DataModels" e pressione Enter.

  2. No Gerenciador de Soluções, clique com o botão direito do mouse no diretório DataModels e selecione Adicionar > Classe.

  3. Na caixa de diálogo Adicionar Novo Item, selecione Classe e altere o campo Nome para SentimentData.cs. Em seguida, selecione o botão Adicionar .

    O arquivo SentimentData.cs é aberto no editor de códigos. Adicione a seguinte instrução using à parte superior da SentimentData.cs:

    using Microsoft.ML.Data;
    

    Remova a definição de classe existente e adicione o seguinte código ao arquivo SentimentData.cs :

    public class SentimentData
    {
        [LoadColumn(0)]
        public string SentimentText;
    
        [LoadColumn(1)]
        [ColumnName("Label")]
        public bool Sentiment;
    }
    
  4. No Gerenciador de Soluções, clique com o botão direito do mouse no diretório DataModels e selecione Adicionar > Classe.

  5. Na caixa de diálogo Adicionar Novo Item, selecione Classe e altere o campo Nome para SentimentPrediction.cs. Em seguida, selecione o botão Adicionar . O arquivo SentimentPrediction.cs é aberto no editor de códigos. Adicione a seguinte instrução using à parte superior da SentimentPrediction.cs:

    using Microsoft.ML.Data;
    

    Remova a definição de classe existente e adicione o seguinte código ao arquivo SentimentPrediction.cs :

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

    SentimentPrediction Herda a partir da SentimentData qual fornece acesso aos dados originais na propriedade, SentimentText bem como a saída gerada pelo modelo.

Registrar o serviço PredictionEnginePool

Para fazer uma única previsão, você tem que criar um PredictionEnginearquivo . PredictionEngine não é thread-safe. Além disso, você precisa criar uma instância dele em todos os lugares em que for necessário em seu aplicativo. À medida que seu aplicativo cresce, esse processo pode se tornar incontrolável. Para melhorar o desempenho e a segurança de threads, use uma combinação de injeção de dependência e o serviço, que cria um ObjectPool de PredictionEngine objetos para uso em todo o PredictionEnginePool aplicativo.

O link a seguir fornece mais informações se você quiser saber mais sobre a injeção de dependência.

  1. No Gerenciador de Soluções, clique com o botão direito do mouse no projeto e selecione Adicionar>Classe.

  2. Na caixa de diálogo Adicionar Novo Item, selecione Classe e altere o campo Nome para Startup.cs. Em seguida, selecione o botão Adicionar .

  3. Adicione as seguintes instruções using à parte superior do 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. Remova o código existente abaixo das instruções using e adicione o seguinte código:

    [assembly: FunctionsStartup(typeof(Startup))]
    namespace SentimentAnalysisFunctionsApp
    {
        public class Startup : FunctionsStartup
        {
    
        }
    }
    
  5. Definir variáveis para armazenar o ambiente em que o aplicativo está sendo executado e o caminho do arquivo onde o modelo está localizado dentro da Startup classe

    private readonly string _environment;
    private readonly string _modelPath;
    
  6. Abaixo disso, crie um construtor para definir os valores das _environment variáveis e _modelPath . Quando o aplicativo está sendo executado localmente, o ambiente padrão é Desenvolvimento.

    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. Em seguida, adicione um novo método chamado Configure para registrar o PredictionEnginePool serviço abaixo do construtor.

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

Em um alto nível, esse código inicializa os objetos e serviços automaticamente para uso posterior quando solicitado pelo aplicativo, em vez de ter que fazê-lo manualmente.

Os modelos de aprendizado de máquina não são estáticos. À medida que novos dados de treinamento ficam disponíveis, o modelo é retreinado e reimplantado. Uma maneira de obter a versão mais recente do modelo em seu aplicativo é reiniciar ou reimplantar seu aplicativo. No entanto, isso introduz o tempo de inatividade do aplicativo. O PredictionEnginePool serviço fornece um mecanismo para recarregar um modelo atualizado sem reiniciar ou reimplantar seu aplicativo.

Defina o watchForChanges parâmetro como true, e inicia PredictionEnginePool um FileSystemWatcher que escuta as notificações de alteração do sistema de arquivos e gera eventos quando há uma alteração no arquivo. Isso solicita que o PredictionEnginePool recarregue automaticamente o modelo.

O modelo é identificado pelo parâmetro para que mais de um modelo por aplicativo possa ser recarregado após a modelName alteração.

Gorjeta

Como alternativa, você pode usar o FromUri método ao trabalhar com modelos armazenados remotamente. Em vez de observar eventos de alteração de arquivo, FromUri sonda o local remoto em busca de alterações. O intervalo de sondagem tem como padrão 5 minutos. Você pode aumentar ou diminuir o intervalo de sondagem com base nos requisitos do seu aplicativo. No exemplo de código abaixo, as PredictionEnginePool sondagens do modelo armazenado no URI especificado a cada minuto.

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

Carregue o modelo na função

Insira o seguinte código dentro da classe AnalyzeSentiment :

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

Este código atribui o PredictionEnginePool passando para o construtor da função que você obtém através da injeção de dependência.

Use o modelo para fazer previsões

Substitua a implementação existente do método Run na classe AnalyzeSentiment pelo seguinte código:

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

Quando o Run método é executado, os dados de entrada da solicitação HTTP são desserializados e usados como entrada para o PredictionEnginePool. O Predict método é então chamado para fazer previsões usando o SentimentAnalysisModel registrado na Startup classe e retorna os resultados de volta para o usuário se bem-sucedido.

Teste localmente

Agora que tudo está configurado, é hora de testar o aplicativo:

  1. Executar a aplicação

  2. Abra o PowerShell e insira o código no prompt onde PORT é a porta em que seu aplicativo está sendo executado. Normalmente, a porta é 7071.

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

    Se for bem-sucedida, a saída deve ser semelhante ao texto abaixo:

    Negative
    

Parabéns! Você serviu com êxito seu modelo para fazer previsões pela Internet usando uma Função do Azure.

Passos Seguintes