Инфраструктура для глубокого обучения

Иллюстрация: Людвиг Петтерссон (Ludwig Pettersson)
Глубокое обучение — это эмпирическая наука, и качество инфраструктуры команды является мультипликатором её прогресса. К счастью, современная экосистема с открытым исходным кодом позволяет любому желающему создать отличную инфраструктуру для глубокого обучения.
Резюме
В этой статье мы расскажем о том, как обычно продвигаются исследования в области глубокого обучения, опишем сделанный нами выбор инфраструктуры для их поддержки и выложим в открытый доступ kubernetes-ec2-autoscaler — оптимизированный под пакетную обработку менеджер масштабирования для Kubernetes. Надеемся, эта публикация окажется полезной при создании собственной инфраструктуры глубокого обучения.
Вариант использования
Типичное достижение в области глубокого обучения начинается с идеи, которую вы тестируете на небольшой задаче. На этом этапе вам хочется быстро проводить множество нерегламентированных экспериментов. В идеале можно просто подключиться по SSH к машине, запустить скрипт в screen и получить результат менее чем за час.
Чтобы модель действительно заработала, обычно требуется увидеть её сбои во всех мыслимых проявлениях и найти способы устранить эти ограничения. (Это похоже на создание любой новой программной системы, где вы запускаете код множество раз, чтобы интуитивно понять его поведение.)
Поэтому инфраструктура глубокого обучения должна позволять пользователям гибко исследовать модели изнутри, и простой выдачи сводной статистики здесь недостаточно.
Как только модель демонстрирует достаточный потенциал, вы масштабируете её на более крупные наборы данных и большее число графических процессоров (GPU). Для этого требуются длительные задания, которые потребляют массу ресурсов и выполняются несколько дней. Вам понадобится тщательное управление экспериментами и предельно продуманный подход к выбору диапазона гиперпараметров.
Начальный этап исследований неструктурирован и динамичен; последующий — методологичен и в какой-то мере утомителен, но всё это абсолютно необходимо для получения великолепного результата.
Пример
Статья Улучшенные методы обучения генеративно-состязательных сетей (GAN) началась с того, что Тим Салиманс (Tim Salimans) предложил несколько идей по улучшению обучения генеративно-состязательных сетей. Мы опишем самую простую из этих идей (которая в итоге дала самые красивые образцы, хотя и не лучшее полуавтоматическое обучение).
GAN состоят из генератора и дискриминатора. Генератор пытается обмануть дискриминатор, а дискриминатор пытается отличить сгенерированные данные от реальных. Интуитивно понятно, что генератор, способный обмануть любой дискриминатор, весьма хорош. Но существует трудноустранимый режим сбоя: генератор может «деградировать», выдавая всегда абсолютно один и тот же (вероятно, выглядящий реалистично!) образец.
У Тима возникла идея подавать дискриминатору на вход целый мини-пакет (minibatch) образцов вместо всего одного. Таким образом, дискриминатор может определить, не выдает ли генератор постоянно одно и то же изображение. Обнаружив деградацию, градиенты будут отправлены генератору для исправления проблемы.
Следующим шагом было создание прототипа идеи на базах MNIST и CIFAR-10. Это потребовало быстрой разработки прототипа небольшой модели, запуска ее на реальных данных и проверки результата. После нескольких быстрых итераций Тим получил очень обнадеживающие образцы CIFAR-10 — пожалуй, лучшие из тех, что мы видели на этом наборе данных.
Тем не менее, глубокое обучение (и алгоритмы ИИ в целом) необходимо масштабировать, чтобы они производили подлинное впечатление: небольшая нейронная сеть — это доказательство концепции, но большая нейронная сеть действительно решает проблему и приносит пользу. Поэтому Иан Гудфеллоу (Ian Goodfellow) занялся масштабированием модели для работы с ImageNet.

Наша модель учится генерировать изображения ImageNet
Работая с более крупной моделью и набором данных, Иану потребовалось распараллелить модель на несколько GPU. Каждое задание нагружало процессоры и GPU нескольких машин до 90%, но даже при этом обучение модели занимало много дней. В таких условиях каждый эксперимент приобретал особую ценность, и результаты каждого из них тщательно фиксировались в логах.
В конечном счете, хотя результаты оказались хорошими, они не превзошли наши ожидания. Мы проверили множество гипотез о том, почему так произошло, но до конца проблему пока не решили. Такова природа науки.
Инфраструктура
Программное обеспечение

