Acessar dados do armazenamento em nuvem do Azure durante o desenvolvimento interativo

APLICA-SE A: SDK do Python azure-ai-ml v2 (atual)

Geralmente, um projeto de machine learning começa com uma EDA (análise exploratória de dados), o pré-processamento de dados (limpeza, engenharia de recursos) e inclui a criação de protótipos de modelos de ML para validar hipóteses. Esta fase do projeto de prototipagem é de natureza altamente interativa, e se presta ao desenvolvimento em um notebook Jupyter ou um IDE com um console interativo do Python. Neste artigo, você aprenderá a:

  • Acessar dados de um URI de armazenamentos de dados do Azure Machine Learning como se eles fossem um sistema de arquivos.
  • Materialize os dados no Pandas usando a biblioteca Python mltable.
  • Materialize os ativos de dados do Azure Machine Learning no Pandas usando a biblioteca mltable do Python.
  • Materialize os dados por meio de um download explícito com o utilitário azcopy.

Pré-requisitos

Dica

As diretrizes neste artigo descrevem o acesso a dados durante o desenvolvimento interativo. Elas se aplicam a qualquer host que possa executar uma sessão do Python. Isso pode incluir seu computador local, uma VM na nuvem, um GitHub Codespace etc. Recomendamos usar uma instância de computação do Azure Machine Learning, uma estação de trabalho na nuvem totalmente gerenciada e pré-configurada. Para obter mais informações, confira Criar uma instância de computação do Azure Machine Learning.

Importante

Verifique se você tem as bibliotecas Python mais recentes azure-fsspec e mltable instaladas no seu ambiente Python:

pip install -U azureml-fsspec mltable

Acessar dados de um URI de armazenamento de dados, como um sistema de arquivos

Um armazenamento de dados do Azure Machine Learning é uma referência a uma conta de armazenamento existente do Azure. Os benefícios da criação e do uso do armazenamento de dados incluem:

  • Uma API comum e fácil de usar para interagir com diferentes tipos de armazenamento (Blob/Arquivos/ADLS).
  • Descoberta fácil de armazenamentos de dados úteis em operações de equipe.
  • Suporte ao acesso baseado em credencial (por exemplo, token SAS) e baseado em identidade (usa o Microsoft Entra ID ou a identidade gerenciada) para acessar dados.
  • Para o acesso baseado em credencial, as informações de conexão são protegidas para anular a exposição de chave em scripts.
  • Procure dados e copie os URIs de armazenamento de dados na interface do usuário do Estúdio.

Um URI de Armazenamento de Dados é um Uniform Resource Identifier, que é uma referência a um local de armazenamento (caminho) na sua conta de armazenamento do Azure. O URI de um armazenamento de dados tem este formato:

# Azure Machine Learning workspace details:
subscription = '<subscription_id>'
resource_group = '<resource_group>'
workspace = '<workspace>'
datastore_name = '<datastore>'
path_on_datastore = '<path>'

# long-form Datastore uri format:
uri = f'azureml://subscriptions/{subscription}/resourcegroups/{resource_group}/workspaces/{workspace}/datastores/{datastore_name}/paths/{path_on_datastore}'.

Esses URIs de armazenamento de dados são uma implementação conhecida da Especificação do sistema de arquivos (fsspec): uma interface unificada compatível com Phyton para sistemas de arquivos e armazenamento de bytes locais, remotos e integrados. Você pode fazer a instalação pip do pacote azureml-fsspec e seu pacote de dependências azureml-dataprep. Em seguida, você pode usar a implementação fsspec do Armazenamento de Dados do Azure Machine Learning.

A implementação fsspec do armazenamento de dados do Azure Machine Learning lida automaticamente com a passagem de credenciais/identidades que o armazenamento de dados do Azure Machine Learning usa. Você pode evitar a exposição da chave de conta em seus scripts e procedimentos de entrada adicionais em uma instância de computação.

