И почему сложная часть ИИ не имеет ничего общего с ИИ

Заканчивая свою докторскую диссертацию по компьютерным системам в Калифорнийском университете в Беркли, я часто задаюсь вопросом, на что похожа жизнь в мире искусственного интеллекта. Мои друзья ИИ постоянно хвастаются тем, что глубокое обучение произведет революцию во всем, от медицины до покупок в Интернете - и их статьи получают сотни ссылок, как только они публикуются (какого черта!). Но мне всегда было интересно, как они на самом деле используют ИИ для решения реальных проблем.

В то же время я недавно заметил, что большую часть времени провожу, отвечая на разговоры в Slack. Вдохновленный недавним сообщением в блоге (и испытывая большую апатию к написанию тезисов), я решил создать и развернуть Slackbot на основе глубокого обучения, чтобы автоматически добавлять реакции на сообщения Slack с наиболее подходящими смайликами. 😃 👍

В этом посте я расскажу о своем опыте создания этого Slackbot на базе DeepMoji. В итоге я развернул DeepMoji с использованием двух разных фреймворков (AWS SageMaker и Algorithmia). Здесь я сравниваю свой опыт использования обеих систем, выделяя некоторые сильные стороны, ограничения и возможности для улучшения систем прогнозирования. Этот пост довольно высокоуровневый, но в этом репозитории есть ссылки с подробными инструкциями и кодом для воспроизведения моего Slackbot.

Лично я последние несколько лет работал над масштабируемыми облачными системами. Я был особенно рад приступить к этой задаче, потому что недавно мы потратили некоторое время на размышления о масштабируемой инфраструктуре прогнозирования. Тем не менее, я определенно не эксперт по системам искусственного интеллекта, поэтому дайте мне знать, если я что-то упустил.

Шаг 0: Настройка Slackbot

Настройка Slackbot довольно проста, но требует частого клика по сайту Slack. Я задокументировал процесс здесь с помощью нескольких снимков экрана, но на высоком уровне я создал бота, связал его со своей рабочей областью и дал ему разрешение на просмотр сообщений и добавление смайликов.

Следующий шаг: выберите модель машинного обучения, благодаря которой мой Slackbot будет реагировать на текст с помощью смайлов!

Шаг 1. Запустите модель на моем ноутбуке

Так какую магию ИИ я должен использовать? У меня нет данных для обучения модели, но, к счастью, есть масса предварительно обученных моделей, которые я могу использовать повторно. Мои коллеги по искусственному интеллекту говорят мне, что это новая тенденция в дизайне моделей: начните с существующей модели и настройте ее под свою задачу. В моем случае модель DeepMoji делает именно то, что мне нужно, и она уже обучена и имеет открытый исходный код.

Для небольшого контекста DeepMoji обучен 1,2 миллиарда твитов с эмодзи, чтобы понять тональность языка и то, как оно соотносится с эмодзи. Мой вариант использования довольно прост: отправьте модели сообщение Slack и отреагируйте смайликом, который, по мнению модели, лучше всего отражает тональность сообщения.

Плохие новости: DeepMoji использует Python 2 (фу). Хорошие новости: хорошие люди из HugginFace разработали torchMoji, реализацию DeepMoji на PyTorch, которая поддерживает Python3. В кодовой базе torchMoji была ошибка, которую мне пришлось исправить, чтобы правильно проанализировать объект PackedSequencePyTorch. Рабочая версия доступна на моей вилке здесь. Для этой части требуется только ноутбук, так что вы можете следить дома, если вам интересно.

После исправления ошибки получить обученную модель очень просто. Сначала я установил torchMoji как пакет:

pip3 install git+https://github.com/cw75/torchMoji

Мне понадобился файл с весами модели и словарный запас для инициализации модели. Файл словаря уже был в репо (здесь). Чтобы загрузить гири, я выполнил:

python3 scripts/download_weights.py

Теперь, когда все предварительные условия загружены, для составления прогноза требуется всего несколько строк Python:

Вы можете протестировать его, чтобы убедиться, что все работает:

Довольно круто! Мне даже не понадобился графический процессор.

Следующий шаг: превратите это в службу прогнозирования с веб-интерфейсом REST, который может вызывать мой Slackbot!

Шаг 2. Настройте службу прогнозирования

