Utiliser les GPU

Cette page explique comment exécuter un pipeline Apache Beam sur Dataflow avec des GPU. Les tâches utilisant des GPU sont facturées comme indiqué sur la page des tarifs de Dataflow.

Pour en savoir plus sur l'utilisation des GPU avec Dataflow, consultez la page Compatibilité de Dataflow avec les GPU. Pour en savoir plus sur le workflow de développement permettant de créer des pipelines à l'aide des GPU, consultez la page Développer avec des GPU.

Utiliser des notebooks Apache Beam

Si vous disposez déjà d'un pipeline que vous souhaitez exécuter avec des GPU sur Dataflow, vous pouvez ignorer cette section.

Les notebooks Apache Beam sont un moyen pratique de créer des prototypes et de développer votre pipeline de manière itérative à l'aide de GPU, sans avoir besoin de configurer d'environnement de développement. Pour commencer, consultez le guide Développer avec des notebooks Apache Beam, lancez une instance de notebook Apache Beam, puis suivez les instructions de l'exemple de notebook Utiliser des GPU avec Apache Beam.

Attribuer un quota de GPU

Les appareils GPU sont soumis à la disponibilité de quota de votre projet Google Cloud. Demandez un quota de GPU dans la région de votre choix.

Installer des pilotes de GPU

Demandez à Dataflow d'installer des pilotes NVIDIA sur les nœuds de calcul en ajoutant install-nvidia-driver à l'option worker_accelerator. Lorsque l'option install-nvidia-driver est spécifiée, Dataflow installe les pilotes NVIDIA sur les nœuds de calcul Dataflow à l'aide de l'utilitaire cos-extensions fourni par Container-Optimized OS. En spécifiant install-nvidia-driver, vous consentez à accepter le contrat de licence NVIDIA.

Les binaires et les bibliothèques fournis par le programme d'installation du pilote NVIDIA sont installés dans le conteneur exécutant le code utilisateur du pipeline à l'adresse /usr/local/nvidia/.

La version du pilote de GPU dépend de la version de Container-Optimized OS actuellement utilisée par Dataflow. Pour trouver la version du pilote de GPU pour une tâche Dataflow donnée, dans les journaux d'étape Dataflow de votre tâche, recherchez GPU driver.

Créer une image de conteneur personnalisée

Pour interagir avec les GPU, vous aurez peut-être besoin d'un logiciel NVIDIA supplémentaire, tel que des bibliothèques accélérées par GPU et le CUDA Toolkit. Fournissez ces bibliothèques dans le conteneur Docker exécutant le code utilisateur.

Vous pouvez personnaliser l'image de conteneur en fournissant une image conforme au contrat d'image de conteneur du SDK Apache Beam et disposant des bibliothèques de GPU nécessaires.

Pour fournir une image de conteneur personnalisé, utilisez Dataflow Runner v2 et fournir l'image de conteneur à l'aide de l'option de pipeline worker_harness_container_image. Si vous utilisez Apache Beam 2.30.0 ou version ultérieure, vous pouvez utiliser un nom d'option plus court comme sdk_container_image pour des raisons de simplicité. Pour en savoir plus, consultez la page Utiliser des conteneurs personnalisés.

Approche 1. Utiliser une image existante configurée pour l'utilisation de GPU

Vous pouvez créer une image Docker qui respecte le contrat de conteneur du SDK Apache Beam à partir d'une image de base existante préconfigurée pour l'utilisation de GPU. Par exemple, les images Docker TensorFlow et les images de conteneurs NVIDIA sont préconfigurées pour l'utilisation de GPU.

Voici un exemple de fichier Dockerfile créé à partir d'une image Docker TensorFlow avec Python 3.6 :

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" ]

Lorsque vous utilisez des images Docker TensorFlow, utilisez TensorFlow 2.5.0 ou une version ultérieure. Les images Docker TensorFlow précédentes installent le package tensorflow-gpu au lieu du package tensorflow. La distinction n'est pas importante après la version 2.1.0 de TensorFlow, mais plusieurs packages en aval, tels que tfx, nécessitent le package tensorflow.

