Tutorial 6: Isolamento de rede com o repositório de recursos

Um repositório de recursos gerenciados do Azure Machine Learning lhe permite descobrir, criar e operacionalizar recursos. Os recursos servem como o tecido conectivo no ciclo de vida de machine learning, começando com a fase de criação de protótipos, na qual você experimenta vários recursos. Esse ciclo de vida continua na fase de operacionalização, na qual você implanta seus modelos e as etapas de inferência pesquisam os dados do recurso. Para obter mais informações sobre repositórios de recursos, leia o documento conceitos sobre o repositório de recursos.

Este tutorial descreve como configurar a entrada segura por meio de um ponto de extremidade privado e proteger a saída por meio de uma rede virtual gerenciada.

A Parte 1 dessa série de tutoriais mostrou como criar uma especificação de conjunto de recursos com transformações personalizadas e usar esse conjunto de recursos para gerar dados de treinamento. A parte 2 da série mostrou como habilitar a materialização e executar um provisionamento. Além disso, a Parte 2 mostrou como experimentar recursos como forma de melhorar o desempenho do modelo. A Parte 3 mostrou também como um repositório de recursos aumenta a agilidade nos fluxos de experimentação e treinamento. A Parte 3 também descreveu como executar a inferência em lote. O Tutorial 4 explicou como usar o repositório de recursos para casos de uso de inferência online/em tempo real. O Tutorial 5 demonstrou como desenvolver um conjunto de recursos com uma fonte de dados personalizada. O Tutorial 6 mostra como

  • Configurar os recursos necessários para o isolamento de rede de um repositório de recursos gerenciados.
  • Criar um recurso do repositório de recursos.
  • Configurar seu repositório de recursos para dar suporte a cenários de isolamento de rede.
  • Atualizar o workspace do projeto (workspace atual) para dar suporte a cenários de isolamento de rede.

Pré-requisitos

Observação

Esse tutorial usa um notebook do Azure Machine Learning com Computação do Spark Sem Servidor.

  • Um workspace do Azure Machine Learning, habilitado com rede virtual gerenciada para trabalhos do Spark sem servidor

  • Para configurar o workspace do projeto:

    1. Crie um arquivo YAML chamado network.yml:

      managed_network:
      isolation_mode: allow_internet_outbound
      
    2. Execute estes comandos para atualizar o workspace e provisionar a rede virtual gerenciada para trabalhos do Spark sem servidor:

      az ml workspace update --file network.yml --resource-group my_resource_group --name
      my_workspace_name
      az ml workspace provision-network --resource-group my_resource_group --name my_workspace_name
      --include-spark
      

    Para obter mais informações, visite Configurar para um trabalho do Spark sem servidor.

  • Sua conta de usuário precisa ter a função Owner ou Contributor atribuída ao grupo de recursos em que você cria o repositório de recursos. Sua conta de usuário também precisa da função User Access Administrator.

Importante

No workspace do Azure Machine Learning, defina o isolation_mode como allow_internet_outbound. Esse é o único modo de isolamento de rede com suporte. Este tutorial mostrará como se conectar a fontes, armazenamento de materialização e dados de observação com segurança por meio de pontos de extremidade privados.

Configuração

Este tutorial usa o SDK principal do repositório de recursos do Python (azureml-featurestore). O SDK do Python é usado apenas para desenvolvimento e teste de conjunto de recursos. A CLI é usada para operações CRUD (criação, leitura, atualização e exclusão), em repositórios de recursos, conjuntos de recursos e entidades do repositório de recursos. Isso é útil em cenários de CI/CD (integração contínua e entrega contínua) ou GitOps, em que a CLI/o YAML é preferencial.

Você não precisa instalar explicitamente esses recursos para este tutorial, pois nas instruções de configuração mostradas aqui, o arquivo conda.yaml os abrange.