Обслуживание прогнозов - это системная проблема в этом сценарии; оперативный движок, который заставит этого бота действительно работать. Важный вопрос: где должна располагаться служба прогнозирования?

Лучшее решение - просто обернуть сценарий прогнозирования, который я написал выше, на сервере Flask и использовать такой инструмент, как ngrok, для создания конечной точки REST на моем ноутбуке или экземпляре EC2. Проблема в том, что я хочу развернуть бота в команде Slack моей лаборатории, чтобы каждый мог с ним играть, поэтому бот должен быть всегда включен и масштабируем.

Так что мне нужно было что-то реальное, и как системный хакер, часть меня хотела создать сервис с нуля: упаковать мой скрипт в образ Docker, запустить кластер Kubernetes и открыть конечную точку REST через AWS ELB. .

С другой стороны, как исследователь, я не хочу изобретать велосипед, и я знаю, что облачные провайдеры, такие как Google, Amazon и Microsoft, имеют предложения для обслуживания прогнозов. Первой платформой, которая пришла в голову, была AWS SageMaker, управляемый сервис на AWS, который охватывает весь жизненный цикл машинного обучения от разработки модели до развертывания. Команда выпустила статью о SageMaker на SIGMOD’20, и я уже много лет использую сервисы AWS для своих исследований, поэтому решил, что это разумно. Я не осознавал, что ступаю в пропасть…

Платформа 1: Amazon SageMaker

Я ожидал, что развернуть модель в SageMaker будет просто. У меня уже был список зависимостей Python и сценарий прогнозирования, который я показал выше. Все, что я хотел сделать, это загрузить сценарий, зависимости и модель в SageMaker, создать конечную точку REST и подключить ее к Slackbot.

Но, увы, нет возможности загрузить модель в SageMaker. Вместо этого мне пришлось создать образ Docker со всеми установленными зависимостями Python. Мне также пришлось написать сервер Flask, который обертывает мой сценарий прогнозирования и отвечает на запросы проверки работоспособности и модели SageMaker - вы можете увидеть документы здесь, Dockerfile здесь и мой сервер Flask здесь. Это не так уж сложно, но если бы я не был знаком с Docker и Flask, мне бы, наверное, потребовалось время, чтобы разобраться.

Я использую Docker много лет, но мои друзья из искусственного интеллекта мало о нем знают. Что вы думаете о Docker: создание контейнеров - это самое современное в искусственном интеллекте? Люди хорошо в этом разбираются?

Я начинаю задаваться вопросом, что для меня делает SageMaker. Если я все это делаю, почему бы просто не запустить собственный кластер Kubernetes? Это может быть даже проще, потому что Kubernetes автоматически позаботится о проверке работоспособности за меня!

SageMaker не работает с DockerHub, поэтому, как только я создал образ Docker, мне пришлось отправить его в собственный реестр Docker Amazon - AWS ECR (Elastic Container Registry). Затем я создал модель SageMaker, которая извлекает этот образ Docker, и конечную точку SageMaker, которая использует мою модель. Это потребовало выбора типа узла (ml.m4.large) и размера кластера. Наконец, я смог создать свою конечную точку REST!

После 10 минут ожидания запуска моей службы я был взволнован, увидев изменение статуса с «Создание» на «InService» с зеленой галочкой. ✅ Отлично! Я скопировал URL-адрес конечной точки в свою конфигурацию Slackbot, готовый поразить всех в лаборатории. И… Slack выплюнул эту ошибку:

Your URL didn't respond with the value of the challenge parameter.

Пришло время устранить неполадки в SageMaker! Мне пришлось написать сценарий Python с использованиемboto3 (с соответствующими разрешениями) и выполнить вызов InvokeEndpoint для проверки конечной точки. Используя этот сценарий для отладки в течение получаса, я обнаружил, что сама конечная точка действительно работает нормально. Настоящая проблема в том, что к SageMaker можно получить доступ только из внутри виртуального частного кластера AWS, и он не должен принимать запросы из внешнего Интернета, поэтому Slack не может до него добраться!

Решение, согласно этому сообщению в блоге, состоит в том, чтобы просто использовать сервис AWS API Gateway для приема трафика от Slack, перенаправить запрос на AWS Lambda , которая аутентифицирует запрос, а затем с помощью Lambda отправляет прогнозирующий запрос в SageMaker. Какие?!? Это заслуживает архитектурной схемы:

Это какое-то безумное перенаправление, когда все, что мне нужно, - это сделать свою модель доступной из Интернета! Итак ... пора написать лямбда-функцию. Я всегда рад возможности использовать бессерверные системы - в конце концов, это было основной темой моих исследований, - но это оказалось немного сложнее, чем я ожидал.

На самом деле, это было намного сложнее, чем я ожидал. Я должен был ответить на «запрос вызова Slack» (строки 24–29), аутентифицировать каждый запрос для защиты от хакеров (строки 31–37) и явно проанализировать текстовое поле из входящего HTTP-запроса (строки 38–43), прежде чем я на самом деле можно было бы назвать модель SageMaker (строки 47–52). Наконец, в строке 55 я использовал клиент Slack Python API, чтобы добавить реакцию на входное сообщение.

Стоит отметить еще несколько вещей, которые я пока пропустил:

  1. Мне пришлось создать роль IAM (сервис безопасности и аутентификации AWS) с sagemaker:InvokeEndpointpolicy и назначить ее функции Lambda, чтобы она могла запрашивать мою конечную точку SageMaker.
  2. При использовании клиента Slack API мне пришлось предоставить боту токен доступа OAuth (строка 13) и секрет подписи (строка 15), которые уникальны для каждого Slackbot.
  3. Мне пришлось явно упаковать сторонние зависимости Python (Slack SDK) и скрипт функции Lambda в zip-файл и загрузить его в AWS Lambda. Подробности здесь.

Подожди, так что ... действительно, что делает для меня SageMaker? Я создал контейнер Docker для своей модели, эффективно написал прокси-службу, вручную аутентифицировал каждый запрос, а также мне нужно настроить отдельную конечную точку REST. Может быть, делать это вручную с EC2 и Kubernetes было бы проще?

Последним шагом было создание шлюза API, который перенаправляет сообщения подписки из Slack в мою функцию Lambda. По пути я попал в, как мне кажется, несколько распространенных ловушек. Например, я забыл проверить Use Lambda Proxy integrationbox, поэтому шлюз API удалял заголовки HTTP из каждого запроса при пересылке его в Lambda. Это привело к сбою аутентификации, поскольку Slack встраивает свои токены в заголовок. Я задокументировал все (многие) шаги здесь, чтобы вы не повторили мои ошибки.

В любом случае, на отладку ушел еще час, но API Gateway наконец сгенерировал настоящую конечную точку REST. Я вставил конечную точку в подписку Slackbot, и, наконец, это сработало! Я отправил сообщение своему боту в рабочую область Slack, и получил реакцию. 😎

Вуаля! Мне потребовалось 6 часов, чтобы собрать все части вместе, но наконец-то все заработало! Каждый запрос занимает несколько секунд, что… ну, не очень интерактивно. Учитывая поток трафика, показанный на «диаграмме архитектуры» выше, это неудивительно. Большинство этих сервисов не были оптимизированы для задержки.

В общем, развертывание torchMoji на SageMaker было проблемой. Хуже того, после всех усилий каждый запрос занимал больше секунды! Не говоря уже о стоимости - помимо постоянной работы сервера модели, теперь мы платим AWS за каждый синхронный вызов Lambda. Это определенно не будет дешевым, если все 400+ пользователей RISELab Slack начнут играть с ботом.

Учитывая, что использование SageMaker было непростой задачей, мне не хотелось уделять больше времени конкурирующим сервисам из Microsoft Azure и Google Cloud. Но это могло быть моей ошибкой - если у вас был лучший опыт использования этих предложений, дайте мне знать в комментариях. Я бы хотел узнать больше!

Вместо этого я решил изучить стартап под названием Algorithmia, о котором я слышал, - он специализируется на развертывании моделей и управлении ими, поэтому, надеюсь, его проще использовать ...

Платформа 2: Алгоритмия

Следуя этим документам, я сначала создал репозиторий Git, связанный с Algorithmia, и поместил в репо слегка измененную версию моего сценария прогнозирования, сделанного ранее. Сценарий очень похож на тот, который я использовал локально - не нужно беспокоиться о настройке веб-серверов и проверке работоспособности. Мне просто нужно было изменить пару строк базового Python, чтобы использовать API Algorithmia. Хорошее начало!

Репо также нужен requirements.txt файл, содержащий список зависимостей Python. Это стандартная рабочая процедура для проектов Python, поэтому я был рад увидеть, что мне не нужно было делать ничего сумасшедшего.

