Blog Post

Azure Architecture Blog
20 MIN READ

High-performance storage for AI Model Training tasks using Azure ML studio with Azure NetApp Files

GeertVanTeylingen's avatar
Aug 26, 2022

Table of Contents

 

Abstract

Introduction

Prepare the environment

Pre-requisites

Note on Connectivity

Provision the working environment

Access Azure Cloud Shell and install extensions

Setting variables

Service provisioning

Provision Azure NetApp Files persistent storage with Azure Machine Learning studio for AI model training

Prepare the repository

Create an Azure Machine Learning studio resource

Start a training job

Training job results

Provision Azure NetApp Files persistent storage with Azure Machine Learning Studio for Studio Notebooks

Preparation and requirements

Provision a compute instance

Configure the compute instance and download a dataset

Accessing Azure NetApp Files from a notebook

Snapshots

Creating a snapshot using the Azure Cloud Shell

Restoring a snapshot using the Azure Cloud Shell

Summary

Additional Information

 

Abstract

 

Artificial Intelligence (AI), Machine Learning (ML) and Deep Learning (DL) workloads all have a similar profile – high performance requirements, large capacity and oftentimes, high file counts, which result in high metadata. When datasets are as large and cumbersome as AI/ML datasets, it becomes as difficult to scale to meet their needs as it is to migrate these workloads where you need them. Because of the need for scale and data real estate, many workload owners are looking towards cloud providers like Microsoft Azure with Microsoft Machine Learning to fulfill their needs without breaking the bank in cost. 

 

Azure NetApp Files is one way to address the unique requirements for an AI/ML/DL workload. Azure NetApp Files delivers a blend of high performance, massive scale and simple migration tools that enhance the AI/ML/DL use case by reducing job completion times and providing a way to save money by changing performance levels on the fly and automatically tiering inactive datasets to lower cost Azure storage.

 

In addition, Azure NetApp Files provides industry-leading snapshot technology for near-instantaneous backup and restore of critical datasets, as well as a fast, efficient method to create exact replicas of datasets across cloud regions in Azure for better data locality.

 

Azure NetApp Files also provides a way to quickly clone volumes to new volumes that can be reformatted, normalized and manipulated while preserving the original “gold-source” without having to physically migrate data.

 

Two possible use-cases are discussed: integration of Azure NetApp Files into training jobs, and integration of Azure NetApp Files into Azure Machine Learning Studio Notebooks. In this article you learn:   

 

  1. How to create an Azure NetApp Files account, capacity pool, and delegated subnet using the CLI
  2. How to provision an Azure NetApp Files NFS volume using the CLI
  3. How to create an Azure Machine learning studio workspace using the CLI
  4. How to leverage a NFS volume for high performance AI model training 
  5. How to connect an NFS volume to an Azure Machine Learning notebook instance

Co-authors: Max Amende,  Prabu Arjunan (NetApp), Diane Patton (Azure NetApp Files)

 

Introduction

 

Data scientists face several challenges today. They need to have access to high performance persistent data volumes to train machine learning models, while also needing to protect these critical datasets. They work with large amounts of data and need to instantly be able to consistently create data volumes that are exact replicas or previous versions of existing volumes. Azure NetApp Files, coupled with the Azure Machine Learning studio, inherently provide the functionality required by today’s data scientists.

 

The Azure Machine Learning studio is the web portal for data scientists in Azure Machine Learning. The studio combines no-code and code-first experiences for an inclusive data science platform. Azure NetApp Files is an enterprise-class, high-performance, metered file storage service. You can select service and performance levels, create capacity pools, volumes, and manage data protection. Azure NetApp Files supports many workload types and is highly available by design.

 

The integration of the Azure Machine Learning studio with Azure NetApp Files is possible in several ways. This article covers step by step configuration of two scenarios: leveraging high-performance storage for AI model training tasks, and provisioning Azure NetApp Files volumes with Azure Machine Learning notebooks for data persistency and protection.

 

Prepare the environment

 

This section describes how to prepare the Azure environment for both use cases covered in this article. It provides steps to set up your resource-group, networking, Azure NetApp Files, and Azure Machine Learning Studio.

 

Pre-requisites

 

You must have:

  • Microsoft Azure credentials that provide the necessary permissions to create resources. For example, a user account with Contributor role would suffice.  
  • Access to an Azure Region where Azure NetApp Files is available
  • Ability to provision an Azure NetApp Files capacity pool
  • Network connectivity between Azure Machine Learning studio and Azure NetApp Files

 

Note on Connectivity

 

You must ensure network connectivity between Azure Machine Learning studio and Azure NetApp Files. For this guide we initialize the Azure Machine Learning studio compute instances and Azure NetApp Files volumes into the same Azure Virtual Network (VNet), separated into two subnets. Azure Machine Learning studio is deployed on one subnet. The second subnet is delegated to Azure NetApp Files.

 

Provision the working environment

 

This section describes how to deploy, configure, and connect Azure Machine Learning studio with Azure NetApp Files using the Azure Cloud Shell and CLI commands hosted at azureml-with-azure-netapp-files.


Although they are not covered in this aericle, you could also execute these steps using the Azure Portal.

 

Access Azure Cloud Shell and install extensions

 

Login to the Microsoft Azure Web-interface and open the Cloud Shell as shown below.

 

 

Login by entering:

 

user [~]$ az login
Cloud Shell is automatically authenticated under the initial account signed-in with. Run 'az login' only if you need to use a different account
To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code “Secure Code” to authenticate.


Install the following CLI extension from the Cloud Shell to allow provisioning Azure Machine Learning from the Cloud Shell. Register Azure NetApp files:

 

user [ ~ ]$az extension add --name ml
user [ ~ ]$az provider register --namespace Microsoft.NetApp --wait

 

Setting variables

 

Create and set variables. Modify the values and location and names to what is applicable for your environment. Ensure the location selected supports Azure NetApp Files and ensure there is network connectivity between Azure Machine Learning Studio subnet and Azure NetApp Files delegated subnet. We use the below variables as an example throughout this article.

 

 These variables are not persistent, if you log out of cloud shell you must re-initialize them.

 

# Resource group name
rg='aml-anf-test'
location='westeurope'

# VNET details
vnet_name='vnet'
vnet_address_range='10.0.0.0/16'
vnet_aml_subnet='10.0.1.0/24'
vnet_anf_subnet='10.0.2.0/24'

# AML details
workspace_name='aml-anf'

# ANF details
anf_name=anf
pool_name=pool1

 

Service provisioning

 

After the variables are initialized, provision the required services and network.

 

As shown below, first create the resource group and define the defaults for the working environment, using the variables identified in the prior step:

 

user [ ~ ]:~$ az group create -n $rg -l $location
{
  "id": "/subscriptions/number/resourceGroups/aml-anf-test",
  "location": "westeurope",
  "managedBy": null,
  "name": "aml-anf-test",
  "properties": {
    "provisioningState": "Succeeded"
  },
  "tags": null,
  "type": "Microsoft.Resources/resourceGroups"
}
user [ ~ ]:~$ az configure --defaults group=$rg workspace=$workspace_name location=$location

 

Add the VNet and two subnets. One subnet will be used for compute, and the other will be delegated to Azure NetApp Files:

 

user [~ ]$ az network vnet create -n $vnet_name –address-prefix $vnet_address_range
{
  “newVNet”: {
    “addressSpace”: {
      “addressPrefixes”: [
        “10.0.0.0/16”
      ]
    },
    …
  }
}
user [~]$ az network vnet subnet create --vnet-name $vnet_name -n anf --address-prefixes $vnet_aml_subnet  
{ "addressPrefix“: "10.0.1.0/24",
  "delegations": [],
  ...
}
user[ ~]$ az network vnet subnet create– --vnet-name $vnet_name -n anf --address-prefixes $vnet_anf_subn– --delegations "Microsoft.NetApp/volumes"
{“  "addressPrefix“: "10.0.2.0”24",
“  "delegations": [
    {
   “  "actions": [
     “  "Microsoft.Network/networkinterface”/*",
     “  "Microsoft.Network/virtualNetworks/subnets/join/action"
      ],
   “  "etag“: "W/\"<number>”\"",
   “  ”id“: "/subscriptions/<number>/resourceGroups/aml-anf-test/providers/Microsoft.Network/virtualNetworks/vnet/subnets/anf/delegation”/0",
   “  "name“:”"0",
   “  "provisioningState“: "Succeeded",
   “  "resourceGroup“: "aml-anf-test",
   “  "serviceName“: "Microsoft.NetApp/volumes",
   “  "type“: "Microsoft.Network/virtualNetworks/subnets/delegations"
    }
  ],
  ...
}

We reduced the output of certain fields indicated by “…” for readability.

 

(!) Note

 

The Azure NetApp Files subnet must be separate from the Azure Machine Learning studio subnet and be explicitly

delegated to Azure NetApp Files.

 

Next, provision the Azure Machine Learning workspace as shown below:

 

user[ ~ ]$ az ml workspace create --name $workspace_name
The deployment request aml-anf-47652685 was accepted. ARM deployment URI for reference:
https://portal.azure.com//#blade/HubsExtension/DeploymentDetailsBlade/overview/id/%2Fsubscriptions%number%2FresourceGroups%2Faml-anf-test%2Fproviders%2FMicrosoft.Resources%2Fdeployments%2Faml-anf-476562285
Creating AppInsights: (amlanfinsights80221d528b9e  )  Done (7s)
Creating KeyVault: (amlanfkeyvault01027221d033  ) ..  Done (23s)
Creating Storage Account: (amlanfstoragecad13288ba5c  )   Done (27s)
Creating workspace: (aml-anf  ) ..  Done (16s)
Total time : 45s
{
  "application_insights": "/subscriptions/<number>/resourceGroups/aml-anf-test/providers/Microsoft.insights/components/amlanfinsights82021d58b9e",
  "description": "aml-anf",
  "discovery_url": "https://westeurope.api.azureml.ms/discovery",
  "display_name": "aml-anf",
  "hbi_workspace": false,
  "id": "/subscriptions/<number>/resourceGroups/aml-anf-test/providers/Microsoft.MachineLearningServices/workspaces/aml-anf",
  "key_vault": "/subscriptions/<number>/resourceGroups/aml-anf-test/providers/Microsoft.Keyvault/vaults/amlanfkeyvault0102712d033",
  "location": "westeurope",
  "mlflow_tracking_uri": "azureml://westeurope.api.azureml.ms/mlflow/v1.0/subscriptions/<number>/resourceGroups/aml-anf-test/providers/Microsoft.MachineLearningServices/workspaces/aml-anf",
  "name": "aml-anf",
  "public_network_access": "Enabled",
  "resourceGroup": "aml-anf-test",
  "resource_group": "aml-anf-test",
  "storage_account": "/subscriptions/<number>/resourceGroups/aml-anf-test/providers/Microsoft.Storage/storageAccounts/amlanfstoragecad132828ba5c",
  "tags": {
    "createdByToolkit": "cli-v2-2.6.1"
  }
}

Configure Azure NetApp Files. Create a NetApp account, a capacity pool, and a NFSv3 volume:

 

user[ ~ ]$ az netappfiles account create --name $anf_name
{
  "activeDirectories": null,
  "disableShowmount": null,
  "encryption": {
    "identity": null,
    "keySource": "Microsoft.NetApp",
    "keyVaultProperties": null
  },
  "etag": "W/\"datetime'2024-01-08T15%3A56%3A57.3097309Z'\"",
….
}
user [ ~ ]$ az netappfiles pool create --account-name $anf_name --name $pool_name --size 4 --service-level premium
{
  "coolAccess": false,
  "encryptionType": "Single",
  "etag": " "W/\"datetime'2024-01-08T15%3A58%3A40.0232694Z'\"",,
  "id": "/subscriptions/<number>/resourceGroups/aml-anf-test/providers/Microsoft.NetApp/netAppAccounts/anf/capacityPools/pool1",
  "location": "westeurope",
  "name": "anf/pool1",
  "poolId": "<number>",
  "provisioningState": "Succeeded",
  "qosType": "Auto",
  "resourceGroup": "aml-anf-test",
  "serviceLevel": "Premium",
  "size": 4398046511104,
  …
 
}
user [ ~ ]$ az netappfiles volume create --account-name $anf_name --pool-name $pool_name --name vol1 --service-level premium --usage-threshold 4096 --file-path "vol1" --vnet $vnet_name --subnet anf --protocol-types NFSv3 --allowed-clients $vnet_aml_subnet --rule-index 1 --unix-read-write true
{
  "avsDataStore": "Disabled",
  "backupId": null,
  "baremetalTenantId": "baremetalTenant_svm_47702141844c3d28e8de7c602a040a58_e7f3a9a9",
  "capacityPoolResourceId": null,
  "cloneProgress": null,
  "coolAccess": false,
  "coolnessPeriod": null,
  "creationToken": "vol1",
...
}

We reduced the output of certain fields indicated by “…” for readability.

 

(!) Note

When creating the capacity pool, the allocation size used here is 4 TiB (defined by “—size 4”). Although that might be a bit much for some customers, the extra space can provide advantages. Azure NetApp Files allows you to provision the speed of a volume independently from its size. Thus, you can provision the extra space’s speed to a smaller volume, and therefore possibly select a lower service level. Furthermore, the capacity pools can be shared with additional volumes for other workloads as required.

 

Provision Azure NetApp Files persistent storage with Azure Machine Learning studio for AI model training

 

After the working environment has been prepared, this section describes the steps to deploy an Azure Machine Learning environment using Azure NetApp Files for AI Model Training. It shows how to use Azure NetApp Files for persistent storage, deploy a compute cluster and run a training job. It also shows how to test and view performance results. It requires a script and yml files downloaded from github.

 

Prepare the repository

 

We have created a repository on github with yaml and python files to use for this setup and demonstration. To access the prepared YAML files, download the repository and unzip it as shown below. After it is unzipped, change directory to the new anf-with-azureml-main directory:

 

user [~ ]$ wget https://github.com/prabuarjunan/anf-with-azureml/archive/refs/heads/main.zip
--2024-01-08 16:19:16--  https://github.com/prabuarjunan/anf-with-azureml/archive/refs/heads/main.zip
Resolving github.com... 140.82.112.3
Connecting to github.com|140.82.112.3|:443... connected.
HTTP request sent, awaiting response... 302 Found
Location: https://codeload.github.com/prabuarjunan/anf-with-azureml/zip/refs/heads/main [following]
--2024-01-08 16:19:16--  https://codeload.github.com/prabuarjunan/anf-with-azureml/zip/refs/heads/main

Resolving codeload.github.com... 140.82.113.10
Connecting to codeload.github.com|140.82.113.10|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [application/zip]
Saving to: ‘main.zip’

main.zip                                    [ <=>                                                                          ]   6.47K  --.-KB/s    in 0.003s 

2024-01-08 16:19:16 (1.82 MB/s) - ‘main.zip’ saved [6630]

user [ ~ ]$ unzip main.zip && rm main.zip
Archive:  main.zip
   creating: anf-with-azureml-main/
  inflating: anf-with-azureml-main/.gitignore 
  inflating: anf-with-azureml-main/README.md 
   creating: anf-with-azureml-main/code/
  inflating: anf-with-azureml-main/code/train.py 
  inflating: anf-with-azureml-main/environment.yml 
   creating: anf-with-azureml-main/environment/
  inflating: anf-with-azureml-main/environment/Dockerfile 
  inflating: anf-with-azureml-main/environment/requirements.txt 
  inflating: anf-with-azureml-main/train.yml 
user@Azure:~$ cd anf-with-azureml-main

 

Create an Azure Machine Learning studio resource

 

From the directory, execute the environment YAML to create an Azure Machine Learning environment. The environment.yaml file uses a Dockerfile to create the environment. The Dockerfile uses an Azure Machine Learning ubuntu image as its base and adds the NFS driver, python libraries for our script, and fio for testing.

 

user [ ~/anf-with-azureml-main ]$ az ml environment create --file environment.yml
Uploading environment (0.0 MBs): 100%|| 638/638 [00:00<00:00, 1260.22it/s]
{
  "build": {
    "dockerfile_path": "Dockerfile",
    "path": "https://amlanfstoraged50e45d9af7.blob.core.windows.net/azureml-blobstore-xxx/LocalUpload/<number>/environment/"
  },
  "creation_context": {
    "created_at": "2024-01-08T16:21:24.448106+00:00",
    "created_by": "user",
    "created_by_type": "User",
    "last_modified_at": "2024-01-08T16:21:24.448106+00:00",
    "last_modified_by": "user",
    "last_modified_by_type": "User"
  },
  "description": "Environment with NFS drivers and a few Python libraries.",
  "id": "azureml:/subscriptions/<number>/resourceGroups/aml-anf-test/providers/Microsoft.MachineLearningServices/workspaces/aml-anf/environments/python-base-nfs/versions/1",
  "name": "python-base-nfs",
  "os_type": "linux",
  "resourceGroup": "aml-anf-test",
  "tags": {},
  "version": "1"
}

 

Spin up an Azure Machine Learning compute cluster:

 

user [ ~/anf-with-azureml-main ]$  az ml compute create -n cpu-cluster --type amlcompute --min-instances 0 --max-instances 1 --size Standard_F16s_v2 --vnet-name $vnet_name --subnet aml --idle-time-before-scale-down 1800
{
  "id": "/subscriptions/<number>/resourceGroups/aml-anf-test/providers/Microsoft.MachineLearningServices/workspaces/aml-anf/computes/cpu-cluster",
  "idle_time_before_scale_down": 1800,
  "location": "westeurope",
  "max_instances": 1,
  "min_instances": 0,
  "name": "cpu-cluster",
  "network_settings": {
    "subnet": "/subscriptions/<number>/resourceGroups/aml-anf-test/providers/Microsoft.Network/virtualNetworks/vnet/subnets/aml"
  },
  "provisioning_state": "Succeeded",
  "resourceGroup": "aml-anf-test",
  "size": "STANDARD_F16S_V2",
  "ssh_public_access_enabled": false,
  "tier": "dedicated",
  "type": "amlcompute"
}

 

Start a training job

 

As soon as the cluster is ready, schedule a job which accesses the Azure NetApp Files volume. Train.yml will mount the VM to the Azure NetApp Files volume. You may need to change the train.yml file to mount to the correct mount path in your environment. Before executing the below command, be sure you are logged into the correct Azure account:

 

user [ ~/anf-with-azureml-main ]$ $ az ml job create -f train.yml --web
Uploading code (0.0 MBs): 100%|| 134/134 [00:00<00:00, 19167.75it/s]

{
  "code": "azureml:/subscriptions/<number>/resourceGroups/aml-anf-test/providers/Microsoft.MachineLearningServices/workspaces/aml-anf/codes/number/versions/1",
  "command": "mkdir /data\nmount -t nfs -o rw,hard,rsize=65536,wsize=65536,vers=3,tcp 10.0.2.4:/vol1 /data\ndf -h\npython train.py\n# Run fio on NFS share\ncd /data\nfio --name=4krandomreads --rw=randread --direct=1 --ioengine=libaio --bs=4k --numjobs=4 --iodepth=128 --size=1G --runtime=60 --group_reporting\n# Run fio on local disk\nmkdir /test\ncd /test\nfio --name=4krandomreads --rw=randread --direct=1 --ioengine=libaio --bs=4k --numjobs=4 --iodepth=128 --size=1G --runtime=60 --group_reporting\n",
  "compute": "azureml:cpu-cluster",
  "creation_context": {
     "created_at":"2024-01-08T16:30:08.808674+00:00", ,
    "created_by": "User",
    "created_by_type": "User"
  },
  "display_name": "purple_potato_5wn2v9vx77",
  "environment": "azureml:python-base-nfs:1",
  "environment_variables": {},
  "experiment_name": "anf-with-azureml-main",
  "id": "azureml:/subscriptions/<number>/resourceGroups/aml-anf-test/providers/Microsoft.MachineLearningServices/workspaces/aml-anf/jobs/purple_potato_5wn2v9vx77",
  "inputs": {},
  "name": " purple_potato_5wn2v9vx77",
  "outputs": {
    "default": {
      "mode": "rw_mount",
      "path": "azureml://datastores/workspaceartifactstore/ExperimentRun/dcid.purple_potato_5wn2v9vx77",
      "type": "uri_folder"
    }
  },
  "parameters": {},
  "properties": {
    "ContentSnapshotId": " a0c92ba6-11e2-4ba5-858d-dddf2969a444",
    "_azureml.ComputeTargetType": "amlctrain"
  },
  "resourceGroup": "aml-anf-test",
  "resources": {
    "instance_count": 1,
    "properties": {},
    "shm_size": "2g"
  },
  "services": {
    "Studio": {
      "endpoint": "https://ml.azure.com/runs/ purple_potato_5wn2v9vx77?wsid=/subscriptions/<number>/resourcegroups/aml-anf-test/workspaces/aml-anf&tid=4b09112a0-929b-4715-944b-c037425165b3a",
      "job_service_type": "Studio"
    },
    "Tracking": {
      "endpoint": "azureml://westeurope.api.azureml.ms/mlflow/v1.0/subscriptions/<number>/resourceGroups/aml-anf-test/providers/Microsoft.MachineLearningServices/workspaces/aml-anf?",
      "job_service_type": "Tracking"
    }
  },
  "status": "Starting",
  "tags": {},
  "type": "command"
}

 

(!) Note 

 

If you receive the following error:

Failed to connect to MSI. Please make sure MSI is configured correctly.
Get Token request returned: <Response [400]>

It may be due to inadequate authentication. Try:

az login

As seen below, train.yml mounts the Azure NetApp Files volume to /data. It then runs a small python script to emulate a real program and does storage benchmark that compares the speed of the compute clusters’ integrated storage on the directory /test to the speed of the attached Azure NetApp Files volume mounted to /data.

 

$ cat train.yml
schema: https://azuremlschemas.azureedge.net/latest/commandJob.schema.json
compute: azureml:cpu-cluster
environment: azureml:python-base-nfs:1
code:
  code/
command: |
  mkdir /data
  mount -t nfs -o rw,hard,rsize=65536,wsize=65536,vers=3,tcp 10.0.2.4:/vol1 /data
  df -h
  python train.py
  # Run fio on NFS share
  cd /data
  fio –name=4krandomreads –rw=randread –direct=1 –ioengine=libaio –bs=4k –numjobs=4 –iodepth=128 –size=1G --runtime=60 –group_reporting
  # Run fio on local disk
  mkdir /test
  cd /test
  fio –name=4krandomreads –rw=randread –direct=1 –ioengine=libaio –bs=4k –numjobs=4 –iodepth=128 –size=1G --runtime=60 –group_reporting

 

The small Python script is being executed to emulate a program for training. For example, the Python script could contain the code to train for Natural Language Processing (NLP) or Object Detection model.

 

Training job results

 

To show the performance difference between using a local disk vs an Azure NetApp Files NFS share, return to the Azure GUI and navigate to the Azure Machine Learning view. There is a workspace with your defined name. If you used the same resource names used in this guide, the name will be “amf-anf”.

 

Next, select this workspace and you’ll see a screen similar to the screen below.

 

 

To see the results, proceed by clicking on the “Studio web URL” on the right. After opening Azure Machine Learning studio click on “Jobs” to the left. All the jobs which have run are displayed in the Azure Machine Learning studio. 

 

 

Next, change the view from “All experiments” to “All jobs”. If you followed this document, there should be one job listed. Wait until the status of the job changes to “Completed”.

 

 

Then click on the job to get more information and options.

 

 

Next, select “Outputs + logs”, followed by a click on  “user_logs”, and then select “std_log.txt” to see the results from the benchmark.

 

 

In the log you’ll see that Azure NetApp Files has almost twice the performance as the compute cluster’s integrated storage.

 

You can now delete the job and the compute cluster.

 

Provision Azure NetApp Files persistent storage with Azure Machine Learning Studio for Studio Notebooks

 

After the working environment has been prepared, this section describes the steps to deploy an Azure Machine Learning environment using Azure NetApp Files for persistent storage with studio notebooks.

 

Preparation and requirements

 

Please follow the steps in Prepare your Environment if you have not already done so.

 

Provision a compute instance

 

Open the Azure Machine Learning studio. In case you have never accessed the Azure Machine Learning studio, follow the steps from Results of training job until the point where we access the results from the training job.

 

Click on “Compute”:

 

 

 

(!) Note

 

In case you followed all previous steps in the preceding section and did not delete the compute cluster, you will see your previously provisioned compute cluster under “Compute clusters”

 

Then select “+ New” from the “Compute instances” tab.

 

 

 

Give the compute instance a name of your choice. We call it “ANFTestCompute” in this example.  Select a Virtual Machine size. For this demo, the least expensive instance is sufficient. Select “Next: ”.

 

(i) Important

 

Do not click on “Create” yet, but select “Next: ”.

 

Select your scheduling preference and hit “Next:” for the Security page.

 

 

In the “Security” tab, activate “Enable virtual network”, and select the VNet which we previously created. If you followed the guide, the VNet should be called “vnet (aml-anf-test)”.

 

Then select the subnet which has not been delegated to Azure NetApp Files. In our case this is called “aml”.

 

Now we can scroll through Applications, add any tags, and Review. click on “Create”.

 

Provisioning the compute instance will take a couple of minutes. Wait until the “State” of the instance becomes “Running” as shown below.

 

 

 

Configure the compute instance and download a dataset

 

Under Notebooks,  click on the “Terminal” to connect to the Compute instance as shown below.

 

 

Install the nfs-common driver to allow nfs mounting onto the compute instance as shown below.

 

azureuser@anftestcompute:~/cloudfiles/code/Users/user$ sudo apt install nfs-common -y
Reading package lists... Done
Building dependency tree      
Reading state information... Done
The following packages were automatically installed and are no longer required:
  ca-certificates-java cmake-data cuda-command-line-tools-11-1
  cuda-command-line-tools-11-3 cuda-compiler-11-1 cuda-compiler-11-3
  cuda-cudart-11-1 cuda-cudart-11-3 cuda-cudart-dev-11-1 cuda-cudart-dev-11-3
  cuda-cuobjdump-11-1 cuda-cuobjdump-11-3 cuda-cupti-11-1 cuda-cupti-11-3
  cuda-cupti-dev-11-1 cuda-cupti-dev-11-3 cuda-cuxxfilt-11-3
  cuda-documentation-11-1 cuda-documentation-11-3 cuda-driver-dev-11-1
  …