Para preparar o ambiente do notebook para desenvolvimento:

  1. Clone o repositório azureml-examples nos recursos locais do seu GitHub com o seguinte comando:

    git clone --depth 1 https://github.com/Azure/azureml-examples

    Você também pode baixar um arquivo zip do repositório azureml-examples. Nesta página, primeiro selecione a lista suspensa code e depois Download ZIP. Em seguida, descompacte o conteúdo em uma pasta no seu dispositivo local.

  2. Carregar o diretório de amostras do repositório de recursos no workspace do projeto

    1. No workspace do Azure Machine Learning, abra a interface do usuário do Estúdio do Azure Machine Learning
    2. Selecione Notebooks no painel de navegação esquerdo
    3. Selecione seu nome de usuário na listagem de diretórios
    4. Selecione reticências (...) e selecione Carregar pasta
    5. Selecione a pasta de exemplos do repositório de recursos no caminho do diretório clonado: azureml-examples/sdk/python/featurestore-sample
  3. Executar o tutorial

    • Opção 1: criar um novo notebook e executar as instruções neste documento, passo a passo

    • Opção 2: Abrir o notebook existente featurestore_sample/notebooks/sdk_and_cli/network_isolation/Network-isolation-feature-store.ipynb. Você pode manter este documento aberto e fazer referência a ele para obter mais explicações e links de documentação

      1. Selecione Computação do Spark Sem Servidor na lista suspensa Computação do painel de navegação superior. Essa operação poderá demorar um ou dois minutos. Aguarde uma barra de status na parte superior para exibir Configurar sessão
      2. Selecione Configurar sessão na barra de status superior
      3. Selecione pacotes do Python
      4. Selecione Carregar arquivo conda
      5. Selecione o arquivo azureml-examples/sdk/python/featurestore-sample/project/env/conda.yml localizado no seu dispositivo local
      6. (Opcional) Aumente o tempo limite da sessão (tempo ocioso em minutos) para reduzir o tempo de inicialização do cluster do Spark sem servidor
  4. Essa célula de código inicia a sessão do Spark. São necessários cerca de dez minutos para instalar todas as dependências e iniciar a sessão do Spark.

    # Run this cell to start the spark session (any code block will start the session ). This can take around 10 mins.
    print("start spark session")
  5. Configurar o diretório raiz para os exemplos

    import os
    
    # Please update your alias below (or any custom directory you have uploaded the samples to).
    # You can find the name from the directory structure in the left navigation.
    root_dir = "./Users/<your_user_alias>/featurestore_sample"
    
    if os.path.isdir(root_dir):
        print("The folder exists.")
    else:
        print("The folder does not exist. Please create or fix the path")
  6. Configure a CLI do Azure Machine Learning:

    • Instale a extensão da CLI do Azure Machine Learning

      # install azure ml cli extension
      !az extension add --name ml
    • Authenticate

      # authenticate
      !az login
    • Definir a assinatura padrão

      # Set default subscription
      import os
      
      subscription_id = os.environ["AZUREML_ARM_SUBSCRIPTION"]
      
      !az account set -s $subscription_id

    Observação

    Um workspace do repositório de recursos dá suporte à reutilização de recursos entre projetos. Um workspace do projeto — o workspace atual em uso — aproveita os recursos de um repositório de recursos específico para treinamento e inferência de modelos. Vários workspaces do projeto podem compartilhar e reutilizar um workspace do repositório de recursos.

Provisionar os recursos necessários

Você pode criar uma conta de armazenamento e contêineres do ADLS (Azure Data Lake Storage) Gen2 ou reutilizar uma conta de armazenamento e os recursos de contêiner existentes para o repositório de recursos. Em uma situação real, diferentes contas de armazenamento podem hospedar os contêineres do ADLS Gen2. Ambas as opções funcionam, dependendo dos seus requisitos específicos.