Пример нашего кода на TensorFlow
Подавляющая часть нашего исследовательского кода написана на Python, что отражено в нашихпроектах соткрытымисходным кодом. Для вычислений на GPU мы в основном используем TensorFlow (или Theano в особых случаях); для CPU мы применяем их же или Numpy. Исследователи также иногда используют фреймворки более высокого уровня, такие как Keras поверх TensorFlow.
Как и большая часть сообщества глубокого обучения, мы используем Python 2.7. Мы в основном применяем Anaconda, в которой удобно упакованы такие в противном случае сложные пакеты, как OpenCV, и настроены оптимизации производительности для некоторых научных библиотек.
Аппаратное обеспечение
Для идеального пакетного задания удвоение количества узлов в кластере должно сократить время его выполнения вдвое. К сожалению, в глубоком обучении при использовании множества GPU люди обычно наблюдают весьма сублинейный прирост скорости. Поэтому для максимальной производительности требуются первоклассные GPU. Мы также используем довольно много ресурсов CPU для симуляторов, сред обучения с подкреплением или мелкомасштабных моделей (которые работают на GPU не быстрее).

nvidia-smi демонстрирует полностью загруженные Titan X
AWS великодушно согласилась предоставить нам в дар большой объем вычислительных мощностей. Мы используем их для инстансов CPU и горизонтального масштабирования задач на GPU. Мы также запускаем собственные физические серверы, на которых работают преимущественно графические процессоры Titan X. Мы рассчитываем использовать гибридное облако в долгосрочной перспективе: ценно экспериментировать с различными GPU, интерконнектами и другими технологиями, которые могут оказаться важными для будущего глубокого обучения.

htop на том же физическом сервере показывает массу свободных ресурсов CPU. Наша ресурсоемкая нагрузка для CPU обычно запускается отдельно от нагрузки для GPU.
Интерфейс инициализации и развертывания (Provisioning)
Мы относимся к инфраструктуре так же, как многие компании к продукту: она должна предоставлять простой интерфейс, а удобство использования так же важно, как и функциональность. Мы используем единый набор инструментов для управления всеми нашими серверами и настраиваем их максимально идентично.

Фрагмент нашей конфигурации Terraform для управления группами Auto Scaling. Terraform создает, изменяет или удаляет работающие облачные ресурсы в соответствии с вашими конфигурационными файлами.
Мы используем Terraform для настройки наших облачных ресурсов AWS (инстансов, сетевых маршрутов, записей DNS и т.д.). Наши облачные и физические узлы работают под управлением Ubuntu и настраиваются с помощью Chef. Для сокращения времени запуска мы предварительно подготавливаем (pre-bake) AMI нашего кластера с помощью Packer. Все наши кластеры используют непересекающиеся диапазоны IP-адресов и объединены через публичный интернет с помощью OpenVPN на ноутбуках пользователей и strongSwan на физических узлах (которые выступают в роли клиентских шлюзов AWS).
Домашние каталоги пользователей, наборы данных и результаты мы храним на NFS (на физическом оборудовании) и EFS/S3 (в AWS).
Оркестрация
Масштабируемая инфраструктура зачастую усложняет решение простых задач. Мы уделяем одинаковое внимание инфраструктуре как для небольших, так и для масштабных задач, и активно совершенствуем наш инструментарий, чтобы сделать распределенные сценарии использования столь же доступными, как и локальные.
Мы предоставляем кластер SSH-узлов (как с графическими процессорами, так и без них) для спонтанных экспериментов и используем Kubernetes в качестве планировщика кластера для физических узлов и узлов AWS. Наш кластер охватывает 3 региона AWS — наши рабочие нагрузки носят настолько скачкообразный характер, что порой мы исчерпываем всю емкость в отдельных регионах.
Kubernetes требует, чтобы каждая задача выполнялась в контейнере Docker, что обеспечивает изоляцию зависимостей и сохранение снимков кода. Тем не менее, сборка нового контейнера Docker может добавлять драгоценные секунды к циклу итераций исследователя, поэтому мы также предоставляем инструменты для прозрачной отправки кода с ноутбука исследователя в стандартный образ.

