Implantar um modelo em uma API Web do ASP.NET Core

Saiba como fornecer um modelo de machine Learning do ML.NET previamente treinado na Web usando uma API Web do ASP.NET Core. Veicular um modelo por uma API Web habilita previsões por meio de métodos HTTP padrão.

Pré-requisitos

Criar o projeto da API Web do ASP.NET Core

  1. Inicie o Visual Studio 2022 e selecione Criar um novo projeto.

  2. Na caixa de diálogo Criar um projeto:

    • Digite Web API na caixa de pesquisa.
    • Selecione o modelo API Web do ASP.NET Core e Avançar.
  3. Na caixa de diálogo Configurar seu projeto:

    • Nomeie o projeto como SentimentAnalysisWebAPI.
    • Selecione Avançar.
  4. Na caixa de diálogo Informações adicionais:

    • Desmarque Não usar declarações de nível superior.
    • Selecione Criar.
  5. Instale os seguintes pacotes NuGet:

    Para obter mais detalhes sobre como instalar pacotes NuGet no Visual Studio, confira o guia Instalar e usar um pacote NuGet no Visual Studio .

Adicionar um modelo ao projeto da API Web do ASP.NET Core

  1. Copie seu modelo predefinido para o diretório do projeto SentimentAnalysisWebAPI .

  2. Configure seu projeto para copiar o arquivo do modelo para o diretório de saída. No Gerenciador de Soluções:

    • Clique com o botão direito do mouse no arquivo zip do modelo e selecione Propriedades.
    • Em Avançado, altere o valor de Copiar para diretório de saída para Copiar se for mais novo.

Criar modelo de dados

Você precisa criar algumas classes para definir o esquema de entrada e saída do modelo.

Observação

As propriedades das classes de esquema de entrada e saída dependem das colunas de conjunto de dados usadas para treinar seu modelo, bem como da tarefa de aprendizado de máquina (regressão, classificação etc.).

Em seu arquivo Program.cs:

  1. Adicione as seguintes instruções using:

    using Microsoft.ML.Data;
    using Microsoft.Extensions.ML;
    
  2. No final do arquivo, adicione as seguintes classes:

    Entrada de modelo

    Para esse modelo, a entrada contém uma única propriedade SentimentText, que é uma cadeia de caracteres que representa um comentário do usuário.

    public class ModelInput
    {
        public string SentimentText;
    }
    

    Saída do modelo

    Depois que o modelo avalia a entrada, ele gera uma previsão com três propriedades: Sentiment, Probability e Score. Nesse caso, o Sentiment é o sentimento previsto do comentário do usuário e o Probability e Score são medidas de confiança para a previsão.

    public class ModelOutput
    {
        [ColumnName("PredictedLabel")]
        public bool Sentiment { get; set; }
    
        public float Probability { get; set; }
    
        public float Score { get; set; }
    }
    

Registrar PredictionEnginePool para uso no aplicativo

Para fazer uma única previsão, você precisa criar um PredictionEngine. PredictionEngine não é thread-safe. Além disso, você precisa criar uma instância dele em qualquer lugar em que seja necessário dentro de seu aplicativo. À medida que seu aplicativo cresce, esse processo pode se tornar não gerenciável. Para melhorar o desempenho e o acesso thread-safe, use uma combinação de injeção de dependência e o serviço PredictionEnginePool, que cria um ObjectPool dos objetos PredictionEngine para uso em todo o aplicativo.

O link a seguir fornece mais informações sobre a injeção de dependência no ASP.NET Core.

Adicione o seguinte código ao seu arquivo Program.cs:

builder.Services.AddPredictionEnginePool<ModelInput, ModelOutput>()
    .FromFile(modelName: "SentimentAnalysisModel", filePath: "sentiment_model.zip", 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 precisar fazê-lo manualmente.

Os modelos de machine learning não são estáticos. À medida que novos dados de treinamento se tornam 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 tempo de inatividade do aplicativo. O serviço PredictionEnginePool fornece um mecanismo para recarregar um modelo atualizado sem reiniciar ou reimplantar seu aplicativo.

Defina o parâmetro watchForChanges como true, e o PredictionEnginePool inicia 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 modelName para que mais de um modelo por aplicativo possa ser recarregado após a alteração.

Dica

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

Mapear ponto de extremidade de previsão

Para processar as solicitações HTTP de entrada, crie um ponto de extremidade.

Substitua o ponto de extremidade / pelo seguinte:

var predictionHandler =
    async (PredictionEnginePool<ModelInput, ModelOutput> predictionEnginePool, ModelInput input) =>
        await Task.FromResult(predictionEnginePool.Predict(modelName: "SentimentAnalysisModel", input));

app.MapPost("/predict", predictionHandler);

O ponto de extremidade /predict aceita solicitações HTTP POST e usa o pool de mecanismos de previsão para retornar uma previsão usando a entrada fornecida.

Quando terminar, o Program.cs deverá parecer com este:

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

Testar a API Web localmente

Depois que tudo estiver definido, é hora de testar o aplicativo.

  1. Executar o aplicativo.

  2. Abra o PowerShell e digite o seguinte código, em que PORT é a porta em que seu aplicativo está escutando.

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

    Se houver êxito, a saída deverá ser semelhante ao texto abaixo:

    sentiment probability score
    --------- ----------- -----
    False         0.5     0
    

Parabéns! Você usou com êxito seu modelo para fazer previsões pela internet usando um ASP.NET Core API Web.

Próximas etapas