Недавно я влюбился в SageMaker. Просто потому, что это так удобно! Мне очень нравится их подход, скрывающий от клиентов все инфраструктурные потребности и позволяющий им сосредоточиться на более важных аспектах машинного обучения в своих решениях. Несколько щелчков мышью и ввод текста здесь и там, вуаля, у вас есть готовая к производству модель, готовая принимать тысячи (если не миллионы) запросов в день. Если вам нужно хорошее представление о SageMaker, посмотрите следующее видео от кого-то другого, кроме Amazon!

Так что же может пойти не так?

Но у вас могут возникнуть проблемы, когда вы пытаетесь настроить и создать свои собственные модели в собственном контейнере докеров для выполнения пользовательских операций! Это не так просто и гладко, как создавать все с помощью SageMaker с самого начала.

Зачем вам нужны собственные модели?

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

  • Использование некоторых конкретных версий библиотеки Python вместо последних (например, TensorFlow)
  • Использование библиотек, недоступных в SageMaker

Прежде чем продолжить…

Прежде чем двигаться дальше, убедитесь, что у вас есть следующее.

  • Докер установлен и запущен в вашей ОС
  • Базовые знания о том, как работает Docker

как нам это сделать?

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

  • Создайте образ докера с вашим кодом
  • Локальное тестирование контейнера докеров
  • Развертывание образа в Amazon ECR (репозиторий эластичных контейнеров)

Позвольте мне пояснить эти моменты здесь. Сначала вы создаете образ докера с библиотеками, кодом и другими требованиями (например, доступом к портам). Затем вы создаете контейнер из этого образа и запускаете контейнер. Затем вы тестируете код / ​​модели с небольшим фрагментом данных в контейнере. После успешного тестирования вы загружаете образ докера в ECR. Затем вы можете указать это изображение в качестве модели машинного обучения и использовать его для обучения / прогнозирования с помощью Amazon SageMaker.

Кроме того, я буду использовать этот учебник / руководство как основу для этого блога. Это действительно хороший урок. Есть несколько причин, по которым я подумал о том, чтобы заново изобрести этот пост в блоге:

  • Это хороший урок, если вы полагаетесь только на scikit-learn. Я подумал о создании контейнера с помощью XGBoost, поэтому нам придется немного повозиться с нашим контейнером Docker.
  • Я хочу Python 3, а не Python 2 по очевидным причинам.
  • Я также чувствую, что некоторые детали отсутствуют кое-где (особенно когда речь идет о локальном тестировании).

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

Обзор Docker

Вы знаете, что еще удивительно, чем SageMaker? Докер. Докер чрезвычайно мощный, портативный и быстрый. Но здесь не место обсуждать, почему. Итак, давайте сразу погрузимся в настройку. При работе с Docker у вас есть четкий набор шагов, которые вы должны предпринять:

  • Создайте папку с кодом / моделями и специальный файл с именем Dockerfile, в котором есть рецепт для создания образа докера.
  • Создайте образ докера, запустив docker build -t <image-tag>
  • Запустите образ, запустив docker run <image>
  • Отправьте образ докера в какое-либо хранилище, в котором будет храниться образ (например, dockerhub или репозиторий AWS ECR), используя docker push <image-tag>

Обзор контейнеров Docker, совместимых с SageMaker

Обратите внимание, что SageMaker требует, чтобы изображение имело определенную структуру папок. Структура папок, которую ищет SageMaker, выглядит следующим образом. В основном есть две родительские папки /opt/program, где находится код, и /opt/ml, где находятся артефакты. И обратите внимание, что я размыл некоторые файлы, которые вам, вероятно, не нужно редактировать (по крайней мере, для этого упражнения), и которые выходят за рамки этого руководства.

Давайте теперь подробно обсудим, что такое каждая из этих сущностей. Во-первых, opt/ml - это место, где будут храниться все артефакты. Теперь поговорим о каждом из подкаталогов.

Каталог: / opt / ml

input/data - это каталог, в котором хранятся данные для вашей модели. Это может быть любой файл, связанный с данными (при условии, что ваш код Python может считывать данные, а в контейнере есть необходимые библиотеки для этого). Здесь <channel_name> - имя некоторого расходуемого входного источника, который будет использоваться моделью.

