Compartilhar via


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

Saiba como servir um modelo de machine learning de ML.NET pré-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

  • Visual Studio 2022 com carga de trabalho ASP.NET e desenvolvimento Web.
  • PowerShell.
  • Modelo previamente treinado. Use o tutorial de Análise de Sentimento ML.NET para criar seu próprio modelo ou baixar este modelo de machine learning de análise de sentimento pré-treinado .

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 de 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 diretivas 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 insira o código a seguir, 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ê serviu com êxito seu modelo para fazer previsões pela Internet usando uma API Web do ASP.NET Core.

Próximas etapas