We reduced the output of certain fields indicated by “…” for readability.

 

Next, create a new folder and mount the Azure NetApp Files volume. Replace the mount path 10.0.2.4:/vol1 with the mount path of your Azure NetApp Files volume if necessary.

azureuser@anftestcompute:~/cloudfiles/code/Users/user$ mkdir data
azureuser@anftestcompute:~/cloudfiles/code/Users/user$ sudo mount -t nfs -o rw,hard,rsize=65536,wsize=65536,vers=3,tcp 10.0.2.4:/vol1 /data

 

Your screen should now look like:

 

 

(!) Note

 

If the “data” folder is not shown on the left side, click on the “Refresh” button.

 

The titanic dataset established itself as the standard first data science project for emerging data scientists. Use this dataset as an example or a dataset of your choosing. Download the dataset to the Azure NetApp Files volume.

 

azureuser@anftestcompute:~$ wget https://web.stanford.edu/class/archive/cs/cs109/cs109.1166/stuff/titanic.csv -P ./data
--2024-01-08 17:55:56--  https://web.stanford.edu/class/archive/cs/cs109/cs109.1166/stuff/titanic.csv
Resolving web.stanford.edu (web.stanford.edu)... 171.67.215.200, 2607:f6d0:0:925a::ab43:d7c8
Connecting to web.stanford.edu (web.stanford.edu)|171.67.215.200|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 44225 (43K) [text/csv]
Saving to: ‘./data/titanic.csv’

titanic.csv                                               100%[=============================>]  43.19K   133KB/s    in 0.3s   

2024-01-08 17:56:00 (133 KB/s) - ‘./data/titanic.csv’ saved [44225/44225]

 

Accessing Azure NetApp Files from a notebook

 

Click on the “Plus Button” on the left to create a new Jupyter/Azure Machine Learning Studio notebook.

 

 

Select “Create new file”.

 

For this example we call the Notebook “ANFNotebook”:

 

 

Click on “Create”.

 

From the Notebook we can now access the files on the Azure NetApp Files volume and build our models based on it. We entered the code seen below into the notebook. We ingest the titanic csv file into a pandas data frame to show access to data on Azure NetApp Files as an example.

 

 

Snapshots

 

Snapshots are a valuable tool for data science tasks to protect the data. They can also be used as an effective and space efficient way to version a data set. You can easily create a snapshot of Azure NetApp Files volumes by:

 

As an example, this article uses the Azure Cloud Shell to create and restore a snapshot.

 

Creating a snapshot using the Azure Cloud Shell

 

Open the Azure Cloud Shell and enter the following command. Replace the account name, resource group, pool name and volume name with the names of your resources. As an example, we are naming the snapshot “timeInPointCopy”:

 

user [ ~ ]$ az netappfiles snapshot create --account-name anf --resource-group aml-anf-test --pool-name pool1 --volume-name vol1  --name timeInPointCopy
{
  "created": "2024-01-08T19:09:51.611000+00:00",
  "id": "/subscriptions/<number>/resourceGroups/aml-anf-test/providers/Microsoft.NetApp/netAppAccounts/anf/capacityPools/pool1/volumes/vol1/snapshots/timeInPointCopy",
  "location": "westeurope",
  "name": "anf/pool1/vol1/timeInPointCopy",
  "provisioningState": "Succeeded",
  "resourceGroup": "aml-anf-test",
  "snapshotId": "7b56521c-4957-df26-0c0a-c19c9fad0474",
  "systemData": null,
  "type": "Microsoft.NetApp/netAppAccounts/capacityPools/volumes/snapshots"

 

(!) Note

 

For this section we used the variable names from Setting variables.

 

Restoring a snapshot using the Azure Cloud Shell

 

Three options exist to restore a snapshot:

 

 

For this example we will restore a snapshot to a new volume. This means a new volume with a new name will be created based on the selected snapshot, and the volume data will automatically be restored to this volume. Be sure there is adequate space left in the capacity pool or expand the capacity pool for this operation. You could also restore to a new capacity pool. In this case, we expanded our current capacity pool using the dropdown menu for the capacity pool pool1.

 

The below example's volume creation is based on the snapshot Setting variables and Provisioning of services. Additionally, we need to specify the new volume's name, the mount point, and the snapshot id. Replace these variables with values in your environment.

 

The snapshot-id can be found using the command az netappfiles snapshot list.

 

user [ ~ ]$ az netappfiles volume create --vnet vnet --subnet anf --account-name anf --usage-threshold 40000 --pool-name pool1 --resource-group aml-anf-test --snapshot-id <id> --name vol1copy --file-path vol1copy --service-level premium --protocol-types NFSv3 --allowed-clients '10.0.1.0/24' --rule-index 1 --unix-read-write true 
{
  "actualThroughputMibps": 6.25,
  "avsDataStore": "Disabled",
  "backupId": null,
  "baremetalTenantId": "baremetalTenant_svm_d284dc8e25fd11ec8df54654d00c1f9e_d6143cc3",
  "capacityPoolResourceId": null,
  "cloneProgress": 0,
  "coolAccess": false,

}

We reduced the output of certain fields indicated by “…” for readability.

 

More information on the az netappfiles volume create command can be found in the documentation.

 

(!) Note

 

Entering the command from above might be prone to errors, due to its length and the number of required details.

This operation might be easier to conduct using the Azure GUI.

 

Summary 

 

In this article we described how we can make Azure training jobs and Azure Machine Learning studio notebooks use enterprise-grade high performance persistent storage backed by Azure NetApp Files volumes for training machine learning models and as persistent storage for studio notebooks. We also showed the ease in creating and restoring from snapshots using Azure NetApp Files. Get started with Azure NetApp Files today.

 

Additional Information

 

  1. https://learn.microsoft.com/en-us/azure/azure-netapp-files/azure-netapp-files-solution-architectures#azure-kubernetes-services-and-kubernetes 
  2. https://azure.microsoft.com/services/machine-learning/
Updated Jan 29, 2024
Version 3.0
No CommentsBe the first to comment
"}},"componentScriptGroups({\"componentId\":\"custom.widget.Social_Sharing\"})":{"__typename":"ComponentScriptGroups","scriptGroups":{"__typename":"ComponentScriptGroupsDefinition","afterInteractive":{"__typename":"PageScriptGroupDefinition","group":"AFTER_INTERACTIVE","scriptIds":[]},"lazyOnLoad":{"__typename":"PageScriptGroupDefinition","group":"LAZY_ON_LOAD","scriptIds":[]}},"componentScripts":[]},"component({\"componentId\":\"custom.widget.MicrosoftFooter\"})":{"__typename":"Component","render({\"context\":{\"component\":{\"entities\":[],\"props\":{}},\"page\":{\"entities\":[\"board:AzureArchitectureBlog\",\"message:3609189\"],\"name\":\"BlogMessagePage\",\"props\":{},\"url\":\"https://techcommunity.microsoft.com/blog/azurearchitectureblog/high-performance-storage-for-ai-model-training-tasks-using-azure-ml-studio-with-/3609189\"}}})":{"__typename":"ComponentRenderResult","html":""}},"componentScriptGroups({\"componentId\":\"custom.widget.MicrosoftFooter\"})":{"__typename":"ComponentScriptGroups","scriptGroups":{"__typename":"ComponentScriptGroupsDefinition","afterInteractive":{"__typename":"PageScriptGroupDefinition","group":"AFTER_INTERACTIVE","scriptIds":[]},"lazyOnLoad":{"__typename":"PageScriptGroupDefinition","group":"LAZY_ON_LOAD","scriptIds":[]}},"componentScripts":[]},"cachedText({\"lastModified\":\"1743151753131\",\"locale\":\"en-US\",\"namespaces\":[\"components/community/NavbarDropdownToggle\"]})":[{"__ref":"CachedAsset:text:en_US-components/community/NavbarDropdownToggle-1743151753131"}],"cachedText({\"lastModified\":\"1743151753131\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/common/QueryHandler\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/common/QueryHandler-1743151753131"}],"cachedText({\"lastModified\":\"1743151753131\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageCoverImage\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageCoverImage-1743151753131"}],"cachedText({\"lastModified\":\"1743151753131\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/nodes/NodeTitle\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/nodes/NodeTitle-1743151753131"}],"cachedText({\"lastModified\":\"1743151753131\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageTimeToRead\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageTimeToRead-1743151753131"}],"cachedText({\"lastModified\":\"1743151753131\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageSubject\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageSubject-1743151753131"}],"cachedText({\"lastModified\":\"1743151753131\",\"locale\":\"en-US\",\"namespaces\":[\"components/users/UserLink\"]})":[{"__ref":"CachedAsset:text:en_US-components/users/UserLink-1743151753131"}],"cachedText({\"lastModified\":\"1743151753131\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/users/UserRank\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/users/UserRank-1743151753131"}],"cachedText({\"lastModified\":\"1743151753131\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageTime\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageTime-1743151753131"}],"cachedText({\"lastModified\":\"1743151753131\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageBody\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageBody-1743151753131"}],"cachedText({\"lastModified\":\"1743151753131\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageCustomFields\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageCustomFields-1743151753131"}],"cachedText({\"lastModified\":\"1743151753131\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageRevision\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageRevision-1743151753131"}],"cachedText({\"lastModified\":\"1743151753131\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageReplyButton\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageReplyButton-1743151753131"}],"cachedText({\"lastModified\":\"1743151753131\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageAuthorBio\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageAuthorBio-1743151753131"}],"cachedText({\"lastModified\":\"1743151753131\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/users/UserAvatar\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/users/UserAvatar-1743151753131"}],"cachedText({\"lastModified\":\"1743151753131\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/ranks/UserRankLabel\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/ranks/UserRankLabel-1743151753131"}],"cachedText({\"lastModified\":\"1743151753131\",\"locale\":\"en-US\",\"namespaces\":[\"components/users/UserRegistrationDate\"]})":[{"__ref":"CachedAsset:text:en_US-components/users/UserRegistrationDate-1743151753131"}],"cachedText({\"lastModified\":\"1743151753131\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/nodes/NodeAvatar\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/nodes/NodeAvatar-1743151753131"}],"cachedText({\"lastModified\":\"1743151753131\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/nodes/NodeDescription\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/nodes/NodeDescription-1743151753131"}],"cachedText({\"lastModified\":\"1743151753131\",\"locale\":\"en-US\",\"namespaces\":[\"components/tags/TagView/TagViewChip\"]})":[{"__ref":"CachedAsset:text:en_US-components/tags/TagView/TagViewChip-1743151753131"}],"cachedText({\"lastModified\":\"1743151753131\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/nodes/NodeIcon\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/nodes/NodeIcon-1743151753131"}]},"CachedAsset:pages-1743057923215":{"__typename":"CachedAsset","id":"pages-1743057923215","value":[{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"BlogViewAllPostsPage","type":"BLOG","urlPath":"/category/:categoryId/blog/:boardId/all-posts/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"CasePortalPage","type":"CASE_PORTAL","urlPath":"/caseportal","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"CreateGroupHubPage","type":"GROUP_HUB","urlPath":"/groups/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"CaseViewPage","type":"CASE_DETAILS","urlPath":"/case/:caseId/:caseNumber","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"InboxPage","type":"COMMUNITY","urlPath":"/inbox","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"HelpFAQPage","type":"COMMUNITY","urlPath":"/help","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"IdeaMessagePage","type":"IDEA_POST","urlPath":"/idea/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"IdeaViewAllIdeasPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId/all-ideas/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"LoginPage","type":"USER","urlPath":"/signin","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"BlogPostPage","type":"BLOG","urlPath":"/category/:categoryId/blogs/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"UserBlogPermissions.Page","type":"COMMUNITY","urlPath":"/c/user-blog-permissions/page","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"ThemeEditorPage","type":"COMMUNITY","urlPath":"/designer/themes","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"TkbViewAllArticlesPage","type":"TKB","urlPath":"/category/:categoryId/kb/:boardId/all-articles/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1730819800000,"localOverride":null,"page":{"id":"AllEvents","type":"CUSTOM","urlPath":"/Events","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"OccasionEditPage","type":"EVENT","urlPath":"/event/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"OAuthAuthorizationAllowPage","type":"USER","urlPath":"/auth/authorize/allow","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"PageEditorPage","type":"COMMUNITY","urlPath":"/designer/pages","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"PostPage","type":"COMMUNITY","urlPath":"/category/:categoryId/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"ForumBoardPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"TkbBoardPage","type":"TKB","urlPath":"/category/:categoryId/kb/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"EventPostPage","type":"EVENT","urlPath":"/category/:categoryId/events/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"UserBadgesPage","type":"COMMUNITY","urlPath":"/users/:login/:userId/badges","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"GroupHubMembershipAction","type":"GROUP_HUB","urlPath":"/membership/join/:nodeId/:membershipType","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"MaintenancePage","type":"COMMUNITY","urlPath":"/maintenance","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"IdeaReplyPage","type":"IDEA_REPLY","urlPath":"/idea/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"UserSettingsPage","type":"USER","urlPath":"/mysettings/:userSettingsTab","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"GroupHubsPage","type":"GROUP_HUB","urlPath":"/groups","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"ForumPostPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"OccasionRsvpActionPage","type":"OCCASION","urlPath":"/event/:boardId/:messageSubject/:messageId/rsvp/:responseType","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"VerifyUserEmailPage","type":"USER","urlPath":"/verifyemail/:userId/:verifyEmailToken","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"AllOccasionsPage","type":"OCCASION","urlPath":"/category/:categoryId/events/:boardId/all-events/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"EventBoardPage","type":"EVENT","urlPath":"/category/:categoryId/events/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"TkbReplyPage","type":"TKB_REPLY","urlPath":"/kb/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"IdeaBoardPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"CommunityGuideLinesPage","type":"COMMUNITY","urlPath":"/communityguidelines","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"CaseCreatePage","type":"SALESFORCE_CASE_CREATION","urlPath":"/caseportal/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"TkbEditPage","type":"TKB","urlPath":"/kb/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"ForgotPasswordPage","type":"USER","urlPath":"/forgotpassword","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"IdeaEditPage","type":"IDEA","urlPath":"/idea/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"TagPage","type":"COMMUNITY","urlPath":"/tag/:tagName","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"BlogBoardPage","type":"BLOG","urlPath":"/category/:categoryId/blog/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"OccasionMessagePage","type":"OCCASION_TOPIC","urlPath":"/event/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"ManageContentPage","type":"COMMUNITY","urlPath":"/managecontent","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"ClosedMembershipNodeNonMembersPage","type":"GROUP_HUB","urlPath":"/closedgroup/:groupHubId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"CommunityPage","type":"COMMUNITY","urlPath":"/","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"ForumMessagePage","type":"FORUM_TOPIC","urlPath":"/discussions/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"IdeaPostPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1730819800000,"localOverride":null,"page":{"id":"CommunityHub.Page","type":"CUSTOM","urlPath":"/Directory","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"BlogMessagePage","type":"BLOG_ARTICLE","urlPath":"/blog/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"RegistrationPage","type":"USER","urlPath":"/register","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"EditGroupHubPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"ForumEditPage","type":"FORUM","urlPath":"/discussions/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"ResetPasswordPage","type":"USER","urlPath":"/resetpassword/:userId/:resetPasswordToken","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1730819800000,"localOverride":null,"page":{"id":"AllBlogs.Page","type":"CUSTOM","urlPath":"/blogs","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"TkbMessagePage","type":"TKB_ARTICLE","urlPath":"/kb/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"BlogEditPage","type":"BLOG","urlPath":"/blog/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"ManageUsersPage","type":"USER","urlPath":"/users/manage/:tab?/:manageUsersTab?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"ForumReplyPage","type":"FORUM_REPLY","urlPath":"/discussions/:boardId/:messageSubject/:messageId/replies/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"PrivacyPolicyPage","type":"COMMUNITY","urlPath":"/privacypolicy","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"NotificationPage","type":"COMMUNITY","urlPath":"/notifications","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"UserPage","type":"USER","urlPath":"/users/:login/:userId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"OccasionReplyPage","type":"OCCASION_REPLY","urlPath":"/event/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"ManageMembersPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/manage/:tab?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"SearchResultsPage","type":"COMMUNITY","urlPath":"/search","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"BlogReplyPage","type":"BLOG_REPLY","urlPath":"/blog/:boardId/:messageSubject/:messageId/replies/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"GroupHubPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"TermsOfServicePage","type":"COMMUNITY","urlPath":"/termsofservice","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"CategoryPage","type":"CATEGORY","urlPath":"/category/:categoryId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"ForumViewAllTopicsPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId/all-topics/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"TkbPostPage","type":"TKB","urlPath":"/category/:categoryId/kbs/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1743057923215,"localOverride":null,"page":{"id":"GroupHubPostPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"}],"localOverride":false},"CachedAsset:text:en_US-components/context/AppContext/AppContextProvider-0":{"__typename":"CachedAsset","id":"text:en_US-components/context/AppContext/AppContextProvider-0","value":{"noCommunity":"Cannot find community","noUser":"Cannot find current user","noNode":"Cannot find node with id {nodeId}","noMessage":"Cannot find message with id {messageId}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/Loading/LoadingDot-0":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/Loading/LoadingDot-0","value":{"title":"Loading..."},"localOverride":false},"User:user:-1":{"__typename":"User","id":"user:-1","uid":-1,"login":"Deleted","email":"","avatar":null,"rank":null,"kudosWeight":1,"registrationData":{"__typename":"RegistrationData","status":"ANONYMOUS","registrationTime":null,"confirmEmailStatus":false,"registrationAccessLevel":"VIEW","ssoRegistrationFields":[]},"ssoId":null,"profileSettings":{"__typename":"ProfileSettings","dateDisplayStyle":{"__typename":"InheritableStringSettingWithPossibleValues","key":"layout.friendly_dates_enabled","value":"false","localValue":"true","possibleValues":["true","false"]},"dateDisplayFormat":{"__typename":"InheritableStringSetting","key":"layout.format_pattern_date","value":"MMM dd yyyy","localValue":"MM-dd-yyyy"},"language":{"__typename":"InheritableStringSettingWithPossibleValues","key":"profile.language","value":"en-US","localValue":"en","possibleValues":["en-US"]}},"deleted":false},"Theme:customTheme1":{"__typename":"Theme","id":"customTheme1"},"Category:category:Azure":{"__typename":"Category","id":"category:Azure","entityType":"CATEGORY","displayId":"Azure","nodeType":"category","depth":3,"title":"Azure","shortTitle":"Azure","parent":{"__ref":"Category:category:products-services"},"categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:top":{"__typename":"Category","id":"category:top","displayId":"top","nodeType":"category","depth":0,"title":"Top","entityType":"CATEGORY","shortTitle":"Top"},"Category:category:communities":{"__typename":"Category","id":"category:communities","displayId":"communities","nodeType":"category","depth":1,"parent":{"__ref":"Category:category:top"},"title":"Communities","entityType":"CATEGORY","shortTitle":"Communities"},"Category:category:products-services":{"__typename":"Category","id":"category:products-services","displayId":"products-services","nodeType":"category","depth":2,"parent":{"__ref":"Category:category:communities"},"title":"Products","entityType":"CATEGORY","shortTitle":"Products"},"Blog:board:AzureArchitectureBlog":{"__typename":"Blog","id":"board:AzureArchitectureBlog","entityType":"BLOG","displayId":"AzureArchitectureBlog","nodeType":"board","depth":4,"conversationStyle":"BLOG","title":"Azure Architecture Blog","description":"","avatar":null,"profileSettings":{"__typename":"ProfileSettings","language":null},"parent":{"__ref":"Category:category:Azure"},"ancestors":{"__typename":"CoreNodeConnection","edges":[{"__typename":"CoreNodeEdge","node":{"__ref":"Community:community:gxcuf89792"}},{"__typename":"CoreNodeEdge","node":{"__ref":"Category:category:communities"}},{"__typename":"CoreNodeEdge","node":{"__ref":"Category:category:products-services"}},{"__typename":"CoreNodeEdge","node":{"__ref":"Category:category:Azure"}}]},"userContext":{"__typename":"NodeUserContext","canAddAttachments":false,"canUpdateNode":false,"canPostMessages":false,"isSubscribed":false},"boardPolicies":{"__typename":"BoardPolicies","canPublishArticleOnCreate":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.forums.policy_can_publish_on_create_workflow_action.accessDenied","key":"error.lithium.policies.forums.policy_can_publish_on_create_workflow_action.accessDenied","args":[]}}},"shortTitle":"Azure Architecture Blog","repliesProperties":{"__typename":"RepliesProperties","sortOrder":"REVERSE_PUBLISH_TIME","repliesFormat":"threaded"},"tagProperties":{"__typename":"TagNodeProperties","tagsEnabled":{"__typename":"PolicyResult","failureReason":null}},"requireTags":false,"tagType":"PRESET_ONLY"},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/cmstNC05WEo0blc\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/cmstNC05WEo0blc","height":512,"width":512,"mimeType":"image/png"},"Rank:rank:4":{"__typename":"Rank","id":"rank:4","position":6,"name":"Microsoft","color":"333333","icon":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/cmstNC05WEo0blc\"}"},"rankStyle":"OUTLINE"},"User:user:222853":{"__typename":"User","id":"user:222853","uid":222853,"login":"GeertVanTeylingen","deleted":false,"avatar":{"__typename":"UserAvatar","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/dS0yMjI4NTMtMzI1MjMwaTVERUE2NzdCRkJBNjkxQzg"},"rank":{"__ref":"Rank:rank:4"},"email":"","messagesCount":50,"biography":null,"topicsCount":38,"kudosReceivedCount":25,"kudosGivenCount":8,"kudosWeight":1,"registrationData":{"__typename":"RegistrationData","status":null,"registrationTime":"2018-10-04T04:12:23.633-07:00","confirmEmailStatus":null},"followersCount":null,"solutionsCount":0},"BlogTopicMessage:message:3609189":{"__typename":"BlogTopicMessage","uid":3609189,"subject":"High-performance storage for AI Model Training tasks using Azure ML studio with Azure NetApp Files","id":"message:3609189","revisionNum":23,"repliesCount":0,"author":{"__ref":"User:user:222853"},"depth":0,"hasGivenKudo":false,"board":{"__ref":"Blog:board:AzureArchitectureBlog"},"conversation":{"__ref":"Conversation:conversation:3609189"},"messagePolicies":{"__typename":"MessagePolicies","canPublishArticleOnEdit":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.forums.policy_can_publish_on_edit_workflow_action.accessDenied","key":"error.lithium.policies.forums.policy_can_publish_on_edit_workflow_action.accessDenied","args":[]}},"canModerateSpamMessage":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.feature.moderation_spam.action.moderate_entity.allowed.accessDenied","key":"error.lithium.policies.feature.moderation_spam.action.moderate_entity.allowed.accessDenied","args":[]}}},"contentWorkflow":{"__typename":"ContentWorkflow","state":"PUBLISH","scheduledPublishTime":null,"scheduledTimezone":null,"userContext":{"__typename":"MessageWorkflowContext","canSubmitForReview":null,"canEdit":false,"canRecall":null,"canSubmitForPublication":null,"canReturnToAuthor":null,"canPublish":null,"canReturnToReview":null,"canSchedule":false},"shortScheduledTimezone":null},"readOnly":false,"editFrozen":false,"moderationData":{"__ref":"ModerationData:moderation_data:3609189"},"teaser":"

This article describes how to provide enterprise grade high performance persistent storage with data protection capability for AI Model training tasks using studio compute instances with Azure NetApp Files (ANF).

\n

 

\n

\n

 

\n

 

","body":"

Table of Contents

\n

 

\n

Abstract

\n

Introduction

\n

Prepare the environment

\n

Pre-requisites

\n

Note on Connectivity

\n

Provision the working environment

\n

Access Azure Cloud Shell and install extensions

\n

Setting variables

\n

Service provisioning

\n

Provision Azure NetApp Files persistent storage with Azure Machine Learning studio for AI model training

\n

Prepare the repository

\n

Create an Azure Machine Learning studio resource

\n

Start a training job

\n

Training job results

\n

Provision Azure NetApp Files persistent storage with Azure Machine Learning Studio for Studio Notebooks

\n

Preparation and requirements

\n

Provision a compute instance

\n

Configure the compute instance and download a dataset

\n

Accessing Azure NetApp Files from a notebook

\n

Snapshots

\n

Creating a snapshot using the Azure Cloud Shell

\n

Restoring a snapshot using the Azure Cloud Shell

\n

Summary

\n

Additional Information

\n

 

\n

Abstract

\n

 

\n

Artificial Intelligence (AI), Machine Learning (ML) and Deep Learning (DL) workloads all have a similar profile – high performance requirements, large capacity and oftentimes, high file counts, which result in high metadata. When datasets are as large and cumbersome as AI/ML datasets, it becomes as difficult to scale to meet their needs as it is to migrate these workloads where you need them. Because of the need for scale and data real estate, many workload owners are looking towards cloud providers like Microsoft Azure with Microsoft Machine Learning to fulfill their needs without breaking the bank in cost. 

\n

 

\n

Azure NetApp Files is one way to address the unique requirements for an AI/ML/DL workload. Azure NetApp Files delivers a blend of high performance, massive scale and simple migration tools that enhance the AI/ML/DL use case by reducing job completion times and providing a way to save money by changing performance levels on the fly and automatically tiering inactive datasets to lower cost Azure storage.

\n

 

\n

In addition, Azure NetApp Files provides industry-leading snapshot technology for near-instantaneous backup and restore of critical datasets, as well as a fast, efficient method to create exact replicas of datasets across cloud regions in Azure for better data locality.

\n

 

\n

Azure NetApp Files also provides a way to quickly clone volumes to new volumes that can be reformatted, normalized and manipulated while preserving the original “gold-source” without having to physically migrate data.

\n

 

\n

Two possible use-cases are discussed: integration of Azure NetApp Files into training jobs, and integration of Azure NetApp Files into Azure Machine Learning Studio Notebooks. In this article you learn:   

\n

 