model - это место, где будет находиться модель. Вы можете либо поместить модель в контейнер, либо указать URL-адрес (расположение корзины S3), где артефакты модели находятся в виде tar.gz файла. Например, если у вас есть артефакты модели в корзине Amazon S3, вы можете указать на эту корзину S3 во время настройки модели в SageMaker. Затем эти артефакты модели будут скопированы в каталог model, когда ваша модель будет запущена и работает.

Наконец, output - это директор, который будет хранить причины сбоя запроса / задачи, если это не удается.

Каталог: / opt / program

Давайте теперь погрузимся в сливки нашей модели. алгоритм. Он должен быть доступен в каталоге /opt/program нашего контейнера Docker. Есть три основных файла, с которыми нужно быть осторожными: train, serve и predictor.py.

train содержит логику для обучения модели и хранения обученной модели. Если файл train работает без сбоев, он сохранит модель (то есть файл pickle) в каталог /opt/ml/model.

serve essential запускает логику, написанную на predictor.py, как веб-службу с использованием Flask, которая будет прослушивать любые входящие запросы, вызывать модель, делать прогнозы и возвращать ответ с прогнозами.

Dockerfile

Это файл, который лежит в основе того, что будет доступно в вашем контейнере Docker. Это означает, что этот файл имеет первостепенное значение. Итак, давайте заглянем внутрь. Это довольно просто, если вы уже знакомы с тем, как писать Dockerfile. Но все же позвольте мне провести вам краткую экскурсию.

  • Инструкция FROM определяет базовое изображение. Итак, здесь мы используем уже созданный образ Ubuntu в качестве нашего базового образа.
  • Затем, используя команду RUN, мы устанавливаем несколько пакетов (включая Python 3.5), используя apt-get install
  • Затем снова, используя команду RUN, мы устанавливаем pip, а затем numpy, scipy, scikit-learn, pandas, flask и т. Д.
  • Впоследствии мы устанавливаем несколько переменных среды в контейнере Docker с помощью команды ENV. Нам нужно добавить наш каталог /opt/program к переменной path, чтобы при вызове контейнера он знал, где находятся файлы, относящиеся к нашему алгоритму.
  • И последнее, но не менее важное: мы COPY папку, содержащую файлы, относящиеся к алгоритму, в /opt/program каталог, а затем устанавливаем это WORKDIR

Создание собственного Docker-контейнера

Во-первых, я собираюсь использовать модифицированную версию (ссылка здесь) замечательного пакета, представленного в репозитории awslabs на Github. В этом исходном репозитории есть все файлы, необходимые для работы нашей модели SageMaker, поэтому нужно отредактировать файлы, чтобы они соответствовали нашим требованиям. Загрузите содержимое из исходной ссылки в папку с именем xgboost-aws-container, если вы хотите начать с нуля, в противном случае вы можете повозиться с моей версией репозитория.

Примечание. Если вы пользователь Windows и один из тех, кому не повезло запустить устаревшую панель инструментов Docker, убедитесь, что вы используете какой-либо каталог в C:\Users каталоге в качестве домашней папки проекта. В противном случае вы столкнетесь с очень неприятным опытом монтирования папки в контейнер.

Изменения в существующих файлах

  1. Переименуйте папку decision-trees в xgboost
  2. Отредактируйте файл train, как указано в репозитории. По сути, я импортировал xgboost и заменил модель дерева решений на модель XGBClassifier. Обратите внимание, что при возникновении исключения оно будет записано в файл сбоя в папке /opt/ml/output. Таким образом, вы можете включить столько описательных исключений, сколько захотите, чтобы убедиться, что вы знаете, что пошло не так, если программа выйдет из строя.
  3. Отредактируйте файл predictor.py, как указано в репозитории. По сути, то, что я сделал, похоже на изменения, сделанные на train. Я импортировал xgboost и изменил классификатор на XGBClassifier.
  4. Откройте свой Dockerfile и сделайте следующие правки.

Вместо python мы используем python3.5, а также добавляем libgcc-5-dev, как того требует xgboost.

