Опубликовано в Serverless автором Anand Menon
Благодаря последним достижениям в экосистеме Deep Learning, таким как улучшенные фреймворки, готовые к производству архитектуры, предварительно обученные модели … и т.д. построить достойную модель легко (на самом деле нет 😅), но самый большой вопрос, который возникает после этого: «Я построил модель, что дальше?».
Модель хороша лишь настолько, насколько она может быть полезна клиентам, поэтому для того, чтобы сделать модель полезной, она должна быть предоставлена миллионам пользователей очень экономически эффективным способом. Как же мы можем предоставить или развернуть модель для пользователей? Легко, мы можем получить данные, хранилище и вычислительную мощность по требованию, используя любую из распространенных облачных платформ, таких как AWS, GCP, Azure … и т.д. В этом учебнике мы будем использовать облачную платформу AWS.
Лучшие вещи в жизни достаются бесплатно, но не ресурсы AWS. Ценообразование в облаке, даже если оно очень конкурентоспособно, может стать препятствием для инженеров при создании масштабируемых и ресурсоемких продуктов. Создание выделенной инфраструктуры экземпляров при создании MVP с возможностями искусственного интеллекта — это самоубийство, потому что мы не имеем представления об удержании пользователей, принятии продукта на рынке, получении дохода от продукта и т. д. Создание такого стека с использованием выделенной облачной инфраструктуры с нуля — дорогостоящая задача по нескольким причинам, о которых мы скоро поговорим*.*.
Итак, типичный стек API глубокого обучения выглядит следующим образом:
Как мы видим, это очень сложный стек, и недостатком такой инфраструктуры является то, что:
-
Мы должны управлять кластером — его размером, типом и логикой масштабирования.
-
Клиент должен платить за незадействованную мощность сервера
-
Мы должны управлять логикой контейнера — логированием, обработкой множества запросов и т.д.
-
Требуется большой опыт в облачной архитектуре
Чтобы решить недостатки выделенной облачной инфраструктуры, облачные провайдеры придумали бессерверные сервисы (например, AWS Lambda), основными преимуществами которых является то, что *нам не нужно управлять серверами, и мы получаем оплату по количеству выполнения функций, а не на почасовой основе* (1М бесплатных запросов в месяц).
Благодаря последним достижениям в экосистеме serverless, таким как поддержка контейнеров, улучшение памяти и т.д., это открыло широкие возможности для всех специалистов по Deep Learning развертывать модели в качестве API для выводов с помощью стека Lambda.
Поэтому сегодня мы развернем модель PyTorch в качестве бессерверного API, используя Lambda, ECR и Serverless framework. Если вы хотите сразу перейти к коду, пожалуйста, загляните в мой репозиторий на GitHub.
В этом руководстве мы развернем простую модель классификации текста с помощью BERT🤗, которая классифицирует ежедневные журналы транзакций пользователей по таким классам, как «еда», «транспорт», «счета»… и т.д., и предоставим ее в качестве API. Я буду подробно освещать следующие темы:
-
Краткое объяснение всех используемых ресурсов
-
Построение нашего конвейера вывода модели
-
Создание лямбда-функции с использованием serverless framework
-
Объединение нашего конвейера выводов с лямбда-функцией
-
Создание образа docker и локальное тестирование нашего API
-
Пометка и развертывание образов в AWS ECR
-
Развертывание лямбда-функций с помощью образа, развернутого в AWS ECR
-
Наконец, вывод модели с помощью бессерверного API.
-
Сервис AWS Lambda — «С большой силой приходит меньшая ответственность»
AWS Lambda — это сервис, позволяющий запускать функции на облачных серверах без фактического управления серверами. Как уже говорилось, управление серверами — задача не из легких. При использовании бессерверной технологии нам не нужно думать о масштабируемости и надежности нашей инфраструктуры, поскольку AWS заботится об этом за нас.
Чтобы программно взаимодействовать с ресурсами AWS, такими как ECR, S3 …и т.д., нам необходимо установить AWS CLI -
**Serverless Framework
**Serverless Framework позволяет быстро создавать и развертывать бессерверные приложения, используя такие сервисы, как AWS Lambda, S3, Amazon API Gateway и др. Этот фреймворк использует AWS CloudFormation для запуска всех ресурсов, необходимых для создания нашего API выводов с помощью конфигурационного файла YAML.
Для установки serverless framework следуйте инструкциям и обязательно настройте serverless с вашими секретными ключами доступа AWS, следуя руководству. -
**AWS ECR — **Docker 🐳 — все, что вам нужно
Amazon Elastic Container Registry (ECR) — это полностью управляемый контейнерный реестр, который упрощает хранение, управление, обмен и развертывание образов контейнеров и артефактов в любом месте. Итак, мы создаем образ docker нашего конвейера классификатора и храним его в AWS ECR.
Наша полная архитектура API показана выше, здесь пользователь делает запрос API с одним из своих ежедневных журналов транзакций, этот журнал проходит через шлюз AWS API, затем этот запрос запускает функцию Lambda. Для нашего первоначального запроса лямбда запускает 10-гигабайтную капсулу и получает образ докера из ECR для запуска нашего контейнера классификатора. Докер-образ состоит из модели и сценария вывода (сохранение модели в объектном хранилище является более эффективным подходом, но пока мы можем использовать этот подход для простоты). Итак, на основе запроса пользователя лямбда-функция выполняет вывод модели и возвращает конечный класс транзакции, как показано ниже:
Поскольку я объяснил весь процесс, теперь мы можем испачкать руки в коде. Я не буду рассказывать обо всем конвейере обучения модели классификатора BERT, поскольку это не является целью данного блога. Вы можете посмотреть мой **лабораторный блокнот** для обучения модели классификации журнала пользователя. После завершения процесса обучения вы получите **pytorch_model.bin **файл, который мы будем использовать в качестве модели для создания нашего бессерверного API.
Теперь мы собираемся создать лямбда-функцию python с помощью команды serverless CLI
serverless create --template aws-python3 --path serverless-logbert
Приведенная выше команда создаст простой boilerplate с базовым скриптом обработчика python, serverless.yml, requirements.txt ..etc. Поскольку мы строим модель классификации текста Deep Learning с использованием фреймворка pytorch, нам нужны некоторые пакеты, которые необходимо установить, поэтому давайте добавим их в наш файл requirements.txt. Поскольку мы не используем GPU для выводов, мы можем использовать минималистскую версию pytorch для процессора, чтобы сэкономить место в памяти.
-f [https://download.pytorch.org/whl/torch_stable.html](https://download.pytorch.org/whl/torch_stable.html)
torch==1.5.0+cpu
tqdm==4.60.0
sentencepiece==0.1.85
transformers==3.4.0
Теперь давайте перейдем непосредственно к нашей функции-обработчику. Обработчик функции Lambda — это метод в коде вашей функции, который обрабатывает события. Когда вызывается ваша функция, Lambda запускает метод обработчика. Когда обработчик выходит или возвращает ответ, он становится доступным для обработки другого события. Наш код обработчика выглядит следующим образом:
В приведенном выше коде метод sentence_prediction() принимает пользовательский ввод, препроцессирует, токенизирует и передает обученной модели BERT, которая в свою очередь возвращает окончательное предсказание. В настоящее время функция возвращает класс предсказания с наибольшей доверительной оценкой. Вы можете ознакомиться с кодом прогнозирования здесь
Теперь мы готовы протестировать наш API-интерфейс локально с помощью docker. Убедитесь, что docker установлен на вашей локальной машине, чтобы протестировать API, пожалуйста, ознакомьтесь с руководством по установке docker. Dockerfile выглядит следующим образом:
FROM public.ecr.aws/lambda/python:3.8
# copy function code and models into /var/task
COPY ./ ${LAMBDA_TASK_ROOT}/
# install our dependencies
RUN python3 -m pip install -r requirements.txt --target ${LAMBDA_TASK_ROOT}
# Set the CMD to your handler
CMD [ "handler.predict"]
Теперь давайте соберем наш образ docker и запустим наш контейнер для тестирования
docker build -t logbert-lambda .
docker run -p 8080:8080 logbert-lambda
Теперь мы готовы протестировать наш API локально.
Конечная точка URL должна иметь следующий формат. {hostname}/{lambda-api-version}/functions/function/invocations
Если функция работает в docker, то она должна работать и везде, так что большая часть нашей работы сделана. Для того чтобы функция Lambda могла получить этот образ, он должен быть развернут в AWS ECR (Elastic container registry). В качестве первого шага нам нужно создать репозиторий для сохранения нашего образа docker, это можно сделать программно с помощью AWS CLI следующим образом:
aws ecr create-repository --repository-name logbert-lambda
Для того чтобы запустить наш образ, нам сначала нужно войти в ECR с нашей машины, а для этого требуются некоторые идентификаторы, такие как регион AWS и идентификатор учетной записи AWS, которые мы можем получить из AWS IAM.
Теперь мы можем войти в ECR с помощью следующей команды:
aws_region=ap-south-1
aws_account_id=<12 digit id>aws ecr get_login-password
--region $aws_region
| docker login
--username AWS
--password-stdin $aws_account_id.dkr.ecr.$aws_region.amazonaws.com
Перед отправкой нашего образа в ECR нам нужно помнить, что по умолчанию все образы docker отправляются в Docker Hub, но здесь нам нужно отправить его в AWS ECR, чтобы лямбда-функция могла получить наш образ. Для этого нам нужно пометить или переименовать образ в такой формат, чтобы он был отправлен в соответствующий репозиторий ECR. Формат для этого следующий:
{AccountID}.dkr.ecr.{region}.amazonaws.com/{repository-name}.
docker tag logbert-lambda $aws_account_id.dkr.ecr.$aws_region.amazonaws.com/logbert-lambda
Проверим список образов docker с помощью команды » *docker image ls» *, мы сможем увидеть образ docker с вышеуказанным форматом. Теперь все готово для отправки образа в ECR.
docker push $aws_account_id.dkr.ecr.$aws_region.amazonaws.com/logbert-lambda
Мы подошли к заключительному этапу нашего руководства — развертыванию AWS Lambda с помощью нашего пользовательского образа. Теперь нам нужно отредактировать наш файл serverless.yml, который был создан как файл-шаблон при создании нашей лямбда-функции. Следующий файл yml позволяет настроить ресурсы AWS, которые должны быть запущены при развертывании нашей функции лямбда.
ECR значительно облегчает нам жизнь, поскольку нам нужно передать только путь url и путь digest, чтобы лямбда могла получить наш локально протестированный образ при запуске сервиса. Мы можем получить путь URL либо с помощью AWS CLI, либо напрямую скопировать его из консоли ECR, дайджест можно найти в только что созданном репозитории. Обязательно замените PATH образа на наш собственный URL путь и дайджест.
Теперь мы готовы развернуть нашу лямбда-функцию с помощью следующей команды:
serverless deploy
Приведенная выше команда запустит все ресурсы, такие как шлюз AWS API, лямбда-функция, ведро s3 …и т.д., используя AWS CloudFormation, которые необходимы для работы API. После завершения процесса развертывания мы получим некоторые журналы, как показано ниже
Мы почти закончили 😁, теперь давайте сделаем самое интересное. Да, протестируем наш только что созданный API. Давайте снова вернемся к Postman и используем URL, который мы получили из вышеприведенного журнала развертывания serverless, и протестируем его.
Да! Он сработал, как и ожидалось, и потребовалось всего полсекунды, чтобы получить ответ, и это при том, что CPU делает выводы.
Эта инфраструктура API без сервера имеет свою долю плюсов и минусов, **самым большим плюсом является то, что она автоматически масштабируется до тысяч параллельных запросов без каких-либо проблем. **Так что нам не нужно беспокоиться о создании масштабируемой и надежной архитектуры самостоятельно (это значит, что никто не будет звонить вам посреди ночи, чтобы исправить перегрузку сервера 😴 🤯).
В то же время он не очень подходит для создания готовых к производству критически важных API из-за проблемы холодного старта, но это можно в некоторой степени исправить, используя AWS CloudWatch для поддержания нашего лямбда-сервиса в теплом состоянии. GPU в настоящее время недоступны для AWS lambda, что является большим разочарованием 😞 для всех специалистов по Deep Learning, мы можем надеяться увидеть такие возможности в будущих итерациях.
Будущее выглядит светлым для бессерверной инфраструктуры, когда дело доходит до создания MVP (минимальных жизнеспособных продуктов) на основе ИИ очень экономически эффективным способом.
Надеюсь, вы сочтете этот пост полезным. Всегда открыт для предложений и критики. Спасибо 😁
Первоначально опубликовано на https://www.serverless.com.