\n
    \n
  1. How to create an Azure NetApp Files account, capacity pool, and delegated subnet using the CLI
  2. \n
  3. How to provision an Azure NetApp Files NFS volume using the CLI
  4. \n
  5. How to create an Azure Machine learning studio workspace using the CLI
  6. \n
  7. How to leverage a NFS volume for high performance AI model training 
  8. \n
  9. How to connect an NFS volume to an Azure Machine Learning notebook instance
  10. \n
\n

Co-authors: Max Amende,  Prabu Arjunan (NetApp), Diane Patton (Azure NetApp Files)

\n

 

\n

Introduction

\n

 

\n

Data scientists face several challenges today. They need to have access to high performance persistent data volumes to train machine learning models, while also needing to protect these critical datasets. They work with large amounts of data and need to instantly be able to consistently create data volumes that are exact replicas or previous versions of existing volumes. Azure NetApp Files, coupled with the Azure Machine Learning studio, inherently provide the functionality required by today’s data scientists.

\n

 

\n

The Azure Machine Learning studio is the web portal for data scientists in Azure Machine Learning. The studio combines no-code and code-first experiences for an inclusive data science platform. Azure NetApp Files is an enterprise-class, high-performance, metered file storage service. You can select service and performance levels, create capacity pools, volumes, and manage data protection. Azure NetApp Files supports many workload types and is highly available by design.

\n

 

\n

The integration of the Azure Machine Learning studio with Azure NetApp Files is possible in several ways. This article covers step by step configuration of two scenarios: leveraging high-performance storage for AI model training tasks, and provisioning Azure NetApp Files volumes with Azure Machine Learning notebooks for data persistency and protection.

\n

 

\n

Prepare the environment

\n

 

\n

This section describes how to prepare the Azure environment for both use cases covered in this article. It provides steps to set up your resource-group, networking, Azure NetApp Files, and Azure Machine Learning Studio.

\n

 

\n

Pre-requisites

\n

 

\n

You must have:

\n\n

 

\n

Note on Connectivity

\n

 

\n

You must ensure network connectivity between Azure Machine Learning studio and Azure NetApp Files. For this guide we initialize the Azure Machine Learning studio compute instances and Azure NetApp Files volumes into the same Azure Virtual Network (VNet), separated into two subnets. Azure Machine Learning studio is deployed on one subnet. The second subnet is delegated to Azure NetApp Files.

\n

 

\n

Provision the working environment

\n

 

\n

This section describes how to deploy, configure, and connect Azure Machine Learning studio with Azure NetApp Files using the Azure Cloud Shell and CLI commands hosted at azureml-with-azure-netapp-files.

\n


Although they are not covered in this aericle, you could also execute these steps using the Azure Portal.

\n

 

\n

Access Azure Cloud Shell and install extensions

\n

 

\n

Login to the Microsoft Azure Web-interface and open the Cloud Shell as shown below.

\n

 

\n

\n

 

\n

Login by entering:

\n

 

\n
user [~]$ az login
Cloud Shell is automatically authenticated under the initial account signed-in with. Run 'az login' only if you need to use a different account
To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code “Secure Code” to authenticate.
\n


Install the following CLI extension from the Cloud Shell to allow provisioning Azure Machine Learning from the Cloud Shell. Register Azure NetApp files:

\n

 

\n
user [ ~ ]$az extension add --name ml
user [ ~ ]$az provider register --namespace Microsoft.NetApp --wait
\n

 

\n

Setting variables

\n

 

\n

Create and set variables. Modify the values and location and names to what is applicable for your environment. Ensure the location selected supports Azure NetApp Files and ensure there is network connectivity between Azure Machine Learning Studio subnet and Azure NetApp Files delegated subnet. We use the below variables as an example throughout this article.

\n

 

\n

 These variables are not persistent, if you log out of cloud shell you must re-initialize them.

\n

 

\n
# Resource group name
rg='aml-anf-test'
location='westeurope'

# VNET details
vnet_name='vnet'
vnet_address_range='10.0.0.0/16'
vnet_aml_subnet='10.0.1.0/24'
vnet_anf_subnet='10.0.2.0/24'

# AML details
workspace_name='aml-anf'

# ANF details
anf_name=anf
pool_name=pool1
\n

 

\n

Service provisioning

\n

 

\n

After the variables are initialized, provision the required services and network.

\n

 

\n

As shown below, first create the resource group and define the defaults for the working environment, using the variables identified in the prior step:

\n

 

\n
user [ ~ ]:~$ az group create -n $rg -l $location
{
  \"id\": \"/subscriptions/number/resourceGroups/aml-anf-test\",
  \"location\": \"westeurope\",
  \"managedBy\": null,
  \"name\": \"aml-anf-test\",
  \"properties\": {
    \"provisioningState\": \"Succeeded\"
  },
  \"tags\": null,
  \"type\": \"Microsoft.Resources/resourceGroups\"
}
user [ ~ ]:~$ az configure --defaults group=$rg workspace=$workspace_name location=$location
\n

 

\n

Add the VNet and two subnets. One subnet will be used for compute, and the other will be delegated to Azure NetApp Files:

\n

 

\n
user [~ ]$ az network vnet create -n $vnet_name –address-prefix $vnet_address_range
{
  “newVNet”: {
    “addressSpace”: {
      “addressPrefixes”: [
        “10.0.0.0/16”
      ]
    },
    …
  }
}
user [~]$ az network vnet subnet create --vnet-name $vnet_name -n anf --address-prefixes $vnet_aml_subnet  
{ \"addressPrefix“: \"10.0.1.0/24\",
  \"delegations\": [],
  ...
}
user[ ~]$ az network vnet subnet create– --vnet-name $vnet_name -n anf --address-prefixes $vnet_anf_subn– --delegations \"Microsoft.NetApp/volumes\"
{“  \"addressPrefix“: \"10.0.2.0”24\",
“  \"delegations\": [
    {
   “  \"actions\": [
     “  \"Microsoft.Network/networkinterface”/*\",
     “  \"Microsoft.Network/virtualNetworks/subnets/join/action\"
      ],
   “  \"etag“: \"W/\\\"<number>”\\\"\",
   “  ”id“: \"/subscriptions/<number>/resourceGroups/aml-anf-test/providers/Microsoft.Network/virtualNetworks/vnet/subnets/anf/delegation”/0\",
   “  \"name“:”\"0\",
   “  \"provisioningState“: \"Succeeded\",
   “  \"resourceGroup“: \"aml-anf-test\",
   “  \"serviceName“: \"Microsoft.NetApp/volumes\",
   “  \"type“: \"Microsoft.Network/virtualNetworks/subnets/delegations\"
    }
  ],
  ...
}
\n

We reduced the output of certain fields indicated by “…” for readability.

\n

 

\n\n\n\n\n\n\n
\n

(!) Note

\n

 

\n

The Azure NetApp Files subnet must be separate from the Azure Machine Learning studio subnet and be explicitly

\n

delegated to Azure NetApp Files.

\n
\n

 

\n

Next, provision the Azure Machine Learning workspace as shown below:

\n

 

\n
user[ ~ ]$ az ml workspace create --name $workspace_name
The deployment request aml-anf-47652685 was accepted. ARM deployment URI for reference:
https://portal.azure.com//#blade/HubsExtension/DeploymentDetailsBlade/overview/id/%2Fsubscriptions%number%2FresourceGroups%2Faml-anf-test%2Fproviders%2FMicrosoft.Resources%2Fdeployments%2Faml-anf-476562285
Creating AppInsights: (amlanfinsights80221d528b9e  )  Done (7s)
Creating KeyVault: (amlanfkeyvault01027221d033  ) ..  Done (23s)
Creating Storage Account: (amlanfstoragecad13288ba5c  )   Done (27s)
Creating workspace: (aml-anf  ) ..  Done (16s)
Total time : 45s
{
  \"application_insights\": \"/subscriptions/<number>/resourceGroups/aml-anf-test/providers/Microsoft.insights/components/amlanfinsights82021d58b9e\",
  \"description\": \"aml-anf\",
  \"discovery_url\": \"https://westeurope.api.azureml.ms/discovery\",
  \"display_name\": \"aml-anf\",
  \"hbi_workspace\": false,
  \"id\": \"/subscriptions/<number>/resourceGroups/aml-anf-test/providers/Microsoft.MachineLearningServices/workspaces/aml-anf\",
  \"key_vault\": \"/subscriptions/<number>/resourceGroups/aml-anf-test/providers/Microsoft.Keyvault/vaults/amlanfkeyvault0102712d033\",
  \"location\": \"westeurope\",
  \"mlflow_tracking_uri\": \"azureml://westeurope.api.azureml.ms/mlflow/v1.0/subscriptions/<number>/resourceGroups/aml-anf-test/providers/Microsoft.MachineLearningServices/workspaces/aml-anf\",
  \"name\": \"aml-anf\",
  \"public_network_access\": \"Enabled\",
  \"resourceGroup\": \"aml-anf-test\",
  \"resource_group\": \"aml-anf-test\",
  \"storage_account\": \"/subscriptions/<number>/resourceGroups/aml-anf-test/providers/Microsoft.Storage/storageAccounts/amlanfstoragecad132828ba5c\",
  \"tags\": {
    \"createdByToolkit\": \"cli-v2-2.6.1\"
  }
}
\n

Configure Azure NetApp Files. Create a NetApp account, a capacity pool, and a NFSv3 volume:

\n

 

\n
user[ ~ ]$ az netappfiles account create --name $anf_name
{
  \"activeDirectories\": null,
  \"disableShowmount\": null,
  \"encryption\": {
    \"identity\": null,
    \"keySource\": \"Microsoft.NetApp\",
    \"keyVaultProperties\": null
  },
  \"etag\": \"W/\\\"datetime'2024-01-08T15%3A56%3A57.3097309Z'\\\"\",
….
}
user [ ~ ]$ az netappfiles pool create --account-name $anf_name --name $pool_name --size 4 --service-level premium
{
  \"coolAccess\": false,
  \"encryptionType\": \"Single\",
  \"etag\": \" \"W/\\\"datetime'2024-01-08T15%3A58%3A40.0232694Z'\\\"\",,
  \"id\": \"/subscriptions/<number>/resourceGroups/aml-anf-test/providers/Microsoft.NetApp/netAppAccounts/anf/capacityPools/pool1\",
  \"location\": \"westeurope\",
  \"name\": \"anf/pool1\",
  \"poolId\": \"<number>\",
  \"provisioningState\": \"Succeeded\",
  \"qosType\": \"Auto\",
  \"resourceGroup\": \"aml-anf-test\",
  \"serviceLevel\": \"Premium\",
  \"size\": 4398046511104,
  …
 
}
user [ ~ ]$ az netappfiles volume create --account-name $anf_name --pool-name $pool_name --name vol1 --service-level premium --usage-threshold 4096 --file-path \"vol1\" --vnet $vnet_name --subnet anf --protocol-types NFSv3 --allowed-clients $vnet_aml_subnet --rule-index 1 --unix-read-write true
{
  \"avsDataStore\": \"Disabled\",
  \"backupId\": null,
  \"baremetalTenantId\": \"baremetalTenant_svm_47702141844c3d28e8de7c602a040a58_e7f3a9a9\",
  \"capacityPoolResourceId\": null,
  \"cloneProgress\": null,
  \"coolAccess\": false,
  \"coolnessPeriod\": null,
  \"creationToken\": \"vol1\",
...
}
\n

We reduced the output of certain fields indicated by “…” for readability.

\n

 

\n\n\n\n\n\n\n
\n

(!) Note

When creating the capacity pool, the allocation size used here is 4 TiB (defined by “—size 4”). Although that might be a bit much for some customers, the extra space can provide advantages. Azure NetApp Files allows you to provision the speed of a volume independently from its size. Thus, you can provision the extra space’s speed to a smaller volume, and therefore possibly select a lower service level. Furthermore, the capacity pools can be shared with additional volumes for other workloads as required.

\n
\n

 

\n

Provision Azure NetApp Files persistent storage with Azure Machine Learning studio for AI model training

\n

 

\n

After the working environment has been prepared, this section describes the steps to deploy an Azure Machine Learning environment using Azure NetApp Files for AI Model Training. It shows how to use Azure NetApp Files for persistent storage, deploy a compute cluster and run a training job. It also shows how to test and view performance results. It requires a script and yml files downloaded from github.

\n

 

\n

Prepare the repository

\n

 

\n

We have created a repository on github with yaml and python files to use for this setup and demonstration. To access the prepared YAML files, download the repository and unzip it as shown below. After it is unzipped, change directory to the new anf-with-azureml-main directory:

\n

 

\n
user [~ ]$ wget https://github.com/prabuarjunan/anf-with-azureml/archive/refs/heads/main.zip
--2024-01-08 16:19:16--  https://github.com/prabuarjunan/anf-with-azureml/archive/refs/heads/main.zip
Resolving github.com... 140.82.112.3
Connecting to github.com|140.82.112.3|:443... connected.
HTTP request sent, awaiting response... 302 Found
Location: https://codeload.github.com/prabuarjunan/anf-with-azureml/zip/refs/heads/main [following]
--2024-01-08 16:19:16--  https://codeload.github.com/prabuarjunan/anf-with-azureml/zip/refs/heads/main

Resolving codeload.github.com... 140.82.113.10
Connecting to codeload.github.com|140.82.113.10|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [application/zip]
Saving to: ‘main.zip’

main.zip                                    [ <=>                                                                          ]   6.47K  --.-KB/s    in 0.003s 

2024-01-08 16:19:16 (1.82 MB/s) - ‘main.zip’ saved [6630]

user [ ~ ]$ unzip main.zip && rm main.zip
Archive:  main.zip
   creating: anf-with-azureml-main/
  inflating: anf-with-azureml-main/.gitignore 
  inflating: anf-with-azureml-main/README.md 
   creating: anf-with-azureml-main/code/
  inflating: anf-with-azureml-main/code/train.py 
  inflating: anf-with-azureml-main/environment.yml 
   creating: anf-with-azureml-main/environment/
  inflating: anf-with-azureml-main/environment/Dockerfile 
  inflating: anf-with-azureml-main/environment/requirements.txt 
  inflating: anf-with-azureml-main/train.yml 
user@Azure:~$ cd anf-with-azureml-main
\n

 

\n

Create an Azure Machine Learning studio resource

\n

 

\n

From the directory, execute the environment YAML to create an Azure Machine Learning environment. The environment.yaml file uses a Dockerfile to create the environment. The Dockerfile uses an Azure Machine Learning ubuntu image as its base and adds the NFS driver, python libraries for our script, and fio for testing.

\n

 

\n
user [ ~/anf-with-azureml-main ]$ az ml environment create --file environment.yml
Uploading environment (0.0 MBs): 100%|| 638/638 [00:00<00:00, 1260.22it/s]
{
  \"build\": {
    \"dockerfile_path\": \"Dockerfile\",
    \"path\": \"https://amlanfstoraged50e45d9af7.blob.core.windows.net/azureml-blobstore-xxx/LocalUpload/<number>/environment/\"
  },
  \"creation_context\": {
    \"created_at\": \"2024-01-08T16:21:24.448106+00:00\",
    \"created_by\": \"user\",
    \"created_by_type\": \"User\",
    \"last_modified_at\": \"2024-01-08T16:21:24.448106+00:00\",
    \"last_modified_by\": \"user\",
    \"last_modified_by_type\": \"User\"
  },
  \"description\": \"Environment with NFS drivers and a few Python libraries.\",
  \"id\": \"azureml:/subscriptions/<number>/resourceGroups/aml-anf-test/providers/Microsoft.MachineLearningServices/workspaces/aml-anf/environments/python-base-nfs/versions/1\",
  \"name\": \"python-base-nfs\",
  \"os_type\": \"linux\",
  \"resourceGroup\": \"aml-anf-test\",
  \"tags\": {},
  \"version\": \"1\"
}
\n

 

\n

Spin up an Azure Machine Learning compute cluster:

\n

 

\n
user [ ~/anf-with-azureml-main ]$  az ml compute create -n cpu-cluster --type amlcompute --min-instances 0 --max-instances 1 --size Standard_F16s_v2 --vnet-name $vnet_name --subnet aml --idle-time-before-scale-down 1800
{
  \"id\": \"/subscriptions/<number>/resourceGroups/aml-anf-test/providers/Microsoft.MachineLearningServices/workspaces/aml-anf/computes/cpu-cluster\",
  \"idle_time_before_scale_down\": 1800,
  \"location\": \"westeurope\",
  \"max_instances\": 1,
  \"min_instances\": 0,
  \"name\": \"cpu-cluster\",
  \"network_settings\": {
    \"subnet\": \"/subscriptions/<number>/resourceGroups/aml-anf-test/providers/Microsoft.Network/virtualNetworks/vnet/subnets/aml\"
  },
  \"provisioning_state\": \"Succeeded\",
  \"resourceGroup\": \"aml-anf-test\",
  \"size\": \"STANDARD_F16S_V2\",
  \"ssh_public_access_enabled\": false,
  \"tier\": \"dedicated\",
  \"type\": \"amlcompute\"
}
\n

 

\n

Start a training job

\n

 

\n

As soon as the cluster is ready, schedule a job which accesses the Azure NetApp Files volume. Train.yml will mount the VM to the Azure NetApp Files volume. You may need to change the train.yml file to mount to the correct mount path in your environment. Before executing the below command, be sure you are logged into the correct Azure account:

\n

 

\n
user [ ~/anf-with-azureml-main ]$ $ az ml job create -f train.yml --web
Uploading code (0.0 MBs): 100%|| 134/134 [00:00<00:00, 19167.75it/s]

{
  \"code\": \"azureml:/subscriptions/<number>/resourceGroups/aml-anf-test/providers/Microsoft.MachineLearningServices/workspaces/aml-anf/codes/number/versions/1\",
  \"command\": \"mkdir /data\\nmount -t nfs -o rw,hard,rsize=65536,wsize=65536,vers=3,tcp 10.0.2.4:/vol1 /data\\ndf -h\\npython train.py\\n# Run fio on NFS share\\ncd /data\\nfio --name=4krandomreads --rw=randread --direct=1 --ioengine=libaio --bs=4k --numjobs=4 --iodepth=128 --size=1G --runtime=60 --group_reporting\\n# Run fio on local disk\\nmkdir /test\\ncd /test\\nfio --name=4krandomreads --rw=randread --direct=1 --ioengine=libaio --bs=4k --numjobs=4 --iodepth=128 --size=1G --runtime=60 --group_reporting\\n\",
  \"compute\": \"azureml:cpu-cluster\",
  \"creation_context\": {
     \"created_at\":\"2024-01-08T16:30:08.808674+00:00\", ,
    \"created_by\": \"User\",
    \"created_by_type\": \"User\"
  },
  \"display_name\": \"purple_potato_5wn2v9vx77\",
  \"environment\": \"azureml:python-base-nfs:1\",
  \"environment_variables\": {},
  \"experiment_name\": \"anf-with-azureml-main\",
  \"id\": \"azureml:/subscriptions/<number>/resourceGroups/aml-anf-test/providers/Microsoft.MachineLearningServices/workspaces/aml-anf/jobs/purple_potato_5wn2v9vx77\",
  \"inputs\": {},
  \"name\": \" purple_potato_5wn2v9vx77\",
  \"outputs\": {
    \"default\": {
      \"mode\": \"rw_mount\",
      \"path\": \"azureml://datastores/workspaceartifactstore/ExperimentRun/dcid.purple_potato_5wn2v9vx77\",
      \"type\": \"uri_folder\"
    }
  },
  \"parameters\": {},
  \"properties\": {
    \"ContentSnapshotId\": \" a0c92ba6-11e2-4ba5-858d-dddf2969a444\",
    \"_azureml.ComputeTargetType\": \"amlctrain\"
  },
  \"resourceGroup\": \"aml-anf-test\",
  \"resources\": {
    \"instance_count\": 1,
    \"properties\": {},
    \"shm_size\": \"2g\"
  },
  \"services\": {
    \"Studio\": {
      \"endpoint\": \"https://ml.azure.com/runs/ purple_potato_5wn2v9vx77?wsid=/subscriptions/<number>/resourcegroups/aml-anf-test/workspaces/aml-anf&tid=4b09112a0-929b-4715-944b-c037425165b3a\",
      \"job_service_type\": \"Studio\"
    },
    \"Tracking\": {
      \"endpoint\": \"azureml://westeurope.api.azureml.ms/mlflow/v1.0/subscriptions/<number>/resourceGroups/aml-anf-test/providers/Microsoft.MachineLearningServices/workspaces/aml-anf?\",
      \"job_service_type\": \"Tracking\"
    }
  },
  \"status\": \"Starting\",
  \"tags\": {},
  \"type\": \"command\"
}
\n

 

\n\n\n\n\n\n\n
\n

(!) Note 

\n

 

\n

If you receive the following error:

\n
Failed to connect to MSI. Please make sure MSI is configured correctly.
Get Token request returned: <Response [400]>
\n

It may be due to inadequate authentication. Try:

\n
az login
\n
\n

\n

As seen below, train.yml mounts the Azure NetApp Files volume to /data. It then runs a small python script to emulate a real program and does storage benchmark that compares the speed of the compute clusters’ integrated storage on the directory /test to the speed of the attached Azure NetApp Files volume mounted to /data.

\n

 

\n
$ cat train.yml
schema: https://azuremlschemas.azureedge.net/latest/commandJob.schema.json
compute: azureml:cpu-cluster
environment: azureml:python-base-nfs:1
code:
  code/
command: |
  mkdir /data
  mount -t nfs -o rw,hard,rsize=65536,wsize=65536,vers=3,tcp 10.0.2.4:/vol1 /data
  df -h
  python train.py
  # Run fio on NFS share
  cd /data
  fio –name=4krandomreads –rw=randread –direct=1 –ioengine=libaio –bs=4k –numjobs=4 –iodepth=128 –size=1G --runtime=60 –group_reporting
  # Run fio on local disk
  mkdir /test
  cd /test
  fio –name=4krandomreads –rw=randread –direct=1 –ioengine=libaio –bs=4k –numjobs=4 –iodepth=128 –size=1G --runtime=60 –group_reporting
\n

 

\n

The small Python script is being executed to emulate a program for training. For example, the Python script could contain the code to train for Natural Language Processing (NLP) or Object Detection model.

\n

 

\n

Training job results

\n

 

\n

To show the performance difference between using a local disk vs an Azure NetApp Files NFS share, return to the Azure GUI and navigate to the Azure Machine Learning view. There is a workspace with your defined name. If you used the same resource names used in this guide, the name will be “amf-anf”.

\n

 

\n

\n

Next, select this workspace and you’ll see a screen similar to the screen below.

\n

 

\n

\n

 

\n

To see the results, proceed by clicking on the “Studio web URL” on the right. After opening Azure Machine Learning studio click on “Jobs” to the left. All the jobs which have run are displayed in the Azure Machine Learning studio. 

\n

 

\n

\n

 

\n

Next, change the view from “All experiments” to “All jobs”. If you followed this document, there should be one job listed. Wait until the status of the job changes to “Completed”.

\n

 

\n

\n

 

\n

Then click on the job to get more information and options.

\n

 

\n

\n

 

\n

Next, select “Outputs + logs”, followed by a click on  “user_logs”, and then select “std_log.txt” to see the results from the benchmark.

\n

 

\n

\n

 

\n

In the log you’ll see that Azure NetApp Files has almost twice the performance as the compute cluster’s integrated storage.

\n

 

\n

You can now delete the job and the compute cluster.

\n

 

\n

Provision Azure NetApp Files persistent storage with Azure Machine Learning Studio for Studio Notebooks

\n

 

\n

After the working environment has been prepared, this section describes the steps to deploy an Azure Machine Learning environment using Azure NetApp Files for persistent storage with studio notebooks.

\n

 

\n

Preparation and requirements

\n

 

\n

Please follow the steps in Prepare your Environment if you have not already done so.

\n

 

\n

Provision a compute instance

\n

 

\n

Open the Azure Machine Learning studio. In case you have never accessed the Azure Machine Learning studio, follow the steps from Results of training job until the point where we access the results from the training job.

\n

 

\n

Click on “Compute”:

\n

 

\n

\n

 

\n

 

\n\n\n\n\n\n\n
\n

(!) Note

\n

 

\n

In case you followed all previous steps in the preceding section and did not delete the compute cluster, you will see your previously provisioned compute cluster under “Compute clusters”

\n
\n

 

\n

Then select “+ New” from the “Compute instances” tab.

\n

\n

 

\n

 

\n

 

\n

Give the compute instance a name of your choice. We call it “ANFTestCompute” in this example.  Select a Virtual Machine size. For this demo, the least expensive instance is sufficient. Select “Next: ”.

\n

 

\n\n\n\n\n\n\n
\n

(i) Important

\n

 

\n

Do not click on “Create” yet, but select “Next: ”.

\n
\n

 

\n

Select your scheduling preference and hit “Next:” for the Security page.

\n

 

\n

\n

 

\n

In the “Security” tab, activate “Enable virtual network”, and select the VNet which we previously created. If you followed the guide, the VNet should be called “vnet (aml-anf-test)”.

\n

 

\n

Then select the subnet which has not been delegated to Azure NetApp Files. In our case this is called “aml”.

\n

 

\n

Now we can scroll through Applications, add any tags, and Review. click on “Create”.

\n

 

\n

Provisioning the compute instance will take a couple of minutes. Wait until the “State” of the instance becomes “Running” as shown below.

\n

 

\n

\n

 

\n

 

\n

Configure the compute instance and download a dataset

\n

 

\n

Under Notebooks,  click on the “Terminal” to connect to the Compute instance as shown below.

\n

 

\n

\n

 

\n

Install the nfs-common driver to allow nfs mounting onto the compute instance as shown below.

\n

 

\n
azureuser@anftestcompute:~/cloudfiles/code/Users/user$ sudo apt install nfs-common -y
Reading package lists... Done
Building dependency tree      
Reading state information... Done
The following packages were automatically installed and are no longer required:
  ca-certificates-java cmake-data cuda-command-line-tools-11-1
  cuda-command-line-tools-11-3 cuda-compiler-11-1 cuda-compiler-11-3
  cuda-cudart-11-1 cuda-cudart-11-3 cuda-cudart-dev-11-1 cuda-cudart-dev-11-3
  cuda-cuobjdump-11-1 cuda-cuobjdump-11-3 cuda-cupti-11-1 cuda-cupti-11-3
  cuda-cupti-dev-11-1 cuda-cupti-dev-11-3 cuda-cuxxfilt-11-3
  cuda-documentation-11-1 cuda-documentation-11-3 cuda-driver-dev-11-1
  …
