Formation de modèles de machine learning avec Snowpark Python

Cette rubrique explique comment former des modèles de machine learning (ML) avec Snowpark.

Dans ce chapitre :

Entrepôts optimisés pour Snowpark

La formation de modèles de machine learning (ML) peut parfois être très exigeante en ressources. Les entrepôts optimisés pour Snowpark sont un type d’entrepôt virtuel Snowflake qui peut être utilisé pour les charges de travail qui nécessitent une grande quantité de mémoire et de ressources de calcul. Par exemple, vous pouvez les utiliser pour former un modèle de ML en utilisant un code personnalisé sur un seul nœud.

Ces entrepôts optimisés peuvent également bénéficier de certains scénarios avec des UDF et des UDTF.

Pour plus d’informations sur la façon de créer un entrepôt optimisé pour Snowpark, voir Entrepôts optimisés pour Snowpark.

Utilisation de procédures stockées Snowpark Python pour la formation ML

Les procédures stockées Snowpark Python peuvent être utilisées pour exécuter du code personnalisé en utilisant un entrepôt Snowflake. Les entrepôts optimisés pour Snowpark permettent d’utiliser les procédures stockées de Snowpark pour exécuter des charges de travail de formation à un seul nœud de ML directement dans Snowflake.

Une procédure stockée Python peut exécuter des requêtes imbriquées, en utilisant l”API Snowpark pour Python, pour charger et transformer l’ensemble de données, qui est ensuite chargé dans la mémoire de la procédure stockée pour effectuer le prétraitement et la formation ML. Le modèle formé peut être chargé dans une zone de préparation Snowflake, et peut être utilisé pour créer des UDFs pour effectuer l’inférence.

Bien que les entrepôts optimisés pour Snowpark puissent être utilisés pour exécuter la logique de prétraitement et de formation, il peut être nécessaire d’exécuter des requêtes imbriquées dans un entrepôt distinct pour obtenir de meilleures performances et une meilleure utilisation des ressources. Un entrepôt de requêtes distinct peut être réglé et mis à l’échelle de manière indépendante en fonction de la taille de l’ensemble de données.

Directives

Suivez ces directives pour effectuer des charges de travail de formation à un seul nœud de ML :

  • Définissez WAREHOUSE_SIZE = MEDIUM pour vous assurer que l’entrepôt optimisé pour Snowpark est composé de 1 nœud optimisé pour Snowpark.

  • Définissez le paramètre MAX_CONCURRENCY_LEVEL de l’entrepôt sur 1 pour maximiser les ressources de mémoire et de calcul pour une procédure stockée Snowpark donnée. Par exemple :

    alter warehouse snowpark_opt_wh set max_concurrency_level = 1;
    
    Copy
  • Envisagez de configurer l’entrepôt en tant qu”entrepôt multi-cluster pour prendre en charge la simultanéité souhaitée si nécessaire.

  • Envisagez d’utiliser un entrepôt séparé pour exécuter les requêtes imbriquées à partir de la procédure stockée :

    • Utilisez l’API session.use_warehouse() pour sélectionner l’entrepôt pour la requête dans la procédure stockée.

  • Ne mélangez pas d’autres charges de travail sur l’entrepôt optimisé pour Snowpark qui est utilisé pour exécuter des procédures stockées de formation ML.

Exemple

L’exemple suivant crée et utilise un entrepôt optimisé pour Snowpark. L’exemple crée ensuite une procédure stockée qui forme un modèle de régression linéaire. La procédure stockée utilise les données d’une table nommée MARKETING_BUDGETS_FEATURES (non représentée ici).

create or replace warehouse snowpark_opt_wh with
  warehouse_size = 'MEDIUM'
  warehouse_type = 'SNOWPARK-OPTIMIZED';
  max_concurrency_level = 1;

create or replace procedure train()
  returns variant
  language python
  runtime_version = 3.8
  packages = ('snowflake-snowpark-python', 'scikit-learn', 'joblib')
  handler = 'main'
as $$
import os
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import PolynomialFeatures
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split, GridSearchCV
from joblib import dump

def main(session):
  # Load features
  df = session.table('MARKETING_BUDGETS_FEATURES').to_pandas()
  X = df.drop('REVENUE', axis = 1)
  y = df['REVENUE']

  # Split dataset into training and test
  X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state = 42)

  # Preprocess numeric columns
  numeric_features = ['SEARCH_ENGINE','SOCIAL_MEDIA','VIDEO','EMAIL']
  numeric_transformer = Pipeline(steps=[('poly',PolynomialFeatures(degree = 2)),('scaler', StandardScaler())])
  preprocessor = ColumnTransformer(transformers=[('num', numeric_transformer, numeric_features)])

  # Create pipeline and train
  pipeline = Pipeline(steps=[('preprocessor', preprocessor),('classifier', LinearRegression(n_jobs=-1))])
  model = GridSearchCV(pipeline, param_grid={}, n_jobs=-1, cv=10)
  model.fit(X_train, y_train)

  # Upload trained model to a stage
  model_file = os.path.join('/tmp', 'model.joblib')
  dump(model, model_file)
  session.file.put(model_file, "@ml_models",overwrite=True)

  # Return model R2 score on train and test data
  return {"R2 score on Train": model.score(X_train, y_train),"R2 score on Test": model.score(X_test, y_test)}
$$;
Copy

Pour appeler la procédure stockée, exécutez la commande suivante :

call train();
Copy

Note

Diverses autres démos Snowpark Python sont disponibles dans le dépôt Snowflake-Labs de GitHub. L’exemple Dépenses publicitaires et prédiction du ROI montre comment créer une procédure stockée qui forme un modèle de régression linéaire.

Limites et problèmes connus

  • La formation ML avec PyTorch n’est pas encore prise en charge.