Anexar GPUs a clusters

O Serviço Gerenciado para Apache Spark permite que unidades de processamento gráfico (GPUs) sejam anexadas aos nós mestre e de trabalho do Compute Engine em um cluster do Serviço Gerenciado para Apache Spark. Use essas GPUs para acelerar cargas de trabalho específicas nas instâncias, como machine learning e processamento de dados.

Para mais informações sobre o que pode ser feito com as GPUs e que tipos de hardware de GPU estão disponíveis, leia GPUs no Google Compute Engine.

Antes de começar

  • As GPUs exigem drivers e softwares especiais. Esses itens são pré-instalados em imagens do Serviço Gerenciado para Apache Spark -ml. Recomendamos usar as imagens -ml. Eles podem ser instalados manualmente quando e se necessário.
  • Leia sobre preços de GPU no Google Compute Engine para entender o custo de usar GPUs nas instâncias.
  • Leia sobre restrições de instâncias com GPUs para saber como essas instâncias funcionam de maneira diferente da maioria das instâncias não GPU.
  • Verifique a página de cotas do projeto para garantir que você tenha uma cota de GPU suficiente (NVIDIA_T4_GPUS, NVIDIA_P100_GPUS ou NVIDIA_V100_GPUS) disponível no projeto. Se as GPUs não estiverem listadas nessa página ou se você precisar de cotas complementares, solicite um aumento de cota.

Tipos de GPUs

Os nós do Serviço Gerenciado para Apache Spark são compatíveis com os seguintes tipos de GPU. Especifique o tipo de GPU ao anexar GPUs ao cluster do Serviço Gerenciado para Apache Spark.

  • nvidia-tesla-l4 - NVIDIA® Tesla® L4
  • nvidia-tesla-a100 - NVIDIA® Tesla® A100
  • nvidia-tesla-p100 - NVIDIA® Tesla® P100
  • nvidia-tesla-v100 - NVIDIA® Tesla® V100
  • nvidia-tesla-p4 - NVIDIA® Tesla® P4
  • nvidia-tesla-t4 - NVIDIA® Tesla® T4
  • nvidia-rtx-pro-6000 - NVIDIA® RTX® PRO 6000
  • nvidia-tesla-p100-vws - NVIDIA® Tesla® P100 Virtual Workstations
  • nvidia-tesla-p4-vws - NVIDIA® Tesla® P4 Virtual Workstations
  • nvidia-tesla-t4-vws - NVIDIA® Tesla® T4 Virtual Workstations

Anexar GPUs a um cluster

Para anexar GPUs a um cluster do Serviço Gerenciado para Apache Spark, ao criar o cluster, especifique uma imagem -ml (recomendado) ou use uma ação de inicialização para instalar drivers de GPU. Os exemplos a seguir especificam a imagem 2.3-ml-ubuntu ao criar um cluster.

CLI do Google Cloud

Para anexar GPUs aos nós de worker principais, secundários e mestres em um cluster do Serviço Gerenciado para Apache Spark, crie o cluster usando as flags gcloud dataproc clusters create ‑‑master-accelerator, ‑‑worker-accelerator e ‑‑secondary-worker-accelerator. Essas flags usam os seguintes valores:

  • O tipo de GPU a ser anexada a um nó
  • O número de GPUs a serem anexadas ao nó

O tipo de GPU é obrigatório, e o número de GPUs é opcional. O padrão é uma GPU.

Exemplo:

gcloud dataproc clusters create cluster-name \
    --image-version=2.3-ml-ubuntu \
    --region=region \
    --master-accelerator type=nvidia-tesla-t4 \
    --worker-accelerator type=nvidia-tesla-t4,count=4 \
    --secondary-worker-accelerator type=nvidia-tesla-t4,count=4 \
    ... other flags

API REST

Para anexar GPUs aos nós de trabalho mestre, principal e secundário em um cluster do Serviço Gerenciado para Apache Spark, preencha os campos acceleratorTypeUri e acceleratorCount em InstanceGroupConfig.AcceleratorConfig como parte da solicitação de API cluster.create. Esses campos usam os seguintes valores:

  • O tipo de GPU a ser anexada a um nó
  • O número de GPUs a serem anexadas ao nó

Console

Para anexar GPUs aos nós de trabalho principais e secundários em um cluster do Serviço Gerenciado para Apache Spark, siga estas etapas:

  1. Abra a página do Serviço Gerenciado para Apache Spark Criar um cluster do Serviço Gerenciado para Apache Spark no Compute Engine.
  2. Selecione o painel Configurar nós.
  3. Nas seções Nó do gerenciador, Nós de worker e Nós de worker secundários, em Plataforma de CPU e GPU > GPUs, especifique o número e o tipo de GPU para os nós.

Instalar os drivers da GPU

Os drivers de GPU são necessários para usar as GPUs anexadas aos nós do Serviço Gerenciado para Apache Spark. Como alternativa ao uso dos drivers de GPU instalados nas imagens -ml do Serviço Gerenciado para Apache Spark, é possível usar as seguintes ações de inicialização para instalar drivers de GPU ao criar um cluster:

Verificar a instalação do driver da GPU

Para verificar a instalação do driver de GPU em um cluster, conecte-se usando SSH ao nó principal do cluster e execute o seguinte comando:

nvidia-smi

Se o driver estiver funcionando corretamente, a saída exibirá a versão do driver e as estatísticas da GPU. Consulte Verificar a instalação do driver da GPU.

Configuração do Spark

Ao enviar um job ao Spark, use a propriedade ambiente de execução da configuração spark.executorEnv do Spark com a variável de ambiente LD_PRELOAD para pré-carregar as bibliotecas necessárias.

Exemplo:

gcloud dataproc jobs submit spark --cluster=CLUSTER_NAME \
  --region=REGION \
  --class=org.apache.spark.examples.SparkPi \
  --jars=file:///usr/lib/spark/examples/jars/spark-examples.jar \
  --properties=spark.executorEnv.LD_PRELOAD=libnvblas.so,spark.task.resource.gpu.amount=1,spark.executor.resource.gpu.amount=1,spark.executor.resource.gpu.discoveryScript=/usr/lib/spark/scripts/gpu/getGpusResources.sh

Exemplo de job da GPU

É possível testar GPUs no Serviço Gerenciado para Apache Spark executando qualquer um dos seguintes jobs, que se beneficiam quando executados com GPUs:

  1. Execute um dos exemplos de Spark ML.
  2. Execute o seguinte exemplo com spark-shell para executar uma computação de matriz:
import org.apache.spark.mllib.linalg._
import org.apache.spark.mllib.linalg.distributed._
import java.util.Random

def makeRandomSquareBlockMatrix(rowsPerBlock: Int, nBlocks: Int): BlockMatrix = {
  val range = sc.parallelize(1 to nBlocks)
  val indices = range.cartesian(range)
  return new BlockMatrix(
      indices.map(
          ij => (ij, Matrices.rand(rowsPerBlock, rowsPerBlock, new Random()))),
      rowsPerBlock, rowsPerBlock, 0, 0)
}

val N = 1024 * 4
val n = 2
val mat1 = makeRandomSquareBlockMatrix(N, n)
val mat2 = makeRandomSquareBlockMatrix(N, n)
val mat3 = mat1.multiply(mat2)
mat3.blocks.persist.count
println("Processing complete!")

A seguir