Para este tutorial, você criará três contêineres de armazenamento separados na mesma conta de armazenamento do ADLS Gen2:

  • Dados de origem
  • Repositório offline
  • Dados de observação
  1. Crie uma conta de armazenamento do ADLS Gen2 para os dados de origem, o repositório offline e os dados de observação.

    1. Forneça o nome de uma conta de armazenamento do Azure Data Lake Storage Gen2 no exemplo de código a seguir. Você pode executar a célula de código a seguir com as configurações padrão fornecidas. Opcionalmente, substitua as configurações padrão.

      ## Default Setting
      # We use the subscription, resource group, region of this active project workspace,
      # We hard-coded default resource names for creating new resources
      
      ## Overwrite
      # You can replace them if you want to create the resources in a different subsciprtion/resourceGroup, or use existing resources
      # At the minimum, provide an ADLS Gen2 storage account name for `storage_account_name`
      
      storage_subscription_id = os.environ["AZUREML_ARM_SUBSCRIPTION"]
      storage_resource_group_name = os.environ["AZUREML_ARM_RESOURCEGROUP"]
      storage_account_name = "<STORAGE_ACCOUNT_NAME>"
      
      storage_location = "eastus"
      storage_file_system_name_offline_store = "offline-store"
      storage_file_system_name_source_data = "source-data"
      storage_file_system_name_observation_data = "observation-data"
    2. Esta célula de código cria a conta de armazenamento do ADLS Gen2 definida na célula de código acima.

      # Create new storage account
      !az storage account create --name $storage_account_name --enable-hierarchical-namespace true --resource-group $storage_resource_group_name --location $storage_location --subscription $storage_subscription_id
    3. Esta célula de código cria um contêiner de armazenamento para o repositório offline.

      # Create a new storage container for offline store
      !az storage fs create --name $storage_file_system_name_offline_store --account-name $storage_account_name --subscription $storage_subscription_id
    4. Esta célula de código cria um contêiner de armazenamento para os dados de origem.

      # Create a new storage container for source data
      !az storage fs create --name $storage_file_system_name_source_data --account-name $storage_account_name --subscription $storage_subscription_id
    5. Esta célula de código cria um contêiner de armazenamento para os dados de observação.

      # Create a new storage container for observation data
      !az storage fs create --name $storage_file_system_name_observation_data --account-name $storage_account_name --subscription $storage_subscription_id
  2. Copie os dados de exemplo necessários nesta série de tutoriais para os contêineres de armazenamento recém-criados.

    1. Para gravar dados nos contêineres de armazenamento, verifique se as funções Colaborador e Colaborador de Dados do Blob de Armazenamento foram atribuídas à identidade do usuário na conta de armazenamento do ADLS Gen2 criada no portal do Azure seguindo estas etapas.

      Importante

      Depois de garantir que as funções Colaborador e Colaborador de Dados de Blob de Armazenamento sejam atribuídas à identidade do usuário, aguarde alguns minutos após a atribuição de função para permitir que as permissões se propaguem antes de prosseguir com as próximas etapas. Para saber mais sobre o controle de acesso, visite RBAC (controle de acesso baseado em função) para contas de armazenamento do Azure

      As próximas células de código copiam dados de origem de exemplo para o conjunto de recursos de transações usado neste tutorial de uma conta de armazenamento pública para a conta de armazenamento recém-criada.

      # Copy sample source data for transactions feature set used in this tutorial series from the public storage account to the newly created storage account
      transactions_source_data_path = "wasbs://data@azuremlexampledata.blob.core.windows.net/feature-store-prp/datasources/transactions-source/*.parquet"
      transactions_src_df = spark.read.parquet(transactions_source_data_path)
      
      transactions_src_df.write.parquet(
          f"abfss://{storage_file_system_name_source_data}@{storage_account_name}.dfs.core.windows.net/transactions-source/"
      )
    2. Para o conjunto de recursos de conta usado neste tutorial, copie os dados de origem de exemplo para o recurso de conta definido para a conta de armazenamento recém-criada.

      # Copy sample source data for account feature set used in this tutorial series from the public storage account to the newly created storage account
      accounts_data_path = "wasbs://data@azuremlexampledata.blob.core.windows.net/feature-store-prp/datasources/accounts-precalculated/*.parquet"
      accounts_data_df = spark.read.parquet(accounts_data_path)
      
      accounts_data_df.write.parquet(
          f"abfss://{storage_file_system_name_source_data}@{storage_account_name}.dfs.core.windows.net/accounts-precalculated/"
      )
    3. Copie os dados de observação de exemplo usados para treinamento de uma conta de armazenamento pública para a conta de armazenamento recém-criada.

      # Copy sample observation data used for training from the public storage account to the newly created storage account
      observation_data_train_path = "wasbs://data@azuremlexampledata.blob.core.windows.net/feature-store-prp/observation_data/train/*.parquet"
      observation_data_train_df = spark.read.parquet(observation_data_train_path)
      
      observation_data_train_df.write.parquet(
          f"abfss://{storage_file_system_name_observation_data}@{storage_account_name}.dfs.core.windows.net/train/"
      )
    4. Copie os dados de observação de exemplo usados para inferência em lote de uma conta de armazenamento pública para a conta de armazenamento recém-criada.

      # Copy sample observation data used for batch inference from a public storage account to the newly created storage account
      observation_data_inference_path = "wasbs://data@azuremlexampledata.blob.core.windows.net/feature-store-prp/observation_data/batch_inference/*.parquet"
      observation_data_inference_df = spark.read.parquet(observation_data_inference_path)
      
      observation_data_inference_df.write.parquet(
          f"abfss://{storage_file_system_name_observation_data}@{storage_account_name}.dfs.core.windows.net/batch_inference/"
      )
  3. Desabilite o acesso à rede pública na conta de armazenamento recém-criada.

    1. Esta célula de código desabilita o acesso à rede pública na conta de armazenamento do ADLS Gen2 criada anteriormente.

      # Disable the public network access for the above created ADLS Gen2 storage account
      !az storage account update --name $storage_account_name --resource-group $storage_resource_group_name --subscription $storage_subscription_id --public-network-access disabled
    2. Defina as IDs do ARM para o repositório offline, os dados de origem e os contêineres de dados de observação.

      # set the container arm id
      offline_store_gen2_container_arm_id = "/subscriptions/{sub_id}/resourceGroups/{rg}/providers/Microsoft.Storage/storageAccounts/{account}/blobServices/default/containers/{container}".format(
          sub_id=storage_subscription_id,
          rg=storage_resource_group_name,
          account=storage_account_name,
          container=storage_file_system_name_offline_store,
      )
      
      print(offline_store_gen2_container_arm_id)
      
      source_data_gen2_container_arm_id = "/subscriptions/{sub_id}/resourceGroups/{rg}/providers/Microsoft.Storage/storageAccounts/{account}/blobServices/default/containers/{container}".format(
          sub_id=storage_subscription_id,
          rg=storage_resource_group_name,
          account=storage_account_name,
          container=storage_file_system_name_source_data,
      )
      
      print(source_data_gen2_container_arm_id)
      
      observation_data_gen2_container_arm_id = "/subscriptions/{sub_id}/resourceGroups/{rg}/providers/Microsoft.Storage/storageAccounts/{account}/blobServices/default/containers/{container}".format(
          sub_id=storage_subscription_id,
          rg=storage_resource_group_name,
          account=storage_account_name,
          container=storage_file_system_name_observation_data,
      )
      
      print(observation_data_gen2_container_arm_id)

Criar um repositório de recursos com a materialização habilitada

Definir os parâmetros do repositório de recursos

Defina o nome do repositório de recursos, o local, a ID da assinatura, o nome do grupo e os valores da ID do ARM, conforme mostrado nesta amostra de célula de código:

# We use the subscription, resource group, region of this active project workspace.
# Optionally, you can replace them to create the resources in a different subsciprtion/resourceGroup, or use existing resources
import os

# At the minimum, define a name for the feature store
featurestore_name = "<FEATURESTORE_NAME>"
# It is recommended to create featurestore in the same location as the storage
featurestore_location = storage_location
featurestore_subscription_id = os.environ["AZUREML_ARM_SUBSCRIPTION"]
featurestore_resource_group_name = os.environ["AZUREML_ARM_RESOURCEGROUP"]

feature_store_arm_id = "/subscriptions/{sub_id}/resourceGroups/{rg}/providers/Microsoft.MachineLearningServices/workspaces/{ws_name}".format(
    sub_id=featurestore_subscription_id,
    rg=featurestore_resource_group_name,
    ws_name=featurestore_name,
)

Essa célula de código gera um arquivo de especificação YAML para um repositório de recursos, com a materialização habilitada.