Por exemplo, você pode usar diretamente URIs de armazenamento de dados no Pandas. Este exemplo mostra como ler um arquivo CSV:

import pandas as pd

df = pd.read_csv("azureml://subscriptions/<subid>/resourcegroups/<rgname>/workspaces/<workspace_name>/datastores/<datastore_name>/paths/<folder>/<filename>.csv")
df.head()

Dica

Em vez de lembrar o formato do URI de armazenamento de dados, você pode copiar e colar o URI do armazenamento de dados da interface do usuário do Estúdio seguindo estas etapas:

  1. Selecione Dados no menu à esquerda e, em seguida, selecione a guia Armazenamentos de dados.
  2. Selecione o nome do armazenamento de dados e, em seguida, Procurar.
  3. Localize o arquivo/a pasta que você deseja ler em Pandas e selecione as reticências (...) ao lado do arquivo/da pasta. Selecione Copiar URI no menu. Você pode selecionar o URI de Armazenamento de Dados a ser copiado para o notebook/script. Screenshot highlighting the copy of the datastore URI.

Você também pode criar uma instância de um sistema de arquivos do Azure Machine Learning para lidar com comandos semelhantes ao sistema de arquivos, como ls, glob, exists, open.

  • O método ls() lista arquivos em um diretório específico. Você pode usar ls(), ls(.), ls (<<folder_level_1>/<folder_level_2>) para listar arquivos. Damos suporte a "." e ".." em caminhos relativos.
  • O método glob() dá suporte a '*' e '**' globbing.
  • O método exists() retorna um valor booliano que indica se existe um arquivo especificado no diretório raiz atual.
  • O método open() retorna um objeto semelhante a um arquivo, que pode ser passado para qualquer outra biblioteca que possa trabalhar com arquivos do Python. Seu código também pode usar esse objeto, como se fosse um objeto de arquivo Python normal. Esses objetos semelhantes a arquivos respeitam o uso de contextos with, como mostrado neste exemplo:
from azureml.fsspec import AzureMachineLearningFileSystem

# instantiate file system using following URI
fs = AzureMachineLearningFileSystem('azureml://subscriptions/<subid>/resourcegroups/<rgname>/workspaces/<workspace_name>/datastore*s*/datastorename')

fs.ls() # list folders/files in datastore 'datastorename'

# output example:
# folder1
# folder2
# file3.csv

# use an open context
with fs.open('./folder1/file1.csv') as f:
    # do some process
    process_file(f)

Carregar arquivos por meio de AzureMachineLearningFileSystem

from azureml.fsspec import AzureMachineLearningFileSystem
# instantiate file system using following URI
fs = AzureMachineLearningFileSystem('azureml://subscriptions/<subid>/resourcegroups/<rgname>/workspaces/<workspace_name>/datastores/<datastorename>/paths/')

# you can specify recursive as False to upload a file
fs.upload(lpath='data/upload_files/crime-spring.csv', rpath='data/fsspec', recursive=False, **{'overwrite': 'MERGE_WITH_OVERWRITE'})

# you need to specify recursive as True to upload a folder
fs.upload(lpath='data/upload_folder/', rpath='data/fsspec_folder', recursive=True, **{'overwrite': 'MERGE_WITH_OVERWRITE'})

lpath é o caminho local e rpath é o caminho remoto. Se as pastas especificadas em rpath ainda não existirem, criaremos as pastas para você.

Damos suporte a três modos de "substituição":

  • APPEND: se já existir um arquivo com o mesmo nome no caminho de destino, esse modo manterá o arquivo original
  • FAIL_ON_FILE_CONFLICT: se já existir um arquivo com o mesmo nome no caminho de destino, um erro será gerado
  • MERGE_WITH_OVERWRITE: se houver um arquivo com o mesmo nome no caminho de destino, esse modo substituirá o arquivo existente pelo novo arquivo

Baixar arquivos por meio de AzureMachineLearningFileSystem

