- tocdepth
2
Собрать и использовать кастомный Docker-образ для задачи обучения на основе внешнего образа
В инструкции описано, как на базе любого публичного образа создать Docker-образ, который можно запустить на платформе ML Space.
Сборка выполняется вне платформы самостоятельно пользователем. Суть сборки — модификация Docker-файла, который содержит команды сборки образа.
См.также
Для использования подготовленного образа на платформе ML Space необходимо добавить образу префикс имени контейнера «job-», например «job-mytrain:py310-torch25-fa2».
Перед началом работы
Убедитесь, что у вас установлен Docker Desktop.
Ознакомьтесь с форматом Dockerfile.
Dockerfile имеет следующий вид:
FROM <image> USER root .... USER user .... SHELL ...
В каждой из его секций описаны определенные действия:
Секция
FROM <image>
— наследование базового образа. Например, может быть введена переменная, которая позволит на этапе сборки динамически управлять образом.Секция
USER root
— глобальные действия для контейнера от имени суперпользователя root. Например, установка пакетов через пакетный менеджер, добавление пользователей, смена прав доступа.Секция
USER user
— действия от имени обычного пользователя платформы ML Space. Здесь размещают действия по установке дополнительных пакетов через conda- или pip-установщики, а также сборку различных библиотек в wheel-формате Python.Секция
SHELL ...
— активация shell для работы.
В этой инструкции рассмотрена настройка параметров из первых трех секций для модификации образа.
Примечание
При установке переменных окружения через действие
ENV
область видимости будет ограничиваться секцией, где эти переменные установлены. Поэтому если выставить переменные в секцииUSER root
, то они не будут видны пользователю. Рекомендуется выставлять переменные через файл загрузки профиля в/etc/profile.d/you_env_vars.sh
и дублировать для обоих пользователей root и user.
Шаг 1. Соберите кастомный Docker-образ
Чтобы ускорить процесс сборки и добавления новых пакетов, перед началом работ скачайте нужный образ в папку на локальном устройстве, где будете собирать обоаз.
Если у вас уже есть подготовленный Dockerfile с набором устанавливаемых или собираемых пакетов, рекомендуется пересмотреть его, чтобы не возник конфликт прав доступа. Возможно, он был собран от имени суперпользователя root, в то время как работа в ML Space осуществляется только от имени обычного пользователя user.
Сборка образа условно разделяется на несколько этапов.
Секция FROM <image>
Укажите путь с нужным тегом до образа, который будет наследоваться для модификации.
FROM <путь до образа>
Например, если за основу берется образ Ubuntu 22.04, указываем:
ARG UBUNTU_VER 22.04
FROM ubuntu:${UBUNTU_VER}
Секция USER root
В этой секции выполняются команды, которые требуют прав привилегированного пользователя (root).
USER root
Создайте пользователя user с заранее определенными атрибутами:
UID: 1000
GID: 1000
HOME: /home/user
USERNAME: user
NFS DIR: /home/jovyan
Установите права пользователя на общую файловую систему, которая размещается в
/home/jovyan
. Домашняя директория пользователя user/home/user
располагается не в общем хранилище, а внутри образа.RUN useradd -u 1000 -m user --shell /bin/bash \ && mkdir -p /home/user \ && chown user:user /home/user \ && mkdir -p /home/jovyan \ && chown user:user /home/jovyan
Установите сервер OpenSSH, Python (при необходимости) и пакеты curl, wget и bzip2. Можно добавить дополнительные пакеты для образа, которые устанавливаем с помощью пакетного менеджера.
RUN apt-get update \ && apt-get install -y --no-install-recommends \ openssh-server openssh-client \ # Устанавливаем OpenSSH для MPI что бы соединятся между контейнерами curl wget bzip2 \ # Эти пакеты потребуются при сборке образа && rm -rf /var/lib/apt/lists/*
Сгенерируйте SSH-ключи:
# Generating keys for SSH RUN mkdir -p /var/run/sshd \ && ssh-keygen -A
Настройте OpenSSH:
Измените конфигурацию SSH, чтобы отключить проверку ключей хоста (
StrictHostKeyChecking no
).Отключите PAM в конфигурации SSH (
UsePAM no
).Установите
PubkeyAcceptedAlgorithms
для использования алгоритма ssh-rsa.Установите порт SSH на 2222.
Установите права доступа 600 для всех файлов в
/etc/ssh/
.Установите пользователя user и группу user в качестве владельцев файлов
/etc/ssh/ssh_host_*
и каталога/run/sshd
.`
RUN echo "StrictHostKeyChecking no" >> /etc/ssh/ssh_config.d/mlspace.conf \ && echo "UsePAM no" > /etc/ssh/sshd_config.d/mlspace.conf \ && echo "PubkeyAcceptedAlgorithms +ssh-rsa" >> /etc/ssh/sshd_config.d/mlspace.conf \ && echo "Port 2222" >> /etc/ssh/sshd_config.d/mlspace.conf \ && echo "PidFile /run/sshd/sshd.pid" >> /etc/ssh/sshd_config.d/mlspace.conf \ && chmod 600 /etc/ssh/* \ && chown user:user /etc/ssh/ssh_host_* \ && chown user:user /run/sshd
(Опционально) Установите OpenMPI.
В базовом наследуемом образе, например из NVIDIA NG, OpenMPI может быть уже установлен или добавлен из репозиториев дистрибутива и привязан к приложению.
Примечание
Ваше приложение может использовать MPI как средство коммуникации, тогда оно будет зависеть от наличия и версии пакета. В ML Space OpenMPI используется только для запуска распределенных задач с последующим контролем из состояния.
Распакуйте его в директорию
/opt/hpcx
. Для примера используется версия 2.18.1 для Ubuntu 22.04.ARG HPCX_VER 2.18.1 ARG UBUNTU_VER 22.04 ARG HPCX_DIR /opt/hpcx ARG HPCX_PACKAGE hpcx-v${HPCX_VER}-gcc-mlnx_ofed-ubuntu${UBUNTU_VER}-cuda12-x86_64.tbz RUN mkdir - ${HPCX_DIR} \ && wget --quiet --no-check-certificate -c https://content.mellanox.com/hpc/hpc-x/v${HPCX_VER}/${HPCX_PACKAGE} -O /tmp/${HPCX_PACKAGE} \ && tar xjf /tmp/${HPCX_PACKAGE} -C ${HPCX_DIR} --strip-components=1
(Опционально) Если в образе не установлен Python, установите miniconda в директорию
/home/user/conda
и обновите переменную PATH, чтобы были доступны Python и связанные инструменты из miniconda.# Установка Python ARG CONDA_DIR=/home/user/conda ARG DOWNLOAD_LINK="https://repo.anaconda.com/miniconda/Miniconda3-py311_24.11.1-0-Linux-x86_64.sh" RUN mkdir -p ${CONDA_DIR} \ && wget --quiet --no-check-certificate ${DOWNLOAD_LINK} -O miniconda.sh \ && chmod +x miniconda.sh \ && /bin/bash miniconda.sh -f -b -p ${CONDA_DIR} \ && rm miniconda.sh \ ENV PATH="$CONDA_DIR/bin:$PATH"
Установите дополнительные пакеты:
RUN apt-get install package-name
Очистите образ и пакетный менеджер от кеша:
RUN apt-get clean \ && rm -rf /var/lib/apt/lists/* \
Выставите переменные окружения, которые необходимы для корректной работы. Ниже приведены переменные окружения для корректной работы HPC-X из шага 5 по настройке OpenSSH:
ENV LD_LIBRARY_PATH=/opt/hpcx/ompi/lib:/opt/hpcx/ucx/lib:/opt/hpcx/ucc/lib:/opt/hpcx/sharp/lib:/opt/hpcx/nccl_rdma_sharp_plugin/lib:/opt/hpcx/hcoll/lib:${LD_LIBRARY_PATH} ENV PATH=/opt/hpcx/ompi/bin:/opt/hpcx/ucx/bin:/opt/hpcx/ucc/bin:/opt/hpcx/sharp/bin:/opt/hpcx/hcoll/bin:${PATH} ENV OPAL_PREFIX=/opt/hpcx/ompi
Для корректного сохранения переменных окружения создайте файл профиля в
/etc/profile.d/mlspace.sh
, который будет содержать необходимые переменные окружения, активирующиеся при работе в образе:RUN echo "export LD_LIBRARY_PATH=$LD_LIBRARY_PATH">/etc/profile.d/mlspace.sh \ && echo "export PATH=$PATH" >> /etc/profile.d/mlspace.sh \ && echo "export OPAL_PREFIX=$OPAL_PREFIX" >> /etc/profile.d/mlspace.sh
Секция USER user
В этой секции выполняются команды, которые не требуют прав суперпользователя.
USER user
(Опционально) Установите пакеты Python и зависимости одним из способов.
Используя репозиторий пакетов pypi:
RUN pip install --no-cache <package>
Используя бинарные пакеты wheel-формата:
RUN pip install --no-cache <package>.whl
Осуществляя сборку пакета:
RUN python setup.py install/bdist_wheel/...
RUN conda install <package> -c <channel>
Повторно установите переменные окружения, чтобы все действия, выполненные при запуске задачи от имени непривилегированного пользователя, стали доступны этому пользователю.
ENV LD_LIBRARY_PATH=/opt/hpcx/ompi/lib:/opt/hpcx/ucx/lib:/opt/hpcx/ucc/lib:/opt/hpcx/sharp/lib:/opt/hpcx/nccl_rdma_sharp_plugin/lib:/opt/hpcx/hcoll/lib:${LD_LIBRARY_PATH} ENV PATH=/opt/hpcx/ompi/bin:/opt/hpcx/ucx/bin:/opt/hpcx/ucc/bin:/opt/hpcx/sharp/bin:/opt/hpcx/hcoll/bin:${PATH} ENV OPAL_PREFIX=/opt/hpcx/ompi
Секция shell
В этой секции добавляются финальные действия для образа, такие как WORKDIR, ENTRYPOINT, CMD, SHELL.
ML Space не использует команды, установленные в образе для старта, и игнорирует все, кроме WORKDIR
.
Ее рекомендуется оставить:
SHELL ["/bin/bash", "-cu"]
Полный код Dockerfile
Собрав все рекомендации выше воедино, вы получите файл со следующим содержанием. Опциональные части и условия их опциональности обозначены комментарием.
Полный код Dockerfile для сборки образа
# Section FROM <image> # Setting the basic image variables and the inherited image itself ARG UBUNTU_VER=22.04 FROM ubuntu:${UBUNTU_VER} # Section USER root # Performing basic actions to support work in ML Space USER root # Creating a user with ID 1000 and a group with ID 1000 # Creating an empty directory with user rights RUN useradd -u 1000 -m user --shell /bin/bash \ && mkdir -p /home/user \ && chown user:user /home/user \ && mkdir -p /home/jovyan \ && chown user:user /home/jovyan # Installing the necessary packages # Additional packages can be installed RUN apt-get update \ && apt-get install -y --no-install-recommends \ openssh-server openssh-client \ curl wget bzip2 \ # python3 python3-pip \ && rm -rf /var/lib/apt/lists/* # Generating keys for SSH RUN mkdir -p /var/run/sshd \ && ssh-keygen -A # Configuring SSH to work on port 2222 and other options for working in ML Space RUN echo "StrictHostKeyChecking no" >> /etc/ssh/ssh_config.d/mlspace.conf \ && echo "UsePAM no" >> /etc/ssh/sshd_config.d/mlspace.conf \ && echo "PubkeyAcceptedAlgorithms +ssh-rsa" >> /etc/ssh/sshd_config.d/mlspace.conf \ && echo "Port 2222" >> /etc/ssh/sshd_config.d/mlspace.conf \ && echo "PidFile /run/sshd/sshd.pid" >> /etc/ssh/sshd_config.d/mlspace.conf \ && chmod 600 /etc/ssh/ssh_host_* \ && chown user:user /etc/ssh/ssh_host_* \ && chown user:user /run/sshd # Adding support for Openmp (optional) # For all images except NVIDIA NGC, which do not require the installation of HPC-X ARG UBUNTU_VER=22.04 ARG HPCX_VER=2.18.1 ARG HPCX_DIR=/opt/hpcx ARG HPCX_PACKAGE=hpcx-v${HPCX_VER}-gcc-mlnx_ofed-ubuntu${UBUNTU_VER}-cuda12-x86_64.tbz RUN mkdir -p ${HPCX_DIR} \ && wget --quiet --no-check-certificate -c https://content.mellanox.com/hpc/hpc-x/v${HPCX_VER}/${HPCX_PACKAGE} -O /tmp/${HPCX_PACKAGE} \ && tar xjf /tmp/${HPCX_PACKAGE} -C ${HPCX_DIR} --strip-components=1 # Installing Python (optional) # Only if Python is not installed in the image ARG CONDA_DIR=/home/user/conda ARG DOWNLOAD_LINK="https://repo.anaconda.com/miniconda/Miniconda3-py311_24.11.1-0-Linux-x86_64.sh" RUN mkdir -p ${CONDA_DIR} \ && wget --quiet --no-check-certificate ${DOWNLOAD_LINK} -O miniconda.sh \ && chmod +x miniconda.sh \ && /bin/bash miniconda.sh -f -b -p ${CONDA_DIR} \ && rm miniconda.sh ENV PATH="$CONDA_DIR/bin:$PATH" # Clearing the apt caches RUN apt-get clean # Setting the environment variables # To save environment variables correctly, we recommend creating a profile file in "/etc/profile.d/mlspace.sh", # which will contain the necessary environment variables that are activated when working in the image ENV LD_LIBRARY_PATH=/opt/hpcx/ompi/lib:/opt/hpcx/ucx/lib:/opt/hpcx/ucc/lib:/opt/hpcx/sharp/lib:/opt/hpcx/nccl_rdma_sharp_plugin/lib:/opt/hpcx/hcoll/lib:${LD_LIBRARY_PATH} ENV PATH=/opt/hpcx/ompi/bin:/opt/hpcx/ucx/bin:/opt/hpcx/ucc/bin:/opt/hpcx/sharp/bin:/opt/hpcx/hcoll/bin:${PATH} ENV OPAL_PREFIX=/opt/hpcx/ompi RUN echo "export LD_LIBRARY_PATH=$LD_LIBRARY_PATH">/etc/profile.d/mlspace.sh \ && echo "export PATH=$PATH" >> /etc/profile.d/mlspace.sh \ && echo "export OPAL_PREFIX=$OPAL_PREFIX" >> /etc/profile.d/mlspace.sh # Section USER user # All necessary actions on behalf of the user are performed in the section below under USER # If you are exporting variables in the section above, then the user # will not see them in this section, therefore they must be located here #### USER user # Installing Python libraries RUN pip install --no-cache-dir \ torch==2.4.0 \ torchvision==0.19.0 \ torchaudio==2.4.0 \ numpy==1.26.2 \ torchelastic \ scipy \ scikit-learn \ librosa \ boto3 \ matplotlib \ pandas \ chardet \ tensorboard \ bitsandbytes \ transformers \ datasets \ peft \ accelerate \ spacy \ nltk # Setting the necessary environment variables on behalf of an unprivileged user ENV LD_LIBRARY_PATH=/opt/hpcx/ompi/lib:/opt/hpcx/ucx/lib:/opt/hpcx/ucc/lib:/opt/hpcx/sharp/lib:/opt/hpcx/nccl_rdma_sharp_plugin/lib:/opt/hpcx/hcoll/lib:${LD_LIBRARY_PATH} ENV PATH=/opt/hpcx/ompi/bin:/opt/hpcx/ucx/bin:/opt/hpcx/ucc/bin:/opt/hpcx/sharp/bin:/opt/hpcx/hcoll/bin:${PATH} ENV OPAL_PREFIX=/opt/hpcx/ompi # Actions for the final stage SHELL ["/bin/bash", "-cu"]
Сборка образа
Перейдите в
.Нажмите Push command и скопируйте появившуюся команду.
Скопируйте имя хоста и неймспейс.
Убедитесь, что для использования в задачах обучения название репозитория начинается с префикса «job-«.
Выполните команду сборки образа в директории с вашим Dockerfile:
docker build -t cr.ai.cloud.ru/хххххххх-хххх-хххх-хххх-хххххххххххх/job-custom-image .
Шаг 2. Проверьте корректность сборки
Чтобы проверить работоспособность образа при запуске распределенной задачи:
Запустите образ локально через используемую вами систему (docker, containerd, cri-o). Вы попадете в образ.
Убедитесь, что вы работаете от имени пользователя user c
UID=GID=1000
:$ id uid=1000(user) gid=1000(user) groups=1000(user) <-- user and groups "user" with ID 1000
Убедитесь, что папка
/home/user
и/home/jovyan
существует и обладает нужными правами:$ ls -la /home total 28 drwxr-xr-x 1 root root 4096 Nov 18 19:56 . drwxr-xr-x 1 root root 4096 Nov 26 01:29 .. drwxr-xr-x 1 user user 4096 Nov 27 11:51 jovyan <-- user and group "user" drwxr-xr-x 1 user user 4096 Nov 26 01:31 user <-- user and group "user"
Убедитесь, что у вас установлен OpenMPI:
$ which mpirun /opt/hpcx/ompi/bin/mpirun <-- for an installed HPC-X, there will be a different path for another OpenMPI $ hostname asdh123asdh <-- Current container name $ mpirun -np 1 hostname asdh123asdh <-- Current container name
Убедитесь, что запуск OpenSSH не возвращает ошибку:
$ /usr/sbin/sshd -p 2222 $ ps ax | grep sshd 1437421 ? Ss 0:00 sshd: /usr/sbin/sshd -p 2222 [listener] 0 of 10-100 startups <-- the process is running
Запустите образ локально, выполнив команду:
docker run -it cr.ai.cloud.ru/хххххххх-хххх-хххх-хххх-хххххххххххх/job-custom-image
Шаг 3. Пройдите аутентификацию в Docker registry
Сгенерируйте ключ для Docker CLI:
В левом меню платформы перейдите в
.Возле воркспейса, для которого нужно сгенерировать ключ, нажмите и выберите Параметры разработчика.
Возле Docker CLI Key нажмите Сгенерировать ключ.
После генерации скопируйте ключ.
В левом меню перейдите в
.Сгенерируйте ключ для Docker registry:
Если в Docker registry нет загруженных образов, вместо виден значок . Чтобы изменить ключ, необходимо сгенерировать новый, нажав Сгенерировать ключ для Docker CLI.
Если в Docker registry есть загруженные образы, нажмите . В появившемся окне нажмите Сгенерировать ключ для Docker CLI.
После генерации скопируйте ключ.
Аутентифицируйтесь в Docker registry.
Откройте терминал на вашем компьютере и аутентифицируйтесь в Docker CLI, используя команду:
docker login cr.ai.cloud.ru --username example@example.com --password examplepsswd
Где параметр
example@example.com
— это email пользователя, аexamplepsswd
— ключ, однократно передаваемый пользователю при нажатии на Сгенерировать ключ для Docker CLI.
Шаг 4. Загрузите образ в Docker registry
Команду для использования тега можно просмотреть, нажав Push command в Docker registry.
docker push cr.ai.cloud.ru/хххххххх-хххх-хххх-хххх-хххххххххххх/job-custom-image:test_tag
Эта команда позволяет загрузить образ job-custom-image
с тегом test_tag
в Docker registry требуемого воркспейса.
Что дальше
Создайте и запустите задачу обучения, выбрав предпочитаемый способ.
для Dev & Test