oc-p07-sentiment-api/notebooks/notebook-connexion-mlflow.ipynb
2025-11-11 08:39:23 +01:00

1 line
No EOL
36 KiB
Text
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{"cells":[{"cell_type":"markdown","metadata":{"id":"fm2J3uruLfrX"},"source":["# Connexion au serveur MLFlow - Test et Configuration Locale\n","\n","Ce notebook permet de **tester la connexion à un serveur MLFlow déployé localement via Docker sur un NAS/Serveur personnel**. Il est conçu pour vérifier que toutes les configurations sont correctes et que nous pouvons commencer à suivre nos expériences de machine learning\n",".\n","## Prérequis\n","\n","Avant d'exécuter ce notebook, assurez-vous d'avoir :\n","- Un serveur MLFlow déployé localement via Docker sur votre NAS. Il sera important d'installer dans le conteneur la librairie boto3 pour que MLFlow puisse échanger avec un serveur de type AWS pour le stockage des artefacts.\n","- Un serveur MinIO (compatible S3) déployé localement via Docker pour le stockage des artefacts et qui remplacera les Amazon Web Services (AWS).\n","- Les informations de connexion nécessaires (URI de tracking, identifiants MinIO).\n","- Les ports 5000 (MLFlow) et 9000 (MinIO API) correctement exposés et/ou gérés par un reverse proxy (SWAG).\n","\n","## Configuration des variables d'environnement dans Jupyter Notebook / Google Collab\n","\n","Pour une connexion réussie, vous devez définir les variables d'environnement dans un fichier `.env` qui sera chargé via la librairie dotenv dans le répertoire courant. Ces variables seront utilisées par la bibliothèque MLflow pour communiquer avec vos services.\n","\n","Voici les variables essentielles à configurer (urls locaux en guise d'exemple) :\n","\n","```\n","MLFLOW_TRACKING_URI=http://mlflow:5000\n","MLFLOW_S3_ENDPOINT_URL=http://minio:9000\n","AWS_ACCESS_KEY_ID=minioadmin\n","AWS_SECRET_ACCESS_KEY=minioadminpassword\n","```\n","\n","Remplacez les valeurs par vos propres informations de connexion.\n","\n","Note : minio possède deux ports :\n","- 9001 pour accéder à l'interface web et gérer le stockage / nettoyage d'artefacts\n","- 9000 qui est l'api qui sera requêté pour l'envoi de buckets S3 par la librairie mlflow\n","\n","## Étapes du test\n","\n","Ce notebook effectue les opérations suivantes :\n","1. Chargement des variables d'environnement depuis le fichier `.env`\n","2. Configuration de MLFlow avec ces variables\n","3. Tentative de connexion au serveur MLFlow\n","4. Récupération de la liste des expériences existantes\n","5. Création d'une expérience si elle n'existe pas déjà\n","6. Enregistrement de métriques test pour vérifier le bon fonctionnement\n","\n","## Résolution des problèmes courants\n","\n","Notez que si vous utilisez des notebooks Google Collab, il est **nécessaire** que votre serveur MLFlow ainsi que l'API de MinIO soient accessibles via un lien public. Vous pouvez simplement ouvrir les ports de votre modem ou, pour plus de sécurité, configurer un reverse proxy (type SWAG pour la gestion et délivrance automatique de certificats SSL). Cette étape ne sera pas développée ici.\n","\n","Notez également que si vous désactivez votre docker MLFlow et le réactivez (par exemple suite à un redémarrage), les expériences seront par défaut perdues. Pour qu'elles soient persistantes, il faudra rajouter dans le yaml du docker l'argument de commande ainsi que le volume suivants :\n","- ` - --backend-store-uri ` \\\n"," ` - sqlite:////mlflow/mlflow.db # <-- pointe vers le volume monté `\n","- ` - ./mlflow-data:/mlflow # Monte un volume local pour préserver mlflow.db`\n","\n","Si vous rencontrez des erreurs lors de la connexion, vérifiez :\n","- Que l'URI de tracking est correct et accessible\n","- Que vos identifiants AWS sont valides (si applicable)\n","- Que le serveur MLFlow est bien en cours d'exécution\n","- Vos paramètres réseau (pare-feu, VPN, etc.)"]},{"cell_type":"code","source":["!pip install mlflow boto3 dotenv --quiet"],"metadata":{"id":"wPht9-36CMzs"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":["from google.colab import drive\n","drive.mount('/content/drive')\n","import os\n","drive_folder= \"/content/drive/MyDrive/Colab_Notebooks/Project_7/notebooks\"\n","os.chdir(drive_folder)\n","# os.listdir()"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"XkhsbZ5Xc3De","executionInfo":{"status":"ok","timestamp":1751547034150,"user_tz":-120,"elapsed":953,"user":{"displayName":"Grégoire","userId":"01249298206117462766"}},"outputId":"7d340543-c848-47da-f5cd-4360a62f5571"},"execution_count":null,"outputs":[{"output_type":"stream","name":"stdout","text":["Drive already mounted at /content/drive; to attempt to forcibly remount, call drive.mount(\"/content/drive\", force_remount=True).\n"]}]},{"cell_type":"code","execution_count":null,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"4DKFKUC8LfrY","executionInfo":{"status":"ok","timestamp":1751547035465,"user_tz":-120,"elapsed":1313,"user":{"displayName":"Grégoire","userId":"01249298206117462766"}},"outputId":"a2c423b4-6e57-4f78-9839-3beed6c39ea1"},"outputs":[{"output_type":"stream","name":"stdout","text":["MLflow Tracking URI: https://mlflow.greg-madman-nas.duckdns.org/\n","Identifiants AWS configurés\n","Tentative de connexion à MLflow...\n","Connexion à MLflow réussie! Nombre d'expériences existantes: 3\n"," - Demo PC (ID: 2)\n"," - OC Projet 7 (ID: 1)\n"," - Default (ID: 0)\n","Expérience existante trouvée: 'Demo PC' (ID: 2)\n","Démarrage d'un run MLflow de test...\n","Métrique de test enregistrée avec succès!\n","🏃 View run test_connexion_simple at: https://mlflow.greg-madman-nas.duckdns.org/#/experiments/2/runs/3127176c596441c48e34590d27494b56\n","🧪 View experiment at: https://mlflow.greg-madman-nas.duckdns.org/#/experiments/2\n","Test terminé avec succès. Vous pouvez vérifier les résultats sur: https://mlflow.greg-madman-nas.duckdns.org/\n"]}],"source":["import os\n","import mlflow\n","from dotenv import load_dotenv\n","\n","# Charger les variables d'environnement depuis le fichier .env\n","load_dotenv(dotenv_path='../.env')\n","\n","# Configuration de MLflow avec les variables d'environnement\n","mlflow_tracking_uri = os.getenv(\"MLFLOW_TRACKING_URI\")\n","mlflow_s3_endpoint_url = os.getenv(\"MLFLOW_S3_ENDPOINT_URL\")\n","aws_access_key_id = os.getenv(\"AWS_ACCESS_KEY_ID\")\n","aws_secret_access_key = os.getenv(\"AWS_SECRET_ACCESS_KEY\")\n","\n","print(f\"MLflow Tracking URI: {mlflow_tracking_uri}\")\n","\n","# Configuration explicite des identifiants AWS pour MLflow\n","os.environ[\"MLFLOW_S3_ENDPOINT_URL\"] = mlflow_s3_endpoint_url\n","os.environ[\"AWS_ACCESS_KEY_ID\"] = aws_access_key_id\n","os.environ[\"AWS_SECRET_ACCESS_KEY\"] = aws_secret_access_key\n","print(\"Identifiants AWS configurés\")\n","\n","# Configuration de MLflow\n","try:\n"," print(\"Tentative de connexion à MLflow...\")\n"," mlflow.set_tracking_uri(mlflow_tracking_uri)\n","\n"," # Liste des expériences pour vérifier la connexion\n"," exps = mlflow.search_experiments()\n"," print(f\"Connexion à MLflow réussie! Nombre d'expériences existantes: {len(exps)}\")\n"," for exp in exps:\n"," print(f\" - {exp.name} (ID: {exp.experiment_id})\")\n","\n"," # Définir le nom de l'expérience\n"," experiment_name = \"Demo PC\"\n","\n"," # Obtenir ou créer l'expérience\n"," experiment = mlflow.get_experiment_by_name(experiment_name)\n"," if experiment is None:\n"," experiment_id = mlflow.create_experiment(experiment_name)\n"," print(f\"Nouvelle expérience créée: '{experiment_name}' (ID: {experiment_id})\")\n"," else:\n"," experiment_id = experiment.experiment_id\n"," print(f\"Expérience existante trouvée: '{experiment_name}' (ID: {experiment_id})\")\n","\n"," # Démarrer un simple run et enregistrer une métrique\n"," with mlflow.start_run(experiment_id=experiment_id, run_name=\"test_connexion_simple\"):\n"," print(\"Démarrage d'un run MLflow de test...\")\n"," mlflow.log_param(\"test_param\", \"valeur_test\")\n"," mlflow.log_metric(\"test_metric\", 1.0)\n"," print(\"Métrique de test enregistrée avec succès!\")\n","\n"," print(f\"Test terminé avec succès. Vous pouvez vérifier les résultats sur: {mlflow_tracking_uri}\")\n","\n","except Exception as e:\n"," print(f\"Erreur lors de la connexion à MLflow: {e}\")\n"," print(\"\\nConseils de débogage:\")\n"," print(\"1. Vérifiez que l'URI de tracking est correct et accessible\")\n"," print(\"2. Vérifiez que vos identifiants AWS sont valides si vous utilisez S3\")\n"," print(\"3. Vérifiez que le serveur MLflow est en cours d'exécution\")\n"," print(\"4. Vérifiez les paramètres réseau (pare-feu, VPN, etc.)\")"]},{"cell_type":"code","execution_count":null,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"nPI-3ULPLfrZ","executionInfo":{"status":"ok","timestamp":1751547035628,"user_tz":-120,"elapsed":159,"user":{"displayName":"Grégoire","userId":"01249298206117462766"}},"outputId":"fcc2197b-0474-4365-8122-f116dff4f562"},"outputs":[{"output_type":"stream","name":"stdout","text":["MLflow Tracking URI: https://mlflow.greg-madman-nas.duckdns.org/\n","Identifiants AWS configurés\n"]}],"source":["import os\n","import mlflow\n","from mlflow.models import infer_signature\n","from mlflow import MlflowClient\n","from dotenv import load_dotenv\n","\n","import pandas as pd\n","import numpy as np\n","from sklearn import datasets\n","from sklearn.model_selection import train_test_split\n","from sklearn.linear_model import LogisticRegression\n","from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, confusion_matrix\n","import matplotlib.pyplot as plt\n","import seaborn as sns\n","\n","# Charger les variables d'environnement depuis le fichier .env\n","load_dotenv()\n","\n","# Configuration de MLflow avec les variables d'environnement\n","mlflow_tracking_uri = os.getenv(\"MLFLOW_TRACKING_URI\")\n","mlflow_s3_endpoint_url = os.getenv(\"MLFLOW_S3_ENDPOINT_URL\")\n","aws_access_key_id = os.getenv(\"AWS_ACCESS_KEY_ID\")\n","aws_secret_access_key = os.getenv(\"AWS_SECRET_ACCESS_KEY\")\n","\n","# Configuration explicite de MLflow\n","mlflow.set_tracking_uri(mlflow_tracking_uri)\n","print(f\"MLflow Tracking URI: {mlflow_tracking_uri}\")\n","\n","# Configuration explicite des identifiants AWS\n","os.environ[\"MLFLOW_S3_ENDPOINT_URL\"] = mlflow_s3_endpoint_url\n","os.environ[\"AWS_ACCESS_KEY_ID\"] = aws_access_key_id\n","os.environ[\"AWS_SECRET_ACCESS_KEY\"] = aws_secret_access_key\n","print(\"Identifiants AWS configurés\")\n","\n","# Create a new MLflow Experiment\n","mlflow.set_experiment(\"Demo PC\")\n","\n","# Define the output directory\n","output_dir = \"./content/mlflow_test/\"\n","\n","# Create the output directory if it doesn't exist\n","if not os.path.exists(output_dir):\n"," os.makedirs(output_dir)\n"," print(f\"Output directory created: {output_dir}\")"]},{"cell_type":"code","execution_count":null,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"OC0vEu6HLfra","executionInfo":{"status":"ok","timestamp":1751547053654,"user_tz":-120,"elapsed":18024,"user":{"displayName":"Grégoire","userId":"01249298206117462766"}},"outputId":"10d22f5d-eb1e-47e2-ea3f-61e8307536db"},"outputs":[{"output_type":"stream","name":"stdout","text":["Chargement du dataset Iris...\n","Aperçu du dataset:\n"," sepal length (cm) sepal width (cm) petal length (cm) petal width (cm) \\\n","0 5.1 3.5 1.4 0.2 \n","1 4.9 3.0 1.4 0.2 \n","2 4.7 3.2 1.3 0.2 \n","3 4.6 3.1 1.5 0.2 \n","4 5.0 3.6 1.4 0.2 \n","\n"," target \n","0 0.0 \n","1 0.0 \n","2 0.0 \n","3 0.0 \n","4 0.0 \n","Dimensions du dataset: (150, 5)\n","Taille de l'ensemble d'entraînement: (120, 4)\n","Taille de l'ensemble de test: (30, 4)\n","Démarrage du run MLflow avec l'ID: c9e768a9ca904c55a963f03568e43ecb\n","Entraînement du modèle de régression logistique...\n","Métriques: Accuracy=1.0000, Precision=1.0000, Recall=1.0000, F1=1.0000\n"]},{"output_type":"stream","name":"stderr","text":["2025/07/03 12:50:45 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.\n"]},{"output_type":"stream","name":"stdout","text":["Modèle enregistré: models:/m-abf8c8b98d6f4d60aa9898de7ee6a795\n","🏃 View run iris_classification at: https://mlflow.greg-madman-nas.duckdns.org/#/experiments/2/runs/c9e768a9ca904c55a963f03568e43ecb\n","🧪 View experiment at: https://mlflow.greg-madman-nas.duckdns.org/#/experiments/2\n","\n","🏃 MLflow Run Infos :\n","⚗️ run_id: c9e768a9ca904c55a963f03568e43ecb\n","⚡ artifacts: ['model/MLmodel', 'model/conda.yaml', 'model/input_example.json', 'model/model.pkl', 'model/python_env.yaml', 'model/requirements.txt', 'model/serving_input_example.json']\n","⚙️ params: {'solver': 'lbfgs', 'max_iter': '1000', 'random_state': '8888'}\n","📝 metrics: {'accuracy': 1.0, 'precision': 1.0, 'recall': 1.0, 'f1_score': 1.0}\n","🏷️ tags: {'model_type': 'LogisticRegression', 'dataset': 'Iris', 'description': 'Classification multiclasse des fleurs Iris'}\n","\n"]}],"source":["# Fonction pour afficher les informations du run MLflow\n","def print_logged_info(r):\n"," print(\"\")\n"," print(\"🏃 MLflow Run Infos :\")\n"," tags = {k: v for k, v in r.data.tags.items() if not k.startswith(\"mlflow.\")}\n"," artifacts = [f.path for f in MlflowClient().list_artifacts(r.info.run_id, \"model\")]\n"," print(f\"⚗️ run_id: {r.info.run_id}\")\n"," print(f\"⚡ artifacts: {artifacts}\")\n"," print(f\"⚙️ params: {r.data.params}\")\n"," print(f\"📝 metrics: {r.data.metrics}\")\n"," print(f\"🏷️ tags: {tags}\")\n"," print()\n","\n","# Chargement du dataset Iris\n","print(\"Chargement du dataset Iris...\")\n","iris = datasets.load_iris()\n","X, y = iris.data, iris.target\n","\n","# Conversion en DataFrame pour une meilleure visualisation\n","iris_df = pd.DataFrame(data=np.c_[iris['data'], iris['target']],\n"," columns=iris['feature_names'] + ['target'])\n","print(f\"Aperçu du dataset:\\n{iris_df.head()}\")\n","print(f\"Dimensions du dataset: {iris_df.shape}\")\n","\n","# Créer une figure pour visualiser la distribution des classes\n","plt.figure(figsize=(8, 6))\n","sns.countplot(x='target', data=iris_df)\n","plt.title('Distribution des classes du dataset Iris')\n","# Save the figure in the output directory\n","plt.savefig(os.path.join(output_dir, 'iris_class_distribution.png'))\n","plt.close()\n","\n","# Division en ensembles d'entraînement et de test\n","X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)\n","print(f\"Taille de l'ensemble d'entraînement: {X_train.shape}\")\n","print(f\"Taille de l'ensemble de test: {X_test.shape}\")\n","\n","# Définition des hyperparamètres du modèle\n","params = {\n"," \"solver\": \"lbfgs\",\n"," \"max_iter\": 1000,\n"," \"random_state\": 8888,\n","}\n","\n","# Démarrer un run MLflow\n","with mlflow.start_run(run_name=\"iris_classification\") as run:\n"," print(f\"Démarrage du run MLflow avec l'ID: {run.info.run_id}\")\n","\n"," # Enregistrer les hyperparamètres\n"," mlflow.log_params(params)\n","\n"," # Entraîner le modèle\n"," print(\"Entraînement du modèle de régression logistique...\")\n"," lr = LogisticRegression(**params)\n"," lr.fit(X_train, y_train)\n","\n"," # Prédire sur l'ensemble de test\n"," y_pred = lr.predict(X_test)\n","\n"," # Calculer les métriques\n"," accuracy = accuracy_score(y_test, y_pred)\n"," precision = precision_score(y_test, y_pred, average='weighted')\n"," recall = recall_score(y_test, y_pred, average='weighted')\n"," f1 = f1_score(y_test, y_pred, average='weighted')\n","\n"," # Enregistrer les métriques\n"," mlflow.log_metric(\"accuracy\", accuracy)\n"," mlflow.log_metric(\"precision\", precision)\n"," mlflow.log_metric(\"recall\", recall)\n"," mlflow.log_metric(\"f1_score\", f1)\n","\n"," print(f\"Métriques: Accuracy={accuracy:.4f}, Precision={precision:.4f}, Recall={recall:.4f}, F1={f1:.4f}\")\n","\n"," # Générer une matrice de confusion\n"," cm = confusion_matrix(y_test, y_pred)\n"," plt.figure(figsize=(8, 6))\n"," sns.heatmap(cm, annot=True, fmt='d', cmap='Blues',\n"," xticklabels=iris.target_names,\n"," yticklabels=iris.target_names)\n"," plt.title('Matrice de confusion')\n"," plt.xlabel('Prédiction')\n"," plt.ylabel('Réalité')\n"," plt.tight_layout()\n"," # Save the figure in the output directory\n"," plt.savefig(os.path.join(output_dir, 'confusion_matrix.png'))\n"," plt.close()\n","\n"," # Enregistrer la matrice de confusion comme artifact\n"," mlflow.log_artifact(os.path.join(output_dir, \"confusion_matrix.png\"))\n"," mlflow.log_artifact(os.path.join(output_dir, \"iris_class_distribution.png\"))\n","\n"," # Définir des tags pour ce run\n"," mlflow.set_tag(\"model_type\", \"LogisticRegression\")\n"," mlflow.set_tag(\"dataset\", \"Iris\")\n"," mlflow.set_tag(\"description\", \"Classification multiclasse des fleurs Iris\")\n","\n"," # Inférer la signature du modèle\n"," signature = infer_signature(X_train, lr.predict(X_train))\n","\n"," # Enregistrer le modèle avec sa signature\n"," model_info = mlflow.sklearn.log_model(\n"," sk_model=lr,\n"," artifact_path=\"model\", # This is the path within the MLflow run artifact storage\n"," signature=signature,\n"," input_example=X_train[:5]\n"," )\n","\n"," print(f\"Modèle enregistré: {model_info.model_uri}\")\n","\n","# Récupérer et afficher les informations du run terminé\n","run_info = mlflow.get_run(run_id=run.info.run_id)\n","print_logged_info(run_info)"]},{"cell_type":"code","execution_count":null,"metadata":{"colab":{"base_uri":"https://localhost:8080/","height":116,"referenced_widgets":["5077141fe2354e538f2728680d165abd","f5679722fc2e419b9eb658ee30c3684d","a5e14ad79a71402ab6f93f67fe2894cb","0a21fa27119c467f84595be0992d481b","b1a3c1bde6854e179dd0ecba4ac0ac19","e294e746a37246f082f8bf2b70367ce3","4713d02de5c44de69db461e8ab6cade1","36e6d82d6909479d9359dd82f6d56d92","fd2489b6f3154eb988b6d987e9445dc4","c5e2cc8df51146d1b61ac06e65cbc9ec","9878155a8ac14ded9f73699160a3da0c","3f94687e5cd24458a1f8cd6b123bbdf7","d7a0ada0295647049b45e572d4167d8d","12bd24eef53d4390a6e12b89d4baa563","06490fc029bf4f1eab964d977a262c73","90eb86a1891848cba01284e60c971dcc","a4b1626a86d64e30a04552da9fda8eb1","0e190cce3832467686ab21f7a226f15b","c95599130eb44eeb98d7013340f55bef","870a99030b7541dd977e4261f025f495","e4a45ed5c60e49c9b4392012805fd903","1bf723dec07d4385b6eb2e423ac81416"]},"id":"bvmWVVraLfra","executionInfo":{"status":"ok","timestamp":1751547076141,"user_tz":-120,"elapsed":22478,"user":{"displayName":"Grégoire","userId":"01249298206117462766"}},"outputId":"d50a7a94-7edf-4406-bafb-5384c86a90eb"},"outputs":[{"name":"stdout","output_type":"stream","text":["Please enter your 🏃 RUN ID : c9e768a9ca904c55a963f03568e43ecb\n"]},{"output_type":"display_data","data":{"text/plain":["Downloading artifacts: 0%| | 0/1 [00:00<?, ?it/s]"],"application/vnd.jupyter.widget-view+json":{"version_major":2,"version_minor":0,"model_id":"5077141fe2354e538f2728680d165abd"}},"metadata":{}},{"output_type":"display_data","data":{"text/plain":["Downloading artifacts: 0%| | 0/7 [00:00<?, ?it/s]"],"application/vnd.jupyter.widget-view+json":{"version_major":2,"version_minor":0,"model_id":"3f94687e5cd24458a1f8cd6b123bbdf7"}},"metadata":{}},{"output_type":"stream","name":"stdout","text":["🚀 Model : LogisticRegression(max_iter=1000, random_state=8888)\n"]}],"source":["# %%\n","# Prompts user with the Run ID from MLflow run\n","# You can find run ID in the Tracking UI\n","while True:\n"," run_id = input('Please enter your 🏃 RUN ID : ')\n"," if run_id.strip() != '':\n"," break\n","\n","artifact_path = \"model\"\n","\n","# Download artifact via the tracking server\n","mlflow_artifact_uri = f\"runs:/{run_id}/{artifact_path}\"\n","\n","try:\n"," # Specify the local directory to download artifacts to\n"," local_path = mlflow.artifacts.download_artifacts(mlflow_artifact_uri, dst_path=output_dir)\n"," # Load the model\n"," model = mlflow.sklearn.load_model(local_path)\n","\n"," # If the model prints, everything works!\n"," print(f\"🚀 Model : {model}\")\n","except:\n"," print(\"❌ Invalid Run ID.\")"]}],"metadata":{"kernelspec":{"display_name":".venv","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.10.12"},"colab":{"provenance":[]},"widgets":{"application/vnd.jupyter.widget-state+json":{"5077141fe2354e538f2728680d165abd":{"model_module":"@jupyter-widgets/controls","model_name":"HBoxModel","model_module_version":"1.5.0","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_f5679722fc2e419b9eb658ee30c3684d","IPY_MODEL_a5e14ad79a71402ab6f93f67fe2894cb","IPY_MODEL_0a21fa27119c467f84595be0992d481b"],"layout":"IPY_MODEL_b1a3c1bde6854e179dd0ecba4ac0ac19"}},"f5679722fc2e419b9eb658ee30c3684d":{"model_module":"@jupyter-widgets/controls","model_name":"HTMLModel","model_module_version":"1.5.0","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_e294e746a37246f082f8bf2b70367ce3","placeholder":"​","style":"IPY_MODEL_4713d02de5c44de69db461e8ab6cade1","value":"Downloading artifacts:   0%"}},"a5e14ad79a71402ab6f93f67fe2894cb":{"model_module":"@jupyter-widgets/controls","model_name":"FloatProgressModel","model_module_version":"1.5.0","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"FloatProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"ProgressView","bar_style":"danger","description":"","description_tooltip":null,"layout":"IPY_MODEL_36e6d82d6909479d9359dd82f6d56d92","max":1,"min":0,"orientation":"horizontal","style":"IPY_MODEL_fd2489b6f3154eb988b6d987e9445dc4","value":0}},"0a21fa27119c467f84595be0992d481b":{"model_module":"@jupyter-widgets/controls","model_name":"HTMLModel","model_module_version":"1.5.0","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_c5e2cc8df51146d1b61ac06e65cbc9ec","placeholder":"​","style":"IPY_MODEL_9878155a8ac14ded9f73699160a3da0c","value":" 0/1 [00:00&lt;?, ?it/s]"}},"b1a3c1bde6854e179dd0ecba4ac0ac19":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","model_module_version":"1.2.0","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"e294e746a37246f082f8bf2b70367ce3":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","model_module_version":"1.2.0","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"4713d02de5c44de69db461e8ab6cade1":{"model_module":"@jupyter-widgets/controls","model_name":"DescriptionStyleModel","model_module_version":"1.5.0","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"36e6d82d6909479d9359dd82f6d56d92":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","model_module_version":"1.2.0","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"fd2489b6f3154eb988b6d987e9445dc4":{"model_module":"@jupyter-widgets/controls","model_name":"ProgressStyleModel","model_module_version":"1.5.0","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","bar_color":null,"description_width":""}},"c5e2cc8df51146d1b61ac06e65cbc9ec":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","model_module_version":"1.2.0","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"9878155a8ac14ded9f73699160a3da0c":{"model_module":"@jupyter-widgets/controls","model_name":"DescriptionStyleModel","model_module_version":"1.5.0","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"3f94687e5cd24458a1f8cd6b123bbdf7":{"model_module":"@jupyter-widgets/controls","model_name":"HBoxModel","model_module_version":"1.5.0","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_d7a0ada0295647049b45e572d4167d8d","IPY_MODEL_12bd24eef53d4390a6e12b89d4baa563","IPY_MODEL_06490fc029bf4f1eab964d977a262c73"],"layout":"IPY_MODEL_90eb86a1891848cba01284e60c971dcc"}},"d7a0ada0295647049b45e572d4167d8d":{"model_module":"@jupyter-widgets/controls","model_name":"HTMLModel","model_module_version":"1.5.0","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_a4b1626a86d64e30a04552da9fda8eb1","placeholder":"​","style":"IPY_MODEL_0e190cce3832467686ab21f7a226f15b","value":"Downloading artifacts: 100%"}},"12bd24eef53d4390a6e12b89d4baa563":{"model_module":"@jupyter-widgets/controls","model_name":"FloatProgressModel","model_module_version":"1.5.0","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"FloatProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"ProgressView","bar_style":"success","description":"","description_tooltip":null,"layout":"IPY_MODEL_c95599130eb44eeb98d7013340f55bef","max":7,"min":0,"orientation":"horizontal","style":"IPY_MODEL_870a99030b7541dd977e4261f025f495","value":7}},"06490fc029bf4f1eab964d977a262c73":{"model_module":"@jupyter-widgets/controls","model_name":"HTMLModel","model_module_version":"1.5.0","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_e4a45ed5c60e49c9b4392012805fd903","placeholder":"​","style":"IPY_MODEL_1bf723dec07d4385b6eb2e423ac81416","value":" 7/7 [00:01&lt;00:00,  4.03it/s]"}},"90eb86a1891848cba01284e60c971dcc":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","model_module_version":"1.2.0","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"a4b1626a86d64e30a04552da9fda8eb1":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","model_module_version":"1.2.0","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"0e190cce3832467686ab21f7a226f15b":{"model_module":"@jupyter-widgets/controls","model_name":"DescriptionStyleModel","model_module_version":"1.5.0","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"c95599130eb44eeb98d7013340f55bef":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","model_module_version":"1.2.0","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"870a99030b7541dd977e4261f025f495":{"model_module":"@jupyter-widgets/controls","model_name":"ProgressStyleModel","model_module_version":"1.5.0","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","bar_color":null,"description_width":""}},"e4a45ed5c60e49c9b4392012805fd903":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","model_module_version":"1.2.0","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"1bf723dec07d4385b6eb2e423ac81416":{"model_module":"@jupyter-widgets/controls","model_name":"DescriptionStyleModel","model_module_version":"1.5.0","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}}}}},"nbformat":4,"nbformat_minor":0}