Примечание. Это объясняет развертывание модели Dockerization for Machine Learning с поддержкой GPU и без нее. Вы можете пропустить разделы в зависимости от того, хотите ли вы, чтобы ваша модель работала на CPU/GPU.

Контейнеризация — это самое простое и быстрое решение для упаковки приложения в стандартные блоки для разработки, доставки и развертывания. Контейнер упаковывает код вместе со всеми его зависимостями, чтобы приложение могло быстро и надежно работать из одной вычислительной среды в другую. Образ контейнера Docker — это легкий, автономный исполняемый пакет приложения, который включает в себя все необходимое для запуска приложения: код, среду выполнения, системные инструменты, системные библиотеки и настройки.

Развертывание модели машинного обучения часто зависит от API-интерфейсов ReST, при этом Flask является популярным выбором из-за его простоты, легкости, масштабируемости и более быстрой разработки/обучения. Anaconda упрощает управление пакетами Python и их развертывание. Часто предпочитают «pip» из-за его высокой производительности при установке пакетов, не зависящих от Python. Conda довольно хорошо справляется с разрешением зависимостей и установкой исходного кода. Он также стал стандартной платформой для науки о данных и разработки машинного обучения в Python.

Здесь мы видим, как докеризировать Flask API, работающий в среде anaconda, для развертывания модели. Это упрощает и ускоряет развертывание ваших моделей; будь то для тестирования или для производства; если вы используете платформу Conda для разработки. Подводя итог, ниже приведены общие шаги по докеризации и развертыванию модели машинного обучения.

  • Организуйте свой код и зависимости (вместе с файлами модели) в той же структуре каталогов, которой вы хотите следовать в докере.
  • Создайте файл «environment.yml», чтобы мы могли реплицировать нашу среду разработки conda внутри docker.
  • Создайте Dockerfile с полными инструкциями по настройке среды приложения в докере и запуску приложения при запуске докера.
  • Создайте образ докера из файла Dockerfile.
  • Бегать!

Предпосылки

Мы предполагаем, что в вашей системе установлены docker и nvidia-docker (на случай, если вам нужна поддержка графического процессора для вашего приложения), а модель машинного обучения готова, запущена и работает. работает для вывода в выделенной среде conda.

Теперь приступим к докеризации!

1. Организация кода и зависимостей

Организуйте свой код, модели и другие зависимости в желаемой структуре каталогов. Мы следуем приведенной ниже структуре на протяжении всей статьи.

my_app
    |- models
    |- src
        |- app.py
    |- Dockerfile
    |- environment.yml

2. Экспортируйте среду conda в файл «.yml».

Активируйте среду conda и выполните приведенную ниже команду, чтобы экспортировать среду в файл .yml.

conda env export > environment.yml

Текущая среда conda будет экспортирована в файл «environment.yml» в текущем каталоге. Он будет похож на шаблон ниже.

name: your-environment-name
channels:
- defaults
dependencies:
- python=3.6
- flask

Файл содержит три части информации. Имя среды при ее создании, из каких каналов будут загружаться библиотеки и, наконец, какая версия Python и библиотеки для установки.

3. Создание файла Docker

Теперь нам нужно создать Dockerfile, который представляет собой не что иное, как набор инструкций для создания образа Docker нашего приложения. Создайте файл с именем «Dockerfile» в том же каталоге и добавьте инструкции. У нас есть небольшие отличия от этого шага для докеризации с поддержкой GPU и без нее.

Продолжайте читать раздел 3.1, если вы хотите докеризовать свое приложение без поддержки графического процессора. Если вам нужна докеризация с поддержкой графического процессора, вы можете пропустить этот раздел и перейти к 3.2.

3.1 Dockerize без поддержки графического процессора

Примечание. Каждая из этих строк Dockerfile представляет собой слой, и каждый слой содержит только дельту или изменения из слоев перед ним.

Построчное описание

FROM continuumio/miniconda:latest

From позволяет нам инициализировать образ поверх базовой сборки. Так как нам нужна среда conda, мы используем облегченное изображение miniconda.

WORKDIR /my_app

Создайте каталог с именем my_app, в котором будет установлен текущий рабочий каталог.

ADD . /my_app

Скопируйте все, что находится в текущем каталоге, в каталог my_app’ в докере.

RUN apt-get update && apt-get -y install gcc

Это необходимо для установки gcc, так как он отсутствует в используемой нами сборке continuumio/miniconda:latest. В противном случае мы можем столкнуться с ошибкой, если на следующем шаге система попытается установить какой-либо пакет, для которого необходимо установить gcc.

RUN conda env create -f environment.yml

Это создает среду conda из файла environment.yml и устанавливает упомянутые в нем пакеты.

SHELL ["conda", "run", "-n", "myenv", "/bin/bash", "-c"]

Это нужно для активации среды conda «myenv».

EXPOSE 5000

Выставляем наружу порт 5000 докера. Это служит портом для API фляги. Таким образом, мы выполнили всю настройку среды внутри докера.

Примечание. Не забудьте указать порт, на котором запущено ваше приложение Flask. Наше приложение Flask работает на порту 5000.

ENTRYPOINT ["conda", "run", "-n", "myenv", "python", "src/myapp.py"]

Эта команда запускается при каждом запуске контейнера. Он активирует нашу среду conda 'myenv' и запускает наше приложение 'myapp.py', которое хранится в Каталог 'src'.

3.2 Докеризация с поддержкой графического процессора

