Implantar um modelo em uma API Web ASP.NET Core

Saiba como servir um modelo de aprendizado de máquina ML.NET pré-treinado na Web usando uma API Web ASP.NET Core. Servir um modelo através de uma API da Web permite previsões através de métodos HTTP padrão.

Pré-requisitos

Criar ASP.NET projeto de API Web principal

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

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

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

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

    • Desmarque Não usar instruçõ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, consulte o guia Instalar e usar um pacote NuGet no Visual Studio .

Adicionar modelo a ASP.NET projeto de API Web principal

  1. Copie seu modelo pré-construído para o diretório do projeto SentimentAnalysisWebAPI .

  2. Configure seu projeto para copiar seu arquivo de 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 recente.

Criar modelos de dados

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

Nota

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

No seu ficheiro Program.cs :

  1. Utilize instruções para adicionar o seguinte:

    using Microsoft.ML.Data;
    using Microsoft.Extensions.ML;
    
  2. Na parte inferior do arquivo, adicione as seguintes classes:

    Entrada do modelo

    Para este 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

    Uma vez que o modelo avalia a entrada, ele produz uma previsão com três propriedades: Sentiment, Probability, e Score. Neste 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; }
    }
    

Registre PredictionEnginePool para uso no aplicativo

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

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

Mapa prever ponto final

Para processar suas 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 /predict ponto de extremidade aceita solicitações HTTP POST e usa o pool do mecanismo de previsão para retornar uma previsão usando a entrada fornecida.

Quando terminar, o seu Program.cs deverá ter o seguinte aspeto:

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

Teste a API da Web localmente

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

  1. Execute a aplicação.

  2. Abra o PowerShell e insira o código a seguir, onde 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 for bem-sucedida, a saída deve ser semelhante ao texto abaixo:

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

Parabéns! Você serviu com sucesso seu modelo para fazer previsões pela Internet usando um ASP.NET Core Web API.

Passos Seguintes