Cómo ejecutar contenedores Docker Compose con acceso GPU

El acceso a GPU en Docker le permite contener cargas de trabajo exigentes, como aplicaciones de aprendizaje automático. Las GPU no están disponibles automáticamente cuando inicia un nuevo contenedor, pero se pueden activar con el --gpus bandera para docker run o agregando campos adicionales a un docker-compose.yml expediente.

En este artículo, mostraremos cómo habilitar la compatibilidad con GPU en Docker Compose. Necesitará Docker Compose versión v1.28 o posterior para seguir la guía. Las GPU no son compatibles con las versiones de Compose v1.18 y anteriores; las versiones entre v1.19 y v1.27 usan una estructura de campo heredada que proporciona menos control.

Índice de contenidos
  1. Preparación de su sistema
  2. Preparando tu imagen
  3. Acceder a las GPU en Docker Compose
  4. Uso de varias GPU
    1. Acceso a un número fijo de dispositivos
    2. Acceso a dispositivos específicos
  5. Resumen

Preparación de su sistema

Su host Docker debe estar preparado antes de que pueda exponer su GPU de hardware. Aunque los contenedores comparten el kernel de su host, no pueden ver los paquetes del sistema que tiene instalados. Un contenedor simple carecerá de los controladores de dispositivo que interactúan con su GPU.

Puede activar la compatibilidad con las GPU NVIDIA instalando Docker Container Toolkit de NVIDIA:

distribution=$(. /etc/os-release;echo $ID$VERSION_ID) 
   && curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add - 
   && curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
sudo apt update
sudo apt install -y nvidia-docker2
sudo systemctl restart docker

Este paquete envuelve el tiempo de ejecución del contenedor de Docker con una interfaz para el controlador NVIDIA de su host. Inspeccionando su /etc/docker/daemon.json El archivo confirmará que el tiempo de ejecución del contenedor configurado ha cambiado. El kit de herramientas de NVIDIA manejará la inyección de conexiones de dispositivos de GPU cuando se inicien nuevos contenedores. Luego se transferirá a su tiempo de ejecución de contenedor habitual.

$ cat /etc/docker/daemon.json
{
    "runtimes": {
        "nvidia": {
            "path": "nvidia-container-runtime",
            "runtimeArgs": []
        }
    }
}

Preparando tu imagen

El acceso a la GPU en Docker también depende de que la imagen de su contenedor esté configurada correctamente. Por lo general, lo más sencillo es basar la imagen en una variante de nvidia/cuda. Este punto de partida proporcionado por NVIDIA viene preconfigurado con compatibilidad con CUDA. Instale cualquier lenguaje de programación que necesite, luego copie su código dependiente de GPU:

FROM nvidia/cuda:11.4.0-base-ubuntu20.04
RUN apt update && 
  apt-get install -y python3 python3-pip &&
  pip install tensorflow-gpu

COPY tensor.py .
ENTRYPONT ["python3", "tensor.py"]

Debe usar la misma versión de CUDA que tiene instalada en su host. Puedes verificar esto ejecutando nvidia-smi:

$ nvidia-smi
Tue May 10 19:15:00 2022       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 470.103.01   Driver Version: 470.103.01   CUDA Version: 11.4     |
|-------------------------------+----------------------+----------------------+
...

Ahora puede escribir un archivo Docker Compose para iniciar su contenedor con un archivo adjunto de GPU.

Acceder a las GPU en Docker Compose

Las GPU se mencionan en un docker-compose.yml archivo a través de la deploy.resources.reservations.devices campo dentro de sus servicios que los necesitan. Este mecanismo le permite identificar las GPU que desea adjuntar. Cada dispositivo seleccionado se proporcionará a sus contenedores.

Aquí hay un ejemplo simple que inicia un contenedor usando el nvidia/cuda imagen. Emitirá información sobre su GPU cuando se inicie el contenedor.

services:
  app:
    image: nvidia/cuda:11.4.0-base-ubuntu20.04
    command: nvidia-smi
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              capabilities: [gpu]

