Usa GPU

Questa pagina spiega come eseguire una pipeline Apache Beam su Dataflow con GPU. I job che utilizzano le GPU comportano addebiti come specificato nella pagina dei prezzi di Dataflow.

Per ulteriori informazioni sull'utilizzo delle GPU con Dataflow, consulta il supporto di Dataflow per le GPU. Per maggiori informazioni sul flusso di lavoro degli sviluppatori per la creazione di pipeline utilizzando le GPU, consulta la pagina Sviluppo con GPU.

Utilizzo dei blocchi note Apache Beam

Se hai già una pipeline che vuoi eseguire con le GPU in Dataflow, puoi saltare questa sezione.

I blocchi note Apache Beam offrono un modo pratico per realizzare un prototipo e sviluppare in modo iterativo la tua pipeline con le GPU senza configurare un ambiente di sviluppo. Per iniziare, leggi la guida Developing with Apache Beam, lancia un'istanza di blocchi note Apache Beam e segui l'esempio di blocco di GPU con Apache Beam.

Provisioning della quota GPU

I dispositivi GPU sono soggetti alla disponibilità della quota del tuo progetto Google Cloud. Richiedi quota GPU nella regione che preferisci.

Installazione dei driver per GPU

Indica a Dataflow di installare i driver NVIDIA sui worker aggiungendo install-nvidia-driver all'opzione worker_accelerator. Quando è specificata l'opzione install-nvidia-driver, Dataflow installa i driver NVIDIA sui worker Dataflow utilizzando l'utilità cos-extensions fornita dal Container-Optimized OS. Se specifichi install-nvidia-driver, accetti di accettare il contratto di licenza di NVIDIA.

I binari e le librerie forniti dal programma di installazione del driver NVIDIA sono montati nel container che esegue il codice utente della pipeline all'indirizzo /usr/local/nvidia/.

La versione del driver della GPU dipende dalla versione Container-Optimized OS attualmente utilizzata da Dataflow. Per trovare la versione del driver GPU per un determinato job Dataflow, nei log dei passaggi Dataflow del tuo job, cerca GPU driver.

Creazione di un'immagine container personalizzata

Per interagire con le GPU, potrebbero essere necessari software NVIDIA aggiuntivi, come le librerie con accelerazione GPU e il toolkit CUDA. Fornisci queste librerie nel container Docker che esegue il codice utente.

Puoi personalizzare l'immagine container fornendo un'immagine che soddisfi il contratto relativo all'immagine container dell'SDK Apache Beam e che disponga delle librerie GPU necessarie.

Per fornire un'immagine container personalizzata, utilizza Dataflow Runner v2 e fornisci l'immagine container utilizzando l'opzione della pipeline worker_harness_container_image. Se utilizzi Apache Beam 2.30.0 o versioni successive, per semplicità puoi utilizzare un nome di opzione più breve: sdk_container_image. Per ulteriori informazioni, consulta la pagina relativa all'utilizzo dei container personalizzati.

Approccio 1. Utilizzo di un'immagine esistente configurata per l'utilizzo della GPU

Puoi creare un'immagine Docker che soddisfi il contratto del container dell'SDK Apache Beam da un'immagine di base esistente preconfigurata per l'utilizzo della GPU. Ad esempio, le immagini Docker TensorFlow e le immagini container NVIDIA sono preconfigurate per l'utilizzo della GPU.

Un Dockerfile di esempio basato sull'immagine Docker di TensorFlow con Python 3.6 ha il seguente aspetto:

ARG BASE=tensorflow/tensorflow:2.5.0-gpu
FROM $BASE

# Check that the chosen base image provides the expected version of Python interpreter.
ARG PY_VERSION=3.6
RUN [[ $PY_VERSION == `python -c 'import sys; print("%s.%s" % sys.version_info[0:2])'` ]] \
   || { echo "Could not find Python interpreter or Python version is different from ${PY_VERSION}"; exit 1; }