RUN apt-get -y update && apt-get install -y — no-install-recommends \
 wget \
 python3.5 \
 nginx \
 ca-certificates \
 libgcc-5-dev \
 && rm -rf /var/lib/apt/lists/*

Мы собираемся запросить конкретные версии numpy, scikit-learn, pandas, xgboost, чтобы убедиться, что они совместимы друг с другом. Еще один лучший момент при указании версий библиотек, которые вы хотите использовать, - это то, что вы знаете, он не сломается только потому, что новая версия какой-либо библиотеки несовместима с вашим кодом.

RUN wget https://bootstrap.pypa.io/3.3/get-pip.py && python3.5 get-pip.py && \
 pip3 install numpy==1.14.3 scipy scikit-learn==0.19.1 xgboost==0.72.1 pandas==0.22.0 flask gevent gunicorn && \
 (cd /usr/local/lib/python3.5/dist-packages/scipy/.libs; rm *; ln ../../numpy/.libs/* .) && \
 rm -rf /root/.cache

Затем мы собираемся изменить команду COPY на следующую

COPY xgboost /opt/program

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

Теперь откройте свой терминал Docker (в Windows или терминал ОС) и перейдите в родительский каталог пакета. Затем выполните следующую команду.

docker build -t xgboost-tut .

Это должно создать образ со всем, что нам нужно. Убедитесь, что образ создан, запустив,

docker images

Вы должны увидеть что-то вроде следующего.

Запуск контейнера Docker для обучения модели

Теперь пора запустить контейнер и запустить следующую команду.

docker run --rm -v $(pwd)/local_test/test_dir:/opt/ml xgboost-tut train

Давайте разберемся с этой командой.

--rm: означает, что контейнер будет уничтожен при выходе из него.

-v <host location>:<container location>: монтирует том в желаемое место в контейнере. Предупреждение: пользователи Windows, у вас возникнут проблемы, если вы выберете что-то другое, кроме C:\Users.

xgboost-tut: Название изображения.

train: При запуске контейнера он автоматически запускает файл train из каталога /opt/program. Вот почему важно указать /opt/program как часть переменной PATH.

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

Starting the training.
Training complete.

Вы также должны увидеть файл xgboost-model.pkl в вашем <project_home>/local_test/test_dir/model каталоге. Это связано с тем, что мы примонтировали каталог local_test/test_dir к /opt/ml контейнера, поэтому все, что происходит с /opt/ml, будет отражено в test_dir.

Тестирование контейнера на месте для обслуживания

Затем мы посмотрим, правильно ли работает логика обслуживания (вывода). А теперь позвольте мне еще раз предупредить, если вы пропустили это выше! Если вы пользователь Windows, будьте осторожны при правильной установке тома. Чтобы избежать ненужных проблем, убедитесь, что вы выбрали папку в папке C:\Users в качестве домашнего каталога вашего проекта.

docker run --rm --network=host -v $(pwd)/local_test/test_dir:/opt/ml xgboost-tut serve

Позвольте мне указать на специальный параметр, который мы указываем в команде Docker run.

--network=host: означает, что сетевой стек хоста будет скопирован в контейнер. Так что это будет похоже на запуск чего-то на локальной машине. Это необходимо, чтобы проверить, нормально ли работают вызовы API.

Примечание. Я использую --network=host, потому что -p <host_ip>:<host_port>:<container_port> не работает (по крайней мере, в Windows). Я рекомендую использовать параметр -p (если он работает), как показано ниже. Предупреждение: используйте только одну из этих команд, а не обе. Но я собираюсь использовать вариант --network=host, чтобы продолжить.

docker run --rm -p 127.0.0.1:8080:8080 -v $(pwd)/local_test/test_dir:/opt/ml xgboost-tut serve

serve: это файл, который вызывает логику вывода

Это должно показать вам результат, аналогичный приведенному ниже.

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

curl http://<docker_ip>:8080/ping

Вы можете узнать IP-адрес Docker-машины,

docker-machine ip default

Эта команда ping должна вызвать два сообщения как на стороне хоста, так и на стороне сервера. Что-то вроде ниже.

Если бы все это прошло гладко (я очень на это надеюсь) до этого момента. Поздравляю! вы почти настроили образ Docker, совместимый с SageMaker. Еще одна вещь, которую нам нужно сделать, прежде чем мы начнем жить.

А теперь давайте попробуем что-нибудь поинтереснее. Давайте попробуем сделать прогноз с помощью нашего веб-сервиса. Для этого мы воспользуемся файлом predict.sh, который находится в папке local_test. Обратите внимание, что я адаптировал его под свои требования, а это означает, что он отличается от того, который был предоставлен в исходном репозитории awslabs. А именно, я представил новый аргумент пользовательской подсказки, который принимает IP-адрес и порт в дополнение к тем, которые были взяты в исходном файле. Мы вызываем этот измененный файл predict.sh, используя следующую команду.

./predict.sh <container_ip>:<port> payload.csv text/csv

Здесь мы вызываем веб-службу вывода, используя данные из payload.csv, и сообщаем, что это файл csv. Он должен вернуть вам следующее. Это говорит о том, что он идентифицировал точку данных в нем как принадлежащую к классу setosa.

* timeout on name lookup is not supported
* Trying <container_ip>…
* TCP_NODELAY set
* Connected to <container_ip> (<container_ip>) port <port> (#0)
> POST /invocations HTTP/1.1
> Host: <container_ip>:<port>
> User-Agent: curl/7.55.0
> Accept: */*
> Content-Type: text/csv
> Content-Length: 23
>
* upload completely sent off: 23 out of 23 bytes
< HTTP/1.1 200 OK
< Server: nginx/1.10.3 (Ubuntu)
< Date: <date and time> GMT
< Content-Type: text/csv; charset=utf-8
< Content-Length: 7
< Connection: keep-alive
<
setosa
* Connection #0 to host <container_ip> left intact