# The below code creates a feature store with enabled materialization
import yaml

config = {
    "$schema": "http://azureml/sdk-2-0/FeatureStore.json",
    "name": featurestore_name,
    "location": featurestore_location,
    "compute_runtime": {"spark_runtime_version": "3.3"},
    "offline_store": {
        "type": "azure_data_lake_gen2",
        "target": offline_store_gen2_container_arm_id,
    },
}

feature_store_yaml = root_dir + "/featurestore/featurestore_with_offline_setting.yaml"

with open(feature_store_yaml, "w") as outfile:
    yaml.dump(config, outfile, default_flow_style=False)

Criar o repositório de recursos

Essa célula de código usa o arquivo de especificação YAML gerado na etapa anterior para criar um repositório de recursos com a materialização habilitada.

!az ml feature-store create --file $feature_store_yaml --subscription $featurestore_subscription_id --resource-group $featurestore_resource_group_name

Inicializar o cliente SDK principal do repositório de recursos do Azure Machine Learning

O cliente SDK inicializado nesta célula facilita o desenvolvimento e o consumo de recursos:

# feature store client
from azureml.featurestore import FeatureStoreClient
from azure.ai.ml.identity import AzureMLOnBehalfOfCredential

featurestore = FeatureStoreClient(
    credential=AzureMLOnBehalfOfCredential(),
    subscription_id=featurestore_subscription_id,
    resource_group_name=featurestore_resource_group_name,
    name=featurestore_name,
)

Atribuir funções à identidade do usuário no repositório de recursos

Siga estas instruções para obter a ID do Objeto do Microsoft Entra para sua identidade de usuário. Em seguida, use a ID de Objeto do Microsoft Entra no próximo comando para atribuir a função Cientista de Dados do AzureML à sua identidade de usuário no repositório de recursos criado.

your_aad_objectid = "<YOUR_AAD_OBJECT_ID>"

!az role assignment create --role "AzureML Data Scientist" --assignee-object-id $your_aad_objectid --assignee-principal-type User --scope $feature_store_arm_id

Obtenha a conta de armazenamento padrão e o cofre de chaves para o repositório de recursos e desabilite o acesso à rede pública aos recursos correspondentes

A próxima célula de código retorna o objeto do repositório de recursos para as etapas a seguir.

fs = featurestore.feature_stores.get()

Essa célula de código retorna os nomes da conta de armazenamento padrão e do cofre de chaves do repositório de recursos.

# Copy the properties storage_account and key_vault from the response returned in feature store show command respectively
default_fs_storage_account_name = fs.storage_account.rsplit("/", 1)[-1]
default_key_vault_name = fs.key_vault.rsplit("/", 1)[-1]

Esta célula de código desabilita o acesso à rede pública na conta de armazenamento padrão para o repositório de recursos.

# Disable the public network access for the above created default ADLS Gen2 storage account for the feature store
!az storage account update --name $default_fs_storage_account_name --resource-group $featurestore_resource_group_name --subscription $featurestore_subscription_id --public-network-access disabled

A próxima célula imprime o nome do cofre de chaves padrão para o repositório de recursos.

print(default_key_vault_name)

Desabilitar o acesso à rede pública no cofre de chaves padrão do repositório de recursos criado anteriormente

  • No portal do Azure, abra o cofre de chaves padrão que você criou na célula anterior.
  • Selecione a guia Rede.
  • Selecione Desabilitar acesso público e Aplicar no canto inferior esquerdo da página.

Habilitar a rede virtual gerenciada para o workspace do repositório de recursos

Atualizar o repositório de recursos com as regras de saída necessárias

A próxima célula de código cria um arquivo de especificação YAML para as regras de saída definidas para o repositório de recursos.

# The below code creates a configuration for managed virtual network for the feature store
import yaml

config = {
    "public_network_access": "disabled",
    "managed_network": {
        "isolation_mode": "allow_internet_outbound",
        "outbound_rules": [
            # You need to add multiple rules here if you have separate storage account for source, observation data and offline store.
            {
                "name": "sourcerulefs",
                "destination": {
                    "spark_enabled": "true",
                    "subresource_target": "dfs",
                    "service_resource_id": f"/subscriptions/{storage_subscription_id}/resourcegroups/{storage_resource_group_name}/providers/Microsoft.Storage/storageAccounts/{storage_account_name}",
                },
                "type": "private_endpoint",
            },
            # This rule is added currently because serverless Spark doesn't automatically create a private endpoint to default key vault.
            {
                "name": "defaultkeyvault",
                "destination": {
                    "spark_enabled": "true",
                    "subresource_target": "vault",
                    "service_resource_id": f"/subscriptions/{featurestore_subscription_id}/resourcegroups/{featurestore_resource_group_name}/providers/Microsoft.Keyvault/vaults/{default_key_vault_name}",
                },
                "type": "private_endpoint",
            },
        ],
    },
}

feature_store_managed_vnet_yaml = (
    root_dir + "/featurestore/feature_store_managed_vnet_config.yaml"
)

with open(feature_store_managed_vnet_yaml, "w") as outfile:
    yaml.dump(config, outfile, default_flow_style=False)

Essa célula de código usa o arquivo de especificação YAML gerado para atualizar o repositório de recursos.

!az ml feature-store update --file $feature_store_managed_vnet_yaml --name $featurestore_name --resource-group $featurestore_resource_group_name

Criar pontos de extremidade privados para as regras de saída definidas

