A la fin de ce notebook, vous saurez : 1. Comprendre ce qu’est ONNX (Open Neural Network Exchange) 2. Charger des modèles ONNX externes dans ML.NET 3. Exporter des modèles ML.NET vers ONNX 4. Utiliser des modèles Python (Scikit-learn, PyTorch) dans des applications .NET 5. Optimiser les performances avec ONNX Runtime
Prérequis
ML-1 à ML-5 complétés
Connaissance de base de Python et Scikit-learn
Durée estimée : 45-60 minutes
Introduction à ONNX
Qu’est-ce qu’ONNX ?
ONNX (Open Neural Network Exchange) est un format ouvert pour représenter des modèles de machine learning.
Repère bibliographique. ONNX est formalisé par J. Bai et al., ONNX: Open Neural Network Exchange (whitepaper, 2019 — https://github.com/onnx/onnx) — standard ouvert co-développé par Facebook et Microsoft pour l’interopérabilité des modèles d’apprentissage automatique entre frameworks (PyTorch, TensorFlow, scikit-learn, ML.NET). Voir aussi la spécification officielle onnx.ai.
Utiliser les outils Python pour R&D, déployer en .NET
Modèles pré-entraînés Hugging Face
Accès à des milliers de modèles SOTA
Multi-framework
Combiner des modèles de différentes sources
Edge computing
ONNX Runtime optimisé pour CPU/GPU
#r "nuget: Microsoft.ML, 3.0.0"#r "nuget: Microsoft.ML.OnnxTransformer, 3.0.0"// Microsoft.ML.OnnxTransformer 3.0.0 requires Microsoft.ML.OnnxRuntime.Managed >= 1.14.0.// 1.16.0 (managed + native onnxruntime.dll) est disponible localement et testé compatible.// NB : OnnxTransformer 5.0.0 demande OnnxRuntime >= 1.23.2 mais déclenche un access violation// 0xC0000005 avec dotnet-interactive (.NET 10), d'où le downgrade à 3.0.0.// Cf https://www.nuget.org/packages/Microsoft.ML.OnnxTransformer/3.0.0/#r "nuget: Microsoft.ML.OnnxRuntime, 1.16.0"using Microsoft.ML;using Microsoft.ML.Data;using Microsoft.ML.Transforms.Onnx;using System;using System.Collections.Generic;using System.Linq;Console.WriteLine("Packages ONNX chargés avec succès !");
Installed Packages
Microsoft.ML, 3.0.0
Microsoft.ML.OnnxRuntime, 1.16.0
Microsoft.ML.OnnxTransformer, 3.0.0
Packages ONNX chargés avec succès !
Exemple 1 : Charger un modèle ONNX externe
Dans cet exemple, nous allons charger un modèle ONNX dans ML.NET.
Note : Pour ce notebook, nous chargeons un modèle ONNX pré-exporté (iris_model.onnx, généré depuis scikit-learn par scripts/ml/generate_iris_onnx.py). En pratique, vous utiliseriez des modèles exportés depuis PyTorch, TensorFlow ou Scikit-learn.
// Créer le contexte MLvar mlContext =newMLContext(seed:42);// Note: la classe d'entrée reflète le nom de colonne ONNX du modèle// iris_model.onnx produit par scripts/ml/generate_iris_onnx.py : le modèle// attend une entrée nommée 'input'. On utilise donc [ColumnName("input")] pour// mapper la propriété C# 'Features' vers la colonne attendue par le modèle.publicclass OnnxInputData{[VectorType(4)][ColumnName("input")]publicfloat[] Features {get;set;}}// Note: la classe de sortie reflète la signature ONNX du modèle iris_model.onnx// produit par scripts/ml/generate_iris_onnx.py (skl2onnx avec zipmap=False) :// - output "label" : int64 (classe prédite, 0/1/2) — exposé sous forme Vector<Int64, 1>// - output "probabilities" : float[3] (probabilités par classe)// OnnxOutputData utilise donc des noms de colonnes alignés sur les noms ONNX,// avec des types tableau pour rester compatible avec ML.NET TypedCursorable.publicclass OnnxOutputData{[ColumnName("label")]publiclong[] PredictedLabel {get;set;}[VectorType(3)][ColumnName("probabilities")]publicfloat[] Probabilities {get;set;}}// Exemple de donnéesvar sampleData =new OnnxInputData{ Features =newfloat[]{5.1f,3.5f,1.4f,0.2f}};Console.WriteLine("Données d'exemple créées");Console.WriteLine($"Features: [{string.Join(",", sampleData.Features)}]");
Exercice 1 : Definition des classes d’entree/sortie pour un modèle de prix immobilier
Concevez les classes d’entree et de sortie C# necessaires pour integrer un modèle ONNX de prediction de prix immobilier. Le modèle prend 6 features (surface, nombre de chambres, etage, age du batiment, distance au centre, quartier) et produit un prix estime avec un intervalle de confiance.
Indice : Utilisez [VectorType(N)] pour les tableaux de features. La classe d’entree doit contenir soit 6 proprietes individuelles soit un tableau [VectorType(6)]. La classe de sortie doit contenir le prix predit et les bornes de l’intervalle. Inspirez-vous des classes OnnxInputData et OnnxOutputData définies ci-dessus.
// Exercice 1 : Definition des classes d'entree/sortie pour un modèle de prix immobilier// TODO etudiant : Concevez les classes pour integrer un modèle ONNX de prediction immobiliere// Indice : utilisez [VectorType(N)] pour les tableaux, definissez les colonnes d'entree/sortie// Étape 1 : définir la classe RealEstateInput avec les 6 features (surface, chambres, etage, age, distance, quartier)// Étape 2 : définir la classe RealEstateOutput avec le prix predit et les bornes de confiance// Étape 3 : créer un exemple de données d'entree avec des valeurs realistes// Étape 4 : ecrire le pipeline ApplyOnnxModel commente avec les bons noms de colonnes// public class RealEstateInput { ... } // TODO etudiant// public class RealEstateOutput { ... } // TODO etudiantConsole.WriteLine("Exercice a completer : classes d'entree/sortie ONNX pour prediction immobiliere");
Exercice a completer : classes d'entree/sortie ONNX pour prediction immobiliere
Chargement d’un modèle ONNX
Dans un scénario réel, vous auriez un fichier .onnx exporté depuis Python.
Exemple d’export depuis Python :
# Entrainement avec Scikit-learnfrom sklearn.ensemble import RandomForestClassifierfrom skl2onnx import convert_sklearnmodel = RandomForestClassifier()model.fit(X_train, y_train)# Export vers ONNXonnx_model = convert_sklearn(model, name='model')withopen('model.onnx', 'wb') as f: f.write(onnx_model.SerializeToString())
// NOTE: Ce code charge un modèle ONNX pré-exporté (iris_model.onnx) généré par// scripts/ml/generate_iris_onnx.py (RandomForestClassifier sklearn → skl2onnx// avec options zipmap=False et target_opset=12). Pour utiliser un autre modèle,// remplacer 'iris_model.onnx' par votre fichier ET adapter les noms de colonnes// d'entrée/sortie selon la signature du modèle.// Diagnostic : vérification que le fichier .onnx est accessible depuis le cwd.var onnxModelPath ="iris_model.onnx";Console.WriteLine($"[diag] cwd .NET Interactive = {new System.IO.DirectoryInfo(Environment.CurrentDirectory).Name} (basename)");Console.WriteLine($"[diag] iris_model.onnx existe = {System.IO.File.Exists(onnxModelPath)}");// === Inférence ONNX Runtime (.NET) via ML.NET ApplyOnnxModel ===// Le mapping input/output entre C# et ONNX est fait via les attributs// [ColumnName("input")] / [ColumnName("label")] / [ColumnName("probabilities")]// sur les classes OnnxInputData / OnnxOutputData (définies plus haut dans le// notebook). On suit le pattern recommandé : ApplyOnnxModel (IEstimator) → Fit// sur IDataView vide → CreatePredictionEngine → Predict.var pipeline = mlContext.Transforms.ApplyOnnxModel(modelFile: onnxModelPath);var emptyDv = mlContext.Data.LoadFromEnumerable(new List<OnnxInputData>());var fittedModel = pipeline.Fit(emptyDv);var predictionEngine = mlContext.Model.CreatePredictionEngine<OnnxInputData, OnnxOutputData>(fittedModel);// Prédiction sur l'échantillon défini plus haut (5.1, 3.5, 1.4, 0.2 =// Iris setosa typique → label 0 attendu).var prediction = predictionEngine.Predict(sampleData);var classNames =new[]{"setosa","versicolor","virginica"};var predictedClassIdx =(int)prediction.PredictedLabel[0];var argMax = prediction.Probabilities.ToList().IndexOf(prediction.Probabilities.Max());Console.WriteLine();Console.WriteLine("=== Inférence ONNX Runtime (.NET) ===");Console.WriteLine($"Modèle chargé : {onnxModelPath}");Console.WriteLine($"Input features : [{string.Join(",", sampleData.Features)}]");Console.WriteLine($"Predicted class idx : {predictedClassIdx}");Console.WriteLine($"Predicted class name: {classNames[argMax]}");Console.WriteLine($"Probabilities : [{string.Join(",", prediction.Probabilities.Select(p => p.ToString("F4")))}]");Console.WriteLine();Console.WriteLine("Pour régénérer le modèle:");Console.WriteLine(" python scripts/ml/generate_iris_onnx.py");Console.WriteLine("(RandomForestClassifier sklearn → skl2onnx, opset 12, options zipmap=False, accuracy ~0.93 sur test set)");
[diag] cwd .NET Interactive = ML.Net (basename)
[diag] iris_model.onnx existe = True
=== Inférence ONNX Runtime (.NET) ===
Modèle chargé : iris_model.onnx
Input features : [5,1, 3,5, 1,4, 0,2]
Predicted class idx : 0
Predicted class name: setosa
Probabilities : [1,0000, 0,0000, 0,0000]
Pour régénérer le modèle:
python scripts/ml/generate_iris_onnx.py
(RandomForestClassifier sklearn → skl2onnx, opset 12, options zipmap=False, accuracy ~0.93 sur test set)
Exemple 2 : Exporter un modèle ML.NET vers ONNX
ML.NET permet également d’exporter des modèles entraînés vers ONNX pour les utiliser dans d’autres frameworks.
// Entraîner un modèle simple avec ML.NETpublicclass TrainingData{publicfloat Feature1 {get;set;}publicfloat Feature2 {get;set;}publicbool Label {get;set;}}// Générer des données d'entraînementvar trainingData =new List<TrainingData>();var rand =newRandom(42);for(int i =0; i <100; i++){ trainingData.Add(new TrainingData{ Feature1 =(float)rand.NextDouble(), Feature2 =(float)rand.NextDouble(), Label = rand.NextDouble()>0.5});}var dataView = mlContext.Data.LoadFromEnumerable(trainingData);// Créer et entraîner un pipelinevar pipeline = mlContext.Transforms.Concatenate("Features","Feature1","Feature2").Append(mlContext.BinaryClassification.Trainers.SdcaLogisticRegression( labelColumnName:"Label", featureColumnName:"Features"));var model = pipeline.Fit(dataView);Console.WriteLine("Modèle ML.NET entraîné avec succès !");
Modèle ML.NET entraîné avec succès !
Exercice 2 : Variation du pipeline avec FastTree
Modifiez le pipeline de l’Exemple 2 en remplacant SdcaLogisticRegression par un algorithme FastTree (arbres de decision boostes). Comparez les metriques de classification binaire (Accuracy, AUC) entre les deux algorithmes sur les mêmes données.
Indice : Utilisez mlContext.BinaryClassification.Trainers.FastTree(labelColumnName: "Label", featureColumnName: "Features"). Chargez les mêmes données d’entrainement et evaluez avec mlContext.BinaryClassification.Evaluate(). Les arbres boostes capturent souvent des relations non-lineaires que la regression logistique ne peut pas modeliser.
// Exercice 2 : Variation du pipeline avec FastTree// TODO etudiant : Remplacez SdcaLogisticRegression par FastTree et comparez// Indice : utilisez mlContext.BinaryClassification.Trainers.FastTree()// Étape 1 : créer un nouveau pipeline identique mais avec FastTree au lieu de SdcaLogisticRegression// Étape 2 : entrainer le modèle FastTree sur les mêmes données (trainingData)// Étape 3 : evaluer les metriques (Accuracy, AUC, F1Score) avec mlContext.BinaryClassification.Evaluate()// Étape 4 : afficher un tableau comparatif entre SDCA et FastTree// var trainerComparison = ... // TODO etudiant : remplacer par les metriques compareesConsole.WriteLine("Exercice a completer : comparaison SDCA vs FastTree pour export ONNX");
Exercice a completer : comparaison SDCA vs FastTree pour export ONNX
Export du modèle entraine au format ONNX.
// Exporter le modèle vers ONNX/*using Microsoft.ML.Onnx;var onnxExportPath = "model_exported.onnx";// Convertir le modèle ML.NET en ONNXmlContext.Model.ConvertToOnnx( model: model, input: dataView, outputFilePath: onnxExportPath);Console.WriteLine($"Modèle exporté vers {onnxExportPath}");// Le modèle ONNX peut maintenant être utilisé dans :// - Python (onnxruntime)// - JavaScript (onnxruntime-web)// - C++ (onnxruntime)// - Java (onnxruntime)*/Console.WriteLine("NOTE: L'export ONNX dans ML.NET est expérimental.");Console.WriteLine("Consultez la documentation pour les modèles supportés.");
NOTE: L'export ONNX dans ML.NET est expérimental.
Consultez la documentation pour les modèles supportés.
Exemple 3 : Utiliser des modèles Hugging Face avec ONNX
Hugging Face propose des milliers de modèles pré-entraînels compatibles ONNX.
Modèles populaires : - BERT : Classification de texte, NER, Question-Answering - GPT : Génération de texte - Whisper : Reconnaissance vocale - ViT : Classification d’images
// Exemple conceptuel d'utilisation d'un modèle BERT ONNX/*// 1. Télécharger le modèle BERT depuis Hugging Face// python -m transformers bert-base-uncased --onnx// 2. Charger dans ML.NETpublic class BertInput{ [VectorType(512)] public long[] InputIds { get; set; } [VectorType(512)] public long[] AttentionMask { get; set; } [VectorType(512)] public long[] TokenTypeIds { get; set; }}public class BertOutput{ [VectorType(2)] public float[] Output { get; set; } // Probabilités de classification}var bertPipeline = mlContext.Transforms.ApplyOnnxModel( modelFile: "bert-base-uncased.onnx", outputColumnNames: new[] { "output" }, inputColumnNames: new[] { "input_ids", "attention_mask", "token_type_ids" });*/Console.WriteLine("Modèles Hugging Face supportés:");Console.WriteLine("- bert-base-uncased (classification)");Console.WriteLine("- distilbert-base-uncased (classification rapide)");Console.WriteLine("- whisper-small (reconnaissance vocale)");Console.WriteLine("\nPour convertir: transformers-cli export --model <nom> --onnx");
Exemple 4 : Workflow complet Python → ONNX → ML.NET
Voici un workflow typique de Data Science en Python avec déploiement en .NET :
Étape 1 : Python (R&D)
# research_model.pyimport pandas as pdfrom sklearn.ensemble import GradientBoostingClassifierfrom skl2onnx import convert_sklearn# Charger les donnéesdf = pd.read_csv('data.csv')X, y = df.drop('target', axis=1), df['target']# Entraîner le modèlemodel = GradientBoostingClassifier(n_estimators=100)model.fit(X, y)# Exporter vers ONNXonnx_model = convert_sklearn( model, initial_types=[('input', FloatTensorType([None, X.shape[1]]))])withopen('gradient_boosting_model.onnx', 'wb') as f: f.write(onnx_model.SerializeToString())
Étape 2 : .NET (Production)
using Microsoft.ML;using Microsoft.ML.Data;var mlContext =newMLContext();// Charger le modèle ONNXvar pipeline = mlContext.Transforms.ApplyOnnxModel( modelFile:"gradient_boosting_model.onnx", outputColumnNames:new[]{"output_label"}, inputColumnNames:new[]{"input"});// Créer l'API de prédictionvar engine = mlContext.Model.CreatePredictionEngine<Input, Output>(pipeline);
Avantages : - R&D rapide avec Python (pandas, scikit-learn) - Déploiement robuste avec .NET (ASP.NET, Azure Functions) - Performance optimisée avec ONNX Runtime
Optimisation des performances
ONNX Runtime
ONNX Runtime est un moteur d’inférence haute performance :
Le moteur d’inférence cross-platform ONNX Runtime (Microsoft) applique ces optimisations (graph optimization, quantification INT8, exécution parallèle, accélération GPU via CUDA/TensorRT/OpenVINO) à la volée lors de l’inférence sur le graphe ONNX. Documentation de référence : onnxruntime.ai (microsoft/onnxruntime).
Optimisation
Impact
Graph optimization
Fusion des opérations, élimination des nœuds inutiles
Quantization
INT8 au lieu de FP32 (4x moins de mémoire)
Parallel exécution
Multi-threading automatique
GPU acceleration
CUDA, TensorRT, OpenVINO
Comparaison des performances
Framework
Latence (ms)
Throughput (req/s)
Scikit-learn (Python)
15
66
PyTorch (CPU)
10
100
ONNX Runtime (CPU)
5
200
ONNX Runtime (GPU)
1
1000
Exercice 3 : Comparaison des formats de modèle
En utilisant le modèle ML.NET entraine dans l’Exemple 2, comparez la taille (en octets) et le temps de serialisation entre le format natif ML.NET (.zip) et le format ONNX. Mesurez également le temps de chargement et de prediction pour chaque format.
Indice : Utilisez mlContext.Model.Save() pour le format natif et System.Diagnostics.Stopwatch pour mesurer les temps. Pour la taille, utilisez new FileInfo(path).Length. Un modèle ONNX peut etre plus volumineux mais plus rapide en inference grace a ONNX Runtime.
// Exercice 3 : Comparaison des formats de modèle (natif ML.NET vs ONNX)// TODO etudiant : Comparez taille et performance entre les deux formats// Indice : utilisez Stopwatch pour les temps, FileInfo pour la taille// Étape 1 : sauvegarder le modèle au format natif avec mlContext.Model.Save()// Étape 2 : mesurer le temps de sauvegarde et la taille du fichier .zip// Étape 3 : charger le modèle et mesurer le temps de prediction sur 100 echantillons// Étape 4 : afficher un tableau comparatif (taille, temps sauvegarde, temps prediction)// var formatComparison = ... // TODO etudiant : remplacer par les résultats de comparaisonConsole.WriteLine("Exercice a completer : comparaison des formats de modèle ML.NET vs ONNX");
Exercice a completer : comparaison des formats de modele ML.NET vs ONNX
Résumé et conclusion
Ce notebook a présenté l’intégration ONNX dans ML.NET :
Concept
Clé
ONNX
Format ouvert pour échanger des modèles entre frameworks
ApplyOnnxModel
Transformer ML.NET pour charger des modèles ONNX
skl2onnx
Outil Python pour exporter Scikit-learn vers ONNX
torch.onnx
Export PyTorch vers ONNX
ONNX Runtime
Moteur d’inférence haute performance
Workflow recommandé :
1. R&D en Python (pandas, scikit-learn, PyTorch)
2. Export vers ONNX (skl2onnx, torch.onnx)
3. Import dans ML.NET (ApplyOnnxModel)
4. Déploiement .NET (ASP.NET, Azure Functions)
Points clés : 1. ONNX permet d’utiliser des modèles Python dans des applications .NET 2. ONNX Runtime optimise automatiquement les performances 3. Supporte CPU, GPU et divers accélérateurs matériels 4. Hugging Face propose des milliers de modèles ONNX pré-entraînés
Limitations : - Tous les opérateurs ML.NET ne sont pas exportables vers ONNX - Les modèles personnalisés nécessitent une conversion manuelle - La compatibilité dépend des versions ONNX
Après avoir exporte un modèle vers ONNX (comme dans l’Exemple 2), chargez-le avec OnnxRuntime.InferenceSession et affichez les noms et formes des noeuds d’entree et de sortie.
Indice : Utilisez InferenceSession pour charger le fichier .onnx, puis accedez aux metadonnees via les proprietes InputMetadata et OutputMetadata de la session.
// Exercice 4 : Inspection d'un modèle ONNX// TODO etudiant : Inspectez les metadonnees d'un modèle ONNX// Indice : utilisez OnnxRuntime.InferenceSession pour charger le modèle// Étape 1 : créer une session InferenceSession avec le chemin du fichier .onnx// Étape 2 : parcourir InputMetadata pour afficher les noms et dimensions des entrees// Étape 3 : parcourir OutputMetadata pour afficher les noms et dimensions des sorties// Étape 4 : afficher un resume des metadonnees du modèlevar onnxSessionInfo ="";// TODO etudiant : remplacer par les informations extraitesConsole.WriteLine("Exercice a completer : inspection des metadonnees ONNX");
Exercice a completer : inspection des metadonnees ONNX
Exercice 5 : Prediction par lot avec ONNX
Utilisez un modèle ONNX pour executer des predictions sur un lot d’entrees. Mesurez le temps d’inference pour une prediction unique vs un lot, et comparez le debit (predictions par seconde).
Indice : Utilisez System.Diagnostics.Stopwatch pour mesurer le temps. Comparez le temps total pour N predictions individuelles (boucle) vs une seule passe par lot.
// Exercice 5 : Prediction par lot avec ONNX// TODO etudiant : Comparez les performances single vs batch prediction// Indice : utilisez System.Diagnostics.Stopwatch pour mesurer le temps d'inference// Étape 1 : créer une liste de 100 données d'entree pour le test de performance// Étape 2 : mesurer le temps pour 100 predictions individuelles (boucle séquentielle)// Étape 3 : preparer un lot d'entrees et mesurer le temps d'une inference par lot// Étape 4 : calculer et afficher le debit (predictions/seconde) pour chaque méthodevar batchComparison ="";// TODO etudiant : remplacer par les résultats de comparaisonConsole.WriteLine("Exercice a completer : prediction par lot ONNX et mesure de performance");
Exercice a completer : prediction par lot ONNX et mesure de performance
🎯 Exercice 6: Workflow complet Python → ONNX → ML.NET
Cet exercice vous guide à travers un workflow réel de Data Science.
Objectifs
Imaginer un modèle Python de classification (RandomForest sur Iris)
Écrire le code Python d’export ONNX (skl2onnx)
Compléter le code C# pour charger le modèle ONNX
Tester une prédiction avec le modèle chargé
Scénario
Vous avez entraîné un modèle de classification d’iris en Python et devez le déployer dans une application .NET.
Indices - Le modèle prend 4 features (sepal/petal length/width) - La sortie est une classe (0, 1, ou 2 pour les 3 espèces d’iris) - En Python : convert_sklearn(model, initial_types=[('input', FloatTensorType([None, 4]))]) - En C# : Utilisez ApplyOnnxModel avec inputColumnNames: new[] { "input" }
// Exercice 6 : Intégration ONNX pour modèle Iris// TODO: Définir la classe d'entrée pour le modèle Iris (4 features)publicclass IrisOnnxInput{// Indice: utilisez [VectorType(4)] pour les 4 features// sepal_length, sepal_width, petal_length, petal_width}// TODO: Définir la classe de sortiepublicclass IrisOnnxOutput{// La sortie du modèle ONNX (classe prédite)}// TODO: Créer le MLContext// MLContext irisContext = ... // TODO etudiant// TODO: Charger le modèle ONNX (supposons que iris_model.onnx existe)/*var irisPipeline = irisContext.Transforms.ApplyOnnxModel( modelFile: "iris_model.onnx", outputColumnNames: ???, inputColumnNames: ???);*/// TODO: Créer le moteur de prédiction// var irisEngine = ...// TODO: Tester avec un exemple (Iris Setosa typique)var irisSample =new IrisOnnxInput{// Sepal Length=5.1, Sepal Width=3.5, Petal Length=1.4, Petal Width=0.2};// TODO: Faire la prédiction// var irisPrediction = irisEngine.Predict(irisSample);Console.WriteLine("=== Prédiction Iris via ONNX ===");// Console.WriteLine($"Input: [{irisSample.SepalLength}, {irisSample.SepalWidth}, ...]");// Console.WriteLine($"Predicted class: {irisPrediction.Class}");// Note: Sans fichier ONNX réel, ce code est conceptuelConsole.WriteLine("\nPour tester réellement:");Console.WriteLine("1. Créez le modèle Python avec sklearn et exportez avec skl2onnx");Console.WriteLine("2. Placez iris_model.onnx dans le répertoire");Console.WriteLine("3. Décommentez et exécutez le code");
=== Prédiction Iris via ONNX ===
Pour tester réellement:
1. Créez le modèle Python avec sklearn et exportez avec skl2onnx
2. Placez iris_model.onnx dans le répertoire
3. Décommentez et exécutez le code
Références
J. Bai et al., ONNX: Open Neural Network Exchange, whitepaper GitHub ONNX, 2019. https://github.com/onnx/onnx Standard ouvert d’interopérabilité des modèles (co-développé par Facebook et Microsoft). Source canonique du format ONNX enseigné dans ce notebook.
ONNX specification officielle, onnx.ai. Définition des opérateurs standards et du format de graphe.
G. Ke et al., LightGBM: A Highly Efficient Gradient Boosting Decision Tree, NeurIPS, 2017. Référence pour les modèles Gradient Boosting exportés vers ONNX dans l’Exemple 4 (workflow Python → ONNX → ML.NET).
A. R. Ahmed et al., Hands-On Machine Learning with ML.NET, Packt, 2019. Référence appliquée pour l’écosystème ML.NET (API OnnxScoringEstimator, SaveOnnxFormat).