ПО для GPU

Контейнеры Docker с GPU и NVIDIA Container Toolkit

Docker и NVIDIA Container Toolkit уже установлены в наших образах Ubuntu. Вот как дать каждому контейнеру доступ к нужным ему GPU — и только к ним.

На этой странице
  1. Проверка Docker и NVIDIA Container Toolkit
  2. Доступ контейнера ко всем GPU или только к некоторым
  3. Резервирование GPU в Docker Compose
  4. Выбор базового образа CUDA или NGC
  5. Достаточный объём разделяемой памяти для PyTorch
  6. GPU AMD: аналог для ROCm
  7. Устранение неполадок

Чтобы запускать задачи на GPU в Docker с NVIDIA Container Toolkit, достаточно одного флага, но в реальных конфигурациях нужно чуть больше: выбирать GPU для каждого контейнера, резервировать их в Docker Compose, подбирать базовый образ под версию драйвера и выделять PyTorch достаточно разделяемой памяти. Docker и NVIDIA Container Toolkit уже установлены в наших образах Ubuntu. На серверах AMD вместо этого используются флаги устройств — о них рассказано ближе к концу страницы.

Проверка Docker и NVIDIA Container Toolkit

docker --version
nvidia-ctk --version
docker info | grep -i runtimes
docker run --rm --gpus all ubuntu nvidia-smi

Последняя команда должна вывести ту же таблицу GPU, что и на хосте. NVIDIA Container Toolkit монтирует драйвер хоста в контейнер, поэтому драйвер никогда не входит в образы: им нужны только библиотеки CUDA, которые использует ваше приложение. Если вы работаете не под root, запускайте docker через sudo или добавьте своего пользователя в группу docker, которая по сути равнозначна root-доступу.

Доступ контейнера ко всем GPU или только к некоторым

# all GPUs
docker run --rm --gpus all ubuntu nvidia-smi -L
# GPUs 0 and 1 (the inner quotes are required because of the comma)
docker run --rm --gpus '"device=0,1"' ubuntu nvidia-smi -L
# one GPU by UUID, as printed by nvidia-smi -L on the host
docker run --rm --gpus device=GPU-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx \
  ubuntu nvidia-smi -L

Внутри контейнера выбранные GPU нумеруются с 0, поэтому GPU 2 и 3 хоста видны как 0 и 1. Надёжнее всего закреплять сервис за конкретным GPU по UUID. Чтобы выполнять восемь независимых задач на 8-GPU-сервере, запускайте по одному контейнеру на каждый GPU с --gpus device=N.

Кроме того, NVIDIA Container Toolkit читает переменную NVIDIA_VISIBLE_DEVICES, если контейнер запущен со средой выполнения NVIDIA:

docker run --rm --runtime=nvidia -e NVIDIA_VISIBLE_DEVICES=0,1 \
  ubuntu nvidia-smi -L

Если nvidia — среда выполнения по умолчанию в /etc/docker/daemon.json, то образы, которые задают эту переменную (так делают CUDA-образы NVIDIA), получают все GPU даже без --gpus, поэтому, если вам нужно ограничение, задавайте её явно. CUDA_VISIBLE_DEVICES работает иначе: эта переменная отбирает GPU внутри контейнера среди уже смонтированных.

Резервирование GPU в Docker Compose

services:
  trainer:
    image: ubuntu:24.04
    command: nvidia-smi -L
    ipc: host
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              device_ids: ["0", "1"]
              capabilities: [gpu]

Запустите сервис командой docker compose up: в выводе должны быть два GPU. Чтобы задавать число GPU, а не их идентификаторы, замените device_ids на count: all или count: 2; эти два ключа нельзя использовать вместе, а capabilities: [gpu] обязателен. Если команда docker compose version завершается с ошибкой, установите плагин Compose: docker-compose-plugin, если Docker установлен из репозитория Docker, или docker-compose-v2, если из репозитория Ubuntu.