Um comando provision-network cria pontos de extremidade privados da rede virtual gerenciada, em que o trabalho de materialização é executado para a origem, o repositório offline, os dados de observação, a conta de armazenamento padrão e o cofre de chaves padrão para o repositório de recursos. Esse comando pode precisar de cerca de 20 minutos para ser concluído.

#### Provision network to create necessary private endpoints (it may take approximately 20 minutes)
!az ml feature-store provision-network --name $featurestore_name --resource-group $featurestore_resource_group_name --include-spark

Essa célula de código confirma a criação de pontos de extremidade privados definidos pelas regras de saída.

### Check that managed virtual network is correctly enabled
### After provisioning the network, all the outbound rules should become active
### For this tutorial, you will see 6 outbound rules
!az ml feature-store show --name $featurestore_name --resource-group $featurestore_resource_group_name

Atualizar a rede virtual gerenciada para o workspace do projeto

Em seguida, atualize a rede virtual gerenciada para o workspace do projeto. Primeiro, obtenha a ID da assinatura, o grupo de recursos e o nome do workspace para o workspace do projeto.

# lookup the subscription id, resource group and workspace name of the current workspace
project_ws_sub_id = os.environ["AZUREML_ARM_SUBSCRIPTION"]
project_ws_rg = os.environ["AZUREML_ARM_RESOURCEGROUP"]
project_ws_name = os.environ["AZUREML_ARM_WORKSPACE_NAME"]

Atualizar o workspace do projeto com as regras de saída necessárias

O workspace do projeto precisa ter acesso a estes recursos:

  • Dados de origem
  • Repositório offline
  • Dados de observação
  • Repositório de recursos
  • Conta de armazenamento padrão do repositório de recursos

Esta célula de código atualiza o workspace do projeto usando o arquivo de especificação YAML gerado com as regras de saída necessárias.

# The below code creates a configuration for managed virtual network for the project workspace
import yaml

config = {
    "managed_network": {
        "isolation_mode": "allow_internet_outbound",
        "outbound_rules": [
            # Incase you have separate storage accounts for source, observation data and offline store, you need to add multiple rules here. No action needed otherwise.
            {
                "name": "projectsourcerule",
                "destination": {
                    "spark_enabled": "true",
                    "subresource_target": "dfs",
                    "service_resource_id": f"/subscriptions/{storage_subscription_id}/resourcegroups/{storage_resource_group_name}/providers/Microsoft.Storage/storageAccounts/{storage_account_name}",
                },
                "type": "private_endpoint",
            },
            # Rule to create private endpoint to default storage of feature store
            {
                "name": "defaultfsstoragerule",
                "destination": {
                    "spark_enabled": "true",
                    "subresource_target": "blob",
                    "service_resource_id": f"/subscriptions/{featurestore_subscription_id}/resourcegroups/{featurestore_resource_group_name}/providers/Microsoft.Storage/storageAccounts/{default_fs_storage_account_name}",
                },
                "type": "private_endpoint",
            },
            # Rule to create private endpoint to default key vault of feature store
            {
                "name": "defaultfskeyvaultrule",
                "destination": {
                    "spark_enabled": "true",
                    "subresource_target": "vault",
                    "service_resource_id": f"/subscriptions/{featurestore_subscription_id}/resourcegroups/{featurestore_resource_group_name}/providers/Microsoft.Keyvault/vaults/{default_key_vault_name}",
                },
                "type": "private_endpoint",
            },
            # Rule to create private endpoint to feature store
            {
                "name": "featurestorerule",
                "destination": {
                    "spark_enabled": "true",
                    "subresource_target": "amlworkspace",
                    "service_resource_id": f"/subscriptions/{featurestore_subscription_id}/resourcegroups/{featurestore_resource_group_name}/providers/Microsoft.MachineLearningServices/workspaces/{featurestore_name}",
                },
                "type": "private_endpoint",
            },
        ],
    }
}

project_ws_managed_vnet_yaml = (
    root_dir + "/featurestore/project_ws_managed_vnet_config.yaml"
)

with open(project_ws_managed_vnet_yaml, "w") as outfile:
    yaml.dump(config, outfile, default_flow_style=False)

Esta célula de código atualiza o workspace do projeto usando o arquivo de especificação YAML gerado com as regras de saída.

#### Update project workspace to create private endpoints for the defined outbound rules (it may take approximately 15 minutes)
!az ml workspace update --file $project_ws_managed_vnet_yaml --name $project_ws_name --resource-group $project_ws_rg

Essa célula de código confirma a criação de pontos de extremidade privados definidos pelas regras de saída.

!az ml workspace show --name $project_ws_name --resource-group $project_ws_rg

Você também pode verificar as regras de saída do portal do Azure. Navegue até Rede do painel de navegação esquerdo para o workspace do projeto e abra a guia Acesso de saída gerenciado do Workspace.

Esta captura de tela mostra as regras de saída de um workspace do projeto no portal do Azure.

Criar um protótipo e desenvolver um conjunto de recursos de agregação de transações sem interrupção

Explorar os dados de origem das transações

Observação

Um contêiner de blob acessível publicamente hospeda os dados de exemplo usados neste tutorial. Ele só pode ser lido no Spark por meio do driver wasbs. Ao criar conjuntos de recursos usando seus dados de origem, hospede-os em uma conta do ADLS Gen2 e use um driver abfss no caminho de dados.

