Utiliser des GPU avec Dataproc sans serveur

Vous pouvez associer des accélérateurs GPU à vos charges de travail par lot Dataproc sans serveur pour obtenir les résultats suivants:

  • Accélérez le traitement des charges de travail d'analyse de données à grande échelle.

  • Accélérez l'entraînement de modèle sur des ensembles de données volumineux à l'aide des bibliothèques de machine learning GPU.

  • effectuer des analyses de données avancées, telles que le traitement de vidéos ou du langage naturel ;

Tous les environnements d'exécution Spark sans serveur compatibles avec Dataproc ajoutent la bibliothèque Spark RAPIDS à chaque nœud de charge de travail. La version 1.1 de l'environnement d'exécution Spark sans serveur de Dataproc ajoute également la bibliothèque XGBoost aux nœuds de charge de travail. Ces bibliothèques fournissent de puissants outils de transformation de données et de machine learning que vous pouvez utiliser dans vos charges de travail accélérées par GPU.

Avantages du GPU

Voici quelques-uns des avantages que vous pouvez tirer lorsque vous utilisez des GPU avec vos charges de travail Dataproc sans serveur Spark:

  • Amélioration des performances:l'accélération du GPU peut considérablement améliorer les performances des charges de travail Spark, en particulier pour les tâches nécessitant beaucoup de ressources de calcul, telles que le machine learning et le deep learning, le traitement graphique et les analyses complexes.

  • Entraînement de modèle plus rapide:pour les tâches de machine learning, l'association de GPU permet de réduire considérablement le temps nécessaire à l'entraînement des modèles, ce qui permet aux data scientists et aux ingénieurs d'effectuer des itérations et des tests rapidement.

  • Évolutivité:les clients peuvent ajouter aux nœuds davantage de nœuds GPU ou des GPU plus puissants pour gérer des besoins de traitement de plus en plus complexes.

  • Rentabilité:bien que les GPU nécessitent un investissement initial, vous pouvez réaliser des économies au fil du temps en réduisant les temps de traitement et en optimisant l'utilisation des ressources.

  • Analyse de données améliorée:l'accélération du GPU vous permet d'effectuer des analyses avancées, telles que l'analyse d'images et de vidéos, ou le traitement du langage naturel, sur de grands ensembles de données.

  • Produits améliorés:un traitement plus rapide permet une prise de décision plus rapide et des applications plus réactives.

Limites et points à noter

Tarification

Pour en savoir plus sur les tarifs des accélérateurs, consultez la page Tarifs de Dataproc sans serveur.

Avant de commencer

Avant de créer une charge de travail par lot sans serveur associée à des accélérateurs GPU, procédez comme suit:

  1. Connectez-vous à votre compte Google Cloud. Si vous débutez sur Google Cloud, créez un compte pour évaluer les performances de nos produits en conditions réelles. Les nouveaux clients bénéficient également de 300 $ de crédits gratuits pour exécuter, tester et déployer des charges de travail.
  2. Dans Google Cloud Console, sur la page de sélection du projet, sélectionnez ou créez un projet Google Cloud.

    Accéder au sélecteur de projet

  3. Vérifiez que la facturation est activée pour votre projet Google Cloud.

  4. Activer les API Dataproc, Compute Engine, and Cloud Storage.

    Activer les API

  5. Installez Google Cloud CLI.
  6. Pour initialiser gcloudCLI, exécutez la commande suivante :

    gcloud init
  7. Dans Google Cloud Console, sur la page de sélection du projet, sélectionnez ou créez un projet Google Cloud.

    Accéder au sélecteur de projet

  8. Vérifiez que la facturation est activée pour votre projet Google Cloud.

  9. Activer les API Dataproc, Compute Engine, and Cloud Storage.

    Activer les API

  10. Installez Google Cloud CLI.
  11. Pour initialiser gcloudCLI, exécutez la commande suivante :

    gcloud init
  12. Dans la console Google Cloud, accédez à la page Buckets Cloud Storage.

    Accéder à la page "Buckets"

  13. Cliquez sur Créer un bucket.
  14. Sur la page Créer un bucket, saisissez les informations concernant votre bucket. Pour passer à l'étape suivante, cliquez sur Continuer.
    • Pour nommer votre bucket, saisissez un nom qui répond aux exigences de dénomination des buckets.
    • Pour Choisir l'emplacement de stockage des données, procédez comme suit :
      • Sélectionnez une option de type d'emplacement.
      • Sélectionnez une option Location (Emplacement).
    • Pour Choisir une classe de stockage par défaut pour vos données, sélectionnez une classe de stockage.
    • Pour le champ Choisir comment contrôler l'accès aux objets, sélectionnez une option de Contrôle des accès.
    • Sous Paramètres avancés (facultatif), choisissez une méthode de chiffrement, une règle de conservation ou des libellés de bucket.
  15. Cliquez sur Create (Créer).