Опубликованный порт, например -p 8000:8000, доступен из интернета, даже если ufw его запрещает, потому что Docker создаёт собственные правила файрвола. Публикуйте сервисы как -p 127.0.0.1:8000:8000 (в Compose — "127.0.0.1:8000:8000") и ставьте перед ними обратный прокси, как показано в руководстве по файрволу.

Выбор базового образа CUDA или NGC

  • Образы nvidia/cuda на Docker Hub бывают трёх видов: base (минимальная среда выполнения CUDA), runtime (плюс библиотеки CUDA) и devel (плюс компилятор и заголовочные файлы), некоторые из них — с cuDNN. Теги строятся по схеме VERSION-FLAVOR-OS, например 12.8.1-runtime-ubuntu24.04.
  • Образы NGC, например nvcr.io/nvidia/pytorch, содержат оптимизированный стек фреймворка и выходят каждый месяц с тегами вида YY.MM-py3. В их примечаниях к выпуску указано, какой драйвер нужен каждому тегу.

Выбирайте тег, версия CUDA в котором не выше значения «CUDA Version» в выводе nvidia-smi на хосте, а для GPU Blackwell — CUDA 12.8 или новее. Если образу нужен более новый драйвер, чем установлен на хосте, контейнер откажется запускаться с ошибкой unsatisfied condition: cuda>=. Это правило объясняется в руководстве по версиям драйвера и CUDA.

Достаточный объём разделяемой памяти для PyTorch

По умолчанию Docker ограничивает /dev/shm объёмом 64 МБ. Рабочие процессы DataLoader в PyTorch и NCCL используют разделяемую память, поэтому обучение завершается с ошибкой «bus error» или сообщением «insufficient shared memory (shm)». Используйте общее с хостом пространство имён IPC или увеличьте лимит (подставьте вместо YY.MM актуальный тег):

# share the host IPC namespace, as NVIDIA recommends for its PyTorch images
docker run --rm -it --gpus all --ipc=host \
  --ulimit memlock=-1 --ulimit stack=67108864 \
  -v /data:/data nvcr.io/nvidia/pytorch:YY.MM-py3

# or keep IPC isolated with a larger /dev/shm
docker run --rm -it --gpus all --shm-size=16g \
  -v /data:/data nvcr.io/nvidia/pytorch:YY.MM-py3

Внутри контейнера команда df -h /dev/shm показывает доступный объём. В Compose используйте ipc: host или shm_size: "16gb". Для образа vLLM нужно сделать то же самое, как показано в руководстве по инференсу LLM (большой языковой модели) на vLLM.

GPU AMD: аналог для ROCm

docker run --rm --device=/dev/kfd --device=/dev/dri \
  --group-add video --ipc=host \
  rocm/pytorch:latest \
  python3 -c "import torch; print(torch.cuda.device_count())"

На сервере MI355X эта команда выводит 8. Стандартный способ запуска контейнеров ROCm — передать файлы устройств вместо --gpus: /dev/kfd — это вычислительный интерфейс, а в /dev/dri находятся файлы устройств GPU. Чтобы ограничить контейнер частью GPU, добавьте -e HIP_VISIBLE_DEVICES=0,1. Остальное — в руководстве по настройке ROCm.

Устранение неполадок

  • could not select device driver "" with capabilities: [[gpu]] или unknown or invalid runtime name: nvidia. Docker не настроен на работу со средой выполнения NVIDIA. Выполните sudo nvidia-ctk runtime configure --runtime=docker, затем sudo systemctl restart docker.
  • unsatisfied condition: cuda>=X.Y. Образу нужен более новый драйвер. Используйте более старый тег образа или создайте тикет в личном кабинете по поводу драйвера.
  • Ошибка «permission denied» при подключении к сокету демона Docker. Используйте sudo или добавьте своего пользователя в группу docker и войдите заново.

Не получается?

Создайте тикет в личном кабинете: укажите сервер, что вы запускали, и приложите вывод ошибок, если он есть. Инженеры отвечают круглосуточно.

Создать тикет

Вход в FullGPU

Управляйте GPU-серверами, балансом и счетами.

Впервые в FullGPU? Создать аккаунт