\n

We reduced the output of certain fields indicated by “…” for readability.

\n

 

\n

Next, create a new folder and mount the Azure NetApp Files volume. Replace the mount path 10.0.2.4:/vol1 with the mount path of your Azure NetApp Files volume if necessary.

\n
azureuser@anftestcompute:~/cloudfiles/code/Users/user$ mkdir data
azureuser@anftestcompute:~/cloudfiles/code/Users/user$ sudo mount -t nfs -o rw,hard,rsize=65536,wsize=65536,vers=3,tcp 10.0.2.4:/vol1 /data
\n

 

\n

Your screen should now look like:

\n

 

\n

\n

 

\n\n\n\n\n\n\n
\n

(!) Note

\n

 

\n

If the “data” folder is not shown on the left side, click on the “Refresh” button.

\n
\n

 

\n

The titanic dataset established itself as the standard first data science project for emerging data scientists. Use this dataset as an example or a dataset of your choosing. Download the dataset to the Azure NetApp Files volume.

\n

 

\n
azureuser@anftestcompute:~$ wget https://web.stanford.edu/class/archive/cs/cs109/cs109.1166/stuff/titanic.csv -P ./data
--2024-01-08 17:55:56--  https://web.stanford.edu/class/archive/cs/cs109/cs109.1166/stuff/titanic.csv
Resolving web.stanford.edu (web.stanford.edu)... 171.67.215.200, 2607:f6d0:0:925a::ab43:d7c8
Connecting to web.stanford.edu (web.stanford.edu)|171.67.215.200|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 44225 (43K) [text/csv]
Saving to: ‘./data/titanic.csv’

titanic.csv                                               100%[=============================>]  43.19K   133KB/s    in 0.3s   

2024-01-08 17:56:00 (133 KB/s) - ‘./data/titanic.csv’ saved [44225/44225]
\n

 

\n

Accessing Azure NetApp Files from a notebook

\n

 

\n

Click on the “Plus Button” on the left to create a new Jupyter/Azure Machine Learning Studio notebook.

\n

 

\n

\n

 

\n

Select “Create new file”.

\n

 

\n

For this example we call the Notebook “ANFNotebook”:

\n

 

\n

\n

 

\n

Click on “Create”.

\n

 

\n

From the Notebook we can now access the files on the Azure NetApp Files volume and build our models based on it. We entered the code seen below into the notebook. We ingest the titanic csv file into a pandas data frame to show access to data on Azure NetApp Files as an example.

\n

 

\n

\n

 

\n

Snapshots

\n

 

\n

Snapshots are a valuable tool for data science tasks to protect the data. They can also be used as an effective and space efficient way to version a data set. You can easily create a snapshot of Azure NetApp Files volumes by:

\n

 

\n\n

As an example, this article uses the Azure Cloud Shell to create and restore a snapshot.

\n

 

\n

Creating a snapshot using the Azure Cloud Shell

\n

 

\n

Open the Azure Cloud Shell and enter the following command. Replace the account name, resource group, pool name and volume name with the names of your resources. As an example, we are naming the snapshot “timeInPointCopy”:

\n

 

\n
user [ ~ ]$ az netappfiles snapshot create --account-name anf --resource-group aml-anf-test --pool-name pool1 --volume-name vol1  --name timeInPointCopy
{
  \"created\": \"2024-01-08T19:09:51.611000+00:00\",
  \"id\": \"/subscriptions/<number>/resourceGroups/aml-anf-test/providers/Microsoft.NetApp/netAppAccounts/anf/capacityPools/pool1/volumes/vol1/snapshots/timeInPointCopy\",
  \"location\": \"westeurope\",
  \"name\": \"anf/pool1/vol1/timeInPointCopy\",
  \"provisioningState\": \"Succeeded\",
  \"resourceGroup\": \"aml-anf-test\",
  \"snapshotId\": \"7b56521c-4957-df26-0c0a-c19c9fad0474\",
  \"systemData\": null,
  \"type\": \"Microsoft.NetApp/netAppAccounts/capacityPools/volumes/snapshots\"
\n

 

\n\n\n\n\n\n\n
\n

(!) Note

\n

 

\n

For this section we used the variable names from Setting variables.

\n
\n

 

\n

Restoring a snapshot using the Azure Cloud Shell

\n

 

\n

Three options exist to restore a snapshot:

\n

 

\n\n

 

\n

For this example we will restore a snapshot to a new volume. This means a new volume with a new name will be created based on the selected snapshot, and the volume data will automatically be restored to this volume. Be sure there is adequate space left in the capacity pool or expand the capacity pool for this operation. You could also restore to a new capacity pool. In this case, we expanded our current capacity pool using the dropdown menu for the capacity pool pool1.

\n

 

\n

The below example's volume creation is based on the snapshot Setting variables and Provisioning of services. Additionally, we need to specify the new volume's name, the mount point, and the snapshot id. Replace these variables with values in your environment.

\n

 

\n

The snapshot-id can be found using the command az netappfiles snapshot list.

\n

 

\n
user [ ~ ]$ az netappfiles volume create --vnet vnet --subnet anf --account-name anf --usage-threshold 40000 --pool-name pool1 --resource-group aml-anf-test --snapshot-id <id> --name vol1copy --file-path vol1copy --service-level premium --protocol-types NFSv3 --allowed-clients '10.0.1.0/24' --rule-index 1 --unix-read-write true 
{
  \"actualThroughputMibps\": 6.25,
  \"avsDataStore\": \"Disabled\",
  \"backupId\": null,
  \"baremetalTenantId\": \"baremetalTenant_svm_d284dc8e25fd11ec8df54654d00c1f9e_d6143cc3\",
  \"capacityPoolResourceId\": null,
  \"cloneProgress\": 0,
  \"coolAccess\": false,

}
\n

We reduced the output of certain fields indicated by “…” for readability.

\n

 

\n

More information on the az netappfiles volume create command can be found in the documentation.

\n

 

\n\n\n\n\n\n\n
\n

(!) Note

\n

 

\n

Entering the command from above might be prone to errors, due to its length and the number of required details.

\n

This operation might be easier to conduct using the Azure GUI.

\n
\n

 

\n

Summary 

\n

 

\n

In this article we described how we can make Azure training jobs and Azure Machine Learning studio notebooks use enterprise-grade high performance persistent storage backed by Azure NetApp Files volumes for training machine learning models and as persistent storage for studio notebooks. We also showed the ease in creating and restoring from snapshots using Azure NetApp Files. Get started with Azure NetApp Files today.

\n

 

\n

Additional Information

\n

 

\n
    \n
  1. https://learn.microsoft.com/en-us/azure/azure-netapp-files/azure-netapp-files-solution-architectures#azure-kubernetes-services-and-kubernetes 
  2. \n
  3. https://azure.microsoft.com/services/machine-learning/
  4. \n
","body@stringLength":"70688","rawBody":"

Table of Contents

\n

 

\n

Abstract

\n

Introduction

\n

Prepare the environment

\n

Pre-requisites

\n

Note on Connectivity

\n

Provision the working environment

\n

Access Azure Cloud Shell and install extensions

\n

Setting variables

\n

Service provisioning

\n

Provision Azure NetApp Files persistent storage with Azure Machine Learning studio for AI model training

\n

Prepare the repository

\n

Create an Azure Machine Learning studio resource

\n

Start a training job

\n

Training job results

\n

Provision Azure NetApp Files persistent storage with Azure Machine Learning Studio for Studio Notebooks

\n

Preparation and requirements

\n

Provision a compute instance

\n

Configure the compute instance and download a dataset

\n

Accessing Azure NetApp Files from a notebook

\n

Snapshots

\n

Creating a snapshot using the Azure Cloud Shell

\n

Restoring a snapshot using the Azure Cloud Shell

\n

Summary

\n

Additional Information

\n

 

\n

Abstract

\n

 

\n

Artificial Intelligence (AI), Machine Learning (ML) and Deep Learning (DL) workloads all have a similar profile – high performance requirements, large capacity and oftentimes, high file counts, which result in high metadata. When datasets are as large and cumbersome as AI/ML datasets, it becomes as difficult to scale to meet their needs as it is to migrate these workloads where you need them. Because of the need for scale and data real estate, many workload owners are looking towards cloud providers like Microsoft Azure with Microsoft Machine Learning to fulfill their needs without breaking the bank in cost. 

\n

 

\n

Azure NetApp Files is one way to address the unique requirements for an AI/ML/DL workload. Azure NetApp Files delivers a blend of high performance, massive scale and simple migration tools that enhance the AI/ML/DL use case by reducing job completion times and providing a way to save money by changing performance levels on the fly and automatically tiering inactive datasets to lower cost Azure storage.

\n

 

\n

In addition, Azure NetApp Files provides industry-leading snapshot technology for near-instantaneous backup and restore of critical datasets, as well as a fast, efficient method to create exact replicas of datasets across cloud regions in Azure for better data locality.

\n

 

\n

Azure NetApp Files also provides a way to quickly clone volumes to new volumes that can be reformatted, normalized and manipulated while preserving the original “gold-source” without having to physically migrate data.

\n

 

\n

Two possible use-cases are discussed: integration of Azure NetApp Files into training jobs, and integration of Azure NetApp Files into Azure Machine Learning Studio Notebooks. In this article you learn:   

\n

 

\n
    \n
  1. How to create an Azure NetApp Files account, capacity pool, and delegated subnet using the CLI
  2. \n
  3. How to provision an Azure NetApp Files NFS volume using the CLI
  4. \n
  5. How to create an Azure Machine learning studio workspace using the CLI
  6. \n
  7. How to leverage a NFS volume for high performance AI model training 
  8. \n
  9. How to connect an NFS volume to an Azure Machine Learning notebook instance
  10. \n
\n

Co-authors: Max Amende,  Prabu Arjunan (NetApp), Diane Patton (Azure NetApp Files)

\n

 

\n

Introduction

\n

 

\n

Data scientists face several challenges today. They need to have access to high performance persistent data volumes to train machine learning models, while also needing to protect these critical datasets. They work with large amounts of data and need to instantly be able to consistently create data volumes that are exact replicas or previous versions of existing volumes. Azure NetApp Files, coupled with the Azure Machine Learning studio, inherently provide the functionality required by today’s data scientists.

\n

 

\n

The Azure Machine Learning studio is the web portal for data scientists in Azure Machine Learning. The studio combines no-code and code-first experiences for an inclusive data science platform. Azure NetApp Files is an enterprise-class, high-performance, metered file storage service. You can select service and performance levels, create capacity pools, volumes, and manage data protection. Azure NetApp Files supports many workload types and is highly available by design.

\n

 

\n

The integration of the Azure Machine Learning studio with Azure NetApp Files is possible in several ways. This article covers step by step configuration of two scenarios: leveraging high-performance storage for AI model training tasks, and provisioning Azure NetApp Files volumes with Azure Machine Learning notebooks for data persistency and protection.

\n

 

\n

Prepare the environment

\n

 

\n

This section describes how to prepare the Azure environment for both use cases covered in this article. It provides steps to set up your resource-group, networking, Azure NetApp Files, and Azure Machine Learning Studio.

\n

 

\n

Pre-requisites

\n

 

\n

You must have:

\n\n

 

\n

Note on Connectivity

\n

 

\n

You must ensure network connectivity between Azure Machine Learning studio and Azure NetApp Files. For this guide we initialize the Azure Machine Learning studio compute instances and Azure NetApp Files volumes into the same Azure Virtual Network (VNet), separated into two subnets. Azure Machine Learning studio is deployed on one subnet. The second subnet is delegated to Azure NetApp Files.

\n

 

\n

Provision the working environment

\n

 

\n

This section describes how to deploy, configure, and connect Azure Machine Learning studio with Azure NetApp Files using the Azure Cloud Shell and CLI commands hosted at azureml-with-azure-netapp-files.

\n


Although they are not covered in this aericle, you could also execute these steps using the Azure Portal.

\n

 

\n

Access Azure Cloud Shell and install extensions

\n

 

\n

Login to the Microsoft Azure Web-interface and open the Cloud Shell as shown below.

\n

 

\n

\n

 

\n

Login by entering:

\n

 

\n
user [~]$ az login
Cloud Shell is automatically authenticated under the initial account signed-in with. Run 'az login' only if you need to use a different account
To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code “Secure Code” to authenticate.
\n


Install the following CLI extension from the Cloud Shell to allow provisioning Azure Machine Learning from the Cloud Shell. Register Azure NetApp files:

\n

 

\n
user [ ~ ]$az extension add --name ml
user [ ~ ]$az provider register --namespace Microsoft.NetApp --wait
\n

 

\n

Setting variables

\n

 

\n

Create and set variables. Modify the values and location and names to what is applicable for your environment. Ensure the location selected supports Azure NetApp Files and ensure there is network connectivity between Azure Machine Learning Studio subnet and Azure NetApp Files delegated subnet. We use the below variables as an example throughout this article.

\n

 

\n

 These variables are not persistent, if you log out of cloud shell you must re-initialize them.

\n

 

\n
# Resource group name
rg='aml-anf-test'
location='westeurope'

# VNET details
vnet_name='vnet'
vnet_address_range='10.0.0.0/16'
vnet_aml_subnet='10.0.1.0/24'
vnet_anf_subnet='10.0.2.0/24'

# AML details
workspace_name='aml-anf'

# ANF details
anf_name=anf
pool_name=pool1
\n

 

\n

Service provisioning

\n

 

\n

After the variables are initialized, provision the required services and network.

\n

 

\n

As shown below, first create the resource group and define the defaults for the working environment, using the variables identified in the prior step:

\n

 

\n
user [ ~ ]:~$ az group create -n $rg -l $location
{
  \"id\": \"/subscriptions/number/resourceGroups/aml-anf-test\",
  \"location\": \"westeurope\",
  \"managedBy\": null,
  \"name\": \"aml-anf-test\",
  \"properties\": {
    \"provisioningState\": \"Succeeded\"
  },
  \"tags\": null,
  \"type\": \"Microsoft.Resources/resourceGroups\"
}
user [ ~ ]:~$ az configure --defaults group=$rg workspace=$workspace_name location=$location
\n

 

\n

Add the VNet and two subnets. One subnet will be used for compute, and the other will be delegated to Azure NetApp Files:

\n

 

\n
user [~ ]$ az network vnet create -n $vnet_name –address-prefix $vnet_address_range
{
  “newVNet”: {
    “addressSpace”: {
      “addressPrefixes”: [
        “10.0.0.0/16”
      ]
    },
    …
  }
}
user [~]$ az network vnet subnet create --vnet-name $vnet_name -n anf --address-prefixes $vnet_aml_subnet  
{ \"addressPrefix“: \"10.0.1.0/24\",
  \"delegations\": [],
  ...
}
user[ ~]$ az network vnet subnet create– --vnet-name $vnet_name -n anf --address-prefixes $vnet_anf_subn– --delegations \"Microsoft.NetApp/volumes\"
{“  \"addressPrefix“: \"10.0.2.0”24\",
“  \"delegations\": [
    {
   “  \"actions\": [
     “  \"Microsoft.Network/networkinterface”/*\",
     “  \"Microsoft.Network/virtualNetworks/subnets/join/action\"
      ],
   “  \"etag“: \"W/\\\"<number>”\\\"\",
   “  ”id“: \"/subscriptions/<number>/resourceGroups/aml-anf-test/providers/Microsoft.Network/virtualNetworks/vnet/subnets/anf/delegation”/0\",
   “  \"name“:”\"0\",
   “  \"provisioningState“: \"Succeeded\",
   “  \"resourceGroup“: \"aml-anf-test\",
   “  \"serviceName“: \"Microsoft.NetApp/volumes\",
   “  \"type“: \"Microsoft.Network/virtualNetworks/subnets/delegations\"
    }
  ],
  ...
}
\n

We reduced the output of certain fields indicated by “…” for readability.

\n

 

\n\n\n\n\n\n\n
\n

(!) Note

\n

 

\n

The Azure NetApp Files subnet must be separate from the Azure Machine Learning studio subnet and be explicitly

\n

delegated to Azure NetApp Files.

\n
\n

 

\n

Next, provision the Azure Machine Learning workspace as shown below:

\n

 

\n
user[ ~ ]$ az ml workspace create --name $workspace_name
The deployment request aml-anf-47652685 was accepted. ARM deployment URI for reference:
https://portal.azure.com//#blade/HubsExtension/DeploymentDetailsBlade/overview/id/%2Fsubscriptions%number%2FresourceGroups%2Faml-anf-test%2Fproviders%2FMicrosoft.Resources%2Fdeployments%2Faml-anf-476562285
Creating AppInsights: (amlanfinsights80221d528b9e  )  Done (7s)
Creating KeyVault: (amlanfkeyvault01027221d033  ) ..  Done (23s)
Creating Storage Account: (amlanfstoragecad13288ba5c  )   Done (27s)
Creating workspace: (aml-anf  ) ..  Done (16s)
Total time : 45s
{
  \"application_insights\": \"/subscriptions/<number>/resourceGroups/aml-anf-test/providers/Microsoft.insights/components/amlanfinsights82021d58b9e\",
  \"description\": \"aml-anf\",
  \"discovery_url\": \"https://westeurope.api.azureml.ms/discovery\",
  \"display_name\": \"aml-anf\",
  \"hbi_workspace\": false,
  \"id\": \"/subscriptions/<number>/resourceGroups/aml-anf-test/providers/Microsoft.MachineLearningServices/workspaces/aml-anf\",
  \"key_vault\": \"/subscriptions/<number>/resourceGroups/aml-anf-test/providers/Microsoft.Keyvault/vaults/amlanfkeyvault0102712d033\",
  \"location\": \"westeurope\",
  \"mlflow_tracking_uri\": \"azureml://westeurope.api.azureml.ms/mlflow/v1.0/subscriptions/<number>/resourceGroups/aml-anf-test/providers/Microsoft.MachineLearningServices/workspaces/aml-anf\",
  \"name\": \"aml-anf\",
  \"public_network_access\": \"Enabled\",
  \"resourceGroup\": \"aml-anf-test\",
  \"resource_group\": \"aml-anf-test\",
  \"storage_account\": \"/subscriptions/<number>/resourceGroups/aml-anf-test/providers/Microsoft.Storage/storageAccounts/amlanfstoragecad132828ba5c\",
  \"tags\": {
    \"createdByToolkit\": \"cli-v2-2.6.1\"
  }
}
\n

Configure Azure NetApp Files. Create a NetApp account, a capacity pool, and a NFSv3 volume:

\n

 

\n
user[ ~ ]$ az netappfiles account create --name $anf_name
{
  \"activeDirectories\": null,
  \"disableShowmount\": null,
  \"encryption\": {
    \"identity\": null,
    \"keySource\": \"Microsoft.NetApp\",
    \"keyVaultProperties\": null
  },
  \"etag\": \"W/\\\"datetime'2024-01-08T15%3A56%3A57.3097309Z'\\\"\",
….
}
user [ ~ ]$ az netappfiles pool create --account-name $anf_name --name $pool_name --size 4 --service-level premium
{
  \"coolAccess\": false,
  \"encryptionType\": \"Single\",
  \"etag\": \" \"W/\\\"datetime'2024-01-08T15%3A58%3A40.0232694Z'\\\"\",,
  \"id\": \"/subscriptions/<number>/resourceGroups/aml-anf-test/providers/Microsoft.NetApp/netAppAccounts/anf/capacityPools/pool1\",
  \"location\": \"westeurope\",
  \"name\": \"anf/pool1\",
  \"poolId\": \"<number>\",
  \"provisioningState\": \"Succeeded\",
  \"qosType\": \"Auto\",
  \"resourceGroup\": \"aml-anf-test\",
  \"serviceLevel\": \"Premium\",
  \"size\": 4398046511104,
  …
 
}
user [ ~ ]$ az netappfiles volume create --account-name $anf_name --pool-name $pool_name --name vol1 --service-level premium --usage-threshold 4096 --file-path \"vol1\" --vnet $vnet_name --subnet anf --protocol-types NFSv3 --allowed-clients $vnet_aml_subnet --rule-index 1 --unix-read-write true
{
  \"avsDataStore\": \"Disabled\",
  \"backupId\": null,
  \"baremetalTenantId\": \"baremetalTenant_svm_47702141844c3d28e8de7c602a040a58_e7f3a9a9\",
  \"capacityPoolResourceId\": null,
  \"cloneProgress\": null,
  \"coolAccess\": false,
  \"coolnessPeriod\": null,
  \"creationToken\": \"vol1\",
...
}
\n

We reduced the output of certain fields indicated by “…” for readability.

\n

 

\n\n\n\n\n\n\n
\n

(!) Note

When creating the capacity pool, the allocation size used here is 4 TiB (defined by “—size 4”). Although that might be a bit much for some customers, the extra space can provide advantages. Azure NetApp Files allows you to provision the speed of a volume independently from its size. Thus, you can provision the extra space’s speed to a smaller volume, and therefore possibly select a lower service level. Furthermore, the capacity pools can be shared with additional volumes for other workloads as required.

\n
\n

 

\n

Provision Azure NetApp Files persistent storage with Azure Machine Learning studio for AI model training

\n

 

\n

After the working environment has been prepared, this section describes the steps to deploy an Azure Machine Learning environment using Azure NetApp Files for AI Model Training. It shows how to use Azure NetApp Files for persistent storage, deploy a compute cluster and run a training job. It also shows how to test and view performance results. It requires a script and yml files downloaded from github.

\n

 

\n

Prepare the repository

\n

 

\n

We have created a repository on github with yaml and python files to use for this setup and demonstration. To access the prepared YAML files, download the repository and unzip it as shown below. After it is unzipped, change directory to the new anf-with-azureml-main directory:

\n

 

\n
user [~ ]$ wget https://github.com/prabuarjunan/anf-with-azureml/archive/refs/heads/main.zip
--2024-01-08 16:19:16--  https://github.com/prabuarjunan/anf-with-azureml/archive/refs/heads/main.zip
Resolving github.com... 140.82.112.3
Connecting to github.com|140.82.112.3|:443... connected.
HTTP request sent, awaiting response... 302 Found
Location: https://codeload.github.com/prabuarjunan/anf-with-azureml/zip/refs/heads/main [following]
--2024-01-08 16:19:16--  https://codeload.github.com/prabuarjunan/anf-with-azureml/zip/refs/heads/main

Resolving codeload.github.com... 140.82.113.10
Connecting to codeload.github.com|140.82.113.10|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [application/zip]
Saving to: ‘main.zip’

main.zip                                    [ <=>                                                                          ]   6.47K  --.-KB/s    in 0.003s 

2024-01-08 16:19:16 (1.82 MB/s) - ‘main.zip’ saved [6630]

user [ ~ ]$ unzip main.zip && rm main.zip
Archive:  main.zip
   creating: anf-with-azureml-main/
  inflating: anf-with-azureml-main/.gitignore 
  inflating: anf-with-azureml-main/README.md 
   creating: anf-with-azureml-main/code/
  inflating: anf-with-azureml-main/code/train.py 
  inflating: anf-with-azureml-main/environment.yml 
   creating: anf-with-azureml-main/environment/
  inflating: anf-with-azureml-main/environment/Dockerfile 
  inflating: anf-with-azureml-main/environment/requirements.txt 
  inflating: anf-with-azureml-main/train.yml 
user@Azure:~$ cd anf-with-azureml-main
\n

 

\n

Create an Azure Machine Learning studio resource

\n

 

\n

From the directory, execute the environment YAML to create an Azure Machine Learning environment. The environment.yaml file uses a Dockerfile to create the environment. The Dockerfile uses an Azure Machine Learning ubuntu image as its base and adds the NFS driver, python libraries for our script, and fio for testing.

\n

 

\n
user [ ~/anf-with-azureml-main ]$ az ml environment create --file environment.yml
Uploading environment (0.0 MBs): 100%|| 638/638 [00:00<00:00, 1260.22it/s]
{
  \"build\": {
    \"dockerfile_path\": \"Dockerfile\",
    \"path\": \"https://amlanfstoraged50e45d9af7.blob.core.windows.net/azureml-blobstore-xxx/LocalUpload/<number>/environment/\"
  },
  \"creation_context\": {
    \"created_at\": \"2024-01-08T16:21:24.448106+00:00\",
    \"created_by\": \"user\",
    \"created_by_type\": \"User\",
    \"last_modified_at\": \"2024-01-08T16:21:24.448106+00:00\",
    \"last_modified_by\": \"user\",
    \"last_modified_by_type\": \"User\"
  },
  \"description\": \"Environment with NFS drivers and a few Python libraries.\",
  \"id\": \"azureml:/subscriptions/<number>/resourceGroups/aml-anf-test/providers/Microsoft.MachineLearningServices/workspaces/aml-anf/environments/python-base-nfs/versions/1\",
  \"name\": \"python-base-nfs\",
  \"os_type\": \"linux\",
  \"resourceGroup\": \"aml-anf-test\",
  \"tags\": {},
  \"version\": \"1\"
}
\n

 

\n

Spin up an Azure Machine Learning compute cluster:

\n

 

\n
user [ ~/anf-with-azureml-main ]$  az ml compute create -n cpu-cluster --type amlcompute --min-instances 0 --max-instances 1 --size Standard_F16s_v2 --vnet-name $vnet_name --subnet aml --idle-time-before-scale-down 1800
{
  \"id\": \"/subscriptions/<number>/resourceGroups/aml-anf-test/providers/Microsoft.MachineLearningServices/workspaces/aml-anf/computes/cpu-cluster\",
  \"idle_time_before_scale_down\": 1800,
  \"location\": \"westeurope\",
  \"max_instances\": 1,
  \"min_instances\": 0,
  \"name\": \"cpu-cluster\",
  \"network_settings\": {
    \"subnet\": \"/subscriptions/<number>/resourceGroups/aml-anf-test/providers/Microsoft.Network/virtualNetworks/vnet/subnets/aml\"
  },
  \"provisioning_state\": \"Succeeded\",
  \"resourceGroup\": \"aml-anf-test\",
  \"size\": \"STANDARD_F16S_V2\",
  \"ssh_public_access_enabled\": false,
  \"tier\": \"dedicated\",
  \"type\": \"amlcompute\"
}
\n

 