Кривые обучения моделей в TensorBoard
Мы предоставляем прямой доступ к сети flannel в Kubernetes для ноутбуков исследователей, обеспечивая пользователям бесшовный сетевой доступ к запускаемым задачам. Это особенно полезно для доступа к службам мониторинга, таким как TensorBoard. (Наш первоначальный подход — более чистый с точки зрения строгой изоляции — требовал от пользователей создания сервиса Kubernetes для каждого порта, который они хотели сделать доступным, однако мы выяснили, что это создает слишком много преград.)
kubernetes-ec2-autoscaler
Наша рабочая нагрузка носит непредсказуемый и скачкообразный характер: направление исследований может быстро перейти от экспериментов на одной машине к потребности в 1000 ядрах. Например, в течение нескольких недель один эксперимент прошел путь от интерактивной фазы на одном Titan X до экспериментальной фазы на 60 Titan X и потребности почти в 1600 графических процессорах AWS. Таким образом, наша облачная инфраструктура должна динамически выделять узлы Kubernetes.
Запускать узлы Kubernetes в группах Auto Scaling довольно просто, но сложнее правильно управлять размером этих групп. После отправки пакетного задания кластер точно знает, какие ресурсы ему нужны, и должен выделять их напрямую. (В отличие от этого, политики масштабирования AWS будут создавать новые узлы по частям до тех пор, пока ресурсы не перестанут быть исчерпанными, что может потребовать множества итераций.) Кроме того, кластер должен очищать (drain) узлы перед их завершением, чтобы избежать потери выполняющихся задач.
Возникает соблазн использовать чистый EC2 для крупных пакетных заданий, и именно с этого мы и начинали. Тем не менее, экосистема Kubernetes приносит огромную пользу: удобный инструментарий, логирование, мониторинг, возможность управлять физическими узлами отдельно от работающих инстансов и многое другое. Настроить правильное автомасштабирование Kubernetes оказалось проще, чем воссоздавать эту экосистему на голом EC2.
Мы выпускаем kubernetes-ec2-autoscaler — оптимизированный для пакетной обработки менеджер масштабирования для Kubernetes. Он работает как обычный подин (Pod) в Kubernetes и требует лишь того, чтобы ваши рабочие узлы находились в группах Auto Scaling.

Конфигурации запуска для нашего кластера Kubernetes
Автомасштабировщик работает путем опроса состояния мастер-узла Kubernetes, которое содержит все необходимое для расчета запроса ресурсов кластера и его емкости. При наличии избыточной емкости он очищает соответствующие узлы и в конечном итоге завершает их работу. Если требуется больше ресурсов, он вычисляет, какие серверы следует создать, и соответствующим образом увеличивает размеры групп Auto Scaling (или просто возвращает в работу (uncordons) очищенные узлы, что позволяет избежать времени на запуск новых узлов).
kubernetes-ec2-autoscaler поддерживает работу с несколькими группами Auto Scaling, ресурсами помимо ЦП (память и графические процессоры), а также детализированными ограничениями для задач, такими как регион AWS и размер инстанса. Кроме того, скачкообразные рабочие нагрузки могут приводить к тайм-аутам и ошибкам групп Auto Scaling, поскольку (как ни удивительно!) даже AWS не располагает бесконечной емкостью. В таких случаях kubernetes-ec2-autoscaler обнаруживает ошибку и перенаправляет нагрузку в резервный регион AWS.
Наша инфраструктура нацелена на максимальное повышение продуктивности исследователей в области глубокого обучения, позволяя им сосредоточиться на науке. Мы создаем инструменты для дальнейшего улучшения нашей инфраструктуры и рабочих процессов и поделимся ими в ближайшие недели и месяцы. Мы приветствуем помощь в ускорении этого процесса!
- Присоединяйтесь к OpenAI
- Общайтесь с другими
Авторы
Полный текст статьи читайте на OpenAI