# you can specify recursive as False to download a file
# downloading overwrite option is determined by local system, and it is MERGE_WITH_OVERWRITE
fs.download(rpath='data/fsspec/crime-spring.csv', lpath='data/download_files/, recursive=False)

# you need to specify recursive as True to download a folder
fs.download(rpath='data/fsspec_folder', lpath='data/download_folder/', recursive=True)

Exemplos

Esses exemplos mostram o uso da especificação do sistema de arquivos em cenários comuns.

Ler um único arquivo CSV no Pandas

Você pode ler um único arquivo CSV no Pandas, conforme mostrado:

import pandas as pd

df = pd.read_csv("azureml://subscriptions/<subid>/resourcegroups/<rgname>/workspaces/<workspace_name>/datastores/<datastore_name>/paths/<folder>/<filename>.csv")

Ler uma pasta de arquivos CSV no Pandas

O método read_csv() do Pandas não dá suporte à leitura de uma pasta de arquivos CSV. Você deve usar o padrão glob nos caminhos CSV e concatená-los em um data frame usando o método concat() do Pandas. O código de exemplo a seguir mostra como obter essa concatenação com o sistema de arquivos do Azure Machine Learning:

import pandas as pd
from azureml.fsspec import AzureMachineLearningFileSystem

# define the URI - update <> placeholders
uri = 'azureml://subscriptions/<subid>/resourcegroups/<rgname>/workspaces/<workspace_name>/datastores/<datastore_name>'

# create the filesystem
fs = AzureMachineLearningFileSystem(uri)

# append csv files in folder to a list
dflist = []
for path in fs.glob('/<folder>/*.csv'):
    with fs.open(path) as f:
        dflist.append(pd.read_csv(f))

# concatenate data frames
df = pd.concat(dflist)
df.head()

Leitura de arquivos CSV no Dask

Este exemplo mostra como ler um arquivo CSV em um data frame do Dask:

import dask.dd as dd

df = dd.read_csv("azureml://subscriptions/<subid>/resourcegroups/<rgname>/workspaces/<workspace_name>/datastores/<datastore_name>/paths/<folder>/<filename>.csv")
df.head()

Ler uma pasta de arquivos Parquet no Pandas

Como parte de um processo de ETL, os arquivos Parquet são tipicamente gravados em uma pasta que pode emitir arquivos relevantes ao ETL, como progresso, commits etc. Este exemplo mostra arquivos criados com um processo de ETL (arquivos que começam com _) para produzir um arquivo Parquet de dados.

Screenshot showing the parquet etl process.

Nesses cenários, convém apenas ler os arquivos Parquet na pasta e ignorar os arquivos de processo do ETL. Este exemplo de código mostra como padrões glob podem ler somente arquivos Parquet em uma pasta:

import pandas as pd
from azureml.fsspec import AzureMachineLearningFileSystem

# define the URI - update <> placeholders
uri = 'azureml://subscriptions/<subid>/resourcegroups/<rgname>/workspaces/<workspace_name>/datastores/<datastore_name>'

# create the filesystem
fs = AzureMachineLearningFileSystem(uri)

# append parquet files in folder to a list
dflist = []
for path in fs.glob('/<folder>/*.parquet'):
    with fs.open(path) as f:
        dflist.append(pd.read_parquet(f))

# concatenate data frames
df = pd.concat(dflist)
df.head()

Acesso a dados do sistema de arquivos do Azure Databricks (dbfs)

A especificação do sistema de arquivos (fsspec) tem uma variedade de implementações conhecidas, incluindo o Sistema de Arquivos do Databricks (dbfs).

Para acessar dados do dbfs, você precisa de:

Com esses valores, você precisará criar uma variável de ambiente na sua instância de computação para o token PAT:

export ADB_PAT=<pat_token>

Em seguida, você pode acessar dados no Pandas, conforme mostrado neste exemplo:

import os
import pandas as pd

pat = os.getenv(ADB_PAT)
path_on_dbfs = '<absolute_path_on_dbfs>' # e.g. /folder/subfolder/file.csv

storage_options = {
    'instance':'adb-<some-number>.<two digits>.azuredatabricks.net', 
    'token': pat
}

df = pd.read_csv(f'dbfs://{path_on_dbfs}', storage_options=storage_options)

Leitura de imagens com pillow

from PIL import Image
from azureml.fsspec import AzureMachineLearningFileSystem

# define the URI - update <> placeholders
uri = 'azureml://subscriptions/<subid>/resourcegroups/<rgname>/workspaces/<workspace_name>/datastores/<datastore_name>'

# create the filesystem
fs = AzureMachineLearningFileSystem(uri)

with fs.open('/<folder>/<image.jpeg>') as f:
    img = Image.open(f)
    img.show()

Exemplo de conjunto de dados personalizado do PyTorch

Neste exemplo, você cria um conjunto de dados personalizado do PyTorch para processar imagens. Estamos supondo que exista um arquivo de anotações (no formato CSV) com esta estrutura geral:

image_path, label
0/image0.png, label0
0/image1.png, label0
1/image2.png, label1
1/image3.png, label1
2/image4.png, label2
2/image5.png, label2

As subpastas armazenam essas imagens, de acordo com seus rótulos:

/
└── 📁images
    ├── 📁0
    │   ├── 📷image0.png
    │   └── 📷image1.png
    ├── 📁1
    │   ├── 📷image2.png
    │   └── 📷image3.png
    └── 📁2
        ├── 📷image4.png
        └── 📷image5.png

Uma classe de conjunto de dados PyTorch personalizada deve implementar três funções: __init__, __len__e __getitem__, conforme mostrado aqui:

import os
import pandas as pd
from PIL import Image
from torch.utils.data import Dataset

class CustomImageDataset(Dataset):
    def __init__(self, filesystem, annotations_file, img_dir, transform=None, target_transform=None):
        self.fs = filesystem
        f = filesystem.open(annotations_file)
        self.img_labels = pd.read_csv(f)
        f.close()
        self.img_dir = img_dir
        self.transform = transform
        self.target_transform = target_transform

    def __len__(self):
        return len(self.img_labels)

    def __getitem__(self, idx):
        img_path = os.path.join(self.img_dir, self.img_labels.iloc[idx, 0])
        f = self.fs.open(img_path)
        image = Image.open(f)
        f.close()
        label = self.img_labels.iloc[idx, 1]
        if self.transform:
            image = self.transform(image)
        if self.target_transform:
            label = self.target_transform(label)
        return image, label

Então, você pode criar uma instância do conjunto de dados, conforme mostrado aqui:

from azureml.fsspec import AzureMachineLearningFileSystem
from torch.utils.data import DataLoader

# define the URI - update <> placeholders
uri = 'azureml://subscriptions/<subid>/resourcegroups/<rgname>/workspaces/<workspace_name>/datastores/<datastore_name>'

# create the filesystem
fs = AzureMachineLearningFileSystem(uri)

# create the dataset
training_data = CustomImageDataset(
    filesystem=fs,
    annotations_file='/annotations.csv', 
    img_dir='/<path_to_images>/'
)

# Prepare your data for training with DataLoaders
train_dataloader = DataLoader(training_data, batch_size=64, shuffle=True)

Materializar dados em Pandas usando a biblioteca mltable

A biblioteca mltable também pode ajudar a acessar dados no armazenamento em nuvem. A leitura de dados no Pandas com mltable tem este formato geral:

import mltable

# define a path or folder or pattern
path = {
    'file': '<supported_path>'
    # alternatives
    # 'folder': '<supported_path>'
    # 'pattern': '<supported_path>'
}

# create an mltable from paths
tbl = mltable.from_delimited_files(paths=[path])
# alternatives
# tbl = mltable.from_parquet_files(paths=[path])
# tbl = mltable.from_json_lines_files(paths=[path])
# tbl = mltable.from_delta_lake(paths=[path])

# materialize to Pandas
df = tbl.to_pandas_dataframe()
df.head()

Caminhos com suporte

A biblioteca mltable dá suporte à leitura de dados tabulares de diferentes tipos de caminho:

Location Exemplos
Um caminho no computador local ./home/username/data/my_data
Um caminho em um servidor https(s) público https://raw.githubusercontent.com/pandas-dev/pandas/main/doc/data/titanic.csv
Um caminho no Armazenamento do Azure wasbs://<container_name>@<account_name>.blob.core.windows.net/<path>
abfss://<file_system>@<account_name>.dfs.core.windows.net/<path>
Um armazenamento de dados contínuo do Azure Machine Learning azureml://subscriptions/<subid>/resourcegroups/<rgname>/workspaces/<wsname>/datastores/<name>/paths/<path>

Observação

A mltable faz a passagem de credenciais do usuário para os caminhos no Armazenamento do Azure e nos armazenamentos de dados do Azure Machine Learning. Se você não tiver permissão para acessar os dados no armazenamento subjacente, não poderá acessá-los.

Arquivos, pastas e globs

mltable dá suporte à leitura de:

  • arquivos – por exemplo, abfss://<file_system>@<account_name>.dfs.core.windows.net/my-csv.csv
  • pastas – por exemplo, abfss://<file_system>@<account_name>.dfs.core.windows.net/my-folder/
  • padrões glob – por exemplo, abfss://<file_system>@<account_name>.dfs.core.windows.net/my-folder/*.csv
  • uma combinação de arquivos, pastas e/ou padrões glob

A flexibilidade da mltable permite a materialização de dados em um só dataframe com base em uma combinação de recursos de armazenamento locais e na nuvem, bem como combinações de arquivos/pastas/globs. Por exemplo:

path1 = {
    'file': 'abfss://filesystem@account1.dfs.core.windows.net/my-csv.csv'
}

path2 = {
    'folder': './home/username/data/my_data'
}

path3 = {
    'pattern': 'abfss://filesystem@account2.dfs.core.windows.net/folder/*.csv'
}

tbl = mltable.from_delimited_files(paths=[path1, path2, path3])

Formatos de arquivo com suporte

O mltable é compatível com os seguintes formatos de arquivo:

  • Texto Delimitado (por exemplo: arquivos CSV): mltable.from_delimited_files(paths=[path])
  • Parquet: mltable.from_parquet_files(paths=[path])
  • Delta: mltable.from_delta_lake(paths=[path])
  • Formato de linhas JSON: mltable.from_json_lines_files(paths=[path])

Exemplos

Ler um arquivo CSV

Atualize os espaços reservados (<>) no snippet de código com seus detalhes específicos:

import mltable

path = {
    'file': 'abfss://<filesystem>@<account>.dfs.core.windows.net/<folder>/<file_name>.csv'
}

tbl = mltable.from_delimited_files(paths=[path])
df = tbl.to_pandas_dataframe()
df.head()

Ler arquivos Parquet em uma pasta

Esse exemplo mostra como o mltable pode usar padrões glob, como curingas, para garantir que apenas os arquivos Parquet sejam lidos.

Atualize os espaços reservados (<>) no snippet de código com seus detalhes específicos:

import mltable

path = {
    'pattern': 'abfss://<filesystem>@<account>.dfs.core.windows.net/<folder>/*.parquet'
}

tbl = mltable.from_parquet_files(paths=[path])
df = tbl.to_pandas_dataframe()
df.head()

Leitura de ativos de dados

Esta seção mostra como acessar os ativos de dados do Azure Machine Learning no Pandas.

Ativo do Table

Se você já criou um ativo de tabela no Azure Machine Learning (uma mltable ou um TabularDataset V1), carregue o ativo de tabela no Pandas com este código:

import mltable
from azure.ai.ml import MLClient
from azure.identity import DefaultAzureCredential

ml_client = MLClient.from_config(credential=DefaultAzureCredential())
data_asset = ml_client.data.get(name="<name_of_asset>", version="<version>")

tbl = mltable.load(f'azureml:/{data_asset.id}')
df = tbl.to_pandas_dataframe()
df.head()

Ativo de arquivo

Se você registrou um ativo de arquivo (um arquivo CSV, por exemplo), poderá ler esse ativo em um dataframe do Pandas com este código:

import mltable
from azure.ai.ml import MLClient
from azure.identity import DefaultAzureCredential

ml_client = MLClient.from_config(credential=DefaultAzureCredential())
data_asset = ml_client.data.get(name="<name_of_asset>", version="<version>")

path = {
    'file': data_asset.path
}

tbl = mltable.from_delimited_files(paths=[path])
df = tbl.to_pandas_dataframe()
df.head()

Ativo de pasta

Se você registrou um ativo de pasta (uri_folder ou um FileDataset V1), por exemplo, uma pasta com um arquivo CSV, você poderá ler esse ativo em um dataframe do Pandas com este código:

import mltable
from azure.ai.ml import MLClient
from azure.identity import DefaultAzureCredential

ml_client = MLClient.from_config(credential=DefaultAzureCredential())
data_asset = ml_client.data.get(name="<name_of_asset>", version="<version>")

path = {
    'folder': data_asset.path
}

tbl = mltable.from_delimited_files(paths=[path])
df = tbl.to_pandas_dataframe()
df.head()

Uma observação sobre leitura e processamento de grandes volumes de dados com o Pandas

Dica

O Pandas não foi criado para lidar com grandes conjuntos de dados. O Pandas só pode processar dados que possam caber na memória da instância de computação.

Para grandes conjuntos de dados, recomendamos o uso do Spark gerenciado pelo Azure Machine Learning. Ele fornece a API PySpark Pandas.

Pode ser interessante iterar rapidamente em um subconjunto menor de um grande conjunto de dados, antes de realizar um trabalho assíncrono remoto. mltable fornece funcionalidade interna para obter exemplos de dados grandes usando o método take_random_sample:

import mltable

path = {
    'file': 'https://raw.githubusercontent.com/pandas-dev/pandas/main/doc/data/titanic.csv'
}

tbl = mltable.from_delimited_files(paths=[path])
# take a random 30% sample of the data
tbl = tbl.take_random_sample(probability=.3)
df = tbl.to_pandas_dataframe()
df.head()

Você também pode usar subconjuntos de dados grandes com essas operações:

Dados de dados usando o utilitário azcopy

Use o utilitário azcopy para baixar os dados no SSD local do host (computador local, VM de nuvem, instância de computação do Azure Machine Learning), no sistema de arquivos local. O utilitário azcopy, que é pré-instalado em uma instância de computação do Azure Machine Learning, cuidará disso. Caso você não use uma instância de computação do Azure Machine Learning ou uma DSVM (Máquina Virtual de Ciência de Dados), talvez precise instalar o azcopy. Confira azcopy para obter mais informações.

Cuidado

Não recomendamos downloads de dados no local /home/azureuser/cloudfiles/code em uma instância de computação. Esse local foi criado para armazenar artefatos de notebook e código, não dados. A leitura de dados desse local incorrerá em uma sobrecarga significativa de desempenho durante o treinamento. Em vez disso, recomendamos o armazenamento de dados no home/azureuser, que é o SSD local do nó de computação.

Abra um terminal e crie um novo diretório, por exemplo:

mkdir /home/azureuser/data

Entre no azcopy usando:

azcopy login

Em seguida, você pode copiar os dados usando um URI de armazenamento

SOURCE=https://<account_name>.blob.core.windows.net/<container>/<path>
DEST=/home/azureuser/data
azcopy cp $SOURCE $DEST

Próximas etapas