Поднимая его до ECR

Ладно! так что тяжелая работа наконец окупилась. Пришло время отправить наш образ в репозиторий Amazon Elastic Container Repository (ECR). Перед этим убедитесь, что у вас есть репозиторий, созданный в ECR для отправки изображений. Это довольно просто, если у вас есть учетная запись AWS.

Перейдите в сервис ECR из панели управления AWS и нажмите «Создать репозиторий».

После того, как вы создадите репозиторий внутри репозитория, вы должны увидеть инструкцию для завершения отправки в ECR.

Примечание: вы также можете использовать build_and_push.sh, предоставленный в репозитории. Но лично мне удобнее заниматься делами самому. И это не так уж и много шагов, чтобы продвинуть репозиторий.

Сначала вам нужно получить учетные данные для входа в ECR.

aws ecr get-login — no-include-email — region <region>

который должен возвращать такой вывод, как,

docker login …

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

docker tag xgboost-tut:latest <account>.dkr.ecr.<region>.amazonaws.com/xgboost-tut:latest

Пришло время отправить изображение в ваше хранилище.

docker push <account>.dkr.ecr.<region>.amazonaws.com/xgboost-tut:latest

Теперь изображение должно появиться в вашем репозитории ECR с тегом latest. Итак, сложная часть сделана, затем вам нужно создать модель SageMaker и указать на изображение, что очень просто, как создание модели с помощью самого SageMaker. Так что я не буду растягивать сообщение в блоге этими деталями.

Вы можете найти репозиторий Github со всем кодом здесь.

Заключение

Путешествие было долгим, но, на мой взгляд, плодотворным. Итак, в этом уроке мы сделали следующее.

  • Сначала мы поняли, зачем нам создавать собственные модели.
  • Затем мы изучили структуру контейнера Docker, необходимого SageMaker для его запуска.
  • Затем мы обсудили, как создать Docker-образ контейнера.
  • Затем последовало создание образа и запуск контейнера.
  • Затем мы обсудили, как протестировать контейнер на локальном компьютере, прежде чем отправлять
  • Наконец, мы обсудили, как отправить изображение в ECR, чтобы оно было доступно для использования через SageMaker.

Особая благодарность участникам, создавшим оригинальный репозиторий Github, что дало мне отличную отправную точку! И последнее, но главное: если вам понравилась эта статья, не забудьте оставить несколько аплодисментов :)

Хотите стать лучше в глубоких сетях и TensorFlow?

Ознакомьтесь с моими работами по этой теме.

[1] (Книга) TensorFlow 2 в действии - Мэннинг

[2] (Видеокурс) Машинный перевод на Python - DataCamp

[3] (Книга) Обработка естественного языка в TensorFlow 1 - Packt

Новый! Присоединяйтесь ко мне на моем новом канале YouTube

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