Snowpark ML FileSystem et FileSet — Obsolète

La bibliothèque ML de Snowpark comprend FileSystem, une abstraction similaire à un système de fichiers pour une zone de préparation interne et chiffrée de Snowflake côté serveur. Plus précisément, il s’agit d’une implémentation de fsspec AbstractFileSystem. La bibliothèque comprend également FileSet, une classe connexe qui vous permet de déplacer des données de machine learning d’une table Snowflake vers la zone de préparation, et de là, d’alimenter les données vers PyTorch ou TensorFlow (voir Connecteur de données Snowpark ML).

Astuce

La plupart des utilisateurs devraient utiliser la nouvelle API d’ensemble de données, plus récent, pour créer des instantanés de données immuables et gouvernés dans Snowflake et les utiliser dans des workflows de machine learning de bout en bout.

Installation

Les APIs FileSystem et FileSet font partie du paquet Python ML de Snowpark, snowflake-ml-python. Voir Utilisation de Snowflake ML en local pour obtenir des instructions d’installation.

Création et utilisation d’un système de fichiers

La création d’un système de fichiers Snowpark ML nécessite soit un objet Connection Connecteur Snowflake pour Python soit une Session Snowpark Python. Pour obtenir des instructions, voir Connexion à Snowflake.

Après avoir établi une connexion ou une session, vous pouvez créer une instance de Snowpark ML SFFileSystem à travers laquelle vous pouvez accéder aux données de votre zone de préparation interne.

Si vous disposez d’une connexion Connecteur Snowflake pour Python, transmettez-la en tant qu’argument sf_connection :

import fsspec
from snowflake.ml.fileset import sfcfs

sf_fs1 = sfcfs.SFFileSystem(sf_connection=sf_connection)
Copy

Si vous avez une session Snowpark Python, transmettez-la en tant qu’argument snowpark_session :

import fsspec
from snowflake.ml.fileset import sfcfs

sf_fs2 = sfcfs.SFFileSystem(snowpark_session=sp_session)
Copy

SFFileSystem hérite de nombreuses fonctions de fsspec.FileSystem, telles que la mise en cache locale des fichiers. Vous pouvez activer cette fonction ainsi que d’autres en instanciant un système de fichiers Snowflake par le biais de la fonction d’usine fsspec.filesystem, en transmettant target_protocol="sfc" pour utiliser l’implémentation FileSystem de Snowflake :

local_cache_path = "/tmp/sf_files/"
cached_fs = fsspec.filesystem("cached", target_protocol="sfc",
                    target_options={"sf_connection": sf_connection,
                                    "cache_types": "bytes",
                                    "block_size": 32 * 2**20},
                    cache_storage=local_cache_path)
Copy

Le système de fichiers Snowflake prend en charge la plupart des méthodes de lecture seule définies pour un fsspec FileSystem, y compris find, info, isdir, isfile, et exists.

Spécification de fichiers

Pour spécifier des fichiers dans une zone de préparation, utilisez un chemin de la forme @database.schema.stage/file_path.

Fichiers d’annonce

La méthode ls du système de fichiers est utilisée pour obtenir la liste des fichiers de la zone de préparation :

print(*cached_fs.ls("@ML_DATASETS.public.my_models/sales_predict/"), end='\n')
Copy

Ouverture et lecture de fichiers

Vous pouvez ouvrir des fichiers dans la zone de préparation en utilisant la méthode open du système de fichiers. Vous pouvez ensuite lire les fichiers en utilisant les mêmes méthodes que celles utilisées pour les fichiers Python ordinaires. L’objet fichier est également un gestionnaire de contexte qui peut être utilisé avec l’instruction with Python, de sorte qu’il est automatiquement fermé lorsqu’il n’est plus nécessaire.

path = '@ML_DATASETS.public.my_models/test/data_7_7_3.snappy.parquet'

with sf_fs1.open(path, mode='rb') as f:
    print(f.read(16))
Copy

Vous pouvez également utiliser l’instance SFFileSystem avec d’autres composants qui acceptent les systèmes de fichiers fsspec. Ici, le fichier de données Parquet mentionné dans le bloc de code précédent est transmis à la méthode read_table PyArrow :

import pyarrow.parquet as pq

table = pq.read_table(path, filesystem=sf_fs1)
table.take([1, 3])
Copy

Les composants Python qui acceptent des fichiers (ou des objets de type fichier) peuvent être transmis à un objet fichier ouvert à partir du système de fichiers Snowflake. Par exemple, si vous avez un fichier compressé en gzip dans votre zone de préparation, vous pouvez l’utiliser avec le module gzip Python en le transmettant à gzip.GzipFile en tant que paramètre fileobj :

path = "sfc://@ML_DATASETS.public.my_models/dataset.csv.gz"

with cached_fs.open(path, mode='rb', sf_connection=sf_connection) as f:
    g = gzip.GzipFile(fileobj=f)
    for i in range(3):
        print(g.readline())
Copy

Création et utilisation d’un FileSet

Un FileSet Snowflake représente un instantané immuable du résultat d’une requête SQL sous forme de fichiers dans une zone de préparation interne chiffrée côté serveur. Ces fichiers sont accessibles via un FileSystem pour alimenter en données des outils tels que PyTorch et TensorFlow afin que vous puissiez former des modèles à l’échelle et dans le cadre de votre modèle de gouvernance des données existant. Pour créer un FileSet, utilisez la méthode FileSet.make.