Les conteneurs de grande taille ralentissent le démarrage du nœud de calcul. Cette modification des performances peut se produire lors de l'utilisation de conteneurs tels que les conteneurs de deep learning.

Installer une version spécifique de Python

Si vous avez des exigences strictes concernant la version Python, vous pouvez créer votre image à partir d'une image de base NVIDIA dotée des bibliothèques GPU nécessaires, puis installer l'interpréteur Python.

L'exemple suivant montre comment sélectionner dans le catalogue d'images de conteneurs CUDA une image NVIDIA qui n'inclut pas l'interpréteur Python. Vous pouvez ajuster l'exemple pour installer les versions de Python 3 et pip que vous souhaitez. L'exemple utilise TensorFlow. Par conséquent, lorsque vous choisissez une image, les versions CUDA et cuDNN de l'image de base répondent aux exigences de la version de TensorFlow.

Voici un exemple de fichier Dockerfile :

# 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" ]

Sur certaines distributions de système d'exploitation, il peut être difficile d'installer des versions spécifiques de Python à l'aide du gestionnaire de packages standard du système d'exploitation. Si tel est le cas, vous pouvez installer l'interpréteur Python à l'aide d'outils tels que Miniconda ou pyenv.

Voici un exemple de fichier Dockerfile :

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" ]

Approche 2. Utiliser des images de conteneurs Apache Beam

Vous pouvez configurer une image de conteneur pour utiliser des GPU sans utiliser d'images préconfigurées. Cette approche n'est pas recommandée, sauf si les images préconfigurées ne sont pas adaptées à vos besoins. La configuration de votre propre image de conteneur nécessite de sélectionner des bibliothèques compatibles et de configurer leur environnement d'exécution.

Voici un exemple de fichier Dockerfile :

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

Les bibliothèques de pilotes dans le répertoire /usr/local/nvidia/lib64 doivent être visibles dans le conteneur en tant que bibliothèques partagées en configurant la variable d'environnement LD_LIBRARY_PATH.

Si vous utilisez TensorFlow, vous devez choisir une combinaison compatible avec les versions CUDA Toolkit et CuDNN. Pour en savoir plus, consultez les articles Configuration logicielle requise et Configurations de compilation testées.

Sélectionner le type et le nombre de GPU pour les nœuds de calcul Dataflow

Dataflow vous permet de configurer le type et le nombre de GPU à associer aux nœuds de calcul Dataflow à l'aide du paramètre worker_accelerator. Vous pouvez sélectionner le type et le nombre de GPU en fonction de votre cas d'utilisation et de la manière dont vous prévoyez d'utiliser les GPU dans votre pipeline.

Les types de GPU suivants sont compatibles avec Dataflow :

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

Pour en savoir plus sur chaque type de GPU, y compris sur les données de performance, consultez le tableau de comparaison des GPU.

Exécuter votre tâche à l'aide de GPU

Pour exécuter une tâche Dataflow à l'aide de GPU, utilisez la commande suivante :

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"

Remplacez l'élément suivant :

  • PIPELINE : fichier de code source de votre pipeline
  • PROJECT : nom du projet Google Cloud
  • BUCKET : bucket Cloud Storage.
  • REGION : point de terminaison régional, par exemple us-central1
  • IMAGE : chemin d'accès à Container Registry pour votre image Docker
  • DISK_SIZE_GB : taille du disque de démarrage pour chaque VM de nœud de calcul, par exemple 50
  • GPU_TYPE : type de GPU disponible, par exemple nvidia-tesla-t4
  • GPU_COUNT : nombre de GPU à associer à chaque VM de nœud de calcul, par exemple 1

Les points à prendre en compte pour exécuter une tâche Dataflow à l'aide de GPU sont les suivants :

Si vous utilisez TensorFlow, envisagez de configurer les nœuds de calcul pour qu'ils utilisent un seul processus (définissez l'option de pipeline --experiments=no_use_multiple_sdk_containers ou utilisez des nœuds de calcul avec un processeur virtuel). Si n1-standard-1 ne fournit pas suffisamment de mémoire, vous pouvez envisager d'utiliser un type de machine personnalisé, tel que n1-custom-1-NUMBER_OF_MB ou n1-custom-1-NUMBER_OF_MB-ext pour bénéficier d'une extension de mémoire. Pour en savoir plus, consultez la section GPU et parallélisme des nœuds de calcul.