RUN pip install --upgrade pip \
    && pip install --no-cache-dir apache-beam[gcp]==2.29.0 \
    # Verify that there are no conflicting dependencies.
    && pip check

# Copy the Apache Beam worker dependencies from the Beam Python 3.6 SDK image.
COPY --from=apache/beam_python3.6_sdk:2.29.0 /opt/apache/beam /opt/apache/beam

# Apache Beam worker expects pip at /usr/local/bin/pip by default.
# Some images have pip in a different location. If necessary, make a symlink.
# This line can be omitted in Beam 2.30.0 and later versions.
RUN [[ `which pip` == "/usr/local/bin/pip" ]] || ln -s `which pip` /usr/local/bin/pip

# Set the entrypoint to Apache Beam SDK worker launcher.
ENTRYPOINT [ "/opt/apache/beam/boot" ]

Quando utilizzi le immagini Docker GKE, utilizza TensorFlow 2.5.0 o versioni successive. Le immagini precedenti di TensorFlow Docker installano il pacchetto tensorflow-gpu invece del pacchetto tensorflow. La distinzione non è importante dopo il rilascio di TensorFlow 2.1.0, ma diversi pacchetti downstream, come tfx, richiedono il pacchetto tensorflow.

Le grandi dimensioni dei container rallentano il tempo di avvio del worker. Questa modifica delle prestazioni può verificarsi quando si utilizzano container come i container di deep learning.

Installazione di una versione specifica di Python

Se hai requisiti rigorosi per la versione Python, puoi creare l'immagine da un'immagine di base NVIDIA con le librerie GPU necessarie. Quindi, installa l'interprete di Python.

L'esempio seguente mostra la selezione di un'immagine NVIDIA dal catalogo di immagini container CUDA che non include l'interprete Python. Puoi regolare l'esempio per installare la versione desiderata di Python 3 e pip. In questo esempio viene utilizzato TensorFlow. Pertanto, quando scegli un'immagine, le versioni CUDA e cuDNN nell'immagine di base soddisfano i requisiti per la versione TensorFlow.

Un Dockerfile di esempio ha il seguente aspetto:

# Select an NVIDIA base image with desired GPU stack from https://ngc.nvidia.com/catalog/containers/nvidia:cuda

FROM nvidia/cuda:11.0.3-cudnn8-runtime-ubuntu20.04