После фиксации этих файлов все, что мне нужно было сделать, это опубликовать мою модель и пометить ее номером версии (например, 0.0.1). И вот так модель torchMoji работала на платформе Algorithmia - намного проще, чем SageMaker!

На панели управления Algorithmia есть удобная функция тестирования, где я мог вводить тестовые предложения и получать смайлы. Это действительно полезно: мне не нужен был другой скрипт для вызова модели, чтобы убедиться, что все работает должным образом, как это было с SageMaker.

Алгоритмия также генерировала фрагменты кода копирования и вставки на нескольких языках, которые я мог использовать для вызова моей модели. Версия Python выглядела так:

Пока все выглядело отлично. Но когда дело дошло до интеграции со Slack, Algorithmia ничем не лучше SageMaker. Из этих документов:

Чтобы ваше приложение Slack могло подключаться к Algorithmia, вам понадобится промежуточная функция: и конечная точка API, которая может принимать GET-запрос от Slack, проверять контент, а затем выполнять POST в один из API-интерфейсов Algorithmia.

Мне все еще нужен был склеивающий код Lambda, который был написан ранее, и писать его было сложно. Хорошей новостью для меня было то, что я мог повторно использовать большую часть моего предыдущего кода для функции Lambda. Мне нужно было только заменить вызов конечной точки SageMaker вызовом Algorithmia, так что, учитывая, что я уже потратил несколько часов на отладку этого в первый раз, сделать это снова было не так уж и плохо. 😃 Полный сценарий доступен здесь.

Тем не менее, что мне показалось странным, так это то, что Algorithmia должна быть бессерверной платформой обслуживания моделей. Но для интеграции с моим Slackbot мне пришлось использовать другую бессерверную платформу (AWS Lambda) для маршрутизации трафика и выполнения проверок безопасности. Сквозная задержка оставалась в секундах, измеряемых одной цифрой, поскольку запросы все еще должны были пройти три перехода: от Slack до API Gateway, от API Gateway до Lambda и от Lambda до Algorithmia.

Я не могу не задаться вопросом: какой смысл помещать мою модель в коробку - будь то SageMaker или Algorithmia - если по-прежнему так сложно связать ее с другими сервисами, такими как Slack. Если «подключение» означает, что мне нужно было узнать, настроить и оплатить две другие услуги, не было бы проще, если бы я просто поместил код прогнозирования в свою лямбда-функцию и полностью пропустил специальные службы? Мне трудно поверить, что это действительно настоящее произведение искусства!

Воспроизведение Slackbot

Если вы хотите воспроизвести мой Slackbot, весь код с подробными инструкциями находится в этом репозитории. Я поделился этим хранилищем с несколькими аспирантами в RISELab, и все они смогли воспроизвести и развернуть бота в течение часа! Однако, похоже, у них не было очень приятных впечатлений ... Вот что они сказали:

Почему развертывание модели требует объединения нескольких сервисов и изучения их жаргона? Если модель может быть запущена локально так же просто, как вызов сценария Python, дополнительная сложность ее развертывания в облаке должна быть минимальной.

- Zongheng Yang, аспирант четвертого курса, занимающийся машинным обучением для систем.

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

- анонимный аспирант третьего курса, работающий над системами машинного обучения.

Подведение итогов

Все мы знаем, что инфраструктура ИИ и такие области, как MLOps, сейчас очень популярны. Это все, о чем все говорят. Но на самом деле требуется много работы, чтобы удовлетворить даже базовые потребности обслуживания онлайн-прогнозов. Мои амбиции здесь были скромными - простая модель с ограниченной масштабируемостью. Так далеко заходить было неприятно, а производительность была ужасной.

С учетом всего сказанного, я уверен, что существуют и другие системы прогнозирования. Мы сами только что построили конвейер предсказаний DSL на базе бессерверной платформы, над которой работали в нашей лаборатории. Если вы знаете производственные системы или методы, которые лучше подходят для этого, - или даже просто хотите поговорить о потенциальных функциях, которые, по вашему мнению, отсутствуют в обсуждаемых здесь услугах, - я хотел бы получить известие от вас через Twitter или по электронной почте ».

Благодарим Викрама Шриканти, Джозефа Гонсалеса и Джо Хеллерстайна за отзывы о ранних черновиках этого сообщения.