Conecta GPU a clústeres de Dataproc

Dataproc proporciona la capacidad de adjuntar unidades de procesamiento de gráficos (GPU) a los nodos trabajadores y principales de Compute Engine en un clúster de Dataproc. Puedes usar estas GPU para acelerar cargas de trabajo específicas en las instancias, como aprendizaje automático y procesamiento de datos.

Para obtener más información sobre lo que puedes hacer con las GPU y qué tipos de hardware de GPU están disponibles, consulta GPU en Compute Engine.

Antes de comenzar

  • Las GPU requieren controladores y software especiales. Estos elementos están preinstalados en las imágenes de Dataproc -ml (se recomienda usar las imágenes -ml) y se pueden instalar manualmente cuando sea necesario.
  • Lee sobre los precios de GPU en Compute Engine para obtener más información sobre el costo del uso de GPU en las instancias.
  • Lee las restricciones para instancias con GPU a fin de aprender cómo esas instancias funcionan de manera diferente a las instancias sin GPU.
  • Verifica la página de cuotas para tu proyecto a fin de asegurarte de que tienes una cuota suficiente de GPU (NVIDIA_T4_GPUS, NVIDIA_P100_GPUS o NVIDIA_V100_GPUS) disponible en el proyecto. Si las GPU no se enumeran en la página de cuotas o necesitas una cuota de GPU adicional, solicita un aumento de la cuota.

Tipos de GPU

Los nodos de ataproc son compatibles con los tipos de GPU siguientes. Debes especificar el tipo de GPU cuando adjuntas una GPU al clúster de Dataproc.

  • 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 - Estaciones de trabajo virtuales NVIDIA® Tesla® P100
  • nvidia-tesla-p4-vws - Estaciones de trabajo virtuales NVIDIA® Tesla® P4
  • nvidia-tesla-t4-vws: estaciones de trabajo virtuales NVIDIA® Tesla® T4

Cómo adjuntar GPUs a un clúster

Para adjuntar GPUs a un clúster de Dataproc, cuando crees el clúster, debes especificar una imagen -ml (recomendado) o usar una acción de inicialización para instalar controladores de GPU. En los siguientes ejemplos, se especifica la imagen 2.3-ml-ubuntu cuando se crea un clúster.

Google Cloud CLI

Para adjuntar GPU a los nodos trabajadores principales, primarios y secundarios en un clúster de Dataproc, crea el clúster con las marcas gcloud dataproc clusters create ‑‑master-accelerator, ‑‑worker-accelerator y ‑‑secondary-worker-accelerator. Esas marcas toman los siguientes valores:

  • El tipo de GPU que se adjuntará a un nodo
  • Cantidad de GPUs que se adjuntarán al nodo

El tipo de GPU es obligatorio, pero la cantidad es opcional (el valor predeterminado es 1 GPU).

Ejemplo:

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 de REST

Para adjuntar GPU a los nodos trabajadores principales, primarios y secundarios en un clúster de Dataproc, completa los campos acceleratorTypeUri y acceleratorCount de InstanceGroupConfig.AcceleratorConfig como parte de la solicitud a la API cluster.create. Estos campos toman los siguientes valores:

  • El tipo de GPU que se adjuntará a un nodo
  • Cantidad de GPUs que se adjuntarán al nodo

Console

Para adjuntar GPUs a los nodos trabajadores principales, primarios y secundarios en un clúster de Dataproc, sigue estos pasos:

  1. Abre la página Crea un clúster de Dataproc en Compute Engine.
  2. Selecciona el panel Configurar nodos.
  3. En las secciones Nodo administrador, Nodos trabajadores y Nodos trabajadores secundarios, en Plataforma de CPU y GPU > GPU, especifica la cantidad de GPU y el tipo de GPU para los nodos.

Instalar los controladores de GPU.

Se requieren controladores de GPU para usar las GPU adjuntas a los nodos de Dataproc. Como alternativa al uso de los controladores de GPU instalados en las imágenes de Dataproc -ml, puedes usar las siguientes acciones de inicialización para instalar controladores de GPU cuando crees un clúster:

Verifica la instalación del controlador de GPU

Para verificar la instalación del controlador de GPU en un clúster, conéctate con SSH al nodo principal del clúster y, luego, ejecuta el siguiente comando:

nvidia-smi

Si el controlador funciona de manera correcta, el resultado mostrará la versión del controlador y las estadísticas de GPU (consulta Verifica la instalación del controlador de GPU).

Configuración de Spark

Cuando envíes un trabajo a Spark, puedes usar la propiedad spark.executorEnv de configuración de Spark propiedad del entorno de ejecución con la variable de entorno LD_PRELOAD para precargar las bibliotecas necesarias.

Ejemplo:

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

Ejemplo de trabajo de GPU

Puedes probar GPU en Dataproc mediante la ejecución de cualquiera de los siguientes trabajos, que se benefician cuando se ejecutan con GPU:

  1. Ejecuta uno de los ejemplos del AA de Spark.
  2. Ejecuta el ejemplo siguiente con spark-shell para ejecutar el cálculo 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!")

Pasos siguientes