共用方式為


在 ASP.NET Core Web API 中部署模型

了解如何使用 ASP.NET Core Web API,在 Web 上提供預先定型的 ML.NET 機器學習模型。 透過 Web API 提供模型可讓您透過標準 HTTP 方法進行預測。

必要條件

建立 ASP.NET Core Web API 專案

  1. 啟動 Visual Studio 2022 並選取 [建立新專案]

  2. 在 [建立新專案] 對話方塊中:

    • 在搜尋方塊中輸入 Web API
    • 選取 [ASP.NET Core Web API] 範本,然後選取 [下一步]
  3. 在 [設定您的專案] 對話方塊中:

    • 將您的專案命名為 SentimentAnalysisWebAPI
    • 選取 [下一步]。
  4. 在 [其他資訊] 對話方塊中:

    • 取消勾選 [不要使用最上層陳述式]
    • 選取 建立
  5. 安裝下列 NuGet 套件:

    如需在 Visual Studio 中安裝 NuGet 套件的詳細資訊,請參閱在 Visual Studio 中安裝並使用 NuGet 套件指南。

將模型新增至 ASP.NET Core Web API 專案

  1. 將預先建置的模型複製到 SentimentAnalysisWebAPI 專案目錄。

  2. 設定您的專案,以將模型檔案複製到輸出目錄。 在方案總管中:

    • 以滑鼠右鍵按一下模型 ZIP 檔案,然後選取 [屬性]
    • 在 [進階] 底下,將 [複製到輸出目錄] 的值變更為 [有更新才複製]

建立資料模型

您必須建立一些類別,以定義模型輸入和輸出的結構描述。

注意

輸入和輸出結構描述類別的屬性取決於用來定型模型的資料集資料行,以及機器學習工作 (迴歸、分類等)。

在您的 Program.cs 檔案中:

  1. 新增下列 using 指示詞:

    using Microsoft.ML.Data;
    using Microsoft.Extensions.ML;
    
  2. 在檔案底部,新增下列類別:

    模型輸入

    此模型的輸入包含單一屬性 SentimentText,這是代表使用者註解的字串。

    public class ModelInput
    {
        public string SentimentText;
    }
    

    模型輸出

    模型在評估輸入後,會輸出具有三個屬性的預測:SentimentProbabilityScore。 在此案例中,Sentiment 是使用者註解的預測情感,而 ProbabilityScore 是預測的信賴度量值。

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

登錄 PredictionEnginePool 以在應用程式中使用

若要進行單一預測,您必須建立 PredictionEnginePredictionEngine 不是安全執行緒。 此外,您必須在應用程式內有需要的任何地方建立其執行個體。 隨著應用程式成長,此程序可能會變得無法管理。 為了提升效能和執行緒安全性,請合併使用相依性插入與 PredictionEnginePool 服務,以建立 PredictionEngine 物件的 ObjectPool 供整個應用程式使用。

若您想要深入了解 ASP.NET Core 中的相依性插入,下列連結提供詳細資訊。

新增以下程式碼至您的 Program.cs 檔案:

builder.Services.AddPredictionEnginePool<ModelInput, ModelOutput>()
    .FromFile(modelName: "SentimentAnalysisModel", filePath: "sentiment_model.zip", watchForChanges: true);

概括而言,此程式碼會在應用程式要求時自動初始化物件和服務以供稍後使用,而不必手動執行。

機器學習模型不是靜態的。 當新的定型資料可供使用時,模型會重新定型並重新部署。 將最新版本的模型放入應用程式的方法之一,就是重新啟動或重新部署您的應用程式。 不過,這會導致應用程式停機。 此 PredictionEnginePool 服務提供一種機制來重新載入更新後的模型,而不需重新啟動或重新部署您的應用程式。

watchForChanges 參數設定為 true,並 PredictionEnginePool 啟動接聽檔案系統變更通知的 FileSystemWatcher,然後在檔案發生變更時引發事件。 這會提示 PredictionEnginePool 自動重新載入模型。

模型是由 modelName 參數所識別,讓每個應用程式可以在變更時重新載入多個模型。

提示

或者,您可以在使用遠端儲存的模型時使用 FromUri 方法。 FromUri 不會監看檔案變更事件,而是輪詢遠端位置是否有變更。 輪詢間隔預設為 5 分鐘。 您可以根據應用程式的需求增加或減少輪詢間隔。 在下列程式碼範例中,PredictionEnginePool 會每隔一分鐘輪詢儲存在指定 URI 的模型。

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

對應預測端點

若要處理傳入的 HTTP 要求,請建立端點。

/ 端點取代為下列內容:

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

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

端點 /predict 會接受 HTTP POST 要求,並使用預測引擎集區和提供的輸入傳回預測。

完成後,您的 Program.cs 應該會顯示如下:

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

在本機測試 Web API

一切都設定好後,就可以開始測試應用程式。

  1. 執行應用程式。

  2. 開啟 PowerShell 並輸入下列程式碼,其中 PORT 是應用程式正在接聽的連接埠。

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

    如果成功,輸出看起來應該類似下列文字:

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

恭喜! 您已成功提供您的模型,使用 ASP.NET Core Web API 在網際網路上進行預測。

後續步驟