Vérifier la tâche Dataflow

Pour vérifier que la tâche utilise des VM de nœud de calcul à l'aide de GPU, procédez comme suit :

  1. Vérifiez que les nœuds de calcul Dataflow pour la tâche ont démarré.
  2. Lorsqu'une tâche est en cours d'exécution, recherchez une VM de nœud de calcul associée à la tâche.
    1. Collez l'ID de tâche dans l'invite Rechercher des produits et des ressources.
    2. Sélectionnez l'instance de VM Compute Engine associée à la tâche.

Vous pouvez également consulter la liste de toutes les instances en cours d'exécution dans la console Compute Engine.

  1. Dans Google Cloud Console, accédez à la page Instances de VM.

    Accéder à la page "Instances de VM"

  2. Cliquez sur Informations sur l'instance de VM.

  3. Vérifiez que la page des détails contient une section GPU et que vos GPU sont associés.

Si votre tâche n'a pas été lancée à l'aide de GPU, vérifiez que l'option de service worker_accelerator est correctement configurée et visible dans l'interface de surveillance Dataflow dans dataflow_service_options. L'ordre des jetons dans les métadonnées de l'accélérateur est important.

Par exemple, une option de pipeline dataflow_service_options dans l'interface de surveillance Dataflow peut se présenter comme suit :

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

Afficher l'utilisation des GPU

Pour consulter l'utilisation des GPU sur les VM de nœud de calcul, procédez comme suit :

  1. Dans Cloud Console, accédez à Monitoring ou cliquez sur le bouton suivant :

    Accéder à Monitoring

  2. Dans le volet de navigation "Surveillance", cliquez sur Explorateur de métriques.

  3. Spécifiez Dataflow Job en tant que type de ressource et GPU utilization ou GPU memory utilization en tant que métrique, en fonction de la métrique que vous souhaitez surveiller.

Pour en savoir plus, consultez le guide Explorateur de métriques.

Utiliser des GPU avec Dataflow Prime

Dataflow Premium vous permet de demander des accélérateurs pour une étape spécifique de votre pipeline. Pour utiliser des GPU avec Dataflow Premium, n'utilisez pas l'option de pipeline --dataflow-service_options=worker_accelerator. À la place, demandez les GPU avec l'optimisation de ressource accelerator. Pour en savoir plus, consultez la section Utiliser les optimisations de ressources.

Résoudre les problèmes liés à la tâche Dataflow

Si vous rencontrez des problèmes lors de l'exécution de votre tâche Dataflow à l'aide de GPU, suivez ces étapes de dépannage.

Les nœuds de calcul ne démarrent pas

Si votre tâche est bloquée et que les nœuds de calcul Dataflow ne commencent jamais à traiter les données, le problème est sûrement lié à l'utilisation d'un conteneur personnalisé avec Dataflow. Pour en savoir plus, consultez le guide de dépannage des conteneurs personnalisés.

Si vous êtes un utilisateur Python, vérifiez que les conditions suivantes sont remplies :

  • La version mineure de l'interpréteur Python dans votre image de conteneur est la même que celle utilisée lors du lancement de votre pipeline. En cas d'incohérence, des erreurs telles que SystemError: unknown opcode peuvent s'afficher, avec une trace de pile impliquant apache_beam/internal/pickler.py.
  • Si vous utilisez le SDK Apache Beam 2.29.0 ou une version antérieure, pip doit être accessible sur l'image dans /usr/local/bin/pip.

Nous vous recommandons de réduire les personnalisations à une configuration fonctionnelle minimale lors de la première utilisation d'une image personnalisée. Utilisez les exemples d'images de conteneurs personnalisés fournis dans les exemples de cette page. Assurez-vous de pouvoir exécuter un pipeline Dataflow simple avec cette image de conteneur sans demander de GPU. Ensuite, effectuez une itération sur la solution.