Здесь вместо образа minoconda мы используем образ nvidia-docker в качестве базового слоя. Давайте посмотрим важные строки.

FROM nvidia/cuda:11.0-cudnn8-runtime-ubuntu18.04

From позволяет нам инициализировать образ поверх базовой сборки. Поскольку нам нужна поддержка графического процессора, мы можем использовать контейнеры докеров, предоставляемые NVIDIA. Это самый простой способ, поскольку он учитывает требования драйвера nvidia и cudnn. В противном случае вам нужно написать команды для установки драйвера nvidia и зависимостей cudnn.

Вы можете выбрать базовый слой в соответствии с вашим драйвером nvidia, cudnn и версией ОС. Список всех возможных тегов nvidia docker можно найти здесь.

WORKDIR /my_app

Создайте каталог с именем my_app, в котором будет установлен текущий рабочий каталог.

ADD . /my_app

Скопируйте все, что находится в текущем каталоге, в каталог my_app’ в докере.

RUN wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O Miniconda.sh && /bin/bash Miniconda.sh -b -p /opt/conda && rm Miniconda.sh

Мы устанавливаем miniconda (более легкая версия anaconda), чтобы мы могли воссоздать среду разработки conda с помощью сгенерированного файла environment.yml.

RUN apt-get update && apt-get -y install gcc

Это необходимо для установки gcc, так как он отсутствует в используемой нами сборке nvidia-docker. В противном случае мы можем столкнуться с ошибкой, если на следующем шаге система попытается установить какой-либо пакет, для которого необходимо установить gcc.

RUN conda env create -f environment.yml

Это создает среду conda из файла environment.yml и устанавливает упомянутые в нем пакеты.

SHELL ["conda", "run", "-n", "myenv", "/bin/bash", "-c"]

Это нужно для активации среды conda «myenv».

EXPOSE 5000

Выставляем наружу порт 5000 докера. Это служит портом для API фляги. Таким образом, мы выполнили всю настройку среды внутри докера.

Примечание. Не забудьте указать порт, на котором запущено ваше приложение Flask. Наше приложение Flask работает на порту 5000.

ENTRYPOINT ["conda", "run", "-n", "myenv", "python", "src/myapp.py"]

Эта команда запускается при каждом запуске контейнера. Он активирует нашу среду conda 'myenv' и запускает наше приложение 'myapp.py', которое хранится в Каталог 'src'.

Чтобы узнать больше о различиях между командами ENTRYPOINT и CMD и о том, когда использовать обе, обратитесь к этому блогу.

4. Сборка образа Docker из Dockerfilee

docker build -t my_docker:latest .

Здесь мы использовали только один вариант. -t или — tag позволяет нам назвать и, при необходимости, пометить наш образ докера, используя формат имя:тег. Не забудьте . в конце команды. Он берет текущий каталог в качестве пути и создает докер из Dockerfile, присутствующего в каталоге. Чтобы узнать больше о доступных параметрах, просмотрите эту официальную документацию от docker.

docker images

Теперь вы можете увидеть все доступные образы докеров. Вы должны увидеть «my_docker» с «latest» в качестве тега в списке! Теперь вы можете подтвердить, что вы успешно создали свой докер.

В процессе создания файла докера вы можете столкнуться с некоторыми ошибками и создать непригодные для использования образы докеров. Это хорошая практика, чтобы очистить между ними! Это поможет вам сохранить много памяти! :)

docker system prune

5. Запуск контейнера!

Здесь снова у нас есть небольшая разница в зависимости от того, должны ли мы работать с поддержкой графического процессора или без нее.

5.1 Без поддержки графического процессора

docker run -p 9000:5000 -d my_docker:latest

Мы должны сопоставить номер внутреннего порта с нашим системным портом. Наше приложение работает внутри докера и прослушивает порт 5000. Мы сопоставляем его с системным портом 9000. Теперь мы можем получить доступ к приложению, используя наш системный IP-адрес и порт 9000.

5.2 С поддержкой графического процессора

docker run --gpus all -p 9000:5000 -d my_docker:latest

Теперь наш докер работает на всех доступных видеокартах. Мы также сопоставили наш внутренний порт 5000 с системным портом 9000. Если вы хотите использовать только часть доступных карт графического процессора, вы можете использовать приведенную ниже опцию.

docker run --gpus device=0,2  -p 9000:5005 -d my_docker:latest

Теперь мы можем проверить, работает ли наш докер.

docker container ls

Это перечислит все контейнеры, которые работают. Если вы видите свой image:tag в списке, все готово! Поздравляем! У вас запущен док-контейнер, и он доступен через номер порта 9000! Используйте почтальон или любое другое средство, чтобы сделать вывод и убедиться, что все работает как надо!

Обратите внимание на идентификатор контейнера для дальнейшего использования! На самом деле полный идентификатор не требуется. Вы можете иметь уникальную подстроку идентификатора контейнера и запускать приведенные ниже команды по мере необходимости.

Полезные команды Docker

docker container logs <container_id>

Эта команда извлекает журналы, имеющиеся на момент выполнения, в пакетном режиме. Он извлекается из stdoutи stderr контейнера.

docker container stop <container_id>

Само собой разумеется, это останавливает ваш контейнер!

docker image rm <name>

Это удаляет образ Docker!

Чтобы попасть внутрь работающего экземпляра Docker, вы можете использовать:

docker exec -it <container_id> /bin/bash

Удачной докеризации! :)