Usar GPUs com o Dataproc sem servidor

Você pode anexar aceleradores de GPU às cargas de trabalho em lote do Dataproc sem servidor para alcançar os seguintes resultados:

  • Acelere o processamento de cargas de trabalho de análise de dados em grande escala.

  • Acelerar treinamento de modelo em grandes conjuntos de dados usando as bibliotecas de machine learning da GPU.

  • Execute análises de dados avançadas, como processamento de vídeo ou linguagem natural.

Todos os ambientes de execução do Spark sem servidor do Dataproc com suporte adicionam a biblioteca Spark RAPIDS a cada nó de carga de trabalho. A versão 1.1 do ambiente de execução do Spark sem servidor do Dataproc também adiciona a biblioteca XGBoost (em inglês) aos nós de carga de trabalho. Essas bibliotecas fornecem ferramentas avançadas de transformação de dados e machine learning que podem ser usadas nas cargas de trabalho aceleradas por GPU.

Benefícios da GPU

Veja alguns dos benefícios de usar GPUs com as cargas de trabalho Spark sem servidor do Dataproc:

  • Melhoria de desempenho: a aceleração de GPU pode melhorar significativamente o desempenho das cargas de trabalho do Spark, especialmente para tarefas de computação intensiva, como aprendizado profundo e de máquina, processamento de gráficos e análises complexas.

  • Treinamento de modelo mais rápido: para tarefas de machine learning, anexar GPUs pode reduzir consideravelmente o tempo necessário para treinar modelos, permitindo que cientistas e engenheiros de dados iterem e façam testes rapidamente.

  • Escalonabilidade:os clientes podem adicionar nós ou GPUs mais avançadas a nós para atender a necessidades de processamento cada vez mais complexas.

  • Eficiência de custos: embora as GPUs exijam um investimento inicial, é possível economizar custos ao longo do tempo devido à redução do tempo de processamento e à utilização mais eficiente dos recursos.

  • Análise de dados aprimorada:a aceleração de GPU permite realizar análises avançadas em grandes conjuntos de dados, como análise de imagens e vídeos e processamento de linguagem natural.

  • Produtos aprimorados:o processamento mais rápido permite uma tomada de decisão mais rápida e aplicativos mais responsivos.

Limitações e considerações

Preços

Consulte Preços do Dataproc sem servidor para informações sobre preços dos aceleradores.

Antes de começar

Antes de criar uma carga de trabalho em lote sem servidor com aceleradores de GPU anexados, faça o seguinte:

  1. Faça login na sua conta do Google Cloud. Se você começou a usar o Google Cloud agora, crie uma conta para avaliar o desempenho de nossos produtos em situações reais. Clientes novos também recebem US$ 300 em créditos para executar, testar e implantar cargas de trabalho.
  2. No console do Google Cloud, na página do seletor de projetos, selecione ou crie um projeto do Google Cloud.

    Acessar o seletor de projetos

  3. Verifique se a cobrança está ativada para o seu projeto do Google Cloud.

  4. Ative as APIs Dataproc, Compute Engine, and Cloud Storage.

    Ative as APIs

  5. Instale a CLI do Google Cloud.
  6. Para inicializar a CLI gcloud, execute o seguinte comando:

    gcloud init
  7. No console do Google Cloud, na página do seletor de projetos, selecione ou crie um projeto do Google Cloud.

    Acessar o seletor de projetos

  8. Verifique se a cobrança está ativada para o seu projeto do Google Cloud.

  9. Ative as APIs Dataproc, Compute Engine, and Cloud Storage.

    Ative as APIs

  10. Instale a CLI do Google Cloud.
  11. Para inicializar a CLI gcloud, execute o seguinte comando:

    gcloud init
  12. No console do Cloud, acesse a página Buckets do Cloud Storage.

    Acessar a página "Buckets"

  13. Clique em Criar bucket.
  14. Na página Criar um bucket, insira as informações do seu bucket. Para ir à próxima etapa, clique em Continuar.
  15. Clique em Criar.

Criar uma carga de trabalho em lote sem servidor com aceleradores de GPU

Enviar uma carga de trabalho em lote do Dataproc sem servidor que use GPUs NVIDIA L4 para executar uma tarefa PySpark em paralelo. Siga estas etapas usando a CLI gcloud:

  1. Clique em Expandir, crie e salve o código PySpark listado em um arquivo test-py-spark-gpu.py na sua máquina local usando um editor de texto ou código.

    #!/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. Use a CLI gcloud na máquina local para enviar o job em lote sem servidor do Dataproc com cinco workers, com cada um deles acelerado com GPUs 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
    