RUN \
    # Add Deadsnakes repository that has a variety of Python packages for Ubuntu.
    # See: https://launchpad.net/~deadsnakes/+archive/ubuntu/ppa
    apt-key adv --keyserver keyserver.ubuntu.com --recv-keys F23C5A6CF475977595C89F51BA6932366A755776 \
    && echo "deb http://ppa.launchpad.net/deadsnakes/ppa/ubuntu focal main" >> /etc/apt/sources.list.d/custom.list \
    && echo "deb-src http://ppa.launchpad.net/deadsnakes/ppa/ubuntu focal main" >> /etc/apt/sources.list.d/custom.list \
    && apt-get update \
    && apt-get install -y curl \
        python3.8 \
        # With python3.8 package, distutils need to be installed separately.
        python3-distutils \
    && rm -rf /var/lib/apt/lists/* \
    && update-alternatives --install /usr/bin/python python /usr/bin/python3.8 10 \
    && curl https://bootstrap.pypa.io/get-pip.py | python \
    && pip install --upgrade pip \
    # Install Apache Beam and Python packages that will interact with GPUs.
    && pip install --no-cache-dir apache-beam[gcp]==2.29.0 tensorflow==2.4.0 \
    # Verify that there are no conflicting dependencies.
    && pip check

# Copy the Apache Beam worker dependencies from the Beam Python 3.8 SDK image.
COPY --from=apache/beam_python3.8_sdk:2.29.0 /opt/apache/beam /opt/apache/beam

# Set the entrypoint to Apache Beam SDK worker launcher.
ENTRYPOINT [ "/opt/apache/beam/boot" ]

Su alcune distribuzioni del sistema operativo, potrebbe essere difficile installare versioni Python specifiche utilizzando il gestore di pacchetti del sistema operativo. In questo caso, puoi installare l'interprete Python con strumenti come Miniconda o Pyenv.

Un Dockerfile di esempio ha il seguente aspetto:

FROM nvidia/cuda:11.0.3-cudnn8-runtime-ubuntu20.04

# The Python version of the Dockerfile must match the Python version you use
# to launch the Dataflow job.

ARG PYTHON_VERSION=3.8

# Update PATH so we find our new Conda and Python installations.
ENV PATH=/opt/python/bin:/opt/conda/bin:$PATH

RUN apt-get update \
    && apt-get install -y wget \
    && rm -rf /var/lib/apt/lists/* \
    # The NVIDIA image doesn't come with Python pre-installed.
    # We use Miniconda to install the Python version of our choice.
    && wget -q https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh \
    && bash Miniconda3-latest-Linux-x86_64.sh -b -p /opt/conda \
    && rm Miniconda3-latest-Linux-x86_64.sh \
    # Create a new Python environment with desired version, and install pip.
    && conda create -y -p /opt/python python=$PYTHON_VERSION pip \
    # Remove unused Conda packages, install necessary Python packages via pip
    # to avoid mixing packages from pip and Conda.
    && conda clean -y --all --force-pkgs-dirs \
    && pip install --upgrade pip \
    # Install Apache Beam and Python packages that will interact with GPUs.
    && pip install --no-cache-dir apache-beam[gcp]==2.29.0 tensorflow==2.4.0 \
    # Verify that there are no conflicting dependencies.
    && pip check \
    # Apache Beam worker expects pip at /usr/local/bin/pip by default.
    # You can omit this line when using Beam 2.30.0 and later versions.
    && ln -s $(which pip) /usr/local/bin/pip

# Copy the Apache Beam worker dependencies from the Apache Beam SDK for Python 3.8 image.
COPY --from=apache/beam_python3.8_sdk:2.29.0 /opt/apache/beam /opt/apache/beam

# Set the entrypoint to Apache Beam SDK worker launcher.
ENTRYPOINT [ "/opt/apache/beam/boot" ]

Approccio 2. Utilizzo delle immagini container Apache Beam

Puoi configurare un'immagine container per l'utilizzo della GPU senza utilizzare immagini preconfigurate. Questo approccio non è consigliato, a meno che le immagini preconfigurate non funzionino per te. Per impostare l'immagine container è necessario selezionare le librerie compatibili e configurare il relativo ambiente di esecuzione.

Un Dockerfile di esempio ha il seguente aspetto:

FROM apache/beam_python3.7_sdk:2.24.0
ENV INSTALLER_DIR="/tmp/installer_dir"

# The base image has TensorFlow 2.2.0, which requires CUDA 10.1 and cuDNN 7.6.
# You can download cuDNN from NVIDIA website
# https://developer.nvidia.com/cudnn
COPY cudnn-10.1-linux-x64-v7.6.0.64.tgz $INSTALLER_DIR/cudnn.tgz
RUN \
    # Download CUDA toolkit.
    wget -q -O $INSTALLER_DIR/cuda.run https://developer.download.nvidia.com/compute/cuda/10.1/Prod/local_installers/cuda_10.1.243_418.87.00_linux.run && \

    # Install CUDA toolkit. Print logs upon failure.
    sh $INSTALLER_DIR/cuda.run --toolkit --silent || (egrep '^\[ERROR\]' /var/log/cuda-installer.log && exit 1) && \
    # Install cuDNN.
    mkdir $INSTALLER_DIR/cudnn && \
    tar xvfz $INSTALLER_DIR/cudnn.tgz -C $INSTALLER_DIR/cudnn && \

    cp $INSTALLER_DIR/cudnn/cuda/include/cudnn*.h /usr/local/cuda/include && \
    cp $INSTALLER_DIR/cudnn/cuda/lib64/libcudnn* /usr/local/cuda/lib64 && \
    chmod a+r /usr/local/cuda/include/cudnn*.h /usr/local/cuda/lib64/libcudnn* && \
    rm -rf $INSTALLER_DIR

# A volume with GPU drivers will be mounted at runtime at /usr/local/nvidia.
ENV LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/nvidia/lib64:/usr/local/cuda/lib64

Le librerie dei driver in /usr/local/nvidia/lib64 devono essere rilevabili nel container come librerie condivise configurando la variabile di ambiente LD_LIBRARY_PATH.

Se utilizzi TensorFlow, devi scegliere una combinazione compatibile di CUDA Toolkit e cuDNN. Per ulteriori dettagli, consulta Requisiti software e Configurazioni di build testate.

Selezione del tipo e del numero di GPU per i worker Dataflow

Dataflow ti consente di configurare il tipo e il numero di GPU da collegare ai worker Dataflow utilizzando il parametro worker_accelerator. Puoi selezionare il tipo e il numero di GPU in base al caso d'uso e al modo in cui prevedi di utilizzare le GPU nella tua pipeline.

Dataflow supporta i seguenti tipi di GPU:

  • NVIDIA® A100
  • NVIDIA® Tesla® T4
  • NVIDIA® Tesla® P4
  • NVIDIA® Tesla® V100
  • NVIDIA® Tesla® P100
  • NVIDIA® Tesla® K80

Per informazioni più dettagliate su ogni tipo di GPU, inclusi i dati sulle prestazioni, consulta il grafico di confronto delle GPU.

Esecuzione del job con le GPU

Per eseguire un job Dataflow con GPU, utilizza il comando seguente:

Python

python PIPELINE \
  --runner "DataflowRunner" \
  --project "PROJECT" \
  --temp_location "gs://BUCKET/tmp" \
  --region "REGION" \
  --worker_harness_container_image "IMAGE" \
  --disk_size_gb "DISK_SIZE_GB" \
  --dataflow_service_options "worker_accelerator=type:GPU_TYPE;count:GPU_COUNT;install-nvidia-driver" \
  --experiments "use_runner_v2"

Sostituisci quanto segue:

  • PIPELINE: il file del codice sorgente della pipeline
  • PROJECT: il nome del progetto Google Cloud
  • BUCKET: il bucket Cloud Storage
  • REGION: un endpoint a livello di regione, ad esempio us-central1
  • IMAGE: il percorso di Container Registry per l'immagine Docker
  • DISK_SIZE_GB: dimensioni del disco di avvio per ogni VM worker, ad esempio 50
  • GPU_TYPE: un tipo di GPU disponibile, ad esempio nvidia-tesla-t4
  • GPU_COUNT: numero di GPU da collegare a ogni VM worker, ad esempio 1

Le considerazioni per eseguire un job Dataflow con GPU includono quanto segue:

Se usi TensorFlow, valuta la possibilità di configurare i worker in modo da utilizzare un singolo processo impostando un'opzione della pipeline --experiments=no_use_multiple_sdk_containers o utilizzando worker con una vCPU. Se n1-standard-1 non fornisce una quantità di memoria sufficiente, puoi prendere in considerazione un tipo di macchina personalizzata, ad esempio n1-custom-1-NUMBER_OF_MB o n1-custom-1-NUMBER_OF_MB-ext per la memoria estesa. Per maggiori informazioni, leggi la pagina GPU e parallelismo dei worker.

Verifica del job Dataflow

Per confermare che il job utilizzi VM worker con GPU, segui questi passaggi:

  1. Verifica che i worker Dataflow per il job siano stati avviati.
  2. Mentre un job è in esecuzione, trova una VM worker associata al job.
    1. Incolla l'ID job nel messaggio Search Products and Resources.
    2. Seleziona l'istanza VM di Compute Engine associata al job.

Puoi anche trovare l'elenco di tutte le istanze in esecuzione nella console di Compute Engine.

  1. Nella console Google Cloud, vai alla pagina Istanze VM.

    Vai a Istanze VM

  2. Fai clic su Dettagli istanza VM.

  3. Verifica che la pagina dei dettagli abbia una sezione GPU e che le GPU siano collegate.

Se il tuo job non è stato avviato con GPU, controlla che l'opzione del servizio worker_accelerator sia configurata correttamente e sia visibile nell'interfaccia di monitoraggio di Dataflow in dataflow_service_options. L'ordine dei token nei metadati dell'acceleratore è importante.

Ad esempio, un'opzione di pipeline dataflow_service_options nell'interfaccia di monitoraggio di Dataflow potrebbe avere il seguente aspetto:

['worker_accelerator=type:nvidia-tesla-t4;count:1;install-nvidia-driver', ...]

Visualizzazione dell'utilizzo della GPU

Per visualizzare l'utilizzo della GPU sulle VM worker, segui questi passaggi:

  1. Nella console Google Cloud, vai a Monitoring o utilizza il pulsante seguente:

    Vai a Monitoring.

  2. Nel riquadro di navigazione di Monitoring, fai clic su Metrics Explorer.

  3. Specifica Dataflow Job come tipo di risorsa e GPU utilization o GPU memory utilization come metrica, a seconda della metrica che vuoi monitorare.

Per ulteriori informazioni, consulta la guida di Metrics Explorer.

Utilizzo di GPU con Dataflow Prime

Dataflow Prime consente di richiedere acceleratori per un passaggio specifico della pipeline. Per utilizzare le GPU con Dataflow Prime, non utilizzare l'opzione della pipeline --dataflow-service_options=worker_accelerator. Richiedi invece le GPU con il suggerimento delle risorse accelerator. Per saperne di più, consulta la sezione Utilizzo dei suggerimenti sulle risorse.

Risoluzione dei problemi del job Dataflow

Se riscontri problemi con l'esecuzione del tuo job Dataflow con le GPU, segui questi passaggi per la risoluzione dei problemi.

I lavoratori non si avviano

Se il tuo job è bloccato e i worker Dataflow non iniziano mai a elaborare dati, è probabile che tu abbia un problema relativo all'utilizzo di un container personalizzato con Dataflow. Per ulteriori dettagli, consulta la guida alla risoluzione dei problemi relativi ai container personalizzati.

Se sei un utente Python, verifica che siano soddisfatte le seguenti condizioni:

  • La versione secondaria dell'interprete Python nell'immagine container è la stessa che utilizzi quando avvii la pipeline. In caso di mancata corrispondenza, potresti notare errori come SystemError: unknown opcode con un'analisi dello stack che comporta apache_beam/internal/pickler.py.
  • Se utilizzi l'SDK Apache Beam 2.29.0 o versioni precedenti, pip deve essere accessibile sull'immagine in /usr/local/bin/pip.

Ti consigliamo di ridurre le personalizzazioni a una configurazione di lavoro minima al primo utilizzo di un'immagine personalizzata. Utilizza le immagini container personalizzate di esempio fornite negli esempi di questa pagina. Assicurati di poter eseguire una semplice pipeline Dataflow con questa immagine container senza richiedere le GPU. Quindi, ripeti la soluzione.

Verifica che i worker dispongano di spazio su disco sufficiente per scaricare l'immagine container. Se necessario, regola le dimensioni del disco. Il download delle immagini di grandi dimensioni richiede più tempo, aumentando i tempi di avvio dei worker.

Il job non funziona immediatamente all'avvio

Se si verificano gli errori ZONE_RESOURCE_POOL_EXHAUSTED o ZONE_RESOURCE_POOL_EXHAUSTED_WITH_DETAILS, puoi seguire questi passaggi:

  • Non specificare la zona worker in modo che Dataflow selezioni per te la zona ottimale.

  • Avvia la pipeline in una zona diversa o con un tipo di acceleratore diverso.

Il job non riesce in fase di runtime

Se il job non va a buon fine in fase di runtime, verifica la presenza di errori di memoria insufficiente sulla macchina worker e sulla GPU. Gli errori OOM GPU possono manifestarsi come errori cudaErrorMemoryAllocation out of memory nei log del worker. Se usi TensorFlow, verifica di utilizzare un solo processo TensorFlow per accedere a un dispositivo GPU. Per maggiori informazioni, leggi la pagina GPU e parallelismo dei worker.

Nessun utilizzo di GPU

Se la pipeline viene eseguita correttamente, ma le GPU non vengono utilizzate, verifica quanto segue:

  • Le librerie NVIDIA installate nell'immagine container soddisfano i requisiti del codice utente della pipeline e delle librerie che usa.
  • Le librerie NVIDIA installate nelle immagini container sono accessibili come librerie condivise.

Se i dispositivi non sono disponibili, è possibile che tu stia utilizzando una configurazione software incompatibile. Ad esempio, se utilizzi TensorFlow, verifica di avere una combinazione compatibile di TensorFlow, versione cuDNN e versione CUDA.

Per verificare la configurazione dell'immagine, valuta la possibilità di eseguire una semplice pipeline che verifichi semplicemente che le GPU siano disponibili e accessibili ai worker.

Eseguire il debug con una VM autonoma

Durante la progettazione e l'iterazione di un'immagine container adatta alle tue esigenze, può essere più rapido ridurre il loop di feedback provando l'immagine container su una VM autonoma.

Puoi eseguire il debug del tuo container personalizzato su una VM autonoma con GPU creando una VM di Compute Engine che esegue le GPU su Container-Optimized OS, installando i driver e avviando il container come indicato di seguito.

  1. Creare un'istanza VM.

    gcloud compute instances create INSTANCE_NAME \
      --project "PROJECT" \
      --image-family cos-stable \
      --image-project=cos-cloud  \
      --zone=us-central1-f \
      --accelerator type=nvidia-tesla-t4,count=1 \
      --maintenance-policy TERMINATE \
      --restart-on-failure  \
      --boot-disk-size=200G \
      --scopes=cloud-platform
    
  2. Usa ssh per connetterti alla VM.

    gcloud compute ssh INSTANCE_NAME --project "PROJECT"
    
  3. Installare i driver della GPU. Dopo la connessione alla VM tramite ssh, esegui i comandi seguenti sulla VM:

    # Run these commands on the virtual machine
    cos-extensions install gpu
    sudo mount --bind /var/lib/nvidia /var/lib/nvidia
    sudo mount -o remount,exec /var/lib/nvidia
    /var/lib/nvidia/bin/nvidia-smi
    
  4. Avvia il tuo contenitore personalizzato.

    I container SDK Apache Beam utilizzano il punto di ingresso /opt/apache/beam/boot. A scopo di debug, puoi avviare il container manualmente con un punto di ingresso diverso:

    docker-credential-gcr configure-docker
    docker run --rm \
      -it \
      --entrypoint=/bin/bash \
      --volume /var/lib/nvidia/lib64:/usr/local/nvidia/lib64 \
      --volume /var/lib/nvidia/bin:/usr/local/nvidia/bin \
      --privileged \
      IMAGE
    

    Sostituisci IMAGE con il percorso di Container Registry per la tua immagine Docker.

  5. Verifica che le librerie GPU installate nel tuo container possano accedere ai dispositivi GPU.

    Se utilizzi TensorFlow, puoi stampare i dispositivi disponibili nell'interprete Python con quanto segue:

    >>> import tensorflow as tf
    >>> print(tf.config.list_physical_devices("GPU"))
    

    Se utilizzi PyTorch, puoi controllare i dispositivi disponibili nell'interprete Python con i seguenti comandi:

    >>> import torch
    >>> print(torch.cuda.is_available())
    >>> print(torch.cuda.device_count())
    >>> print(torch.cuda.get_device_name(0))
    

Per eseguire l'iterazione della tua pipeline, puoi avviarla su Direct Runner. Puoi anche avviare pipeline su Dataflow Runner da questo ambiente.

Per ulteriori informazioni, vedi:

Passaggi successivi