# remove the "." in the root directory path as we need to generate absolute path to read from Spark
transactions_source_data_path = f"abfss://{storage_file_system_name_source_data}@{storage_account_name}.dfs.core.windows.net/transactions-source/*.parquet"
transactions_src_df = spark.read.parquet(transactions_source_data_path)

display(transactions_src_df.head(5))
# Note: display(training_df.head(5)) displays the timestamp column in a different format. You can can call transactions_src_df.show() to see correctly formatted value

Desenvolver um conjunto de recursos de transações localmente

Uma especificação de conjunto de recursos é uma definição de conjunto de recursos autônoma que pode ser desenvolvida e testada localmente.

Crie os seguintes recursos de agregação de janela sem interrupção:

  • contagem de três dias de transações
  • soma de três dias do valor de transações
  • média de três dias do valor de transações
  • contagem de sete dias de transações
  • soma de sete dias do valor de transações
  • média de sete dias do valor de transações

Inspecione o arquivo do código de transformação de recursos featurestore/featuresets/transactions/spec/transformation_code/transaction_transform.py. Esse transformador do Spark executa a agregação sem interrupção definida para os recursos.

Para obter mais informações sobre o conjunto de recursos e transformações com mais detalhes, visite conceitos do repositório de recursos.

from azureml.featurestore import create_feature_set_spec, FeatureSetSpec
from azureml.featurestore.contracts import (
    DateTimeOffset,
    FeatureSource,
    TransformationCode,
    Column,
    ColumnType,
    SourceType,
    TimestampColumn,
)


transactions_featureset_code_path = (
    root_dir + "/featurestore/featuresets/transactions/transformation_code"
)

transactions_featureset_spec = create_feature_set_spec(
    source=FeatureSource(
        type=SourceType.parquet,
        path=f"abfss://{storage_file_system_name_source_data}@{storage_account_name}.dfs.core.windows.net/transactions-source/*.parquet",
        timestamp_column=TimestampColumn(name="timestamp"),
        source_delay=DateTimeOffset(days=0, hours=0, minutes=20),
    ),
    transformation_code=TransformationCode(
        path=transactions_featureset_code_path,
        transformer_class="transaction_transform.TransactionFeatureTransformer",
    ),
    index_columns=[Column(name="accountID", type=ColumnType.string)],
    source_lookback=DateTimeOffset(days=7, hours=0, minutes=0),
    temporal_join_lookback=DateTimeOffset(days=1, hours=0, minutes=0),
    infer_schema=True,
)
# Generate a spark dataframe from the feature set specification
transactions_fset_df = transactions_featureset_spec.to_spark_dataframe()
# display few records
display(transactions_fset_df.head(5))

Exportar uma especificação do conjunto de recursos

Para registrar a especificação do conjunto de recursos no repositório de recursos, essa especificação precisa ser salva em um formato específico.

Para inspecionar a especificação do conjunto de recursos de transações geradas, abra este arquivo na árvore de arquivos para exibir a especificação:

featurestore/featuresets/accounts/spec/FeaturesetSpec.yaml

A especificação contém estes elementos:

  • source: uma referência a um recurso de armazenamento, nesse caso, um arquivo Parquet em um recurso de armazenamento de blobs
  • features: uma lista de recursos e seus tipos de dados. Se você fornecer um código de transformação
  • index_columns: as chaves de junção necessárias para acessar valores do conjunto de recursos

Como outro benefício de persistir uma especificação de conjunto de recursos como um arquivo YAML, a especificação pode ter controle de versão. Saiba mais sobre a especificação do conjunto de recursos no documento de entidades do repositório de recursos de nível superior e na referência de YAML da especificação do conjunto de recursos.

import os

# create a new folder to dump the feature set specification
transactions_featureset_spec_folder = (
    root_dir + "/featurestore/featuresets/transactions/spec"
)

# check if the folder exists, create one if not
if not os.path.exists(transactions_featureset_spec_folder):
    os.makedirs(transactions_featureset_spec_folder)

transactions_featureset_spec.dump(transactions_featureset_spec_folder, overwrite=True)

Registrar uma entidade de repositório de recursos

As entidades ajudam a impor o uso das mesmas definições de chave de junção entre conjuntos de recursos que usam as mesmas entidades lógicas. Entre os exemplos de entidades podem estar entidades de conta, entidades de cliente etc. Normalmente, as entidades são criadas uma vez e, depois, reutilizadas entre os conjuntos de recursos. Para obter mais informações, visite o documento de entidades do repositório de recursos de nível superior.

Esta célula de código cria uma entidade de conta para o repositório de recursos.

account_entity_path = root_dir + "/featurestore/entities/account.yaml"
!az ml feature-store-entity create --file $account_entity_path --resource-group $featurestore_resource_group_name --workspace-name $featurestore_name

Registrar o conjunto de recursos de transações no repositório de recursos e enviar um trabalho de materialização

Para compartilhar e reutilizar um ativo do conjunto de recursos, primeiro, você precisa registrar o ativo no repositório de recursos. O registro de ativos do conjunto de recursos oferece funcionalidades gerenciadas, incluindo controle de versão e materialização. Esta série de tutoriais aborda esses tópicos.

O ativo do conjunto de recursos faz referência à especificação do conjunto de recursos que você criou anteriormente e a outras propriedades, por exemplo, configurações de versão e materialização.

Criar um conjunto de recursos

A próxima célula de código usa um arquivo de especificação YAML predefinido para criar um conjunto de recursos.

