Partilhar via


Tutorial 6: Isolamento de rede com armazenamento de recursos

Um repositório de recursos gerenciados do Azure Machine Learning permite descobrir, criar e operacionalizar recursos. Os recursos servem como tecido conjuntivo no ciclo de vida do aprendizado de máquina, começando pela fase de prototipagem, onde você experimenta vários recursos. Esse ciclo de vida continua até a fase de operacionalização, onde 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 de conceitos do repositório de recursos.

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

A Parte 1 desta 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 permitir a materialização e realizar um backfill. Além disso, a Parte 2 mostrou como experimentar recursos, como uma maneira de melhorar o desempenho do modelo. A Parte 3 mostrou como uma loja 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. Tutorial 6 mostra como

  • Configure os recursos necessários para o isolamento de rede de um repositório de recursos gerenciados.
  • Crie um novo recurso de armazenamento de recursos.
  • Configure seu repositório de recursos para oferecer suporte a cenários de isolamento de rede.
  • Atualize o espaço de trabalho do projeto (espaço de trabalho atual) para oferecer suporte a cenários de isolamento de rede.

Pré-requisitos

Nota

Este tutorial usa um bloco de anotações do Azure Machine Learning com o Serverless Spark Compute.

  • Um espaço de trabalho do Azure Machine Learning, habilitado com rede virtual gerenciada para trabalhos de faísca sem servidor

  • Para configurar o espaço de trabalho do projeto:

    1. Crie um arquivo YAML chamado network.yml:

      managed_network:
      isolation_mode: allow_internet_outbound
      
    2. Execute estes comandos para atualizar o espaço de trabalho 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 trabalho de faísca sem servidor.

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

Importante

Para seu espaço de trabalho do Azure Machine Learning, defina como isolation_mode allow_internet_outbound. Este é o único modo de isolamento de rede suportado. Este tutorial mostrará como se conectar a fontes, armazenamento de materialização e dados de observação com segurança através de endpoints privados.

Configurar

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

Não é necessário instalar explicitamente esses recursos para este tutorial, porque nas instruções de configuração mostradas aqui, o conda.yaml arquivo os abrange.

Para preparar o ambiente de notebook para desenvolvimento:

  1. Clone o repositório azureml-examples para seus recursos locais do GitHub com este 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, selecione primeiro a code lista suspensa e, em seguida, selecione Download ZIP. Em seguida, descompacte o conteúdo em uma pasta no dispositivo local.

  2. Carregue o diretório de exemplos do repositório de recursos para o espaço de trabalho do projeto

    1. No espaço de trabalho do Azure Machine Learning, abra a interface do usuário do estúdio do Azure Machine Learning
    2. Selecione Blocos de Anotações no painel de navegação esquerdo
    3. Selecione seu nome de usuário na listagem de diretórios
    4. Selecione reticências (...) e, em seguida, 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. Execute o tutorial

    • Opção 1: Criar um novo bloco de notas e executar as instruções neste documento, passo a passo

    • Opção 2: Abra o bloco de notas featurestore_sample/notebooks/sdk_and_cli/network_isolation/Network-isolation-feature-store.ipynbexistente . Você pode manter este documento aberto e consultá-lo para obter mais explicações e links de documentação

      1. Selecione Serverless Spark Compute na lista suspensa Compute de navegação superior. Esta operação pode demorar um a dois minutos. Aguarde até que uma barra de status na parte superior exiba Configurar sessão
      2. Selecione Configurar sessão na barra de status superior
      3. Selecionar pacotes Python
      4. Selecione Upload conda file
      5. Selecione o arquivo azureml-examples/sdk/python/featurestore-sample/project/env/conda.yml localizado em 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 de faísca sem servidor
  4. Esta célula de código inicia a sessão do Spark. Ele precisa de cerca de 10 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:

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

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

      # authenticate
      !az login
    • Definir a subscrição predefinida

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

    Nota

    Um espaço de trabalho de repositório de recursos oferece suporte à reutilização de recursos entre projetos. Um espaço de trabalho de projeto - o espaço de trabalho atual em uso - aproveita recursos de um repositório de recursos específico para treinar e inferir modelos. Muitos espaços de trabalho de projeto podem compartilhar e reutilizar o mesmo espaço de trabalho de armazenamento de recursos.

Disponibilizar os recursos necessários

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

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

  • Dados de origem
  • Loja offline
  • Dados de observação
  1. Crie uma conta de armazenamento ADLS Gen2 para dados de origem, armazenamento offline e 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, você pode substituir 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 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. Essa célula de código cria um novo contêiner de armazenamento para armazenamento 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. Essa célula de código cria um novo contêiner de armazenamento para 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. Essa célula de código cria um novo contêiner de armazenamento para 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 para esta série de tutoriais nos contêineres de armazenamento recém-criados.

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

      Importante

      Depois de garantir que as funções de Colaborador e Colaborador de Dados de Blob de Armazenamento sejam atribuídas à identidade do usuário, aguarde alguns minutos após a atribuição da função para permitir que as permissões se propaguem antes de prosseguir com as próximas etapas. Para saber mais sobre 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úblico 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 conjunto de recursos de conta 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. Desative o acesso à rede pública na conta de armazenamento recém-criada.

    1. Esta célula de código desativa o acesso à rede pública para a conta de armazenamento 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 IDs ARM para o armazenamento offline, dados de origem e 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 uma loja de recursos com a materialização ativada

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 ARM, conforme mostrado neste exemplo 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,
)