\n

Start a training job

\n

 

\n

As soon as the cluster is ready, schedule a job which accesses the Azure NetApp Files volume. Train.yml will mount the VM to the Azure NetApp Files volume. You may need to change the train.yml file to mount to the correct mount path in your environment. Before executing the below command, be sure you are logged into the correct Azure account:

\n

 

\n
user [ ~/anf-with-azureml-main ]$ $ az ml job create -f train.yml --web
Uploading code (0.0 MBs): 100%|| 134/134 [00:00<00:00, 19167.75it/s]

{
  \"code\": \"azureml:/subscriptions/<number>/resourceGroups/aml-anf-test/providers/Microsoft.MachineLearningServices/workspaces/aml-anf/codes/number/versions/1\",
  \"command\": \"mkdir /data\\nmount -t nfs -o rw,hard,rsize=65536,wsize=65536,vers=3,tcp 10.0.2.4:/vol1 /data\\ndf -h\\npython train.py\\n# Run fio on NFS share\\ncd /data\\nfio --name=4krandomreads --rw=randread --direct=1 --ioengine=libaio --bs=4k --numjobs=4 --iodepth=128 --size=1G --runtime=60 --group_reporting\\n# Run fio on local disk\\nmkdir /test\\ncd /test\\nfio --name=4krandomreads --rw=randread --direct=1 --ioengine=libaio --bs=4k --numjobs=4 --iodepth=128 --size=1G --runtime=60 --group_reporting\\n\",
  \"compute\": \"azureml:cpu-cluster\",
  \"creation_context\": {
     \"created_at\":\"2024-01-08T16:30:08.808674+00:00\", ,
    \"created_by\": \"User\",
    \"created_by_type\": \"User\"
  },
  \"display_name\": \"purple_potato_5wn2v9vx77\",
  \"environment\": \"azureml:python-base-nfs:1\",
  \"environment_variables\": {},
  \"experiment_name\": \"anf-with-azureml-main\",
  \"id\": \"azureml:/subscriptions/<number>/resourceGroups/aml-anf-test/providers/Microsoft.MachineLearningServices/workspaces/aml-anf/jobs/purple_potato_5wn2v9vx77\",
  \"inputs\": {},
  \"name\": \" purple_potato_5wn2v9vx77\",
  \"outputs\": {
    \"default\": {
      \"mode\": \"rw_mount\",
      \"path\": \"azureml://datastores/workspaceartifactstore/ExperimentRun/dcid.purple_potato_5wn2v9vx77\",
      \"type\": \"uri_folder\"
    }
  },
  \"parameters\": {},
  \"properties\": {
    \"ContentSnapshotId\": \" a0c92ba6-11e2-4ba5-858d-dddf2969a444\",
    \"_azureml.ComputeTargetType\": \"amlctrain\"
  },
  \"resourceGroup\": \"aml-anf-test\",
  \"resources\": {
    \"instance_count\": 1,
    \"properties\": {},
    \"shm_size\": \"2g\"
  },
  \"services\": {
    \"Studio\": {
      \"endpoint\": \"https://ml.azure.com/runs/ purple_potato_5wn2v9vx77?wsid=/subscriptions/<number>/resourcegroups/aml-anf-test/workspaces/aml-anf&tid=4b09112a0-929b-4715-944b-c037425165b3a\",
      \"job_service_type\": \"Studio\"
    },
    \"Tracking\": {
      \"endpoint\": \"azureml://westeurope.api.azureml.ms/mlflow/v1.0/subscriptions/<number>/resourceGroups/aml-anf-test/providers/Microsoft.MachineLearningServices/workspaces/aml-anf?\",
      \"job_service_type\": \"Tracking\"
    }
  },
  \"status\": \"Starting\",
  \"tags\": {},
  \"type\": \"command\"
}
\n

 

\n\n\n\n\n\n\n
\n

(!) Note 

\n

 

\n

If you receive the following error:

\n
Failed to connect to MSI. Please make sure MSI is configured correctly.
Get Token request returned: <Response [400]>
\n

It may be due to inadequate authentication. Try:

\n
az login
\n
\n

\n

As seen below, train.yml mounts the Azure NetApp Files volume to /data. It then runs a small python script to emulate a real program and does storage benchmark that compares the speed of the compute clusters’ integrated storage on the directory /test to the speed of the attached Azure NetApp Files volume mounted to /data.

\n

 

\n
$ cat train.yml
schema: https://azuremlschemas.azureedge.net/latest/commandJob.schema.json
compute: azureml:cpu-cluster
environment: azureml:python-base-nfs:1
code:
  code/
command: |
  mkdir /data
  mount -t nfs -o rw,hard,rsize=65536,wsize=65536,vers=3,tcp 10.0.2.4:/vol1 /data
  df -h
  python train.py
  # Run fio on NFS share
  cd /data
  fio –name=4krandomreads –rw=randread –direct=1 –ioengine=libaio –bs=4k –numjobs=4 –iodepth=128 –size=1G --runtime=60 –group_reporting
  # Run fio on local disk
  mkdir /test
  cd /test
  fio –name=4krandomreads –rw=randread –direct=1 –ioengine=libaio –bs=4k –numjobs=4 –iodepth=128 –size=1G --runtime=60 –group_reporting
\n

 

\n

The small Python script is being executed to emulate a program for training. For example, the Python script could contain the code to train for Natural Language Processing (NLP) or Object Detection model.

\n

 

\n

Training job results

\n

 

\n

To show the performance difference between using a local disk vs an Azure NetApp Files NFS share, return to the Azure GUI and navigate to the Azure Machine Learning view. There is a workspace with your defined name. If you used the same resource names used in this guide, the name will be “amf-anf”.

\n

 

\n

\n

Next, select this workspace and you’ll see a screen similar to the screen below.

\n

 

\n

\n

 

\n

To see the results, proceed by clicking on the “Studio web URL” on the right. After opening Azure Machine Learning studio click on “Jobs” to the left. All the jobs which have run are displayed in the Azure Machine Learning studio. 

\n

 

\n

\n

 

\n

Next, change the view from “All experiments” to “All jobs”. If you followed this document, there should be one job listed. Wait until the status of the job changes to “Completed”.

\n

 

\n

\n

 

\n

Then click on the job to get more information and options.

\n

 

\n

\n

 

\n

Next, select “Outputs + logs”, followed by a click on  “user_logs”, and then select “std_log.txt” to see the results from the benchmark.

\n

 

\n

\n

 

\n

In the log you’ll see that Azure NetApp Files has almost twice the performance as the compute cluster’s integrated storage.

\n

 

\n

You can now delete the job and the compute cluster.

\n

 

\n

Provision Azure NetApp Files persistent storage with Azure Machine Learning Studio for Studio Notebooks

\n

 

\n

After the working environment has been prepared, this section describes the steps to deploy an Azure Machine Learning environment using Azure NetApp Files for persistent storage with studio notebooks.

\n

 

\n

Preparation and requirements

\n

 

\n

Please follow the steps in Prepare your Environment if you have not already done so.

\n

 

\n

Provision a compute instance

\n

 

\n

Open the Azure Machine Learning studio. In case you have never accessed the Azure Machine Learning studio, follow the steps from Results of training job until the point where we access the results from the training job.

\n

 

\n

Click on “Compute”:

\n

 

\n

\n

 

\n

 

\n\n\n\n\n\n\n
\n

(!) Note

\n

 

\n

In case you followed all previous steps in the preceding section and did not delete the compute cluster, you will see your previously provisioned compute cluster under “Compute clusters”

\n
\n

 

\n

Then select “+ New” from the “Compute instances” tab.

\n

\n

 

\n

 

\n

 

\n

Give the compute instance a name of your choice. We call it “ANFTestCompute” in this example.  Select a Virtual Machine size. For this demo, the least expensive instance is sufficient. Select “Next: ”.

\n

 

\n\n\n\n\n\n\n
\n

(i) Important

\n

 

\n

Do not click on “Create” yet, but select “Next: ”.

\n
\n

 

\n

Select your scheduling preference and hit “Next:” for the Security page.

\n

 

\n

\n

 

\n

In the “Security” tab, activate “Enable virtual network”, and select the VNet which we previously created. If you followed the guide, the VNet should be called “vnet (aml-anf-test)”.

\n

 

\n

Then select the subnet which has not been delegated to Azure NetApp Files. In our case this is called “aml”.

\n

 

\n

Now we can scroll through Applications, add any tags, and Review. click on “Create”.

\n

 

\n

Provisioning the compute instance will take a couple of minutes. Wait until the “State” of the instance becomes “Running” as shown below.

\n

 

\n

\n

 

\n

 

\n

Configure the compute instance and download a dataset

\n

 

\n

Under Notebooks,  click on the “Terminal” to connect to the Compute instance as shown below.

\n

 

\n

\n

 

\n

Install the nfs-common driver to allow nfs mounting onto the compute instance as shown below.

\n

 

\n
azureuser@anftestcompute:~/cloudfiles/code/Users/user$ sudo apt install nfs-common -y
Reading package lists... Done
Building dependency tree      
Reading state information... Done
The following packages were automatically installed and are no longer required:
  ca-certificates-java cmake-data cuda-command-line-tools-11-1
  cuda-command-line-tools-11-3 cuda-compiler-11-1 cuda-compiler-11-3
  cuda-cudart-11-1 cuda-cudart-11-3 cuda-cudart-dev-11-1 cuda-cudart-dev-11-3
  cuda-cuobjdump-11-1 cuda-cuobjdump-11-3 cuda-cupti-11-1 cuda-cupti-11-3
  cuda-cupti-dev-11-1 cuda-cupti-dev-11-3 cuda-cuxxfilt-11-3
  cuda-documentation-11-1 cuda-documentation-11-3 cuda-driver-dev-11-1
  …
\n

We reduced the output of certain fields indicated by “…” for readability.

\n

 

\n

Next, create a new folder and mount the Azure NetApp Files volume. Replace the mount path 10.0.2.4:/vol1 with the mount path of your Azure NetApp Files volume if necessary.

\n
azureuser@anftestcompute:~/cloudfiles/code/Users/user$ mkdir data
azureuser@anftestcompute:~/cloudfiles/code/Users/user$ sudo mount -t nfs -o rw,hard,rsize=65536,wsize=65536,vers=3,tcp 10.0.2.4:/vol1 /data
\n

 

\n

Your screen should now look like:

\n

 

\n

\n

 

\n\n\n\n\n\n\n
\n

(!) Note

\n

 

\n

If the “data” folder is not shown on the left side, click on the “Refresh” button.

\n
\n

 

\n

The titanic dataset established itself as the standard first data science project for emerging data scientists. Use this dataset as an example or a dataset of your choosing. Download the dataset to the Azure NetApp Files volume.

\n

 

\n
azureuser@anftestcompute:~$ wget https://web.stanford.edu/class/archive/cs/cs109/cs109.1166/stuff/titanic.csv -P ./data
--2024-01-08 17:55:56--  https://web.stanford.edu/class/archive/cs/cs109/cs109.1166/stuff/titanic.csv
Resolving web.stanford.edu (web.stanford.edu)... 171.67.215.200, 2607:f6d0:0:925a::ab43:d7c8
Connecting to web.stanford.edu (web.stanford.edu)|171.67.215.200|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 44225 (43K) [text/csv]
Saving to: ‘./data/titanic.csv’

titanic.csv                                               100%[=============================>]  43.19K   133KB/s    in 0.3s   

2024-01-08 17:56:00 (133 KB/s) - ‘./data/titanic.csv’ saved [44225/44225]
\n

 

\n

Accessing Azure NetApp Files from a notebook

\n

 

\n

Click on the “Plus Button” on the left to create a new Jupyter/Azure Machine Learning Studio notebook.

\n

 

\n

\n

 

\n

Select “Create new file”.

\n

 

\n

For this example we call the Notebook “ANFNotebook”:

\n

 

\n

\n

 

\n

Click on “Create”.

\n

 

\n

From the Notebook we can now access the files on the Azure NetApp Files volume and build our models based on it. We entered the code seen below into the notebook. We ingest the titanic csv file into a pandas data frame to show access to data on Azure NetApp Files as an example.

\n

 

\n

\n

 

\n

Snapshots

\n

 

\n

Snapshots are a valuable tool for data science tasks to protect the data. They can also be used as an effective and space efficient way to version a data set. You can easily create a snapshot of Azure NetApp Files volumes by:

\n

 

\n\n

As an example, this article uses the Azure Cloud Shell to create and restore a snapshot.

\n

 

\n

Creating a snapshot using the Azure Cloud Shell

\n

 

\n

Open the Azure Cloud Shell and enter the following command. Replace the account name, resource group, pool name and volume name with the names of your resources. As an example, we are naming the snapshot “timeInPointCopy”:

\n

 