transactions_featureset_path = (
    root_dir
    + "/featurestore/featuresets/transactions/featureset_asset_offline_enabled.yaml"
)
!az ml feature-set create --file $transactions_featureset_path --resource-group $featurestore_resource_group_name --workspace-name $featurestore_name

Esta célula de código mostra uma pré-visualização do conjunto de recursos recém-criado.

# Preview the newly created feature set

!az ml feature-set show --resource-group $featurestore_resource_group_name --workspace-name $featurestore_name -n transactions -v 1

Enviar um trabalho de materialização de provisionamento

A próxima célula de código define os valores de hora de início e de término para a janela de materialização do recurso e envia um trabalho de materialização de arquivo de fundo.

feature_window_start_time = "2023-02-01T00:00.000Z"
feature_window_end_time = "2023-03-01T00:00.000Z"

!az ml feature-set backfill --name transactions --version 1 --by-data-status "['None']" --workspace-name $featurestore_name --resource-group $featurestore_resource_group_name --feature-window-start-time $feature_window_start_time --feature-window-end-time $feature_window_end_time

Essa célula de código fornece <JOB_ID_FROM_PREVIOUS_COMMAND> para verificar o status do trabalho de materialização de provisionamento.

### Check the job status

!az ml job show --name <JOB_ID_FROM_PREVIOUS_COMMAND> -g $featurestore_resource_group_name -w $featurestore_name

Essa célula de código lista todos os trabalhos de materialização para o conjunto de recursos atual.

### List all the materialization jobs for the current feature set

!az ml feature-set list-materialization-operation --name transactions --version 1 -g $featurestore_resource_group_name -w $featurestore_name

Anexar o Cache do Azure para Redis como uma loja online

Criar um Cache do Azure para Redis

Na próxima célula de código, defina o nome do Cache do Azure para Redis que você deseja criar ou reutilizar. Opcionalmente, você pode substituir outras configurações padrão.

redis_subscription_id = os.environ["AZUREML_ARM_SUBSCRIPTION"]
redis_resource_group_name = os.environ["AZUREML_ARM_RESOURCEGROUP"]
redis_name = "my-redis"
redis_location = storage_location

Você pode selecionar a camada de cache Redis (básica, padrão ou premium). Você deve escolher uma família de SKU que esteja disponível para a camada de cache selecionada. Visite este recurso de documentação para obter mais informações sobre como a seleção de diferentes camadas pode afetar o desempenho do cache. Visite este recurso de documentação para obter mais informações sobre preços para diferentes camadas de SKU e famílias do Cache do Azure para Redis.

Execute a célula de código a seguir para criar um Cache do Azure para Redis com camada premium, família de SKU P e capacidade de cache 2. Pode levar aproximadamente de 5 a 10 minutos para provisionar a instância do Redis.

# Create new redis cache
from azure.mgmt.redis import RedisManagementClient
from azure.mgmt.redis.models import RedisCreateParameters, Sku, SkuFamily, SkuName

management_client = RedisManagementClient(
    AzureMLOnBehalfOfCredential(), redis_subscription_id
)

# It usually takes about 5 - 10 min to finish the provision of the Redis instance.
# If the following begin_create() call still hangs for longer than that,
# please check the status of the Redis instance on the Azure portal and cancel the cell if the provision has completed.
# This sample uses a PREMIUM tier Redis SKU from family P, which may cost more than a STANDARD tier SKU from family C.
# Please choose the SKU tier and family according to your performance and pricing requirements.

redis_arm_id = (
    management_client.redis.begin_create(
        resource_group_name=redis_resource_group_name,
        name=redis_name,
        parameters=RedisCreateParameters(
            location=redis_location,
            sku=Sku(name=SkuName.PREMIUM, family=SkuFamily.P, capacity=2),
            public_network_access="Disabled",  # can only disable PNA to redis cache during creation
        ),
    )
    .result()
    .id
)
print(redis_arm_id)

Atualizar o repositório de recursos com a loja online

Anexe o Cache do Azure para Redis ao repositório de recursos para usá-lo como o repositório de materialização online. A próxima célula de código cria um arquivo de especificação YAML com regras de saída do repositório online, definidas para o repositório de recursos.

# The following code cell creates a YAML specification file for outbound rules that are defined for the feature store.
## rule 1: PE to online store (redis cache): this is optional if online store is not used

import yaml

config = {
    "public_network_access": "disabled",
    "managed_network": {
        "isolation_mode": "allow_internet_outbound",
        "outbound_rules": [
            {
                "name": "sourceruleredis",
                "destination": {
                    "spark_enabled": "true",
                    "subresource_target": "redisCache",
                    "service_resource_id": f"/subscriptions/{storage_subscription_id}/resourcegroups/{storage_resource_group_name}/providers/Microsoft.Cache/Redis/{redis_name}",
                },
                "type": "private_endpoint",
            },
        ],
    },
    "online_store": {"target": f"{redis_arm_id}", "type": "redis"},
}

feature_store_managed_vnet_yaml = (
    root_dir + "/featurestore/feature_store_managed_vnet_config.yaml"
)

with open(feature_store_managed_vnet_yaml, "w") as outfile:
    yaml.dump(config, outfile, default_flow_style=False)

A próxima célula de código atualiza o repositório de recursos com o arquivo de especificação YAML gerado com as regras de saída para o repositório online.

!az ml feature-store update --file $feature_store_managed_vnet_yaml --name $featurestore_name --resource-group $featurestore_resource_group_name

Atualizar regras de saída do workspace do projeto

