Docker для специалиста по анализу данных. Разбираемся с Контейнерами.

Введение

Часто у начинающих Data Scientists возникает вопрос, как демонстрировать работу своих моделей другим людям. Банальный пример – прикрепить ссылку на гитхаб репозиторий в отклике на вакансию или показать свое “детище” знакомым со словами “смотрите, что умею”.

Проще говоря, мы хотим задеплоить нашу модель, превратить ее в демо нашего исследования.

Проблема в том, что для этого нужно скачивать репозиторий, установливать нужную версию python и всех необходимых библиотек, а также разбираться, как запускать приложение. Слишком много сложностей для человека, который хочет использовать или просто посмотреть вашу работу. То есть вопрос в том, как передать продукт клиенту.

В статье я расскажу простыми словами, что такое Docker и как его можно использовать для реализации своих решений в Machine Learning.

Что такое контейнеризация?

Docker для специалиста по анализу данных. Разбираемся с Контейнерами.

Одна из болей Data Scientist’a — клиенты, которые “запутались в установке”, у которых “непонятно написано” или “все сломалось”. Контейнеризация позволяет решить эту проблему.

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

Docker

Docker для специалиста по анализу данных. Разбираемся с Контейнерами.

Прежде чем начинать работу, необходимо установить docker на компьютер или сервер.

Создание образа

Сначала нужно создать образ сервера, который называется docker image. Это можно сделать несколькими способами, но самый простой и понятный – создать файл с названием Dockerfile. Это будет скрипт, содержащий последовательность действий для сборки образа.

В Docker образы могут наследоваться друг от друга, поэтому обычно в первой строчке за основу берут готовый образ:

FROM python:3.8-slim-buster

Готовые образы вы можете найти на docker hub

Теперь следует описать логику инициализации контейнера.

Для этого существует много директив, например RUN – для запуска какой-либо команды на сервере при сборке образа.

Ниже я опишу директивы, которые сам использовал для создания своего первого Docker-образа:

RUN mkdir /app

Команда, которая создает папку app внутри контейнера.

COPY . /app/
WORKDIR /app

Следующей командой мы копируем все файлы из локального диска (директории, где находится Dockerfile) в папку app. Затем мы объявляем app рабочей директорией.

RUN pip install -r requirements.txt

Я снова запускаю команду RUN для того, чтобы установить все зависимости внутри контейнера.

Еще раз уточню, что все пакеты с зависимостями находятся внутри контейнера и никак не пересекаются с версиями библиотек на локальном компьютере. То есть внутри контейнера своя виртуальная среда.

ENTRYPOINT ["python"]
CMD ["demo.py"]

Команда ENTRYPOINT позволяет объявить точку входа для сервера. Таким образом, при развертке сервера я запускаю Python в контейнере. Директива CMD говорит, что в командной строке/терминале я выполняю код внутри скобок.

Мы можем объединить две эти команды в одну:

CMD ["python", "demo.py"]

Создание контейнера

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

docker build . -t simp_server

Точка означает, что мы хотим собрать образ из Dockerfile, который находится в данной директории.

  • -t – тег для обозначения имени сервера
  • simp_server – любое имя сервера.

Итак, образ собран.

Для того, чтобы увидеть все образы на хост-машине, пропишем

docker images

Запускаем сервер следующей командой:

docker run --rm -it -p 8888:8888 simp_server
  • run создает контейнер.
  • --rm удаляет контейнер после завершения его работы.
  • -p 8888:8888 пробрасывает порты между хост-машиной и контейнером (порт на хост соответствует порту в контейнере).
  • simp_server определяет образ запускаемого сервера.

Пример деплоя модели c использованием Docker и flask

github репозиторий проекта

Суть проекта в том, что пользователь загружает картинку с персонажем из “Симпсонов” и получает предположение сети о том, кто на ней изображен.

Docker для специалиста по анализу данных. Разбираемся с Контейнерами.

Сначала я описываю логику приложения, используя библиотеку flask в файле demo.py. В нем находится один метод, который запрашивает у пользователя картинку и возвращает предсказание.

Это тот код, который я прошу запустить docker сервер на старте.

import os

from flask import Flask
from flask import request
from flask import render_template

from model.model import MobNetSimpsons


app = Flask(__name__)
UPLOAD_FOLDER = "static/"

@app.route('/', methods=['GET', 'POST'])
def upload_predict():
    if request.method == "POST":
        image_file = request.files["image"]
        image_location = os.path.join(
            UPLOAD_FOLDER,
            image_file.filename
        )
        if image_file:
            image_file.save(image_location)
            pred = model.predict(image_location)
            return render_template(
                "index.html", 
                prediction=pred[0],
                proba=round(pred[1], 2),
                image_loc=image_file.filename
            )
    return render_template("index.html", prediction=0, image_loc=None)

if __name__ == "__main__":
    model = MobNetSimpsons()
    app.run(port=8888, debug=True, host='0.0.0.0')

Также, мне понадобится класс, в котором инициализируется модель и объявляется метод для получения предсказания:

import pickle
import numpy as np

from torchvision import models
from torch import nn

from model.utils import *

DEVICE = 'cuda' if torch.cuda.is_available() else 'cpu'

class MobNetSimpsons():
    def __init__(self):
        print("Loading model...")
        self.model = models.mobilenet_v3_large(pretrained=True)
        num_features = 960
        n_classes = 42
        self.model.classifier = nn.Sequential(
            nn.Linear(num_features, 1280, bias=True),
            nn.Hardswish(),
            nn.Dropout(p=0.2, inplace=True),
            nn.Linear(1280, n_classes, bias=True) 
        )
        print("Seting parameters...")
        self.model.load_state_dict(torch.load('model/mobNetLarge.pth', map_location=DEVICE))
        print("Seting on evaluation mode...")
        self.model.eval()

        self.label_encoder = pickle.loads(open('model/label_encoder.pkl', 'rb').read())
        print("Model is ready!")

    def predict(self, image_path):
        img = prepare_img(image_path)

        proba = predict_one_sample(self.model, img, device=DEVICE)
        predicted_proba = np.max(proba)*100
        y_pred = np.argmax(proba)

        label = self.label_encoder.inverse_transform([y_pred])[0].split('_')
        label = label_to_string(label)

        return [label, predicted_proba]

Затем создаю Dockerfile и собираю образ:

docker build . -t simp_server

Далее создаю контейнер:

docker run --rm -it -p 8888:8888 simp_server

После этого перехожу по адресу http://localhost:8888/.

Если контейнер и приложение работают на вашем компьютере, то они будут работать и на другом компьютере, например, у вашего клиента.

Остается дать порядок команд для Docker’a.

Для моего приложения порядок установки выглядит так:

  1. Install and run Docker
  2. Build Docker image using docker build . -t simp_server
  3. Run Docker container using docker run --rm -it -p 8888:8888 simp_server
  4. Go to http://localhost:8888/

Магия

Если вашей моделью захотят воспользоваться, для этого нужно будет:

  1. Установить Docker
  2. Загрузить репозиторий
  3. Собрать образ (docker image)
  4. Создать и запустить контейнер

Что дальше?

В статье я расскрыл лишь одну проблему, которую может решить Docker, – доставка приложения до клиента.

Вы можете попробовать задеплоить свою модель, даже если она просто классифицирует ирис.

Docker для специалиста по анализу данных. Разбираемся с Контейнерами.

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

Полезные ссылки

— Подробнее про Docker

— Docker Documentation

— Flask Documentation

Источник

+1
0
+1
2
+1
0
+1
0
+1
0

Ответить

Ваш адрес email не будет опубликован. Обязательные поля помечены *