Observações:

  • PROJECT_ID pelo ID do projeto do Google Cloud.
  • REGION: uma região disponível do Compute Engine para executar a carga de trabalho.
  • BUCKET_NAME: o nome do bucket do Cloud Storage. O Spark faz o upload das dependências de carga de trabalho para uma pasta /dependencies nesse bucket antes de executar a carga de trabalho em lote.
  • --version: todos os ambientes de execução sem servidor do Dataproc compatíveis adicionam a biblioteca RAPIDS a cada nó de uma carga de trabalho acelerada por GPU. No momento, apenas a versão 1.1 do ambiente de execução adiciona a biblioteca XGBoost a cada nó de uma carga de trabalho acelerada por GPU.
  • --properties (consulte Propriedades de alocação de recursos do Spark) :

    • spark.dataproc.driverEnv.LANG=C.UTF-8 e spark.executorEnv.LANG=C.UTF-8 (obrigatório com versões de ambiente de execução anteriores a 2.2): essas propriedades definem o conjunto de caracteres padrão como C.UTF-8.
    • spark.dataproc.executor.compute.tier=premium (obrigatório): as cargas de trabalho aceleradas pela GPU são faturadas usando unidades de computação de dados (DCUs) premium. Consulte os Preços do acelerador do Dataproc sem servidor.

    • spark.dataproc.executor.disk.tier=premium (obrigatório): os nós com aceleradores A100-40, A100-80 ou L4 precisam usar o nível de disco premium.

    • spark.dataproc.executor.resource.accelerator.type=l4 (obrigatório): apenas um tipo de GPU precisa ser especificado. O job de exemplo seleciona a GPU L4. Os seguintes tipos de acelerador podem ser especificados com os seguintes nomes de argumentos:

      Tipo de GPU Nome do argumento
      A100 40 GB a100-40
      A100 80 GB a100-80

    • spark.executor.instances=5 (obrigatório): precisa ser pelo menos dois. Defina como cinco para este exemplo.

    • spark.executor.cores (opcional): é possível definir essa propriedade para especificar o número de vCPUs principais. Os valores válidos para GPUs L4 são 4, o padrão, ou 8, 12 ou 16. O único valor válido e padrão para GPUs A100 é 12.

    • spark.dataproc.executor.disk.size (opcional para GPUs A100-40 e A100-80): o Dataproc sem servidor define o tamanho do disco SSD da GPU padrão como 375 GB. É possível alterar o tamanho ao usar GPUs A100 40 ou A100 80. Consulte as propriedades de alocação de recursos do Spark. As GPUs L4 exigem o tamanho de 375 GB. Se você definir essa propriedade com um valor diferente ao enviar uma carga de trabalho acelerada por L4, vai ocorrer um erro.

    • spark.executor.memory (opcional) e spark.executor.memoryOverhead (opcional): é possível definir uma dessas propriedades, mas não ambas. A quantidade de memória disponível não consumida pela propriedade "set" é aplicada à propriedade não definida. Por padrão, spark.executor.memoryOverhead é definido como 40% da memória disponível para cargas de trabalho em lote do PySpark e 10% para outras cargas de trabalho. Consulte Propriedades de alocação de recursos do Spark.

      A tabela a seguir mostra a quantidade máxima de memória que pode ser definida para diferentes configurações de GPU A100 e L4. O valor mínimo para qualquer uma das propriedades é 1024 MB.

      A100 (40 GB) A100 (80 GB) L4 (4 núcleos) L4 (8 núcleos) L4 (12 núcleos) L4 (16 núcleos)
      Memória total máxima (MB) 78040 165080 13384 26768 40152 53536
    • Propriedades do Spark RAPIDS (opcional): por padrão, o Dataproc sem servidor define os seguintes valores de propriedade do RAPIDS do Spark:

      • spark.plugins=com.nvidia.spark.SQLPlugin
      • spark.executor.resource.gpu.amount=1
      • spark.task.resource.gpu.amount=1/$spark_executor_cores
      • spark.shuffle.manager=''. Por padrão, essa propriedade não é definida. No entanto, a NVIDIA recomenda ativar o gerenciador de embaralhamento RAPIDS ao usar GPUs para melhorar o desempenho. Para fazer isso, defina spark.shuffle.manager=com.nvidia.spark.rapids.RapidsShuffleManager ao enviar uma carga de trabalho.

      Consulte RAPIDS Accelerator for Apache Spark Configuration para definir as propriedades de RAPIDS do Spark e RAPIDS Accelerator para configuração avançada do Apache Spark para configurar essas propriedades.