Déployer un modèle sur Azure Functions
Découvrez comment déployer un modèle Machine Learning ML.NET préentraîné pour effectuer des prédictions sur HTTP par le bais d’un environnement serverless Azure Functions.
Prérequis
- Visual Studio 2022 avec les charges de travail Développement de bureau .NET et Développement Azure installées. Le SDK .NET 6 est automatiquement installé lorsque vous sélectionnez cette charge de travail.
- Azure Functions Tools ;
- PowerShell
- un modèle préentraîné : Téléchargez ce modèle d’analyse des sentiments préentraîné ou utilisez le tutoriel d’analyse des sentiments ML.NET pour créer votre propre modèle.
Vue d’ensemble de l’exemple Azure Functions
Cet exemple est un une application Azure Functions de déclencheur HTTP C# qui utilise un modèle de classification binaire préentraîné pour catégoriser le sentiment de texte comme positif ou négatif. Azure Functions fournit un moyen simple d’exécuter de petits morceaux de code à grande échelle sur un environnement serverless managé dans le cloud. Vous trouverez le code de cet exemple dans le dépôt dotnet/machinelearning-samples sur GitHub.
Créer un projet Azure Functions
Dans Visual Studio 2022, ouvrez la boîte de dialogue Créer un projet.
Dans la boîte de dialogue « Créer un projet », sélectionnez le modèle de projet Azure Functions.
Dans la zone de texte Nom, tapez « SentimentAnalysisFunctionsApp », puis sélectionnez le bouton Suivant.
Dans la boîte de dialogue « Informations supplémentaires », laissez toutes les valeurs par défaut, puis sélectionnez le bouton Créer.
Installez le package NuGet Microsoft.ML
- Dans l'Explorateur de solutions, cliquez avec le bouton droit sur votre projet, puis sélectionnez Gérer les packages NuGet.
- Choisissez « nuget.org » comme source du package.
- Sélectionnez l’onglet « Parcourir ».
- Recherchez Microsoft.ML.
- Sélectionnez ce package dans la liste, puis sélectionnez le bouton Installer.
- Sélectionnez le bouton OK dans la boîte de dialogue Aperçu des modifications
- Sélectionnez le bouton J’accepte dans la boîte de dialogue Acceptation de la licence si vous acceptez les termes du contrat de licence pour les packages de la liste.
Suivez les mêmes étapes pour installer les packages NuGet Microsoft.Extensions.ML, Microsoft.Extensions.DependencyInjection et Microsoft.Azure.Functions.Extensions.
Ajouter un modèle préentraîné au projet
- Créez un répertoire nommé MLModels dans votre projet pour enregistrer votre modèle prégénéré : dans l’Explorateur de solutions, cliquez avec le bouton droit sur votre projet, puis sélectionnez Ajouter > Nouveau dossier. Tapez « MLModels » et appuyez sur Entrée.
- Copiez votre modèle prédéfini dans le dossier MLModels.
- Dans l’Explorateur de solutions, cliquez avec le bouton droit sur votre fichier de modèle prédéfini et sélectionnez Propriétés. Sous Avancé, définissez la valeur Copier dans le répertoire de sortie sur Copier si plus récent.
Créer une fonction Azure d’analyse des sentiments
Créez une classe pour prédire le sentiment. Ajoutez une nouvelle classe à votre projet :
Dans l’Explorateur de solutions, cliquez avec le bouton de droite sur le projet, puis sélectionnez Ajouter>Nouvelle fonction Azure.
Dans la boîte de dialogue Ajouter un nouvel élément, sélectionnez Fonction Azure et remplacez la valeur du champ Nom par AnalyzeSentiment.cs. Ensuite, sélectionnez le bouton Ajouter.
Dans la boîte de dialogue Nouvelle fonction Azure, sélectionnez Déclencheur Http et choisissez Anonyme dans la liste déroulante Niveau d’autorisation. Ensuite, sélectionnez le bouton OK.
Le fichier AnalyzeSentiment.cs s’ouvre dans l’éditeur de code. Ajoutez la directive
using
suivante en haut de 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;
Par défaut, la classe
AnalyzeSentiment
eststatic
. Veillez à supprimer le mot cléstatic
de la définition de classe.public class AnalyzeSentiment { }
Créer des modèles de données
Vous devez créer des classes pour vos données d’entrée et prévisions. Ajoutez une nouvelle classe à votre projet :
Créez un répertoire nommé DataModels dans votre projet pour enregistrer vos modèles de données : dans l’Explorateur de solutions, cliquez avec le bouton droit sur votre projet et sélectionnez Ajouter > Nouveau dossier. Tapez « DataModels » et appuyez sur Entrée.
Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le répertoire DataModels, puis sélectionnez Ajouter > Classe.
Dans la boîte de dialogue Ajouter un nouvel élément, sélectionnez Classe, puis remplacez la valeur du champ Nom par SentimentData.cs. Ensuite, sélectionnez le bouton Ajouter.
Le fichier SentimentData.cs s’ouvre dans l’éditeur de code. Ajoutez la directive
using
suivante en haut de SentimentData.cs:using Microsoft.ML.Data;
Supprimez la définition de classe existante et ajoutez le code suivant au fichier SentimentData.cs :
public class SentimentData { [LoadColumn(0)] public string SentimentText; [LoadColumn(1)] [ColumnName("Label")] public bool Sentiment; }
Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le répertoire DataModels, puis sélectionnez Ajouter > Classe.
Dans la boîte de dialogue Ajouter un nouvel élément, sélectionnez Classe et remplacez la valeur du champ Nom par SentimentPrediction.cs. Ensuite, sélectionnez le bouton Ajouter. Le fichier SentimentPrediction.cs s’ouvre dans l’éditeur de code. Ajoutez la directive
using
suivante en haut de SentimentPrediction.cs:using Microsoft.ML.Data;
Supprimez la définition de classe existante et ajoutez le code suivant au fichier SentimentPrediction.cs :
public class SentimentPrediction : SentimentData { [ColumnName("PredictedLabel")] public bool Prediction { get; set; } public float Probability { get; set; } public float Score { get; set; } }
SentimentPrediction
hérite deSentimentData
, qui fournit l’accès aux données d’origine dans la propriétéSentimentText
ainsi que la sortie générée par le modèle.
Inscrire le service PredictionEnginePool
Pour effectuer une prédiction unique, vous devez créer un PredictionEngine
. PredictionEngine
n’est pas thread-safe. En outre, vous devez créer une instance de celui-ci partout où il est nécessaire dans votre application. À mesure que votre application croît, ce processus peut devenir non gérable. Pour améliorer les performances et la sécurité des threads, utilisez une combinaison d’injection de dépendances et du service PredictionEnginePool
, qui crée un ObjectPool
d’objets PredictionEngine
à utiliser dans votre application.
Pour plus d’informations, voir Injection de dépendances.
Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le projet, puis sélectionnez Ajouter>Classe.
Dans la boîte de dialogue Ajouter un nouvel élément, sélectionnez Classe et définissez la valeur du champ Nom sur Startup.cs. Ensuite, sélectionnez le bouton Ajouter.
Ajoutez les directives
using
suivantes en haut de 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;
Supprimez le code existant sous les directives
using
et ajoutez le code suivant :[assembly: FunctionsStartup(typeof(Startup))] namespace SentimentAnalysisFunctionsApp { public class Startup : FunctionsStartup { } }
Définissez des variables pour stocker l’environnement dans lequel l’application s’exécute et le chemin du fichier où se trouve le modèle à l’intérieur de la classe
Startup
private readonly string _environment; private readonly string _modelPath;
En dessous de cela, créez un constructeur pour définir les valeurs des variables
_environment
et_modelPath
. Lorsque l’application s’exécute localement, l’environnement par défaut est Développement.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"); } }
Ensuite, ajoutez une nouvelle méthode appelée
Configure
pour inscrire le servicePredictionEnginePool
sous le constructeur.public override void Configure(IFunctionsHostBuilder builder) { builder.Services.AddPredictionEnginePool<SentimentData, SentimentPrediction>() .FromFile(modelName: "SentimentAnalysisModel", filePath: _modelPath, watchForChanges: true); }
À haut niveau, ce code initialise automatiquement les objets et services pour une utilisation ultérieure à la demande de l’application, ce qui évite d’avoir à le faire manuellement.
Les modèles Machine Learning ne sont pas statiques. À mesure que de nouvelles données de formation deviennent disponibles, le modèle est réentraîné et redéployé. Pour obtenir la dernière version du modèle dans votre application, vous pouvez redémarrer ou redéployer votre application. Toutefois, cela entraîne un temps d’arrêt de l’application. Le service PredictionEnginePool
fournit un mécanisme pour recharger un modèle mis à jour sans redémarrer ou redéployer votre application.
Définissez le paramètre watchForChanges
sur true
et PredictionEnginePool
démarre un FileSystemWatcher
qui écoute les notifications de modification du système de fichiers et déclenche des événements en cas de modification du fichier. Cela invite le PredictionEnginePool
à recharger automatiquement le modèle.
Le modèle est identifié par le paramètre modelName
afin que plusieurs modèles par application puissent être rechargés en cas de modification.
Conseil
Vous pouvez également utiliser la méthode FromUri
lors de l’utilisation de modèles stockés à distance. Au lieu de surveiller les événements de modification de fichiers, FromUri
interroge l’emplacement distant pour les modifications. L’intervalle d’interrogation est de 5 minutes par défaut. Vous pouvez augmenter ou diminuer l’intervalle d’interrogation en fonction des exigences de votre application. Dans l’exemple de code ci-dessous, le PredictionEnginePool
sonde le modèle stocké au niveau de l’URI spécifié chaque minute.
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));
Charger le modèle dans la fonction
Insérez le code suivant à l’intérieur de la classe AnalyzeSentiment :
public AnalyzeSentiment(PredictionEnginePool<SentimentData, SentimentPrediction> predictionEnginePool)
{
_predictionEnginePool = predictionEnginePool;
}
Ce code affecte le PredictionEnginePool
en le passant au constructeur de la fonction, obtenu par injection de dépendances.
Utiliser le modèle pour élaborer des prédictions
Remplacez l’implémentation existante de la méthode Run dans la classe AnalyzeSentiment par le code suivant :
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);
}
Quand la méthode Run
s’exécute, les données entrantes issues de la requête HTTP sont désérialisées et utilisées comme entrée pour le PredictionEnginePool
. La méthode Predict
est ensuite appelée pour effectuer des prédictions à l’aide du SentimentAnalysisModel
inscrit dans la classe Startup
, et retourne les résultats à l’utilisateur en cas de réussite.
Tester les topologies localement
Maintenant que tout est configuré, il est temps de tester l’application :
Exécution de l'application
Ouvrez PowerShell et entrez le code dans l’invite, où PORT est le port sur lequel s’exécute votre application, en règle générale 7071.
Invoke-RestMethod "http://localhost:<PORT>/api/AnalyzeSentiment" -Method Post -Body (@{SentimentText="This is a very bad steak"} | ConvertTo-Json) -ContentType "application/json"
En cas de réussite, la sortie devrait se présenter ainsi :
Negative
Félicitations ! Vous avez réussi à alimenter votre modèle de façon à effectuer des prédictions sur Internet à l’aide d’une fonction Azure.