O workspace do projeto precisa de acesso ao repositório online. A célula de código a seguir cria um arquivo de especificação YAML com as regras de saída necessárias para o workspace do projeto.

import yaml

config = {
    "managed_network": {
        "isolation_mode": "allow_internet_outbound",
        "outbound_rules": [
            {
                "name": "onlineruleredis",
                "destination": {
                    "spark_enabled": "true",
                    "subresource_target": "redisCache",
                    "service_resource_id": f"/subscriptions/{storage_subscription_id}/resourcegroups/{storage_resource_group_name}/providers/Microsoft.Cache/Redis/{redis_name}",
                },
                "type": "private_endpoint",
            },
        ],
    }
}

project_ws_managed_vnet_yaml = (
    root_dir + "/featurestore/project_ws_managed_vnet_config.yaml"
)

with open(project_ws_managed_vnet_yaml, "w") as outfile:
    yaml.dump(config, outfile, default_flow_style=False)

Execute a próxima célula de código para atualizar o workspace do projeto com o arquivo de especificação YAML gerado com as regras de saída para o repositório online.

#### Update project workspace to create private endpoints for the defined outbound rules (it may take approximately 15 minutes)
!az ml workspace update --file $project_ws_managed_vnet_yaml --name $project_ws_name --resource-group $project_ws_rg

Materializar o recurso de transações definido como repositório online

A próxima célula de código habilita a materialização online para o conjunto de recursos transactions.

# Update featureset to enable online materialization
transactions_featureset_path = (
    root_dir
    + "/featurestore/featuresets/transactions/featureset_asset_online_enabled.yaml"
)
!az ml feature-set update --file $transactions_featureset_path --resource-group $featurestore_resource_group_name --workspace-name $featurestore_name

A próxima célula de código define os horários de início e término da janela de materialização do recurso e envia um trabalho de materialização de arquivo de fundo.

feature_window_start_time = "2024-01-24T00:00.000Z"
feature_window_end_time = "2024-01-25T00:00.000Z"

!az ml feature-set backfill --name transactions --version 1 --by-data-status "['None']" --feature-window-start-time $feature_window_start_time --feature-window-end-time $feature_window_end_time --feature-store-name $featurestore_name --resource-group $featurestore_resource_group_name

Usar os recursos registrados para gerar dados de treinamento

Carregar dados de observação

Primeiro, explore os dados de observação. Os dados principais usados para treinamento e inferência normalmente envolvem os dados de observação. Esses dados são associados a dados de recursos para criar um recurso de dados de treinamento completo. Dados de observação são os dados capturados durante o tempo do evento. Nesse caso, há os dados principais da transação, incluindo a ID da transação, a ID da conta e os valores da transação. Aqui, como os dados de observação são usados para treinamento, eles também têm a variável de destino acrescentada (is_fraud).

observation_data_path = f"abfss://{storage_file_system_name_observation_data}@{storage_account_name}.dfs.core.windows.net/train/*.parquet"
observation_data_df = spark.read.parquet(observation_data_path)
obs_data_timestamp_column = "timestamp"

display(observation_data_df)
# Note: the timestamp column is displayed in a different format. Optionally, you can can call training_df.show() to see correctly formatted value

Obter o conjunto de recursos registrado e listar seus recursos

Em seguida, obtenha um conjunto de recursos fornecendo o nome e a versão dele e liste os recursos do conjunto de recursos. Além disso, imprima alguns valores de recursos de exemplo.

# look up the featureset by providing name and version
transactions_featureset = featurestore.feature_sets.get("transactions", "1")
# list its features
transactions_featureset.features
# print sample values
display(transactions_featureset.to_spark_dataframe().head(5))

Selecionar recursos e gerar dados de treinamento

Escolha os recursos para os dados de treinamento e use o SDK do repositório de recursos para gerar os dados de treinamento.

from azureml.featurestore import get_offline_features

# you can select features in pythonic way
features = [
    transactions_featureset.get_feature("transaction_amount_7d_sum"),
    transactions_featureset.get_feature("transaction_amount_7d_avg"),
]

# you can also specify features in string form: featurestore:featureset:version:feature
more_features = [
    "transactions:1:transaction_3d_count",
    "transactions:1:transaction_amount_3d_avg",
]

more_features = featurestore.resolve_feature_uri(more_features)
features.extend(more_features)

# generate training dataframe by using feature data and observation data
training_df = get_offline_features(
    features=features,
    observation_data=observation_data_df,
    timestamp_column=obs_data_timestamp_column,
)

# Ignore the message that says feature set is not materialized (materialization is optional). We will enable materialization in the next part of the tutorial.
display(training_df)
# Note: the timestamp column is displayed in a different format. Optionally, you can can call training_df.show() to see correctly formatted value

Uma junção pontual anexou os recursos aos dados de treinamento.

Próximas etapas opcionais

Agora que você criou com êxito um repositório de recursos seguro e enviou uma execução de materialização bem-sucedida, você pode prosseguir pela série de tutoriais para criar uma compreensão do repositório de recursos.

Este tutorial contém uma combinação de etapas dos tutoriais 1 e 2 desta série. Lembre-se de substituir os contêineres de armazenamento público necessários usados nos outros blocos de anotações do tutorial pelos criados neste notebook de tutorial para o isolamento de rede.

Isso conclui o tutorial. Seus dados de treinamento usam recursos de um repositório de recursos. Salve-os no armazenamento para uso posterior ou execute o treinamento de modelo diretamente neles.

Próximas etapas