Развертывание модели в Функциях Azure
Сведения о развертывании предварительно обученной модели машинного обучения ML.NET для создания прогнозов по протоколу HTTP через бессерверную среду Функций Azure.
Необходимые компоненты
- Visual Studio 2022 с установленными рабочими нагрузками разработки классических приложений .NET и Azure. Пакет SDK для .NET 6 устанавливается автоматически при выборе этой рабочей нагрузки.
- Средства Функций Azure.
- PowerShell
- Предварительно обученная модель. Скачайте эту предварительно обученную модель машинного обучения анализа тональности или используйте руководство по анализу тональности ML.NET для создания собственной модели.
Обзор примера для Функций Azure
В этом примере предоставляется приложение триггера HTTP на языке C# для Функций Azure, которое использует предварительно обученную модель двоичной классификации для выбора положительной или отрицательной тональности текста. Функции Azure предоставляют простой способ выполнять небольшие фрагменты кода в большом масштабе для управляемой бессерверной облачной среды. Код для этого примера можно найти в репозитории dotnet/machinelearning-samples на сайте GitHub.
Создание проекта Функций Azure
В Visual Studio 2022 откройте диалоговое окно "Создание проекта ".
В диалоговом окне "Создание проекта" выберите шаблон проекта Функции Azure.
В текстовом поле "Имя " введите "SentimentAnalysisFunctionsApp" и нажмите кнопку "Далее ".
В диалоговом окне "Дополнительные сведения" оставьте все значения по умолчанию и нажмите кнопку "Создать ".
Установка пакета NuGet Microsoft.ML
- В обозревателе решений щелкните проект правой кнопкой мыши и выберите Управление пакетами NuGet.
- Выберите nuget.org в качестве источника пакета.
- Перейдите на вкладку "Обзор".
- Выполните поиск Microsoft.ML.
- Выберите этот пакет в списке и нажмите кнопку "Установить ".
- Нажмите кнопку ОК в диалоговом окне Предварительный просмотр изменений.
- Нажмите кнопку Принимаю в диалоговом окне Принятие условий лицензионного соглашения, если вы согласны с условиями лицензионного соглашения для указанных пакетов.
Выполните те же действия, чтобы установить пакеты NuGet Microsoft.Extensions.ML, Microsoft.Extensions.DependencyInjection и Microsoft.Azure.Functions.Extensions .
Добавление предварительно обученной модели в проект
- Создайте каталог с именем MLModels в проекте, чтобы сохранить модель предварительной сборки: в Обозреватель решений щелкните проект правой кнопкой мыши и выберите "Добавить > новую папку". Введите MLModels и нажмите клавишу ВВОД.
- Скопируйте предварительно созданную модель в папку MLModels.
- В обозревателе решений щелкните правой кнопкой мыши файл предварительно созданной модели и выберите Свойства. В разделе Дополнительно для параметра Копировать в выходной каталог установите значение Копировать более позднюю версию.
Создание функции Azure для анализа тональности
Создайте класс для прогнозирования тональности. Добавьте в проект новый класс:
В Обозреватель решений щелкните проект правой кнопкой мыши и выберите "Добавить>новую функцию Azure".
В диалоговом окне Добавление нового элемента выберите Функция Azure и измените значение поля Имя на AnalyzeSentiment.cs. Теперь нажмите кнопку Добавить.
В диалоговом окне "Новая функция Azure" выберите "Триггер HTTP" и выберите "Анонимный" в раскрывающемся списке "Уровень авторизации". Затем нажмите кнопку OK.
В редакторе кода откроется файл AnalyzeSentiment.cs. Добавьте следующую
using
директиву в начало 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;
По умолчанию класс
AnalyzeSentiment
—static
. Удалите ключевое словоstatic
из объявления класса.public class AnalyzeSentiment { }
Создание моделей данных
Вам потребуется создать несколько классов для входных данных и прогнозов. Добавьте в проект новый класс:
Создайте каталог с именем DataModels в проекте для сохранения моделей данных: в Обозреватель решений щелкните проект правой кнопкой мыши и выберите "Добавить > новую папку". Введите DataModels и нажмите клавишу ВВОД.
В Обозреватель решений щелкните правой кнопкой мыши каталог DataModels и выберите пункт "Добавить > класс".
В диалоговом окне Добавление нового элемента выберите Класс и измените значение поля Имя на SentimentData.cs. Теперь нажмите кнопку Добавить.
Файл SentimentData.cs откроется в редакторе кода. Добавьте следующую
using
директиву в начало SentimentData.cs:using Microsoft.ML.Data;
Удалите из файла SentimentData.cs существующее определение класса и добавьте следующий код:
public class SentimentData { [LoadColumn(0)] public string SentimentText; [LoadColumn(1)] [ColumnName("Label")] public bool Sentiment; }
В Обозреватель решений щелкните правой кнопкой мыши каталог DataModels и выберите пункт "Добавить > класс".
В диалоговом окне Добавление нового элемента выберите Класс и измените значение поля Имя на SentimentPrediction.cs. Теперь нажмите кнопку Добавить. В редакторе кода откроется файл SentimentPrediction.cs. Добавьте следующую
using
директиву в начало SentimentPrediction.cs:using Microsoft.ML.Data;
Удалите из файла SentimentPrediction.cs существующее определение класса и добавьте следующий код:
public class SentimentPrediction : SentimentData { [ColumnName("PredictedLabel")] public bool Prediction { get; set; } public float Probability { get; set; } public float Score { get; set; } }
SentimentPrediction
наследует отSentimentData
, который обеспечивает доступ к исходным данным в свойствеSentimentText
, а также выходным данным модели.
Регистрация службы PredictionEnginePool
Для формирования одного прогноза необходимо создать PredictionEngine
. PredictionEngine
не является потокобезопасным. Кроме того, необходимо создать его экземпляр везде, где он понадобится в вашем приложении. По мере увеличения размера приложения этот процесс может стать неуправляемым. Для улучшенной производительности и потокобезопасности используйте сочетание внедрения зависимостей и службы PredictionEnginePool
, которое создает объекты PredictionEngine
(ObjectPool
) для использования во всем приложении.
См. дополнительные сведения о внедрении зависимостей по следующей ссылке.
В Обозреватель решений щелкните проект правой кнопкой мыши и выберите пункт "Добавить>класс".
В диалоговом окне Добавление нового элемента выберите Класс и измените значение поля Имя на Startup.cs. Теперь нажмите кнопку Добавить.
Добавьте следующие
using
директивы в начало 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;
Удалите существующий код под
using
директивами и добавьте следующий код:[assembly: FunctionsStartup(typeof(Startup))] namespace SentimentAnalysisFunctionsApp { public class Startup : FunctionsStartup { } }
Определите в классе
Startup
переменные для хранения среды, в которой выполняется приложение, и путь к файлу, в котором находится модель.private readonly string _environment; private readonly string _modelPath;
Ниже показано, как создать конструктор для задания значений переменных
_environment
и_modelPath
. При локальном запуске приложения средой по умолчанию считается среда Development (Разработка).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"); } }
Затем добавьте под конструктором новый метод с именем
Configure
, который будет регистрировать службуPredictionEnginePool
.public override void Configure(IFunctionsHostBuilder builder) { builder.Services.AddPredictionEnginePool<SentimentData, SentimentPrediction>() .FromFile(modelName: "SentimentAnalysisModel", filePath: _modelPath, watchForChanges: true); }
Вкратце, этот код инициализирует объекты и службы автоматически для использования в дальнейшем по запросу приложения, вместо того чтобы вы делали это вручную.
Модели машинного обучения не являются статическими. По мере появления новых данных для обучения модель переобучается и развертывается повторно. Одним из способов получения последней версии модели в приложении является повторный запуск или повторное развертывание всего приложения. Однако это приводит к простою приложения. Служба PredictionEnginePool
предоставляет механизм перезагрузки обновленной модели без перезапуска или повторного развертывания приложения.
Задайте для параметра watchForChanges
значение true
. В таком случае PredictionEnginePool
запустит объект FileSystemWatcher
, который прослушивает уведомления об изменениях файловой системы и вызывает события при изменении файла. При наличии изменений PredictionEnginePool
автоматически перезагружает модель.
Модель определяется параметром modelName
, поэтому при изменении может быть перезагружено несколько моделей на одно приложение.
Совет
Кроме того, можно использовать метод FromUri
при работе с моделями, сохраненными удаленно. Вместо наблюдения за событиями изменения файлов FromUri
опрашивает удаленное расположение на предмет изменений. Интервал опроса по умолчанию равен 5 минутам. Вы можете увеличить или уменьшить интервал опроса в зависимости от требований вашего приложения. В приведенном ниже примере кода PredictionEnginePool
опрашивает модель, сохраненную по указанному универсальному коду ресурса (URI), каждую минуту.
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));
Загрузка модели в функцию
Вставьте следующий код внутри класса AnalyzeSentiment:
public AnalyzeSentiment(PredictionEnginePool<SentimentData, SentimentPrediction> predictionEnginePool)
{
_predictionEnginePool = predictionEnginePool;
}
Этот код назначает PredictionEnginePool
, передав его в конструктор функции, который можно получить путем внедрения зависимостей.
Использование модели для прогнозирования
Замените существующую реализацию метода запуска в классе AnalyzeSentiment следующим кодом:
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);
}
Когда метод Run
выполняется, входящие данные из HTTP-запроса десериализуются и используются в качестве входных данных для PredictionEnginePool
. Затем метод Predict
вызывается для формирования прогнозов с использованием модели SentimentAnalysisModel
, зарегистрированной в классе Startup
, и возвращает результаты пользователю в случае успеха.
Локальное тестирование.
Завершив настройку параметров, протестируйте приложение:
Выполнение приложения
Откройте PowerShell и введите код в командной строке, где PORT — это порт, через который работает приложение. Как правило, используется порт 7071.
Invoke-RestMethod "http://localhost:<PORT>/api/AnalyzeSentiment" -Method Post -Body (@{SentimentText="This is a very bad steak"} | ConvertTo-Json) -ContentType "application/json"
В случае успешного выполнения результат должен выглядеть, как показано ниже:
Negative
Поздравляем! Вы успешно использовали модель для прогнозирования через Интернет с помощью Функций Azure.