Vous avez besoin d’une connexion Python Snowflake ou d’une session Snowpark pour créer un FileSet. Pour obtenir des instructions, voir Connexion à Snowflake. Vous devez également indiquer le chemin à une zone de préparation interne chiffrée côté serveur existante, ou à un sous-répertoire d’une telle zone de préparation, où sera stocké le FileSet.

Pour créer un FileSet à partir d’un DataFrame Snowpark, construisez un DataFrame et transmettez-le à FileSet.make en tant que snowpark_dataframe ; n’appelez pas la méthode collect du DataFrame :

# Snowpark Python equivalent of "SELECT * FROM MYDATA LIMIT 5000000"
df = snowpark_session.table('mydata').limit(5000000)
fileset_df = fileset.FileSet.make(
    target_stage_loc="@ML_DATASETS.public.my_models/",
    name="from_dataframe",
    snowpark_dataframe=df,
    shuffle=True,
)
Copy

Pour créer un FileSet à l’aide d’une connexion Connecteur Snowflake pour Python, transmettez la connexion à Fileset.make en tant que sf_connection, et transmettez la requête SQL en tant que query :

fileset_sf = fileset.FileSet.make(
    target_stage_loc="@ML_DATASETS.public.my_models/",
    name="from_connector",
    sf_connection=sf_connection,
    query="SELECT * FROM MYDATA LIMIT 5000000",
    shuffle=True,           # see later section about shuffling
)
Copy

Note

Consultez Brassage de données dans des FileSets pour obtenir des informations sur le brassage de vos données à l’aide du paramètre shuffle.

Utilisez la méthode files pour obtenir la liste des fichiers contenus dans le FileSet :

print(*fileset_df.files())
Copy

Pour obtenir des informations sur l’introduction des données contenues dans FileSet dans PyTorch ou TensorFlow, voir Alimenter un FileSet avec PyTorch ou Alimenter un FileSet avec TensorFlow, respectivement.

Alimenter un FileSet avec PyTorch

À partir d’un FileSet Snowflake, vous pouvez obtenir un DataPipe PyTorch, qui peut être transmis à un DataLoader PyTorch. Le DataLoader itère sur les données du FileSet et produit des tenseurs PyTorch en lots. Créez le DataPipe à l’aide de la méthode to_torch_datapipe du FileSet, puis transmettez le DataPipe au DataLoader de PyTorch :

from torch.utils.data import DataLoader

# See later sections about shuffling and batching
pipe = fileset_df.to_torch_datapipe(
    batch_size=4,
    shuffle=True,
    drop_last_batch=True)

for batch in DataLoader(pipe, batch_size=None, num_workers=0):
    print(batch)
    break
Copy

Alimenter un FileSet avec TensorFlow

Vous pouvez obtenir un jeu de données TensorFlow à partir d’un FileSet Snowflake en utilisant la méthode to_tf_dataset du FileSet :

import tensorflow as tf

# See following sections about shuffling and batching
ds = fileset_df.to_tf_dataset(
    batch_size=4,
    shuffle=True,
    drop_last_batch=True)

for batch in ds:
    print(batch)
    break
Copy

L’itération sur l’ensemble de données permet d’obtenir des tenseurs en lots.

Brassage de données dans des FileSets

Il est souvent utile de brasser des données d’entraînement pour éviter une adaptation excessive et d’autres problèmes. Pour une discussion sur la valeur du brassage, consultez Pourquoi les données doivent-elles être brassées pour les tâches de machine learning ?

Si votre requête ne brasse pas déjà suffisamment vos données, un FileSet peut mélanger les données en deux points :

  • Lorsque le FileSet est créé à l’aide de FileSet.make.

    Toutes les lignes de votre requête sont brassées avant d’être écrites sur le FileSet. Il s’agit d’un brassage global de haute qualité qui peut s’avérer coûteux pour les grands ensembles de données. Il n’est donc effectué qu’une seule fois, lors de la matérialisation du FileSet. Transmettez shuffle=True comme argument clé à FileSet.make.

  • Lorsque vous créez un DataPipe PyTorch ou un jeu de données TensorFlow à partir d’un FileSet.

    À ce stade, l’ordre des fichiers dans le FileSet est aléatoire, de même que l’ordre des lignes dans chaque fichier. On peut considérer qu’il s’agit d’un brassage global « approximatif ». Il est de moins bonne qualité qu’un véritable brassage global, mais il est beaucoup moins cher. Pour procéder à un brassage à ce stade, transmettez shuffle=True comme argument clé à la méthode to_torch_datapipe ou to_tf_dataset du FileSet.

Pour de meilleurs résultats, procédez deux fois au brassage : lors de la création du FileSet et lors de l’envoi des données à PyTorch ou TensorFlow.

Mise en lots des données dans des FileSets

Les FileSets disposent d’une fonction de mise en lots qui fonctionne de la même manière que la fonction de mise en lots dans PyTorch et TensorFlow, mais qui est plus efficace. Snowflake vous recommande d’utiliser le paramètre batch_size dans les méthodes to_torch_datapipe et to_tf_dataset du FileSet au lieu de demander à PyTorch ou TensorFlow de procéder à la mise en lots. Avec PyTorch, pour désactiver sa fonctionnalité de mise en lots, vous devez explicitement transmettre batch_size=None lors de l’instanciation du DataLoader.

Vous pouvez également supprimer le dernier lot s’il est incomplet en transmettant drop_last_batch=True à to_torch_datapipe ou à to_tf_dataset.