Créer une charge de travail par lot sans serveur avec des accélérateurs GPU

Soumettez une charge de travail par lot Dataproc sans serveur utilisant des GPU NVIDIA L4 pour exécuter une tâche PySpark en parallèle. Procédez comme suit à l'aide de la gcloud CLI:

  1. Cliquez sur Développer, puis créez et enregistrez le code PySpark dans un fichier test-py-spark-gpu.py sur votre ordinateur local à l'aide d'un éditeur de texte ou de code.

    #!/usr/bin/env python
    
    """S8s Accelerators Example."""
    
    import subprocess
    from typing import Any
    from pyspark.sql import SparkSession
    from pyspark.sql.functions import col
    from pyspark.sql.types import IntegerType
    from pyspark.sql.types import StructField
    from pyspark.sql.types import StructType
    
    spark = SparkSession.builder.appName("joindemo").getOrCreate()
    
    def get_num_gpus(_: Any) -> int:
      """Returns the number of GPUs."""
      p_nvidia_smi = subprocess.Popen(
          ["nvidia-smi", "-L"], stdin=None, stdout=subprocess.PIPE
      )
      p_wc = subprocess.Popen(
          ["wc", "-l"],
          stdin=p_nvidia_smi.stdout,
          stdout=subprocess.PIPE,
          stderr=subprocess.PIPE,
          universal_newlines=True,
      )
      [out, _] = p_wc.communicate()
      return int(out)
    
    num_workers = 5
    result = (
        spark.sparkContext.range(0, num_workers, 1, num_workers)
        .map(get_num_gpus)
        .collect()
    )
    num_gpus = sum(result)
    print(f"Total accelerators: {num_gpus}")
    
    # Run the join example
    schema = StructType([StructField("value", IntegerType(), True)])
    df = (
        spark.sparkContext.parallelize(range(1, 10000001), 6)
        .map(lambda x: (x,))
        .toDF(schema)
    )
    df2 = (
        spark.sparkContext.parallelize(range(1, 10000001), 6)
        .map(lambda x: (x,))
        .toDF(schema)
    )
    joined_df = (
        df.select(col("value").alias("a"))
        .join(df2.select(col("value").alias("b")), col("a") == col("b"))
        .explain()
    )
    
    
  2. Utilisez la gcloud CLI sur votre ordinateur local pour envoyer la job par lot sans serveur Dataproc sans serveur avec cinq nœuds de calcul, chaque nœud étant accéléré avec des GPU L4:

    gcloud dataproc batches submit pyspark test-py-spark-gpu.py \
        --project=PROJECT_ID \
        --region=REGION \
        --deps-bucket=BUCKET_NAME \
        --version=1.1 \
        --properties=spark.dataproc.executor.compute.tier=premium,spark.dataproc.executor.disk.tier=premium,spark.dataproc.executor.resource.accelerator.type=l4,spark.executor.instances=5,spark.dataproc.driverEnv.LANG=C.UTF-8,spark.executorEnv.LANG=C.UTF-8,spark.shuffle.manager=com.nvidia.spark.rapids.RapidsShuffleManager
    