Esta 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

Esta 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 de objeto do Microsoft Entra para sua identidade de usuário. Em seguida, use sua ID de Objeto do Microsoft Entra no próximo comando para atribuir a função de 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 de armazenamento 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 para o 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 desativa o acesso à rede pública à 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)

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

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

Habilitar a rede virtual gerenciada para o espaço de trabalho do repositório de recursos

Atualize 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)

Esta 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 provision-network comando cria pontos de extremidade privados da rede virtual gerenciada, onde o trabalho de materialização é executado na origem, no armazenamento offline, nos dados de observação, na conta de armazenamento padrão e no cofre de chaves padrão para o repositório de recursos. Este 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

Esta 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 espaço de trabalho do projeto

Em seguida, atualize a rede virtual gerenciada para o espaço de trabalho do projeto. Primeiro, obtenha a ID da assinatura, o grupo de recursos e o nome do espaço de trabalho para o espaço de trabalho 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 espaço de trabalho do projeto com as regras de saída necessárias

O espaço de trabalho do projeto precisa de acesso a estes recursos:

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

Esta célula de código atualiza o espaço de trabalho 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 espaço de trabalho 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

Esta 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 no portal do Azure. Navegue até Rede no painel de navegação esquerdo do espaço de trabalho do projeto e abra a guia Acesso de saída gerenciado pelo espaço de trabalho.

Esta captura de tela mostra regras de saída para um espaço de trabalho de projeto no portal do Azure.

Prototipar e desenvolver um conjunto de recursos de agregação contínua de transações

Explore os dados de origem das transações

Nota

Um contêiner de blob acessível publicamente hospeda os dados de exemplo usados neste tutorial. Ele só pode ser lido no Spark via wasbs driver. Ao criar conjuntos de recursos usando seus próprios dados de origem, hospede-os em uma conta ADLS Gen2 e use um abfss driver 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 localmente um conjunto de recursos de transações

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

Crie os seguintes recursos de agregação de janela contínua:

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

Inspecione o arquivo featurestore/featuresets/transactions/spec/transformation_code/transaction_transform.pyde código de transformação de recurso . Este transformador de faísca executa a agregação de rolamento definida para as características.

Para obter mais informações sobre o conjunto de recursos e as transformações com mais detalhes, visite Conceitos da loja 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 de conjunto de recursos

Para registrar uma especificação de conjunto de recursos no repositório de recursos, essa especificação deve 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 - neste caso, um arquivo parquet em um recurso de armazenamento de blob
  • features: uma lista de recursos e seus tipos de dados. Se você fornecer 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 ser controlada por 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 YAML de 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 armazenamento de recursos

As entidades ajudam a impor o uso das mesmas definições de chave de junção em conjuntos de recursos que usam as mesmas entidades lógicas. Os exemplos de entidades podem incluir entidades de contas, entidades de clientes, etc. Normalmente, as entidades são criadas uma vez e, em seguida, reutilizadas em 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

Registre o conjunto de recursos de transação no repositório de recursos e envie um trabalho de materialização

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

O ativo do conjunto de recursos faz referência às especificações 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 visualiza o 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 backfill

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

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

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

### Check the job status

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

Esta 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 uma Cache do Azure para Redis

Na próxima célula de código, defina o nome do Cache Redis do Azure 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 Redis do Azure com camada premium, família P SKU 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 a loja de funcionalidades com a loja online

Anexe o Cache Redis do Azure 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 da loja 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 a loja 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 espaço de trabalho do projeto

O espaço de trabalho do projeto precisa de acesso à loja 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 espaço de trabalho 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 espaço de trabalho do projeto com o arquivo de especificação YAML gerado com as regras de saída para a loja 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 para a loja online

A próxima célula de código permite a materialização on-line para o transactions conjunto de recursos.

# 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 as horas de início e término da janela de materialização de recursos e envia um trabalho de materialização de preenchimento.

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

Use os recursos registrados para gerar dados de treinamento

Carregar dados de observação

Primeiro, explore os dados de observação. Os principais dados usados para treinamento e inferência normalmente envolvem dados de observação. Esses dados são então unidos aos dados do recurso, 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, ele tem os principais dados de transação, incluindo ID da transação, ID da conta e valores do valor da transação. Aqui, como os dados de observação são usados para treinamento, também tem a variável alvo anexada (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

Obtenha o conjunto de recursos registrado e liste seus recursos

Em seguida, obtenha um conjunto de recursos fornecendo seu nome e versão e, em seguida, liste os recursos nesse conjunto de recursos. Além disso, imprima alguns valores de recurso 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))

Selecione recursos e gere dados de treinamento

Selecione 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 point-in-time anexou os recursos aos dados de treinamento.

Próximos passos opcionais

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

Este tutorial contém uma mistura 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 bloco de anotações do tutorial, para o isolamento da rede.

Deste modo, conclui-se o tutorial. Seus dados de treinamento usam recursos de um repositório de recursos. Você pode salvá-lo no armazenamento para uso posterior ou executar diretamente o treinamento do modelo nele.

Próximos passos