los deploy.resources.reservations.devices El campo especifica los dispositivos que su contenedor puede usar. Configuración de la driver a nvidia y agregando el gpu La capacidad define un dispositivo GPU.

Correr docker-compose up (o docker compose up para Compose v2) para iniciar su contenedor:

$ docker compose up
Creating network "scratch_default" with the default driver
Creating scratch_app_1 ... done
Attaching to scratch_app_1
app_1  | Tue May 10 14:21:14 2022       
app_1  | +-----------------------------------------------------------------------------+
app_1  | | NVIDIA-SMI 470.103.01   Driver Version: 470.103.01   CUDA Version: 11.4     |
app_1  | |-------------------------------+----------------------+----------------------+

El contenedor debería obtener acceso a su GPU con éxito. Las versiones del controlador y CUDA coincidirán con las instaladas en su host.

Uso de varias GPU

Su contenedor recibe acceso a todas las GPU en su sistema a menos que se proporcione una configuración adicional. Hay dos formas diferentes de acceder a un subconjunto de sus dispositivos GPU.

Acceso a un número fijo de dispositivos

los count El campo reserva un número específico de dispositivos. En este ejemplo, un sistema con dos GPU proporcionará una de ellas al contenedor. Es arbitrario cuál será seleccionado.

services:
  app:
    image: nvidia/cuda:11.4.0-base-ubuntu20.04
    command: nvidia-smi
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1
              capabilities: [gpu]

Acceso a dispositivos específicos

Puede identificar dispositivos individuales en su sistema usando el device_ids campo. Esto acepta una matriz de ID de dispositivos indexados en 0 para proporcionar al contenedor. Puede encontrar estos ID enumerando sus GPU con nvidia-smi:

$ nvidia-smi --list-gpus
GPU 0: NVIDIA GeForce GTX 1080 Ti (UUID: GPU-5ba4538b-234f-2c18-6a7a-458d0a7fb348)
GPU 1: NVIDIA GeForce GTX 1080 Ti (UUID: GPU-d5ce9af3-710c-4222-95f8-271db933d438)
GPU 2: NVIDIA GeForce GTX 1080 Ti (UUID: GPU-50d4eb4f-7b08-4f8f-8d20-27d797fb7f19)
GPU 3: NVIDIA GeForce GTX 1080 Ti (UUID: GPU-bed2d40a-c6e7-4547-8d7d-a1576c5247b2)

Para acceder de manera confiable a los dos últimos dispositivos de la lista, incluya sus ID de dispositivo en la configuración de su servicio:

services:
  app:
    image: nvidia/cuda:11.4.0-base-ubuntu20.04
    command: nvidia-smi
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              device_ids: ["2", "3"]
              capabilities: [gpu]

Puedes usar count o device_ids en cada una de sus definiciones de servicio. Recibirás un error cuando ejecutes docker-compose up si intenta combinar ambos, especifique un ID de dispositivo no válido o utilice un valor de count eso es más alto que la cantidad de GPU en su sistema.

Resumen

Las versiones modernas de Docker Compose admiten el acceso a la GPU a través de deploy.resources función de reservas de dispositivos. Sigue siendo responsable de preparar su entorno de host y usar una imagen de contenedor habilitada para GPU. Una vez que se solucione, ejecutar docker-compose up -d es más simple que recordar incluir el --gpus all marca cada vez que usas docker run.

Puedes comprometer tu docker-compose.yml archivo en el control de código fuente para que todos tengan acceso automático a la GPU. Debe asegurarse de estandarizar versiones coherentes del controlador NVIDIA, ya que la versión utilizada por su imagen debe coincidir con la instalada en sus hosts. En el futuro, la compatibilidad con la GPU de Docker también podría funcionar con dispositivos Intel y AMD, pero intentar usarla hoy generará un error. NVIDIA es el único proveedor de GPU actualmente compatible con el proyecto Moby.

Descubre más contenido

Subir Change privacy settings