Vérifiez que les nœuds de calcul disposent d'un espace disque suffisant pour télécharger votre image de conteneur. Ajustez la taille du disque si nécessaire. Le téléchargement d'images volumineuses prend plus de temps, ce qui augmente le temps de démarrage des nœuds de calcul.

La tâche échoue immédiatement au démarrage

Si vous rencontrez les erreurs ZONE_RESOURCE_POOL_EXHAUSTED ou ZONE_RESOURCE_POOL_EXHAUSTED_WITH_DETAILS, procédez comme suit :

  • Ne spécifiez pas la zone de nœud de calcul et laissez Dataflow sélectionner la zone optimale pour vous.

  • Lancez le pipeline dans une autre zone ou à l'aide d'un autre type d'accélérateur.

La tâche échoue au moment de l'exécution

Si la tâche échoue au moment de l'exécution, vérifiez les éventuelles erreurs de mémoire saturée (OOM, Out Of Memory) sur le nœud de calcul et le GPU. Les erreurs OOM des GPU peuvent se manifester sous la forme d'erreurs cudaErrorMemoryAllocation out of memory dans les journaux des nœuds de calcul. Si vous utilisez TensorFlow, vérifiez que vous n'utilisez qu'un seul processus TensorFlow pour accéder à un appareil GPU. Pour en savoir plus, consultez la section GPU et parallélisme des nœuds de calcul.

Aucune utilisation du GPU

Si votre pipeline s'exécute correctement, mais que les GPU ne sont pas utilisés, effectuez les vérifications suivantes :

  • Les bibliothèques NVIDIA installées dans l'image de conteneur correspondent aux exigences du code utilisateur du pipeline et des bibliothèques qu'il utilise.
  • Les bibliothèques NVIDIA installées dans les images de conteneurs sont accessibles en tant que bibliothèques partagées.

Si les appareils ne sont pas disponibles, vous utilisez peut-être une configuration logicielle incompatible. Par exemple, si vous utilisez TensorFlow, vérifiez que vous disposez d'une combinaison compatible de TensorFlow, de la version CuDNN et de la version CUDA Toolkit.

Pour vérifier la configuration de l'image, vous pouvez exécuter un pipeline simple qui vérifie uniquement que les GPU sont disponibles et que les nœuds de calcul peuvent y accéder.

Déboguer à l'aide d'une VM autonome

Lorsque vous concevez et itérez une image de conteneur adaptée à vos besoins, il peut être plus rapide de réduire la boucle de rétroaction en testant l'image de conteneur sur une VM autonome.

Vous pouvez déboguer votre conteneur personnalisé sur une VM autonome à l'aide de GPU en créant une VM Compute Engine qui exécute des GPU sur Container-Optimized OS, en installant des pilotes et en démarrant votre conteneur comme suit.

  1. Créez une instance de 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. Utilisez ssh pour vous connecter à la VM.

    gcloud compute ssh INSTANCE_NAME --project "PROJECT"
    
  3. Installez les pilotes de GPU. Une fois connecté à la VM à l'aide de ssh, exécutez les commandes suivantes sur la 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. Lancez votre conteneur personnalisé.

    Les conteneurs du SDK Apache Beam utilisent le point d'entrée /opt/apache/beam/boot. À des fins de débogage, vous pouvez lancer votre conteneur manuellement avec un point d'entrée différent :

    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
    

    Remplacez IMAGE par le chemin d'accès à Container Registry pour votre image Docker.

  5. Vérifiez que les bibliothèques de GPU installées dans votre conteneur peuvent accéder aux appareils GPU.

    Si vous utilisez TensorFlow, vous pouvez imprimer les informations des appareils disponibles dans l'interpréteur Python à l'aide de la commande suivante :

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

    Si vous utilisez PyTorch, vous pouvez inspecter les appareils disponibles dans l'interpréteur Python à l'aide de la commande suivante :

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

Pour effectuer une itération sur votre pipeline, vous pouvez lancer le pipeline sur Direct Runner. Vous pouvez également lancer des pipelines sur l'exécuteur Dataflow Runner à partir de cet environnement.

Pour en savoir plus, consultez les pages suivantes :

Étape suivante