\n
user [ ~ ]$ az netappfiles snapshot create --account-name anf --resource-group aml-anf-test --pool-name pool1 --volume-name vol1  --name timeInPointCopy
{
  \"created\": \"2024-01-08T19:09:51.611000+00:00\",
  \"id\": \"/subscriptions/<number>/resourceGroups/aml-anf-test/providers/Microsoft.NetApp/netAppAccounts/anf/capacityPools/pool1/volumes/vol1/snapshots/timeInPointCopy\",
  \"location\": \"westeurope\",
  \"name\": \"anf/pool1/vol1/timeInPointCopy\",
  \"provisioningState\": \"Succeeded\",
  \"resourceGroup\": \"aml-anf-test\",
  \"snapshotId\": \"7b56521c-4957-df26-0c0a-c19c9fad0474\",
  \"systemData\": null,
  \"type\": \"Microsoft.NetApp/netAppAccounts/capacityPools/volumes/snapshots\"
\n

 

\n\n\n\n\n\n\n
\n

(!) Note

\n

 

\n

For this section we used the variable names from Setting variables.

\n
\n

 

\n

Restoring a snapshot using the Azure Cloud Shell

\n

 

\n

Three options exist to restore a snapshot:

\n

 

\n\n

 

\n

For this example we will restore a snapshot to a new volume. This means a new volume with a new name will be created based on the selected snapshot, and the volume data will automatically be restored to this volume. Be sure there is adequate space left in the capacity pool or expand the capacity pool for this operation. You could also restore to a new capacity pool. In this case, we expanded our current capacity pool using the dropdown menu for the capacity pool pool1.

\n

 

\n

The below example's volume creation is based on the snapshot Setting variables and Provisioning of services. Additionally, we need to specify the new volume's name, the mount point, and the snapshot id. Replace these variables with values in your environment.

\n

 

\n

The snapshot-id can be found using the command az netappfiles snapshot list.

\n

 

\n
user [ ~ ]$ az netappfiles volume create --vnet vnet --subnet anf --account-name anf --usage-threshold 40000 --pool-name pool1 --resource-group aml-anf-test --snapshot-id <id> --name vol1copy --file-path vol1copy --service-level premium --protocol-types NFSv3 --allowed-clients '10.0.1.0/24' --rule-index 1 --unix-read-write true 
{
  \"actualThroughputMibps\": 6.25,
  \"avsDataStore\": \"Disabled\",
  \"backupId\": null,
  \"baremetalTenantId\": \"baremetalTenant_svm_d284dc8e25fd11ec8df54654d00c1f9e_d6143cc3\",
  \"capacityPoolResourceId\": null,
  \"cloneProgress\": 0,
  \"coolAccess\": false,

}
\n

We reduced the output of certain fields indicated by “…” for readability.

\n

 

\n

More information on the az netappfiles volume create command can be found in the documentation.

\n

 

\n\n\n\n\n\n\n
\n

(!) Note

\n

 

\n

Entering the command from above might be prone to errors, due to its length and the number of required details.

\n

This operation might be easier to conduct using the Azure GUI.

\n
\n

 

\n

Summary 

\n

 

\n

In this article we described how we can make Azure training jobs and Azure Machine Learning studio notebooks use enterprise-grade high performance persistent storage backed by Azure NetApp Files volumes for training machine learning models and as persistent storage for studio notebooks. We also showed the ease in creating and restoring from snapshots using Azure NetApp Files. Get started with Azure NetApp Files today.

\n

 

\n

Additional Information

\n

 

\n
    \n
  1. https://learn.microsoft.com/en-us/azure/azure-netapp-files/azure-netapp-files-solution-architectures#azure-kubernetes-services-and-kubernetes 
  2. \n
  3. https://azure.microsoft.com/services/machine-learning/
  4. \n
","kudosSumWeight":1,"postTime":"2022-08-26T14:12:55.936-07:00","images":{"__typename":"AssociatedImageConnection","edges":[{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDE","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTM5ODgzOGkxRUY4RURDOERGMUIyNjVE?revision=23\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDI","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM0MGk0QTNFMEJGNjZGOEY1MDlB?revision=23\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDM","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM3OWlDRDE0NkJEQ0U4RDA5N0JE?revision=23\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDQ","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM4MGkzOTJDN0E3MTBFMDA3MTg1?revision=23\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDU","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM4MWk3QURCOTM2NUE0QUVDRDk2?revision=23\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDY","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM4MmkwOUQzQkQxQkJDNTM2RDhC?revision=23\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDc","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM4NGk2RDQxQTk3MzMxNUI3RTFD?revision=23\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDg","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM4NWk2RjUyQjk4NzNCOEI0MTY4?revision=23\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDk","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM4NmlGRjEzQTVCMTU1NUFCQjdC?revision=23\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDEw","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM4OGk1NjcwM0Y2RTUxOTJGMzM5?revision=23\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDEx","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM5MGkyMkRDQjFDOTZDNzk4NkNC?revision=23\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDEy","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM5MWkxQkFCMzUzMzA4ODFGRjI5?revision=23\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDEz","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM5Mmk5RTAxRTYxMDUyODU4Nzcy?revision=23\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDE0","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM5M2k0MTYzQjdCNDUxNjRFODRG?revision=23\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDE1","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM5NGlCOEFGQUY0OEEyMzkzM0Q3?revision=23\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDE2","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM5NWlERTREOTYwM0U2QUM1NDQz?revision=23\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuMXwyLjF8b3wyNXxfTlZffDE3","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM5NmlGMzhFMjlCOThFREExRDg5?revision=23\"}"}}],"totalCount":17,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"attachments":{"__typename":"AttachmentConnection","pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null},"edges":[]},"tags":{"__typename":"TagConnection","pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null},"edges":[{"__typename":"TagEdge","cursor":"MjUuMXwyLjF8b3wxMHxfTlZffDE","node":{"__typename":"Tag","id":"tag:advance analytics","text":"advance analytics","time":"2020-09-10T20:54:30.687-07:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}},{"__typename":"TagEdge","cursor":"MjUuMXwyLjF8b3wxMHxfTlZffDI","node":{"__typename":"Tag","id":"tag:application","text":"application","time":"2017-06-20T00:43:01.797-07:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}},{"__typename":"TagEdge","cursor":"MjUuMXwyLjF8b3wxMHxfTlZffDM","node":{"__typename":"Tag","id":"tag:apps & devops","text":"apps & devops","time":"2020-06-05T02:24:34.709-07:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}},{"__typename":"TagEdge","cursor":"MjUuMXwyLjF8b3wxMHxfTlZffDQ","node":{"__typename":"Tag","id":"tag:artificial intelligence","text":"artificial intelligence","time":"2018-02-28T01:21:24.829-08:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}},{"__typename":"TagEdge","cursor":"MjUuMXwyLjF8b3wxMHxfTlZffDU","node":{"__typename":"Tag","id":"tag:data platform","text":"data platform","time":"2018-03-10T04:35:28.700-08:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}},{"__typename":"TagEdge","cursor":"MjUuMXwyLjF8b3wxMHxfTlZffDY","node":{"__typename":"Tag","id":"tag:infrastructure","text":"infrastructure","time":"2019-04-04T11:59:26.153-07:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}},{"__typename":"TagEdge","cursor":"MjUuMXwyLjF8b3wxMHxfTlZffDc","node":{"__typename":"Tag","id":"tag:integration","text":"integration","time":"2016-07-19T05:25:31.751-07:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}}]},"timeToRead":20,"rawTeaser":"

This article describes how to provide enterprise grade high performance persistent storage with data protection capability for AI Model training tasks using studio compute instances with Azure NetApp Files (ANF).

\n

 

\n

\n

 

\n

 

","introduction":"","coverImage":null,"coverImageProperties":{"__typename":"CoverImageProperties","style":"STANDARD","titlePosition":"BOTTOM","altText":""},"currentRevision":{"__ref":"Revision:revision:3609189_23"},"latestVersion":{"__typename":"FriendlyVersion","major":"3","minor":"0"},"metrics":{"__typename":"MessageMetrics","views":9995},"visibilityScope":"PUBLIC","canonicalUrl":null,"seoTitle":"Providing persistent volume with data protection to Azure Machine Learning studio workloads with Azure NetApp Files","seoDescription":"This article describes how to create a notebook service in Azure Machine learning studio with attached PVC on Azure NetApp Files volumes, the user can take advantage of the data protection features which come with Azure NetApp Files. The integration helps the data scientists quickly create clones of datasets that they can reformat, normalize, and manipulate while preserving the original “gold-source” dataset. ","placeholder":false,"originalMessageForPlaceholder":null,"contributors":{"__typename":"UserConnection","edges":[]},"nonCoAuthorContributors":{"__typename":"UserConnection","edges":[]},"coAuthors":{"__typename":"UserConnection","edges":[]},"blogMessagePolicies":{"__typename":"BlogMessagePolicies","canDoAuthoringActionsOnBlog":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.blog.action_can_do_authoring_action.accessDenied","key":"error.lithium.policies.blog.action_can_do_authoring_action.accessDenied","args":[]}}},"archivalData":null,"replies":{"__typename":"MessageConnection","edges":[],"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"customFields":[],"revisions({\"constraints\":{\"isPublished\":{\"eq\":true}},\"first\":1})":{"__typename":"RevisionConnection","totalCount":23}},"Conversation:conversation:3609189":{"__typename":"Conversation","id":"conversation:3609189","solved":false,"topic":{"__ref":"BlogTopicMessage:message:3609189"},"lastPostingActivityTime":"2024-01-29T13:28:14.956-08:00","lastPostTime":"2022-08-26T14:12:55.936-07:00","unreadReplyCount":0,"isSubscribed":false},"ModerationData:moderation_data:3609189":{"__typename":"ModerationData","id":"moderation_data:3609189","status":"APPROVED","rejectReason":null,"isReportedAbuse":false,"rejectUser":null,"rejectTime":null,"rejectActorType":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTM5ODgzOGkxRUY4RURDOERGMUIyNjVE?revision=23\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTM5ODgzOGkxRUY4RURDOERGMUIyNjVE?revision=23","title":"GeertVanTeylingen_0-1661422328301.png","associationType":"TEASER","width":556,"height":371,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM0MGk0QTNFMEJGNjZGOEY1MDlB?revision=23\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM0MGk0QTNFMEJGNjZGOEY1MDlB?revision=23","title":"GeertVanTeylingen_0-1705932065904.png","associationType":"BODY","width":975,"height":538,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM3OWlDRDE0NkJEQ0U4RDA5N0JE?revision=23\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM3OWlDRDE0NkJEQ0U4RDA5N0JE?revision=23","title":"GeertVanTeylingen_0-1705938441813.png","associationType":"BODY","width":975,"height":308,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM4MGkzOTJDN0E3MTBFMDA3MTg1?revision=23\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM4MGkzOTJDN0E3MTBFMDA3MTg1?revision=23","title":"GeertVanTeylingen_1-1705938461954.png","associationType":"BODY","width":975,"height":245,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM4MWk3QURCOTM2NUE0QUVDRDk2?revision=23\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM4MWk3QURCOTM2NUE0QUVDRDk2?revision=23","title":"GeertVanTeylingen_2-1705938480956.png","associationType":"BODY","width":975,"height":324,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM4MmkwOUQzQkQxQkJDNTM2RDhC?revision=23\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM4MmkwOUQzQkQxQkJDNTM2RDhC?revision=23","title":"GeertVanTeylingen_3-1705938520942.png","associationType":"BODY","width":975,"height":414,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM4NGk2RDQxQTk3MzMxNUI3RTFD?revision=23\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM4NGk2RDQxQTk3MzMxNUI3RTFD?revision=23","title":"GeertVanTeylingen_4-1705938541695.png","associationType":"BODY","width":975,"height":972,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM4NWk2RjUyQjk4NzNCOEI0MTY4?revision=23\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM4NWk2RjUyQjk4NzNCOEI0MTY4?revision=23","title":"GeertVanTeylingen_5-1705938564662.png","associationType":"BODY","width":975,"height":736,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM4NmlGRjEzQTVCMTU1NUFCQjdC?revision=23\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM4NmlGRjEzQTVCMTU1NUFCQjdC?revision=23","title":"GeertVanTeylingen_6-1705938614262.png","associationType":"BODY","width":975,"height":540,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM4OGk1NjcwM0Y2RTUxOTJGMzM5?revision=23\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM4OGk1NjcwM0Y2RTUxOTJGMzM5?revision=23","title":"GeertVanTeylingen_7-1705938668069.png","associationType":"BODY","width":975,"height":608,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM5MGkyMkRDQjFDOTZDNzk4NkNC?revision=23\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM5MGkyMkRDQjFDOTZDNzk4NkNC?revision=23","title":"GeertVanTeylingen_8-1705938843521.png","associationType":"BODY","width":975,"height":533,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM5MWkxQkFCMzUzMzA4ODFGRjI5?revision=23\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM5MWkxQkFCMzUzMzA4ODFGRjI5?revision=23","title":"GeertVanTeylingen_9-1705938877793.png","associationType":"BODY","width":975,"height":418,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM5Mmk5RTAxRTYxMDUyODU4Nzcy?revision=23\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM5Mmk5RTAxRTYxMDUyODU4Nzcy?revision=23","title":"GeertVanTeylingen_10-1705938896134.png","associationType":"BODY","width":975,"height":446,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM5M2k0MTYzQjdCNDUxNjRFODRG?revision=23\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM5M2k0MTYzQjdCNDUxNjRFODRG?revision=23","title":"GeertVanTeylingen_11-1705938958302.png","associationType":"BODY","width":975,"height":203,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM5NGlCOEFGQUY0OEEyMzkzM0Q3?revision=23\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM5NGlCOEFGQUY0OEEyMzkzM0Q3?revision=23","title":"GeertVanTeylingen_12-1705939068091.png","associationType":"BODY","width":975,"height":253,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM5NWlERTREOTYwM0U2QUM1NDQz?revision=23\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM5NWlERTREOTYwM0U2QUM1NDQz?revision=23","title":"GeertVanTeylingen_13-1705939087096.png","associationType":"BODY","width":829,"height":944,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM5NmlGMzhFMjlCOThFREExRDg5?revision=23\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjA5MTg5LTU0NDM5NmlGMzhFMjlCOThFREExRDg5?revision=23","title":"GeertVanTeylingen_14-1705939110400.png","associationType":"BODY","width":975,"height":652,"altText":null},"Revision:revision:3609189_23":{"__typename":"Revision","id":"revision:3609189_23","lastEditTime":"2024-01-29T12:33:54.659-08:00"},"CachedAsset:theme:customTheme1-1743057922765":{"__typename":"CachedAsset","id":"theme:customTheme1-1743057922765","value":{"id":"customTheme1","animation":{"fast":"150ms","normal":"250ms","slow":"500ms","slowest":"750ms","function":"cubic-bezier(0.07, 0.91, 0.51, 1)","__typename":"AnimationThemeSettings"},"avatar":{"borderRadius":"50%","collections":["default"],"__typename":"AvatarThemeSettings"},"basics":{"browserIcon":{"imageAssetName":"favicon-1730836283320.png","imageLastModified":"1730836286415","__typename":"ThemeAsset"},"customerLogo":{"imageAssetName":"favicon-1730836271365.png","imageLastModified":"1730836274203","__typename":"ThemeAsset"},"maximumWidthOfPageContent":"1300px","oneColumnNarrowWidth":"800px","gridGutterWidthMd":"30px","gridGutterWidthXs":"10px","pageWidthStyle":"WIDTH_OF_BROWSER","__typename":"BasicsThemeSettings"},"buttons":{"borderRadiusSm":"3px","borderRadius":"3px","borderRadiusLg":"5px","paddingY":"5px","paddingYLg":"7px","paddingYHero":"var(--lia-bs-btn-padding-y-lg)","paddingX":"12px","paddingXLg":"16px","paddingXHero":"60px","fontStyle":"NORMAL","fontWeight":"700","textTransform":"NONE","disabledOpacity":0.5,"primaryTextColor":"var(--lia-bs-white)","primaryTextHoverColor":"var(--lia-bs-white)","primaryTextActiveColor":"var(--lia-bs-white)","primaryBgColor":"var(--lia-bs-primary)","primaryBgHoverColor":"hsl(var(--lia-bs-primary-h), var(--lia-bs-primary-s), calc(var(--lia-bs-primary-l) * 0.85))","primaryBgActiveColor":"hsl(var(--lia-bs-primary-h), var(--lia-bs-primary-s), calc(var(--lia-bs-primary-l) * 0.7))","primaryBorder":"1px solid transparent","primaryBorderHover":"1px solid transparent","primaryBorderActive":"1px solid transparent","primaryBorderFocus":"1px solid var(--lia-bs-white)","primaryBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","secondaryTextColor":"var(--lia-bs-gray-900)","secondaryTextHoverColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.95))","secondaryTextActiveColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.9))","secondaryBgColor":"var(--lia-bs-gray-200)","secondaryBgHoverColor":"hsl(var(--lia-bs-gray-200-h), var(--lia-bs-gray-200-s), calc(var(--lia-bs-gray-200-l) * 0.96))","secondaryBgActiveColor":"hsl(var(--lia-bs-gray-200-h), var(--lia-bs-gray-200-s), calc(var(--lia-bs-gray-200-l) * 0.92))","secondaryBorder":"1px solid transparent","secondaryBorderHover":"1px solid transparent","secondaryBorderActive":"1px solid transparent","secondaryBorderFocus":"1px solid transparent","secondaryBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","tertiaryTextColor":"var(--lia-bs-gray-900)","tertiaryTextHoverColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.95))","tertiaryTextActiveColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.9))","tertiaryBgColor":"transparent","tertiaryBgHoverColor":"transparent","tertiaryBgActiveColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.04)","tertiaryBorder":"1px solid transparent","tertiaryBorderHover":"1px solid hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","tertiaryBorderActive":"1px solid transparent","tertiaryBorderFocus":"1px solid transparent","tertiaryBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","destructiveTextColor":"var(--lia-bs-danger)","destructiveTextHoverColor":"hsl(var(--lia-bs-danger-h), var(--lia-bs-danger-s), calc(var(--lia-bs-danger-l) * 0.95))","destructiveTextActiveColor":"hsl(var(--lia-bs-danger-h), var(--lia-bs-danger-s), calc(var(--lia-bs-danger-l) * 0.9))","destructiveBgColor":"var(--lia-bs-gray-200)","destructiveBgHoverColor":"hsl(var(--lia-bs-gray-200-h), var(--lia-bs-gray-200-s), calc(var(--lia-bs-gray-200-l) * 0.96))","destructiveBgActiveColor":"hsl(var(--lia-bs-gray-200-h), var(--lia-bs-gray-200-s), calc(var(--lia-bs-gray-200-l) * 0.92))","destructiveBorder":"1px solid transparent","destructiveBorderHover":"1px solid transparent","destructiveBorderActive":"1px solid transparent","destructiveBorderFocus":"1px solid transparent","destructiveBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","__typename":"ButtonsThemeSettings"},"border":{"color":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","mainContent":"NONE","sideContent":"LIGHT","radiusSm":"3px","radius":"5px","radiusLg":"9px","radius50":"100vw","__typename":"BorderThemeSettings"},"boxShadow":{"xs":"0 0 0 1px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.08), 0 3px 0 -1px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.16)","sm":"0 2px 4px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.12)","md":"0 5px 15px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.3)","lg":"0 10px 30px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.3)","__typename":"BoxShadowThemeSettings"},"cards":{"bgColor":"var(--lia-panel-bg-color)","borderRadius":"var(--lia-panel-border-radius)","boxShadow":"var(--lia-box-shadow-xs)","__typename":"CardsThemeSettings"},"chip":{"maxWidth":"300px","height":"30px","__typename":"ChipThemeSettings"},"coreTypes":{"defaultMessageLinkColor":"var(--lia-bs-link-color)","defaultMessageLinkDecoration":"none","defaultMessageLinkFontStyle":"NORMAL","defaultMessageLinkFontWeight":"400","defaultMessageFontStyle":"NORMAL","defaultMessageFontWeight":"400","forumColor":"#4099E2","forumFontFamily":"var(--lia-bs-font-family-base)","forumFontWeight":"var(--lia-default-message-font-weight)","forumLineHeight":"var(--lia-bs-line-height-base)","forumFontStyle":"var(--lia-default-message-font-style)","forumMessageLinkColor":"var(--lia-default-message-link-color)","forumMessageLinkDecoration":"var(--lia-default-message-link-decoration)","forumMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","forumMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","forumSolvedColor":"#148563","blogColor":"#1CBAA0","blogFontFamily":"var(--lia-bs-font-family-base)","blogFontWeight":"var(--lia-default-message-font-weight)","blogLineHeight":"1.75","blogFontStyle":"var(--lia-default-message-font-style)","blogMessageLinkColor":"var(--lia-default-message-link-color)","blogMessageLinkDecoration":"var(--lia-default-message-link-decoration)","blogMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","blogMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","tkbColor":"#4C6B90","tkbFontFamily":"var(--lia-bs-font-family-base)","tkbFontWeight":"var(--lia-default-message-font-weight)","tkbLineHeight":"1.75","tkbFontStyle":"var(--lia-default-message-font-style)","tkbMessageLinkColor":"var(--lia-default-message-link-color)","tkbMessageLinkDecoration":"var(--lia-default-message-link-decoration)","tkbMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","tkbMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","qandaColor":"#4099E2","qandaFontFamily":"var(--lia-bs-font-family-base)","qandaFontWeight":"var(--lia-default-message-font-weight)","qandaLineHeight":"var(--lia-bs-line-height-base)","qandaFontStyle":"var(--lia-default-message-link-font-style)","qandaMessageLinkColor":"var(--lia-default-message-link-color)","qandaMessageLinkDecoration":"var(--lia-default-message-link-decoration)","qandaMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","qandaMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","qandaSolvedColor":"#3FA023","ideaColor":"#FF8000","ideaFontFamily":"var(--lia-bs-font-family-base)","ideaFontWeight":"var(--lia-default-message-font-weight)","ideaLineHeight":"var(--lia-bs-line-height-base)","ideaFontStyle":"var(--lia-default-message-font-style)","ideaMessageLinkColor":"var(--lia-default-message-link-color)","ideaMessageLinkDecoration":"var(--lia-default-message-link-decoration)","ideaMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","ideaMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","contestColor":"#FCC845","contestFontFamily":"var(--lia-bs-font-family-base)","contestFontWeight":"var(--lia-default-message-font-weight)","contestLineHeight":"var(--lia-bs-line-height-base)","contestFontStyle":"var(--lia-default-message-link-font-style)","contestMessageLinkColor":"var(--lia-default-message-link-color)","contestMessageLinkDecoration":"var(--lia-default-message-link-decoration)","contestMessageLinkFontStyle":"ITALIC","contestMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","occasionColor":"#D13A1F","occasionFontFamily":"var(--lia-bs-font-family-base)","occasionFontWeight":"var(--lia-default-message-font-weight)","occasionLineHeight":"var(--lia-bs-line-height-base)","occasionFontStyle":"var(--lia-default-message-font-style)","occasionMessageLinkColor":"var(--lia-default-message-link-color)","occasionMessageLinkDecoration":"var(--lia-default-message-link-decoration)","occasionMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","occasionMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","grouphubColor":"#333333","categoryColor":"#949494","communityColor":"#FFFFFF","productColor":"#949494","__typename":"CoreTypesThemeSettings"},"colors":{"black":"#000000","white":"#FFFFFF","gray100":"#F7F7F7","gray200":"#F7F7F7","gray300":"#E8E8E8","gray400":"#D9D9D9","gray500":"#CCCCCC","gray600":"#717171","gray700":"#707070","gray800":"#545454","gray900":"#333333","dark":"#545454","light":"#F7F7F7","primary":"#0069D4","secondary":"#333333","bodyText":"#333333","bodyBg":"#FFFFFF","info":"#409AE2","success":"#41C5AE","warning":"#FCC844","danger":"#BC341B","alertSystem":"#FF6600","textMuted":"#707070","highlight":"#FFFCAD","outline":"var(--lia-bs-primary)","custom":["#D3F5A4","#243A5E"],"__typename":"ColorsThemeSettings"},"divider":{"size":"3px","marginLeft":"4px","marginRight":"4px","borderRadius":"50%","bgColor":"var(--lia-bs-gray-600)","bgColorActive":"var(--lia-bs-gray-600)","__typename":"DividerThemeSettings"},"dropdown":{"fontSize":"var(--lia-bs-font-size-sm)","borderColor":"var(--lia-bs-border-color)","borderRadius":"var(--lia-bs-border-radius-sm)","dividerBg":"var(--lia-bs-gray-300)","itemPaddingY":"5px","itemPaddingX":"20px","headerColor":"var(--lia-bs-gray-700)","__typename":"DropdownThemeSettings"},"email":{"link":{"color":"#0069D4","hoverColor":"#0061c2","decoration":"none","hoverDecoration":"underline","__typename":"EmailLinkSettings"},"border":{"color":"#e4e4e4","__typename":"EmailBorderSettings"},"buttons":{"borderRadiusLg":"5px","paddingXLg":"16px","paddingYLg":"7px","fontWeight":"700","primaryTextColor":"#ffffff","primaryTextHoverColor":"#ffffff","primaryBgColor":"#0069D4","primaryBgHoverColor":"#005cb8","primaryBorder":"1px solid transparent","primaryBorderHover":"1px solid transparent","__typename":"EmailButtonsSettings"},"panel":{"borderRadius":"5px","borderColor":"#e4e4e4","__typename":"EmailPanelSettings"},"__typename":"EmailThemeSettings"},"emoji":{"skinToneDefault":"#ffcd43","skinToneLight":"#fae3c5","skinToneMediumLight":"#e2cfa5","skinToneMedium":"#daa478","skinToneMediumDark":"#a78058","skinToneDark":"#5e4d43","__typename":"EmojiThemeSettings"},"heading":{"color":"var(--lia-bs-body-color)","fontFamily":"Segoe UI","fontStyle":"NORMAL","fontWeight":"400","h1FontSize":"34px","h2FontSize":"32px","h3FontSize":"28px","h4FontSize":"24px","h5FontSize":"20px","h6FontSize":"16px","lineHeight":"1.3","subHeaderFontSize":"11px","subHeaderFontWeight":"500","h1LetterSpacing":"normal","h2LetterSpacing":"normal","h3LetterSpacing":"normal","h4LetterSpacing":"normal","h5LetterSpacing":"normal","h6LetterSpacing":"normal","subHeaderLetterSpacing":"2px","h1FontWeight":"var(--lia-bs-headings-font-weight)","h2FontWeight":"var(--lia-bs-headings-font-weight)","h3FontWeight":"var(--lia-bs-headings-font-weight)","h4FontWeight":"var(--lia-bs-headings-font-weight)","h5FontWeight":"var(--lia-bs-headings-font-weight)","h6FontWeight":"var(--lia-bs-headings-font-weight)","__typename":"HeadingThemeSettings"},"icons":{"size10":"10px","size12":"12px","size14":"14px","size16":"16px","size20":"20px","size24":"24px","size30":"30px","size40":"40px","size50":"50px","size60":"60px","size80":"80px","size120":"120px","size160":"160px","__typename":"IconsThemeSettings"},"imagePreview":{"bgColor":"var(--lia-bs-gray-900)","titleColor":"var(--lia-bs-white)","controlColor":"var(--lia-bs-white)","controlBgColor":"var(--lia-bs-gray-800)","__typename":"ImagePreviewThemeSettings"},"input":{"borderColor":"var(--lia-bs-gray-600)","disabledColor":"var(--lia-bs-gray-600)","focusBorderColor":"var(--lia-bs-primary)","labelMarginBottom":"10px","btnFontSize":"var(--lia-bs-font-size-sm)","focusBoxShadow":"0 0 0 3px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","checkLabelMarginBottom":"2px","checkboxBorderRadius":"3px","borderRadiusSm":"var(--lia-bs-border-radius-sm)","borderRadius":"var(--lia-bs-border-radius)","borderRadiusLg":"var(--lia-bs-border-radius-lg)","formTextMarginTop":"4px","textAreaBorderRadius":"var(--lia-bs-border-radius)","activeFillColor":"var(--lia-bs-primary)","__typename":"InputThemeSettings"},"loading":{"dotDarkColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.2)","dotLightColor":"hsla(var(--lia-bs-white-h), var(--lia-bs-white-s), var(--lia-bs-white-l), 0.5)","barDarkColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.06)","barLightColor":"hsla(var(--lia-bs-white-h), var(--lia-bs-white-s), var(--lia-bs-white-l), 0.4)","__typename":"LoadingThemeSettings"},"link":{"color":"var(--lia-bs-primary)","hoverColor":"hsl(var(--lia-bs-primary-h), var(--lia-bs-primary-s), calc(var(--lia-bs-primary-l) - 10%))","decoration":"none","hoverDecoration":"underline","__typename":"LinkThemeSettings"},"listGroup":{"itemPaddingY":"15px","itemPaddingX":"15px","borderColor":"var(--lia-bs-gray-300)","__typename":"ListGroupThemeSettings"},"modal":{"contentTextColor":"var(--lia-bs-body-color)","contentBg":"var(--lia-bs-white)","backgroundBg":"var(--lia-bs-black)","smSize":"440px","mdSize":"760px","lgSize":"1080px","backdropOpacity":0.3,"contentBoxShadowXs":"var(--lia-bs-box-shadow-sm)","contentBoxShadow":"var(--lia-bs-box-shadow)","headerFontWeight":"700","__typename":"ModalThemeSettings"},"navbar":{"position":"FIXED","background":{"attachment":null,"clip":null,"color":"var(--lia-bs-white)","imageAssetName":"","imageLastModified":"0","origin":null,"position":"CENTER_CENTER","repeat":"NO_REPEAT","size":"COVER","__typename":"BackgroundProps"},"backgroundOpacity":0.8,"paddingTop":"15px","paddingBottom":"15px","borderBottom":"1px solid var(--lia-bs-border-color)","boxShadow":"var(--lia-bs-box-shadow-sm)","brandMarginRight":"30px","brandMarginRightSm":"10px","brandLogoHeight":"30px","linkGap":"10px","linkJustifyContent":"flex-start","linkPaddingY":"5px","linkPaddingX":"10px","linkDropdownPaddingY":"9px","linkDropdownPaddingX":"var(--lia-nav-link-px)","linkColor":"var(--lia-bs-body-color)","linkHoverColor":"var(--lia-bs-primary)","linkFontSize":"var(--lia-bs-font-size-sm)","linkFontStyle":"NORMAL","linkFontWeight":"400","linkTextTransform":"NONE","linkLetterSpacing":"normal","linkBorderRadius":"var(--lia-bs-border-radius-sm)","linkBgColor":"transparent","linkBgHoverColor":"transparent","linkBorder":"none","linkBorderHover":"none","linkBoxShadow":"none","linkBoxShadowHover":"none","linkTextBorderBottom":"none","linkTextBorderBottomHover":"none","dropdownPaddingTop":"10px","dropdownPaddingBottom":"15px","dropdownPaddingX":"10px","dropdownMenuOffset":"2px","dropdownDividerMarginTop":"10px","dropdownDividerMarginBottom":"10px","dropdownBorderColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","controllerBgHoverColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.1)","controllerIconColor":"var(--lia-bs-body-color)","controllerIconHoverColor":"var(--lia-bs-body-color)","controllerTextColor":"var(--lia-nav-controller-icon-color)","controllerTextHoverColor":"var(--lia-nav-controller-icon-hover-color)","controllerHighlightColor":"hsla(30, 100%, 50%)","controllerHighlightTextColor":"var(--lia-yiq-light)","controllerBorderRadius":"var(--lia-border-radius-50)","hamburgerColor":"var(--lia-nav-controller-icon-color)","hamburgerHoverColor":"var(--lia-nav-controller-icon-color)","hamburgerBgColor":"transparent","hamburgerBgHoverColor":"transparent","hamburgerBorder":"none","hamburgerBorderHover":"none","collapseMenuMarginLeft":"20px","collapseMenuDividerBg":"var(--lia-nav-link-color)","collapseMenuDividerOpacity":0.16,"__typename":"NavbarThemeSettings"},"pager":{"textColor":"var(--lia-bs-link-color)","textFontWeight":"var(--lia-font-weight-md)","textFontSize":"var(--lia-bs-font-size-sm)","__typename":"PagerThemeSettings"},"panel":{"bgColor":"var(--lia-bs-white)","borderRadius":"var(--lia-bs-border-radius)","borderColor":"var(--lia-bs-border-color)","boxShadow":"none","__typename":"PanelThemeSettings"},"popover":{"arrowHeight":"8px","arrowWidth":"16px","maxWidth":"300px","minWidth":"100px","headerBg":"var(--lia-bs-white)","borderColor":"var(--lia-bs-border-color)","borderRadius":"var(--lia-bs-border-radius)","boxShadow":"0 0.5rem 1rem hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.15)","__typename":"PopoverThemeSettings"},"prism":{"color":"#000000","bgColor":"#f5f2f0","fontFamily":"var(--font-family-monospace)","fontSize":"var(--lia-bs-font-size-base)","fontWeightBold":"var(--lia-bs-font-weight-bold)","fontStyleItalic":"italic","tabSize":2,"highlightColor":"#b3d4fc","commentColor":"#62707e","punctuationColor":"#6f6f6f","namespaceOpacity":"0.7","propColor":"#990055","selectorColor":"#517a00","operatorColor":"#906736","operatorBgColor":"hsla(0, 0%, 100%, 0.5)","keywordColor":"#0076a9","functionColor":"#d3284b","variableColor":"#c14700","__typename":"PrismThemeSettings"},"rte":{"bgColor":"var(--lia-bs-white)","borderRadius":"var(--lia-panel-border-radius)","boxShadow":" var(--lia-panel-box-shadow)","customColor1":"#bfedd2","customColor2":"#fbeeb8","customColor3":"#f8cac6","customColor4":"#eccafa","customColor5":"#c2e0f4","customColor6":"#2dc26b","customColor7":"#f1c40f","customColor8":"#e03e2d","customColor9":"#b96ad9","customColor10":"#3598db","customColor11":"#169179","customColor12":"#e67e23","customColor13":"#ba372a","customColor14":"#843fa1","customColor15":"#236fa1","customColor16":"#ecf0f1","customColor17":"#ced4d9","customColor18":"#95a5a6","customColor19":"#7e8c8d","customColor20":"#34495e","customColor21":"#000000","customColor22":"#ffffff","defaultMessageHeaderMarginTop":"40px","defaultMessageHeaderMarginBottom":"20px","defaultMessageItemMarginTop":"0","defaultMessageItemMarginBottom":"10px","diffAddedColor":"hsla(170, 53%, 51%, 0.4)","diffChangedColor":"hsla(43, 97%, 63%, 0.4)","diffNoneColor":"hsla(0, 0%, 80%, 0.4)","diffRemovedColor":"hsla(9, 74%, 47%, 0.4)","specialMessageHeaderMarginTop":"40px","specialMessageHeaderMarginBottom":"20px","specialMessageItemMarginTop":"0","specialMessageItemMarginBottom":"10px","__typename":"RteThemeSettings"},"tags":{"bgColor":"var(--lia-bs-gray-200)","bgHoverColor":"var(--lia-bs-gray-400)","borderRadius":"var(--lia-bs-border-radius-sm)","color":"var(--lia-bs-body-color)","hoverColor":"var(--lia-bs-body-color)","fontWeight":"var(--lia-font-weight-md)","fontSize":"var(--lia-font-size-xxs)","textTransform":"UPPERCASE","letterSpacing":"0.5px","__typename":"TagsThemeSettings"},"toasts":{"borderRadius":"var(--lia-bs-border-radius)","paddingX":"12px","__typename":"ToastsThemeSettings"},"typography":{"fontFamilyBase":"Segoe UI","fontStyleBase":"NORMAL","fontWeightBase":"400","fontWeightLight":"300","fontWeightNormal":"400","fontWeightMd":"500","fontWeightBold":"700","letterSpacingSm":"normal","letterSpacingXs":"normal","lineHeightBase":"1.5","fontSizeBase":"16px","fontSizeXxs":"11px","fontSizeXs":"12px","fontSizeSm":"14px","fontSizeLg":"20px","fontSizeXl":"24px","smallFontSize":"14px","customFonts":[{"source":"SERVER","name":"Segoe UI","styles":[{"style":"NORMAL","weight":"400","__typename":"FontStyleData"},{"style":"NORMAL","weight":"300","__typename":"FontStyleData"},{"style":"NORMAL","weight":"600","__typename":"FontStyleData"},{"style":"NORMAL","weight":"700","__typename":"FontStyleData"},{"style":"ITALIC","weight":"400","__typename":"FontStyleData"}],"assetNames":["SegoeUI-normal-400.woff2","SegoeUI-normal-300.woff2","SegoeUI-normal-600.woff2","SegoeUI-normal-700.woff2","SegoeUI-italic-400.woff2"],"__typename":"CustomFont"},{"source":"SERVER","name":"MWF Fluent Icons","styles":[{"style":"NORMAL","weight":"400","__typename":"FontStyleData"}],"assetNames":["MWFFluentIcons-normal-400.woff2"],"__typename":"CustomFont"}],"__typename":"TypographyThemeSettings"},"unstyledListItem":{"marginBottomSm":"5px","marginBottomMd":"10px","marginBottomLg":"15px","marginBottomXl":"20px","marginBottomXxl":"25px","__typename":"UnstyledListItemThemeSettings"},"yiq":{"light":"#ffffff","dark":"#000000","__typename":"YiqThemeSettings"},"colorLightness":{"primaryDark":0.36,"primaryLight":0.74,"primaryLighter":0.89,"primaryLightest":0.95,"infoDark":0.39,"infoLight":0.72,"infoLighter":0.85,"infoLightest":0.93,"successDark":0.24,"successLight":0.62,"successLighter":0.8,"successLightest":0.91,"warningDark":0.39,"warningLight":0.68,"warningLighter":0.84,"warningLightest":0.93,"dangerDark":0.41,"dangerLight":0.72,"dangerLighter":0.89,"dangerLightest":0.95,"__typename":"ColorLightnessThemeSettings"},"localOverride":false,"__typename":"Theme"},"localOverride":false},"CachedAsset:text:en_US-components/common/EmailVerification-1743151753131":{"__typename":"CachedAsset","id":"text:en_US-components/common/EmailVerification-1743151753131","value":{"email.verification.title":"Email Verification Required","email.verification.message.update.email":"To participate in the community, you must first verify your email address. The verification email was sent to {email}. To change your email, visit My Settings.","email.verification.message.resend.email":"To participate in the community, you must first verify your email address. The verification email was sent to {email}. Resend email."},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/Loading/LoadingDot-1743151753131":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/Loading/LoadingDot-1743151753131","value":{"title":"Loading..."},"localOverride":false},"CachedAsset:quilt:o365.prod:pages/blogs/BlogMessagePage:board:AzureArchitectureBlog-1743151744811":{"__typename":"CachedAsset","id":"quilt:o365.prod:pages/blogs/BlogMessagePage:board:AzureArchitectureBlog-1743151744811","value":{"id":"BlogMessagePage","container":{"id":"Common","headerProps":{"backgroundImageProps":null,"backgroundColor":null,"addComponents":null,"removeComponents":["community.widget.bannerWidget"],"componentOrder":null,"__typename":"QuiltContainerSectionProps"},"headerComponentProps":{"community.widget.breadcrumbWidget":{"disableLastCrumbForDesktop":false}},"footerProps":null,"footerComponentProps":null,"items":[{"id":"blog-article","layout":"ONE_COLUMN","bgColor":null,"showTitle":null,"showDescription":null,"textPosition":null,"textColor":null,"sectionEditLevel":"LOCKED","bgImage":null,"disableSpacing":null,"edgeToEdgeDisplay":null,"fullHeight":null,"showBorder":null,"__typename":"OneColumnQuiltSection","columnMap":{"main":[{"id":"blogs.widget.blogArticleWidget","className":"lia-blog-container","props":null,"__typename":"QuiltComponent"}],"__typename":"OneSectionColumns"}},{"id":"section-1729184836777","layout":"MAIN_SIDE","bgColor":"transparent","showTitle":false,"showDescription":false,"textPosition":"CENTER","textColor":"var(--lia-bs-body-color)","sectionEditLevel":null,"bgImage":null,"disableSpacing":null,"edgeToEdgeDisplay":null,"fullHeight":null,"showBorder":null,"__typename":"MainSideQuiltSection","columnMap":{"main":[],"side":[{"id":"custom.widget.Social_Sharing","className":null,"props":{"widgetVisibility":"signedInOrAnonymous","useTitle":true,"useBackground":true,"title":"Share","lazyLoad":false},"__typename":"QuiltComponent"}],"__typename":"MainSideSectionColumns"}}],"__typename":"QuiltContainer"},"__typename":"Quilt","localOverride":false},"localOverride":false},"CachedAsset:text:en_US-pages/blogs/BlogMessagePage-1743151753131":{"__typename":"CachedAsset","id":"text:en_US-pages/blogs/BlogMessagePage-1743151753131","value":{"title":"{contextMessageSubject} | {communityTitle}","errorMissing":"This blog post cannot be found","name":"Blog Message Page","section.blog-article.title":"Blog Post","archivedMessageTitle":"This Content Has Been Archived","section.section-1729184836777.title":"","section.section-1729184836777.description":"","section.CncIde.title":"Blog Post","section.tifEmD.description":"","section.tifEmD.title":""},"localOverride":false},"CachedAsset:quiltWrapper:o365.prod:Common:1743057753381":{"__typename":"CachedAsset","id":"quiltWrapper:o365.prod:Common:1743057753381","value":{"id":"Common","header":{"backgroundImageProps":{"assetName":null,"backgroundSize":"COVER","backgroundRepeat":"NO_REPEAT","backgroundPosition":"CENTER_CENTER","lastModified":null,"__typename":"BackgroundImageProps"},"backgroundColor":"transparent","items":[{"id":"community.widget.navbarWidget","props":{"showUserName":true,"showRegisterLink":true,"useIconLanguagePicker":true,"useLabelLanguagePicker":true,"className":"QuiltComponent_lia-component-edit-mode__0nCcm","links":{"sideLinks":[],"mainLinks":[{"children":[],"linkType":"INTERNAL","id":"gxcuf89792","params":{},"routeName":"CommunityPage"},{"children":[],"linkType":"EXTERNAL","id":"external-link","url":"/Directory","target":"SELF"},{"children":[{"linkType":"INTERNAL","id":"microsoft365","params":{"categoryId":"microsoft365"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-teams","params":{"categoryId":"MicrosoftTeams"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"windows","params":{"categoryId":"Windows"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-securityand-compliance","params":{"categoryId":"microsoft-security"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"outlook","params":{"categoryId":"Outlook"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"planner","params":{"categoryId":"Planner"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"windows-server","params":{"categoryId":"Windows-Server"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"azure","params":{"categoryId":"Azure"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"exchange","params":{"categoryId":"Exchange"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-endpoint-manager","params":{"categoryId":"microsoft-endpoint-manager"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"s-q-l-server","params":{"categoryId":"SQL-Server"},"routeName":"CategoryPage"},{"linkType":"EXTERNAL","id":"external-link-2","url":"/Directory","target":"SELF"}],"linkType":"EXTERNAL","id":"communities","url":"/","target":"BLANK"},{"children":[{"linkType":"INTERNAL","id":"education-sector","params":{"categoryId":"EducationSector"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"a-i","params":{"categoryId":"AI"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"i-t-ops-talk","params":{"categoryId":"ITOpsTalk"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"partner-community","params":{"categoryId":"PartnerCommunity"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-mechanics","params":{"categoryId":"MicrosoftMechanics"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"healthcare-and-life-sciences","params":{"categoryId":"HealthcareAndLifeSciences"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"public-sector","params":{"categoryId":"PublicSector"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"io-t","params":{"categoryId":"IoT"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"driving-adoption","params":{"categoryId":"DrivingAdoption"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"s-m-b","params":{"categoryId":"SMB"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"startupsat-microsoft","params":{"categoryId":"StartupsatMicrosoft"},"routeName":"CategoryPage"},{"linkType":"EXTERNAL","id":"external-link-1","url":"/Directory","target":"SELF"}],"linkType":"EXTERNAL","id":"communities-1","url":"/","target":"SELF"},{"children":[],"linkType":"EXTERNAL","id":"external","url":"/Blogs","target":"SELF"},{"children":[],"linkType":"EXTERNAL","id":"external-1","url":"/Events","target":"SELF"},{"children":[{"linkType":"INTERNAL","id":"microsoft-learn-1","params":{"categoryId":"MicrosoftLearn"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-learn-blog","params":{"boardId":"MicrosoftLearnBlog","categoryId":"MicrosoftLearn"},"routeName":"BlogBoardPage"},{"linkType":"EXTERNAL","id":"external-10","url":"https://learningroomdirectory.microsoft.com/","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-3","url":"https://docs.microsoft.com/learn/dynamics365/?WT.mc_id=techcom_header-webpage-m365","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-4","url":"https://docs.microsoft.com/learn/m365/?wt.mc_id=techcom_header-webpage-m365","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-5","url":"https://docs.microsoft.com/learn/topics/sci/?wt.mc_id=techcom_header-webpage-m365","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-6","url":"https://docs.microsoft.com/learn/powerplatform/?wt.mc_id=techcom_header-webpage-powerplatform","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-7","url":"https://docs.microsoft.com/learn/github/?wt.mc_id=techcom_header-webpage-github","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-8","url":"https://docs.microsoft.com/learn/teams/?wt.mc_id=techcom_header-webpage-teams","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-9","url":"https://docs.microsoft.com/learn/dotnet/?wt.mc_id=techcom_header-webpage-dotnet","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-2","url":"https://docs.microsoft.com/learn/azure/?WT.mc_id=techcom_header-webpage-m365","target":"BLANK"}],"linkType":"INTERNAL","id":"microsoft-learn","params":{"categoryId":"MicrosoftLearn"},"routeName":"CategoryPage"},{"children":[],"linkType":"INTERNAL","id":"community-info-center","params":{"categoryId":"Community-Info-Center"},"routeName":"CategoryPage"}]},"style":{"boxShadow":"var(--lia-bs-box-shadow-sm)","controllerHighlightColor":"hsla(30, 100%, 50%)","linkFontWeight":"400","dropdownDividerMarginBottom":"10px","hamburgerBorderHover":"none","linkBoxShadowHover":"none","linkFontSize":"14px","backgroundOpacity":0.8,"controllerBorderRadius":"var(--lia-border-radius-50)","hamburgerBgColor":"transparent","hamburgerColor":"var(--lia-nav-controller-icon-color)","linkTextBorderBottom":"none","brandLogoHeight":"30px","linkBgHoverColor":"transparent","linkLetterSpacing":"normal","collapseMenuDividerOpacity":0.16,"dropdownPaddingBottom":"15px","paddingBottom":"15px","dropdownMenuOffset":"2px","hamburgerBgHoverColor":"transparent","borderBottom":"1px solid var(--lia-bs-border-color)","hamburgerBorder":"none","dropdownPaddingX":"10px","brandMarginRightSm":"10px","linkBoxShadow":"none","collapseMenuDividerBg":"var(--lia-nav-link-color)","linkColor":"var(--lia-bs-body-color)","linkJustifyContent":"flex-start","dropdownPaddingTop":"10px","controllerHighlightTextColor":"var(--lia-yiq-dark)","controllerTextColor":"var(--lia-nav-controller-icon-color)","background":{"imageAssetName":"","color":"var(--lia-bs-white)","size":"COVER","repeat":"NO_REPEAT","position":"CENTER_CENTER","imageLastModified":""},"linkBorderRadius":"var(--lia-bs-border-radius-sm)","linkHoverColor":"var(--lia-bs-body-color)","position":"FIXED","linkBorder":"none","linkTextBorderBottomHover":"2px solid var(--lia-bs-body-color)","brandMarginRight":"30px","hamburgerHoverColor":"var(--lia-nav-controller-icon-color)","linkBorderHover":"none","collapseMenuMarginLeft":"20px","linkFontStyle":"NORMAL","controllerTextHoverColor":"var(--lia-nav-controller-icon-hover-color)","linkPaddingX":"10px","linkPaddingY":"5px","paddingTop":"15px","linkTextTransform":"NONE","dropdownBorderColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","controllerBgHoverColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.1)","linkBgColor":"transparent","linkDropdownPaddingX":"var(--lia-nav-link-px)","linkDropdownPaddingY":"9px","controllerIconColor":"var(--lia-bs-body-color)","dropdownDividerMarginTop":"10px","linkGap":"10px","controllerIconHoverColor":"var(--lia-bs-body-color)"},"showSearchIcon":false,"languagePickerStyle":"iconAndLabel"},"__typename":"QuiltComponent"},{"id":"community.widget.breadcrumbWidget","props":{"backgroundColor":"transparent","linkHighlightColor":"var(--lia-bs-primary)","visualEffects":{"showBottomBorder":true},"linkTextColor":"var(--lia-bs-gray-700)"},"__typename":"QuiltComponent"},{"id":"custom.widget.community_banner","props":{"widgetVisibility":"signedInOrAnonymous","useTitle":true,"usePageWidth":false,"useBackground":false,"title":"","lazyLoad":false},"__typename":"QuiltComponent"},{"id":"custom.widget.HeroBanner","props":{"widgetVisibility":"signedInOrAnonymous","usePageWidth":false,"useTitle":true,"cMax_items":3,"useBackground":false,"title":"","lazyLoad":false,"widgetChooser":"custom.widget.HeroBanner"},"__typename":"QuiltComponent"}],"__typename":"QuiltWrapperSection"},"footer":{"backgroundImageProps":{"assetName":null,"backgroundSize":"COVER","backgroundRepeat":"NO_REPEAT","backgroundPosition":"CENTER_CENTER","lastModified":null,"__typename":"BackgroundImageProps"},"backgroundColor":"transparent","items":[{"id":"custom.widget.MicrosoftFooter","props":{"widgetVisibility":"signedInOrAnonymous","useTitle":true,"useBackground":false,"title":"","lazyLoad":false},"__typename":"QuiltComponent"}],"__typename":"QuiltWrapperSection"},"__typename":"QuiltWrapper","localOverride":false},"localOverride":false},"CachedAsset:text:en_US-components/common/ActionFeedback-1743151753131":{"__typename":"CachedAsset","id":"text:en_US-components/common/ActionFeedback-1743151753131","value":{"joinedGroupHub.title":"Welcome","joinedGroupHub.message":"You are now a member of this group and are subscribed to updates.","groupHubInviteNotFound.title":"Invitation Not Found","groupHubInviteNotFound.message":"Sorry, we could not find your invitation to the group. The owner may have canceled the invite.","groupHubNotFound.title":"Group Not Found","groupHubNotFound.message":"The grouphub you tried to join does not exist. It may have been deleted.","existingGroupHubMember.title":"Already Joined","existingGroupHubMember.message":"You are already a member of this group.","accountLocked.title":"Account Locked","accountLocked.message":"Your account has been locked due to multiple failed attempts. Try again in {lockoutTime} minutes.","editedGroupHub.title":"Changes Saved","editedGroupHub.message":"Your group has been updated.","leftGroupHub.title":"Goodbye","leftGroupHub.message":"You are no longer a member of this group and will not receive future updates.","deletedGroupHub.title":"Deleted","deletedGroupHub.message":"The group has been deleted.","groupHubCreated.title":"Group Created","groupHubCreated.message":"{groupHubName} is ready to use","accountClosed.title":"Account Closed","accountClosed.message":"The account has been closed and you will now be redirected to the homepage","resetTokenExpired.title":"Reset Password Link has Expired","resetTokenExpired.message":"Try resetting your password again","invalidUrl.title":"Invalid URL","invalidUrl.message":"The URL you're using is not recognized. Verify your URL and try again.","accountClosedForUser.title":"Account Closed","accountClosedForUser.message":"{userName}'s account is closed","inviteTokenInvalid.title":"Invitation Invalid","inviteTokenInvalid.message":"Your invitation to the community has been canceled or expired.","inviteTokenError.title":"Invitation Verification Failed","inviteTokenError.message":"The url you are utilizing is not recognized. Verify your URL and try again","pageNotFound.title":"Access Denied","pageNotFound.message":"You do not have access to this area of the community or it doesn't exist","eventAttending.title":"Responded as Attending","eventAttending.message":"You'll be notified when there's new activity and reminded as the event approaches","eventInterested.title":"Responded as Interested","eventInterested.message":"You'll be notified when there's new activity and reminded as the event approaches","eventNotFound.title":"Event Not Found","eventNotFound.message":"The event you tried to respond to does not exist.","redirectToRelatedPage.title":"Showing Related Content","redirectToRelatedPageForBaseUsers.title":"Showing Related Content","redirectToRelatedPageForBaseUsers.message":"The content you are trying to access is archived","redirectToRelatedPage.message":"The content you are trying to access is archived","relatedUrl.archivalLink.flyoutMessage":"The content you are trying to access is archived View Archived Content"},"localOverride":false},"CachedAsset:component:custom.widget.community_banner-en-1743057957505":{"__typename":"CachedAsset","id":"component:custom.widget.community_banner-en-1743057957505","value":{"component":{"id":"custom.widget.community_banner","template":{"id":"community_banner","markupLanguage":"HANDLEBARS","style":".community-banner {\n a.top-bar.btn {\n top: 0px;\n width: 100%;\n z-index: 999;\n text-align: center;\n left: 0px;\n background: #0068b8;\n color: white;\n padding: 10px 0px;\n display:block;\n box-shadow:none !important;\n border: none !important;\n border-radius: none !important;\n margin: 0px !important;\n font-size:14px;\n }\n}","texts":null,"defaults":{"config":{"applicablePages":[],"description":"community announcement text","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.community_banner","form":null,"config":null,"props":[],"__typename":"Component"}],"grouping":"CUSTOM","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":"community announcement text","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"form":null,"__typename":"Component","localOverride":false},"globalCss":{"css":".custom_widget_community_banner_community-banner_1a5zb_1 {\n a.custom_widget_community_banner_top-bar_1a5zb_2.custom_widget_community_banner_btn_1a5zb_2 {\n top: 0;\n width: 100%;\n z-index: 999;\n text-align: center;\n left: 0;\n background: #0068b8;\n color: white;\n padding: 0.625rem 0;\n display:block;\n box-shadow:none !important;\n border: none !important;\n border-radius: none !important;\n margin: 0 !important;\n font-size:0.875rem;\n }\n}","tokens":{"community-banner":"custom_widget_community_banner_community-banner_1a5zb_1","top-bar":"custom_widget_community_banner_top-bar_1a5zb_2","btn":"custom_widget_community_banner_btn_1a5zb_2"}},"form":null},"localOverride":false},"CachedAsset:component:custom.widget.HeroBanner-en-1743057957505":{"__typename":"CachedAsset","id":"component:custom.widget.HeroBanner-en-1743057957505","value":{"component":{"id":"custom.widget.HeroBanner","template":{"id":"HeroBanner","markupLanguage":"REACT","style":null,"texts":{"searchPlaceholderText":"Search this community","followActionText":"Follow","unfollowActionText":"Following","searchOnHoverText":"Please enter your search term(s) and then press return key to complete a search."},"defaults":{"config":{"applicablePages":[],"description":null,"fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[{"id":"max_items","dataType":"NUMBER","list":false,"defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"control":"INPUT","__typename":"PropDefinition"}],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.HeroBanner","form":{"fields":[{"id":"widgetChooser","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"title","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useTitle","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useBackground","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"widgetVisibility","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"moreOptions","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"cMax_items","validation":null,"noValidation":null,"dataType":"NUMBER","list":false,"control":"INPUT","defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"__typename":"FormField"}],"layout":{"rows":[{"id":"widgetChooserGroup","type":"fieldset","as":null,"items":[{"id":"widgetChooser","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"titleGroup","type":"fieldset","as":null,"items":[{"id":"title","className":null,"__typename":"FormFieldRef"},{"id":"useTitle","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"useBackground","type":"fieldset","as":null,"items":[{"id":"useBackground","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"widgetVisibility","type":"fieldset","as":null,"items":[{"id":"widgetVisibility","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"moreOptionsGroup","type":"fieldset","as":null,"items":[{"id":"moreOptions","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"componentPropsGroup","type":"fieldset","as":null,"items":[{"id":"cMax_items","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"}],"actionButtons":null,"className":"custom_widget_HeroBanner_form","formGroupFieldSeparator":"divider","__typename":"FormLayout"},"__typename":"Form"},"config":null,"props":[],"__typename":"Component"}],"grouping":"CUSTOM","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":null,"fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[{"id":"max_items","dataType":"NUMBER","list":false,"defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"control":"INPUT","__typename":"PropDefinition"}],"__typename":"ComponentProperties"},"form":{"fields":[{"id":"widgetChooser","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"title","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useTitle","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useBackground","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"widgetVisibility","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"moreOptions","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"cMax_items","validation":null,"noValidation":null,"dataType":"NUMBER","list":false,"control":"INPUT","defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"__typename":"FormField"}],"layout":{"rows":[{"id":"widgetChooserGroup","type":"fieldset","as":null,"items":[{"id":"widgetChooser","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"titleGroup","type":"fieldset","as":null,"items":[{"id":"title","className":null,"__typename":"FormFieldRef"},{"id":"useTitle","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"useBackground","type":"fieldset","as":null,"items":[{"id":"useBackground","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"widgetVisibility","type":"fieldset","as":null,"items":[{"id":"widgetVisibility","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"moreOptionsGroup","type":"fieldset","as":null,"items":[{"id":"moreOptions","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"componentPropsGroup","type":"fieldset","as":null,"items":[{"id":"cMax_items","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"}],"actionButtons":null,"className":"custom_widget_HeroBanner_form","formGroupFieldSeparator":"divider","__typename":"FormLayout"},"__typename":"Form"},"__typename":"Component","localOverride":false},"globalCss":null,"form":{"fields":[{"id":"widgetChooser","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"title","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useTitle","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useBackground","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"widgetVisibility","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"moreOptions","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"cMax_items","validation":null,"noValidation":null,"dataType":"NUMBER","list":false,"control":"INPUT","defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"__typename":"FormField"}],"layout":{"rows":[{"id":"widgetChooserGroup","type":"fieldset","as":null,"items":[{"id":"widgetChooser","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"titleGroup","type":"fieldset","as":null,"items":[{"id":"title","className":null,"__typename":"FormFieldRef"},{"id":"useTitle","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"useBackground","type":"fieldset","as":null,"items":[{"id":"useBackground","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"widgetVisibility","type":"fieldset","as":null,"items":[{"id":"widgetVisibility","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"moreOptionsGroup","type":"fieldset","as":null,"items":[{"id":"moreOptions","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"componentPropsGroup","type":"fieldset","as":null,"items":[{"id":"cMax_items","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"}],"actionButtons":null,"className":"custom_widget_HeroBanner_form","formGroupFieldSeparator":"divider","__typename":"FormLayout"},"__typename":"Form"}},"localOverride":false},"CachedAsset:component:custom.widget.Social_Sharing-en-1743057957505":{"__typename":"CachedAsset","id":"component:custom.widget.Social_Sharing-en-1743057957505","value":{"component":{"id":"custom.widget.Social_Sharing","template":{"id":"Social_Sharing","markupLanguage":"HANDLEBARS","style":".social-share {\n .sharing-options {\n position: relative;\n margin: 0;\n padding: 0;\n line-height: 10px;\n display: flex;\n justify-content: left;\n gap: 5px;\n list-style-type: none;\n li {\n text-align: left;\n a {\n min-width: 30px;\n min-height: 30px;\n display: block;\n padding: 1px;\n .social-share-linkedin {\n img {\n background-color: rgb(0, 119, 181);\n }\n }\n .social-share-facebook {\n img {\n background-color: rgb(59, 89, 152);\n }\n }\n .social-share-x {\n img {\n background-color: rgb(0, 0, 0);\n }\n }\n .social-share-rss {\n img {\n background-color: rgb(0, 0, 0);\n }\n }\n .social-share-reddit {\n img {\n background-color: rgb(255, 69, 0);\n }\n }\n .social-share-email {\n img {\n background-color: rgb(132, 132, 132);\n }\n }\n }\n a {\n img {\n height: 2rem;\n }\n }\n }\n }\n}\n","texts":null,"defaults":{"config":{"applicablePages":[],"description":"Adds buttons to share to various social media websites","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.Social_Sharing","form":null,"config":null,"props":[],"__typename":"Component"}],"grouping":"CUSTOM","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":"Adds buttons to share to various social media websites","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"form":null,"__typename":"Component","localOverride":false},"globalCss":{"css":".custom_widget_Social_Sharing_social-share_c7xxz_1 {\n .custom_widget_Social_Sharing_sharing-options_c7xxz_2 {\n position: relative;\n margin: 0;\n padding: 0;\n line-height: 0.625rem;\n display: flex;\n justify-content: left;\n gap: 0.3125rem;\n list-style-type: none;\n li {\n text-align: left;\n a {\n min-width: 1.875rem;\n min-height: 1.875rem;\n display: block;\n padding: 0.0625rem;\n .custom_widget_Social_Sharing_social-share-linkedin_c7xxz_18 {\n img {\n background-color: rgb(0, 119, 181);\n }\n }\n .custom_widget_Social_Sharing_social-share-facebook_c7xxz_23 {\n img {\n background-color: rgb(59, 89, 152);\n }\n }\n .custom_widget_Social_Sharing_social-share-x_c7xxz_28 {\n img {\n background-color: rgb(0, 0, 0);\n }\n }\n .custom_widget_Social_Sharing_social-share-rss_c7xxz_33 {\n img {\n background-color: rgb(0, 0, 0);\n }\n }\n .custom_widget_Social_Sharing_social-share-reddit_c7xxz_38 {\n img {\n background-color: rgb(255, 69, 0);\n }\n }\n .custom_widget_Social_Sharing_social-share-email_c7xxz_43 {\n img {\n background-color: rgb(132, 132, 132);\n }\n }\n }\n a {\n img {\n height: 2rem;\n }\n }\n }\n }\n}\n","tokens":{"social-share":"custom_widget_Social_Sharing_social-share_c7xxz_1","sharing-options":"custom_widget_Social_Sharing_sharing-options_c7xxz_2","social-share-linkedin":"custom_widget_Social_Sharing_social-share-linkedin_c7xxz_18","social-share-facebook":"custom_widget_Social_Sharing_social-share-facebook_c7xxz_23","social-share-x":"custom_widget_Social_Sharing_social-share-x_c7xxz_28","social-share-rss":"custom_widget_Social_Sharing_social-share-rss_c7xxz_33","social-share-reddit":"custom_widget_Social_Sharing_social-share-reddit_c7xxz_38","social-share-email":"custom_widget_Social_Sharing_social-share-email_c7xxz_43"}},"form":null},"localOverride":false},"CachedAsset:component:custom.widget.MicrosoftFooter-en-1743057957505":{"__typename":"CachedAsset","id":"component:custom.widget.MicrosoftFooter-en-1743057957505","value":{"component":{"id":"custom.widget.MicrosoftFooter","template":{"id":"MicrosoftFooter","markupLanguage":"HANDLEBARS","style":".context-uhf {\n min-width: 280px;\n font-size: 15px;\n box-sizing: border-box;\n -ms-text-size-adjust: 100%;\n -webkit-text-size-adjust: 100%;\n & *,\n & *:before,\n & *:after {\n box-sizing: inherit;\n }\n a.c-uhff-link {\n color: #616161;\n word-break: break-word;\n text-decoration: none;\n }\n &a:link,\n &a:focus,\n &a:hover,\n &a:active,\n &a:visited {\n text-decoration: none;\n color: inherit;\n }\n & div {\n font-family: 'Segoe UI', SegoeUI, 'Helvetica Neue', Helvetica, Arial, sans-serif;\n }\n}\n.c-uhff {\n background: #f2f2f2;\n margin: -1.5625;\n width: auto;\n height: auto;\n}\n.c-uhff-nav {\n margin: 0 auto;\n max-width: calc(1600px + 10%);\n padding: 0 5%;\n box-sizing: inherit;\n &:before,\n &:after {\n content: ' ';\n display: table;\n clear: left;\n }\n @media only screen and (max-width: 1083px) {\n padding-left: 12px;\n }\n .c-heading-4 {\n color: #616161;\n word-break: break-word;\n font-size: 15px;\n line-height: 20px;\n padding: 36px 0 4px;\n font-weight: 600;\n }\n .c-uhff-nav-row {\n .c-uhff-nav-group {\n display: block;\n float: left;\n min-height: 1px;\n vertical-align: text-top;\n padding: 0 12px;\n width: 100%;\n zoom: 1;\n &:first-child {\n padding-left: 0;\n @media only screen and (max-width: 1083px) {\n padding-left: 12px;\n }\n }\n @media only screen and (min-width: 540px) and (max-width: 1082px) {\n width: 33.33333%;\n }\n @media only screen and (min-width: 1083px) {\n width: 16.6666666667%;\n }\n ul.c-list.f-bare {\n font-size: 11px;\n line-height: 16px;\n margin-top: 0;\n margin-bottom: 0;\n padding-left: 0;\n list-style-type: none;\n li {\n word-break: break-word;\n padding: 8px 0;\n margin: 0;\n }\n }\n }\n }\n}\n.c-uhff-base {\n background: #f2f2f2;\n margin: 0 auto;\n max-width: calc(1600px + 10%);\n padding: 30px 5% 16px;\n &:before,\n &:after {\n content: ' ';\n display: table;\n }\n &:after {\n clear: both;\n }\n a.c-uhff-ccpa {\n font-size: 11px;\n line-height: 16px;\n float: left;\n margin: 3px 0;\n }\n a.c-uhff-ccpa:hover {\n text-decoration: underline;\n }\n ul.c-list {\n font-size: 11px;\n line-height: 16px;\n float: right;\n margin: 3px 0;\n color: #616161;\n li {\n padding: 0 24px 4px 0;\n display: inline-block;\n }\n }\n .c-list.f-bare {\n padding-left: 0;\n list-style-type: none;\n }\n @media only screen and (max-width: 1083px) {\n display: flex;\n flex-wrap: wrap;\n padding: 30px 24px 16px;\n }\n}\n","texts":{"New tab":"What's New","New 1":"Surface Laptop Studio 2","New 2":"Surface Laptop Go 3","New 3":"Surface Pro 9","New 4":"Surface Laptop 5","New 5":"Surface Studio 2+","New 6":"Copilot in Windows","New 7":"Microsoft 365","New 8":"Windows 11 apps","Store tab":"Microsoft Store","Store 1":"Account Profile","Store 2":"Download Center","Store 3":"Microsoft Store Support","Store 4":"Returns","Store 5":"Order tracking","Store 6":"Certified Refurbished","Store 7":"Microsoft Store Promise","Store 8":"Flexible Payments","Education tab":"Education","Edu 1":"Microsoft in education","Edu 2":"Devices for education","Edu 3":"Microsoft Teams for Education","Edu 4":"Microsoft 365 Education","Edu 5":"How to buy for your school","Edu 6":"Educator Training and development","Edu 7":"Deals for students and parents","Edu 8":"Azure for students","Business tab":"Business","Bus 1":"Microsoft Cloud","Bus 2":"Microsoft Security","Bus 3":"Dynamics 365","Bus 4":"Microsoft 365","Bus 5":"Microsoft Power Platform","Bus 6":"Microsoft Teams","Bus 7":"Microsoft Industry","Bus 8":"Small Business","Developer tab":"Developer & IT","Dev 1":"Azure","Dev 2":"Developer Center","Dev 3":"Documentation","Dev 4":"Microsoft Learn","Dev 5":"Microsoft Tech Community","Dev 6":"Azure Marketplace","Dev 7":"AppSource","Dev 8":"Visual Studio","Company tab":"Company","Com 1":"Careers","Com 2":"About Microsoft","Com 3":"Company News","Com 4":"Privacy at Microsoft","Com 5":"Investors","Com 6":"Diversity and inclusion","Com 7":"Accessiblity","Com 8":"Sustainibility"},"defaults":{"config":{"applicablePages":[],"description":"The Microsoft Footer","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.MicrosoftFooter","form":null,"config":null,"props":[],"__typename":"Component"}],"grouping":"CUSTOM","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":"The Microsoft Footer","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"form":null,"__typename":"Component","localOverride":false},"globalCss":{"css":".custom_widget_MicrosoftFooter_context-uhf_f95yq_1 {\n min-width: 17.5rem;\n font-size: 0.9375rem;\n box-sizing: border-box;\n -ms-text-size-adjust: 100%;\n -webkit-text-size-adjust: 100%;\n & *,\n & *:before,\n & *:after {\n box-sizing: inherit;\n }\n a.custom_widget_MicrosoftFooter_c-uhff-link_f95yq_12 {\n color: #616161;\n word-break: break-word;\n text-decoration: none;\n }\n &a:link,\n &a:focus,\n &a:hover,\n &a:active,\n &a:visited {\n text-decoration: none;\n color: inherit;\n }\n & div {\n font-family: 'Segoe UI', SegoeUI, 'Helvetica Neue', Helvetica, Arial, sans-serif;\n }\n}\n.custom_widget_MicrosoftFooter_c-uhff_f95yq_12 {\n background: #f2f2f2;\n margin: -1.5625;\n width: auto;\n height: auto;\n}\n.custom_widget_MicrosoftFooter_c-uhff-nav_f95yq_35 {\n margin: 0 auto;\n max-width: calc(100rem + 10%);\n padding: 0 5%;\n box-sizing: inherit;\n &:before,\n &:after {\n content: ' ';\n display: table;\n clear: left;\n }\n @media only screen and (max-width: 1083px) {\n padding-left: 0.75rem;\n }\n .custom_widget_MicrosoftFooter_c-heading-4_f95yq_49 {\n color: #616161;\n word-break: break-word;\n font-size: 0.9375rem;\n line-height: 1.25rem;\n padding: 2.25rem 0 0.25rem;\n font-weight: 600;\n }\n .custom_widget_MicrosoftFooter_c-uhff-nav-row_f95yq_57 {\n .custom_widget_MicrosoftFooter_c-uhff-nav-group_f95yq_58 {\n display: block;\n float: left;\n min-height: 0.0625rem;\n vertical-align: text-top;\n padding: 0 0.75rem;\n width: 100%;\n zoom: 1;\n &:first-child {\n padding-left: 0;\n @media only screen and (max-width: 1083px) {\n padding-left: 0.75rem;\n }\n }\n @media only screen and (min-width: 540px) and (max-width: 1082px) {\n width: 33.33333%;\n }\n @media only screen and (min-width: 1083px) {\n width: 16.6666666667%;\n }\n ul.custom_widget_MicrosoftFooter_c-list_f95yq_78.custom_widget_MicrosoftFooter_f-bare_f95yq_78 {\n font-size: 0.6875rem;\n line-height: 1rem;\n margin-top: 0;\n margin-bottom: 0;\n padding-left: 0;\n list-style-type: none;\n li {\n word-break: break-word;\n padding: 0.5rem 0;\n margin: 0;\n }\n }\n }\n }\n}\n.custom_widget_MicrosoftFooter_c-uhff-base_f95yq_94 {\n background: #f2f2f2;\n margin: 0 auto;\n max-width: calc(100rem + 10%);\n padding: 1.875rem 5% 1rem;\n &:before,\n &:after {\n content: ' ';\n display: table;\n }\n &:after {\n clear: both;\n }\n a.custom_widget_MicrosoftFooter_c-uhff-ccpa_f95yq_107 {\n font-size: 0.6875rem;\n line-height: 1rem;\n float: left;\n margin: 0.1875rem 0;\n }\n a.custom_widget_MicrosoftFooter_c-uhff-ccpa_f95yq_107:hover {\n text-decoration: underline;\n }\n ul.custom_widget_MicrosoftFooter_c-list_f95yq_78 {\n font-size: 0.6875rem;\n line-height: 1rem;\n float: right;\n margin: 0.1875rem 0;\n color: #616161;\n li {\n padding: 0 1.5rem 0.25rem 0;\n display: inline-block;\n }\n }\n .custom_widget_MicrosoftFooter_c-list_f95yq_78.custom_widget_MicrosoftFooter_f-bare_f95yq_78 {\n padding-left: 0;\n list-style-type: none;\n }\n @media only screen and (max-width: 1083px) {\n display: flex;\n flex-wrap: wrap;\n padding: 1.875rem 1.5rem 1rem;\n }\n}\n","tokens":{"context-uhf":"custom_widget_MicrosoftFooter_context-uhf_f95yq_1","c-uhff-link":"custom_widget_MicrosoftFooter_c-uhff-link_f95yq_12","c-uhff":"custom_widget_MicrosoftFooter_c-uhff_f95yq_12","c-uhff-nav":"custom_widget_MicrosoftFooter_c-uhff-nav_f95yq_35","c-heading-4":"custom_widget_MicrosoftFooter_c-heading-4_f95yq_49","c-uhff-nav-row":"custom_widget_MicrosoftFooter_c-uhff-nav-row_f95yq_57","c-uhff-nav-group":"custom_widget_MicrosoftFooter_c-uhff-nav-group_f95yq_58","c-list":"custom_widget_MicrosoftFooter_c-list_f95yq_78","f-bare":"custom_widget_MicrosoftFooter_f-bare_f95yq_78","c-uhff-base":"custom_widget_MicrosoftFooter_c-uhff-base_f95yq_94","c-uhff-ccpa":"custom_widget_MicrosoftFooter_c-uhff-ccpa_f95yq_107"}},"form":null},"localOverride":false},"CachedAsset:text:en_US-components/community/Breadcrumb-1743151753131":{"__typename":"CachedAsset","id":"text:en_US-components/community/Breadcrumb-1743151753131","value":{"navLabel":"Breadcrumbs","dropdown":"Additional parent page navigation"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageBanner-1743151753131":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageBanner-1743151753131","value":{"messageMarkedAsSpam":"This post has been marked as spam","messageMarkedAsSpam@board:TKB":"This article has been marked as spam","messageMarkedAsSpam@board:BLOG":"This post has been marked as spam","messageMarkedAsSpam@board:FORUM":"This discussion has been marked as spam","messageMarkedAsSpam@board:OCCASION":"This event has been marked as spam","messageMarkedAsSpam@board:IDEA":"This idea has been marked as spam","manageSpam":"Manage Spam","messageMarkedAsAbuse":"This post has been marked as abuse","messageMarkedAsAbuse@board:TKB":"This article has been marked as abuse","messageMarkedAsAbuse@board:BLOG":"This post has been marked as abuse","messageMarkedAsAbuse@board:FORUM":"This discussion has been marked as abuse","messageMarkedAsAbuse@board:OCCASION":"This event has been marked as abuse","messageMarkedAsAbuse@board:IDEA":"This idea has been marked as abuse","preModCommentAuthorText":"This comment will be published as soon as it is approved","preModCommentModeratorText":"This comment is awaiting moderation","messageMarkedAsOther":"This post has been rejected due to other reasons","messageMarkedAsOther@board:TKB":"This article has been rejected due to other reasons","messageMarkedAsOther@board:BLOG":"This post has been rejected due to other reasons","messageMarkedAsOther@board:FORUM":"This discussion has been rejected due to other reasons","messageMarkedAsOther@board:OCCASION":"This event has been rejected due to other reasons","messageMarkedAsOther@board:IDEA":"This idea has been rejected due to other reasons","messageArchived":"This post was archived on {date}","relatedUrl":"View Related Content","relatedContentText":"Showing related content","archivedContentLink":"View Archived Content"},"localOverride":false},"Category:category:Exchange":{"__typename":"Category","id":"category:Exchange","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Planner":{"__typename":"Category","id":"category:Planner","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Outlook":{"__typename":"Category","id":"category:Outlook","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Community-Info-Center":{"__typename":"Category","id":"category:Community-Info-Center","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:EducationSector":{"__typename":"Category","id":"category:EducationSector","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:DrivingAdoption":{"__typename":"Category","id":"category:DrivingAdoption","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Windows-Server":{"__typename":"Category","id":"category:Windows-Server","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:SQL-Server":{"__typename":"Category","id":"category:SQL-Server","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:MicrosoftTeams":{"__typename":"Category","id":"category:MicrosoftTeams","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:PublicSector":{"__typename":"Category","id":"category:PublicSector","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:microsoft365":{"__typename":"Category","id":"category:microsoft365","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:IoT":{"__typename":"Category","id":"category:IoT","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:HealthcareAndLifeSciences":{"__typename":"Category","id":"category:HealthcareAndLifeSciences","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:SMB":{"__typename":"Category","id":"category:SMB","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:ITOpsTalk":{"__typename":"Category","id":"category:ITOpsTalk","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:microsoft-endpoint-manager":{"__typename":"Category","id":"category:microsoft-endpoint-manager","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:MicrosoftLearn":{"__typename":"Category","id":"category:MicrosoftLearn","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Blog:board:MicrosoftLearnBlog":{"__typename":"Blog","id":"board:MicrosoftLearnBlog","blogPolicies":{"__typename":"BlogPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:AI":{"__typename":"Category","id":"category:AI","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:MicrosoftMechanics":{"__typename":"Category","id":"category:MicrosoftMechanics","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:StartupsatMicrosoft":{"__typename":"Category","id":"category:StartupsatMicrosoft","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:PartnerCommunity":{"__typename":"Category","id":"category:PartnerCommunity","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Windows":{"__typename":"Category","id":"category:Windows","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:microsoft-security":{"__typename":"Category","id":"category:microsoft-security","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"QueryVariables:TopicReplyList:message:3609189:23":{"__typename":"QueryVariables","id":"TopicReplyList:message:3609189:23","value":{"id":"message:3609189","first":10,"sorts":{"postTime":{"direction":"DESC"}},"repliesFirst":3,"repliesFirstDepthThree":1,"repliesSorts":{"postTime":{"direction":"DESC"}},"useAvatar":true,"useAuthorLogin":true,"useAuthorRank":true,"useBody":true,"useKudosCount":true,"useTimeToRead":false,"useMedia":false,"useReadOnlyIcon":false,"useRepliesCount":true,"useSearchSnippet":false,"useAcceptedSolutionButton":false,"useSolvedBadge":false,"useAttachments":false,"attachmentsFirst":5,"useTags":true,"useNodeAncestors":false,"useUserHoverCard":false,"useNodeHoverCard":false,"useModerationStatus":true,"usePreviewSubjectModal":false,"useMessageStatus":true}},"ROOT_MUTATION":{"__typename":"Mutation"},"CachedAsset:text:en_US-components/community/Navbar-1743151753131":{"__typename":"CachedAsset","id":"text:en_US-components/community/Navbar-1743151753131","value":{"community":"Community Home","inbox":"Inbox","manageContent":"Manage Content","tos":"Terms of Service","forgotPassword":"Forgot Password","themeEditor":"Theme Editor","edit":"Edit Navigation Bar","skipContent":"Skip to content","gxcuf89792":"Tech Community","external-1":"Events","s-m-b":"Small and Medium Businesses","windows-server":"Windows Server","education-sector":"Education Sector","driving-adoption":"Driving Adoption","microsoft-learn":"Microsoft Learn","s-q-l-server":"SQL Server","partner-community":"Microsoft Partner Community","microsoft365":"Microsoft 365","external-9":".NET","external-8":"Teams","external-7":"Github","products-services":"Products","external-6":"Power Platform","communities-1":"Topics","external-5":"Microsoft Security","planner":"Planner","external-4":"Microsoft 365","external-3":"Dynamics 365","azure":"Azure","healthcare-and-life-sciences":"Healthcare and Life Sciences","external-2":"Azure","microsoft-mechanics":"Microsoft Mechanics","microsoft-learn-1":"Community","external-10":"Learning Room Directory","microsoft-learn-blog":"Blog","windows":"Windows","i-t-ops-talk":"ITOps Talk","external-link-1":"View All","microsoft-securityand-compliance":"Microsoft Security","public-sector":"Public Sector","community-info-center":"Lounge","external-link-2":"View All","microsoft-teams":"Microsoft Teams","external":"Blogs","microsoft-endpoint-manager":"Microsoft Intune and Configuration Manager","startupsat-microsoft":"Startups at Microsoft","exchange":"Exchange","a-i":"AI and Machine Learning","io-t":"Internet of Things (IoT)","outlook":"Outlook","external-link":"Community Hubs","communities":"Products"},"localOverride":false},"CachedAsset:text:en_US-components/community/NavbarHamburgerDropdown-1743151753131":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarHamburgerDropdown-1743151753131","value":{"hamburgerLabel":"Side Menu"},"localOverride":false},"CachedAsset:text:en_US-components/community/BrandLogo-1743151753131":{"__typename":"CachedAsset","id":"text:en_US-components/community/BrandLogo-1743151753131","value":{"logoAlt":"Khoros","themeLogoAlt":"Brand Logo"},"localOverride":false},"CachedAsset:text:en_US-components/community/NavbarTextLinks-1743151753131":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarTextLinks-1743151753131","value":{"more":"More"},"localOverride":false},"CachedAsset:text:en_US-components/authentication/AuthenticationLink-1743151753131":{"__typename":"CachedAsset","id":"text:en_US-components/authentication/AuthenticationLink-1743151753131","value":{"title.login":"Sign In","title.registration":"Register","title.forgotPassword":"Forgot Password","title.multiAuthLogin":"Sign In"},"localOverride":false},"CachedAsset:text:en_US-components/nodes/NodeLink-1743151753131":{"__typename":"CachedAsset","id":"text:en_US-components/nodes/NodeLink-1743151753131","value":{"place":"Place {name}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageView/MessageViewStandard-1743151753131":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageView/MessageViewStandard-1743151753131","value":{"anonymous":"Anonymous","author":"{messageAuthorLogin}","authorBy":"{messageAuthorLogin}","board":"{messageBoardTitle}","replyToUser":" to {parentAuthor}","showMoreReplies":"Show More","replyText":"Reply","repliesText":"Replies","markedAsSolved":"Marked as Solved","movedMessagePlaceholder.BLOG":"{count, plural, =0 {This comment has been} other {These comments have been} }","movedMessagePlaceholder.TKB":"{count, plural, =0 {This comment has been} other {These comments have been} }","movedMessagePlaceholder.FORUM":"{count, plural, =0 {This reply has been} other {These replies have been} }","movedMessagePlaceholder.IDEA":"{count, plural, =0 {This comment has been} other {These comments have been} }","movedMessagePlaceholder.OCCASION":"{count, plural, =0 {This comment has been} other {These comments have been} }","movedMessagePlaceholderUrlText":"moved.","messageStatus":"Status: ","statusChanged":"Status changed: {previousStatus} to {currentStatus}","statusAdded":"Status added: {status}","statusRemoved":"Status removed: {status}","labelExpand":"expand replies","labelCollapse":"collapse replies","unhelpfulReason.reason1":"Content is outdated","unhelpfulReason.reason2":"Article is missing information","unhelpfulReason.reason3":"Content is for a different Product","unhelpfulReason.reason4":"Doesn't match what I was searching for"},"localOverride":false},"CachedAsset:text:en_US-components/messages/ThreadedReplyList-1743151753131":{"__typename":"CachedAsset","id":"text:en_US-components/messages/ThreadedReplyList-1743151753131","value":{"title":"{count, plural, one{# Reply} other{# Replies}}","title@board:BLOG":"{count, plural, one{# Comment} other{# Comments}}","title@board:TKB":"{count, plural, one{# Comment} other{# Comments}}","title@board:IDEA":"{count, plural, one{# Comment} other{# Comments}}","title@board:OCCASION":"{count, plural, one{# Comment} other{# Comments}}","noRepliesTitle":"No Replies","noRepliesTitle@board:BLOG":"No Comments","noRepliesTitle@board:TKB":"No Comments","noRepliesTitle@board:IDEA":"No Comments","noRepliesTitle@board:OCCASION":"No Comments","noRepliesDescription":"Be the first to reply","noRepliesDescription@board:BLOG":"Be the first to comment","noRepliesDescription@board:TKB":"Be the first to comment","noRepliesDescription@board:IDEA":"Be the first to comment","noRepliesDescription@board:OCCASION":"Be the first to comment","messageReadOnlyAlert:BLOG":"Comments have been turned off for this post","messageReadOnlyAlert:TKB":"Comments have been turned off for this article","messageReadOnlyAlert:IDEA":"Comments have been turned off for this idea","messageReadOnlyAlert:FORUM":"Replies have been turned off for this discussion","messageReadOnlyAlert:OCCASION":"Comments have been turned off for this event"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageReplyCallToAction-1743151753131":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageReplyCallToAction-1743151753131","value":{"leaveReply":"Leave a reply...","leaveReply@board:BLOG@message:root":"Leave a comment...","leaveReply@board:TKB@message:root":"Leave a comment...","leaveReply@board:IDEA@message:root":"Leave a comment...","leaveReply@board:OCCASION@message:root":"Leave a comment...","repliesTurnedOff.FORUM":"Replies are turned off for this topic","repliesTurnedOff.BLOG":"Comments are turned off for this topic","repliesTurnedOff.TKB":"Comments are turned off for this topic","repliesTurnedOff.IDEA":"Comments are turned off for this topic","repliesTurnedOff.OCCASION":"Comments are turned off for this topic","infoText":"Stop poking me!"},"localOverride":false},"CachedAsset:text:en_US-components/community/NavbarDropdownToggle-1743151753131":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarDropdownToggle-1743151753131","value":{"ariaLabelClosed":"Press the down arrow to open the menu"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/QueryHandler-1743151753131":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/QueryHandler-1743151753131","value":{"title":"Query Handler"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageCoverImage-1743151753131":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageCoverImage-1743151753131","value":{"coverImageTitle":"Cover Image"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/nodes/NodeTitle-1743151753131":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/nodes/NodeTitle-1743151753131","value":{"nodeTitle":"{nodeTitle, select, community {Community} other {{nodeTitle}}} "},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageTimeToRead-1743151753131":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageTimeToRead-1743151753131","value":{"minReadText":"{min} MIN READ"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageSubject-1743151753131":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageSubject-1743151753131","value":{"noSubject":"(no subject)"},"localOverride":false},"CachedAsset:text:en_US-components/users/UserLink-1743151753131":{"__typename":"CachedAsset","id":"text:en_US-components/users/UserLink-1743151753131","value":{"authorName":"View Profile: {author}","anonymous":"Anonymous"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/users/UserRank-1743151753131":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/users/UserRank-1743151753131","value":{"rankName":"{rankName}","userRank":"Author rank {rankName}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageTime-1743151753131":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageTime-1743151753131","value":{"postTime":"Published: {time}","lastPublishTime":"Last Update: {time}","conversation.lastPostingActivityTime":"Last posting activity time: {time}","conversation.lastPostTime":"Last post time: {time}","moderationData.rejectTime":"Rejected time: {time}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageBody-1743151753131":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageBody-1743151753131","value":{"showMessageBody":"Show More","mentionsErrorTitle":"{mentionsType, select, board {Board} user {User} message {Message} other {}} No Longer Available","mentionsErrorMessage":"The {mentionsType} you are trying to view has been removed from the community.","videoProcessing":"Video is being processed. Please try again in a few minutes.","bannerTitle":"Video provider requires cookies to play the video. Accept to continue or {url} it directly on the provider's site.","buttonTitle":"Accept","urlText":"watch"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageCustomFields-1743151753131":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageCustomFields-1743151753131","value":{"CustomField.default.label":"Value of {name}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageRevision-1743151753131":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageRevision-1743151753131","value":{"lastUpdatedDatePublished":"{publishCount, plural, one{Published} other{Updated}} {date}","lastUpdatedDateDraft":"Created {date}","version":"Version {major}.{minor}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageReplyButton-1743151753131":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageReplyButton-1743151753131","value":{"repliesCount":"{count}","title":"Reply","title@board:BLOG@message:root":"Comment","title@board:TKB@message:root":"Comment","title@board:IDEA@message:root":"Comment","title@board:OCCASION@message:root":"Comment"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageAuthorBio-1743151753131":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageAuthorBio-1743151753131","value":{"sendMessage":"Send Message","actionMessage":"Follow this blog board to get notified when there's new activity","coAuthor":"CO-PUBLISHER","contributor":"CONTRIBUTOR","userProfile":"View Profile","iconlink":"Go to {name} {type}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/users/UserAvatar-1743151753131":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/users/UserAvatar-1743151753131","value":{"altText":"{login}'s avatar","altTextGeneric":"User's avatar"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/ranks/UserRankLabel-1743151753131":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/ranks/UserRankLabel-1743151753131","value":{"altTitle":"Icon for {rankName} rank"},"localOverride":false},"CachedAsset:text:en_US-components/users/UserRegistrationDate-1743151753131":{"__typename":"CachedAsset","id":"text:en_US-components/users/UserRegistrationDate-1743151753131","value":{"noPrefix":"{date}","withPrefix":"Joined {date}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/nodes/NodeAvatar-1743151753131":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/nodes/NodeAvatar-1743151753131","value":{"altTitle":"Node avatar for {nodeTitle}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/nodes/NodeDescription-1743151753131":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/nodes/NodeDescription-1743151753131","value":{"description":"{description}"},"localOverride":false},"CachedAsset:text:en_US-components/tags/TagView/TagViewChip-1743151753131":{"__typename":"CachedAsset","id":"text:en_US-components/tags/TagView/TagViewChip-1743151753131","value":{"tagLabelName":"Tag name {tagName}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/nodes/NodeIcon-1743151753131":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/nodes/NodeIcon-1743151753131","value":{"contentType":"Content Type {style, select, FORUM {Forum} BLOG {Blog} TKB {Knowledge Base} IDEA {Ideas} OCCASION {Events} other {}} icon"},"localOverride":false}}}},"page":"/blogs/BlogMessagePage/BlogMessagePage","query":{"boardId":"azurearchitectureblog","messageSubject":"high-performance-storage-for-ai-model-training-tasks-using-azure-ml-studio-with-","messageId":"3609189"},"buildId":"HEhyUrv5OXNBIbfCLaOrw","runtimeConfig":{"buildInformationVisible":false,"logLevelApp":"info","logLevelMetrics":"info","openTelemetryClientEnabled":false,"openTelemetryConfigName":"o365","openTelemetryServiceVersion":"25.1.0","openTelemetryUniverse":"prod","openTelemetryCollector":"http://localhost:4318","openTelemetryRouteChangeAllowedTime":"5000","apolloDevToolsEnabled":false,"inboxMuteWipFeatureEnabled":false},"isFallback":false,"isExperimentalCompile":false,"dynamicIds":["./components/community/Navbar/NavbarWidget.tsx","./components/community/Breadcrumb/BreadcrumbWidget.tsx","./components/customComponent/CustomComponent/CustomComponent.tsx","./components/blogs/BlogArticleWidget/BlogArticleWidget.tsx","./components/external/components/ExternalComponent.tsx","./components/messages/MessageView/MessageViewStandard/MessageViewStandard.tsx","./components/messages/ThreadedReplyList/ThreadedReplyList.tsx","../shared/client/components/common/List/UnwrappedList/UnwrappedList.tsx","./components/tags/TagView/TagView.tsx","./components/tags/TagView/TagViewChip/TagViewChip.tsx"],"appGip":true,"scriptLoader":[{"id":"analytics","src":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/pagescripts/1730819800000/analytics.js?page.id=BlogMessagePage&entity.id=board%3Aazurearchitectureblog&entity.id=message%3A3609189","strategy":"afterInteractive"}]}