Remarques :

  • PROJECT_ID : ID de votre projet Google Cloud.
  • REGION: région Compute Engine disponible pour exécuter la charge de travail.
  • BUCKET_NAME : nom du bucket Cloud Storage. Spark importe les dépendances des charges de travail dans un dossier /dependencies de ce bucket avant d'exécuter la charge de travail par lot.
  • --version::tous les environnements d'exécution Dataproc sans serveur compatibles ajoutent la bibliothèque RAPIDS à chaque nœud d'une charge de travail accélérée par GPU. Actuellement, seule la version d'exécution 1.1 ajoute la bibliothèque XGBoost à chaque nœud d'une charge de travail accélérée par GPU.
  • --properties (voir Propriétés d'allocation des ressources Spark) :

    • spark.dataproc.driverEnv.LANG=C.UTF-8 et spark.executorEnv.LANG=C.UTF-8 (obligatoires avec les versions d'exécution antérieures à 2.2): ces propriétés définissent le jeu de caractères par défaut sur C.UTF-8.
    • spark.dataproc.executor.compute.tier=premium (obligatoire) : les charges de travail accélérées par GPU sont facturées à l'aide d'unités de calcul de données premium. Consultez les tarifs de l'accélérateur Dataproc sans serveur.

    • spark.dataproc.executor.disk.tier=premium (obligatoire): les nœuds avec des accélérateurs A100-40, A100-80 ou L4 doivent utiliser le niveau de disque Premium.

    • spark.dataproc.executor.resource.accelerator.type=l4 (obligatoire): un seul type de GPU doit être spécifié. L'exemple de job sélectionne le GPU L4. Les types d'accélérateurs suivants peuvent être spécifiés avec les noms d'argument suivants:

      Type de GPU Nom de l'argument
      A100 40 Go a100-40
      A100 80 Go a100-80

    • spark.executor.instances=5 (obligatoire): au moins deux. Définissez la valeur sur "cinq" pour cet exemple.

    • spark.executor.cores (facultatif) : vous pouvez définir cette propriété pour spécifier le nombre de processeurs virtuels principaux. Les valeurs valides pour les GPU L4 sont 4, la valeur par défaut, ou 8, 12 ou 16. La seule valeur valide par défaut pour les GPU A100 est 12.

    • spark.dataproc.executor.disk.size (facultatif pour les GPU A100-40 et A100-80) : Dataproc sans serveur définit la taille par défaut du disque SSD des GPU sur 375 Go. Vous pouvez modifier la taille lorsque vous utilisez des GPU A100 40 ou A100 80 (consultez la section Propriétés d'allocation des ressources Spark). Les GPU L4 nécessitent une taille de 375 Go. Si vous définissez cette propriété sur une valeur différente lorsque vous soumettez une charge de travail accélérée de couche 4, une erreur se produit.

    • spark.executor.memory (facultatif) et spark.executor.memoryOverhead (facultatif): vous pouvez définir une de ces propriétés, mais pas les deux. La quantité de mémoire disponible non consommée par la propriété d'ensemble est appliquée à la propriété non définie. Par défaut, spark.executor.memoryOverhead est défini sur 40% de la mémoire disponible pour les charges de travail par lot PySpark et sur 10% pour les autres charges de travail (consultez la section Propriétés d'allocation de ressources Spark).

      Le tableau suivant indique la quantité maximale de mémoire pouvant être définie pour différentes configurations de GPU A100 et L4. La valeur minimale de l'une des propriétés est de 1024 Mo.

      A100 (40 Go) A100 (80 Go) L4 (4 cœurs) L4 (8 cœurs) L4 (12 cœurs) L4 (16 cœurs)
      Mémoire totale maximale (Mo) 78040 165080 13384 26768 40152 53536
    • Propriétés Spark RAPIDS (facultatif): par défaut, Dataproc sans serveur définit les valeurs de propriété Spark RAPIDS suivantes:

      • spark.plugins=com.nvidia.spark.SQLPlugin
      • spark.executor.resource.gpu.amount=1
      • spark.task.resource.gpu.amount=1/$spark_executor_cores
      • spark.shuffle.manager=''. Par défaut, cette propriété n'est pas définie. Toutefois, NVIDIA recommande d'activer le gestionnaire de brassage RAPIDS lorsque vous utilisez des GPU pour améliorer les performances. Pour ce faire, définissez spark.shuffle.manager=com.nvidia.spark.rapids.RapidsShuffleManager lorsque vous envoyez une charge de travail.

      Consultez les pages RAPIDS Accelerator for Apache Spark Configuration pour définir les propriétés Spark RAPIDS et RAPIDS Accelerator for Apache Spark Advanced pour définir les propriétés avancées de Spark.