ML в облаке: как я попробовал Yandex DataSphere и почему его так непросто сравнить с Google Colab

Привет, Хабр! Меня зовут Дмитрий (@pagin), и я специализируюсь на вопросах ускорения и уменьшения свёрточных сетей. Моя основная работа — распознавание автомобилей и классификация транспорта, поэтому я обучаю много небольших CNN и часто пользуюсь облачными сервисами для ML. Раньше я использовал Google Colab и был в меру доволен. Но огорчался каждые 12 часов, когда ноутбук и окружение умирали. Недавно услышал про DataSphere от Yandex. Под катом расскажу про его отличия от Google Colab, опыт запуска обучения, особенности окружения и ценовую политику. Если любишь ресёрчить в ML и хочешь удобное рабочее пространство, то го под кат.

Чем я занимаюсь

Мы в TrafficData пилим ПО для оценки дорожного трафика. В процессе решаем задачу классификации транспорта на 23 типа. Топорный метод с обучением CNN на 23 класса заходит плохо из-за несбалансированности классов. Чтобы вы прочувствовали всю боль несбалансированности классов, вот распределение экземпляров на класс:
Однако есть дополнительная информация о том, что часть этих классов можно объединить в надклассы — все грузовые, все автопоезда или все автобусы. А ошибки внутри таких надклассов более предпочтительны, чем, например, между легковыми и грузовыми. Поэтому более правильное решение — одна CNN для определения надкласса и ещё 4 для уточнения подклассов. В таком случае и распределение экземпляров на класс становится более приятным:
Итого — 5 CNN по 500К весов, которые не так-то удобно учить одновременно на наших 2−3 свободных GPU. В таком контексте мне и подвернутся под руку Yandex DataSphere.

Yandex DataSphere: что это за зверь и как к нему подкатить

Разработчики Яндекса позиционируют DataSphere как платформу для исследований, разработки и эксплуатации сервисов в области анализа данных, машинного обучения и искусственного интеллекта. И тут нельзя сказать, что это ещё один «Облачный Jupyter Notebook», — решение оказывается гораздо шире. Для себя я нашёл встроенные механизмы версионирования (кода, переменных и состояний!), необычное решение выделения аппаратных ресурсов, кучу готовых сниппетов, фоновые операции, пригодность для продакшена и удобную среду для работы. Но обо всём по порядку.

Создание аккаунта и проекта

Итак, я зашёл на Yandex.Cloud. В консоли управления выбрал DataSphere. Дальше наткнулся на неочевидную вещь: чтобы создать рабочее пространство DataSphere, нужно выйти на уровень выше, зайти в биллинг и создать там свой платёжный аккаунт. Что хорошо, сейчас Яндекс даёт бонусные гранты, чтобы попробовать сервисы в Yandex.Cloud. DataSphere здесь относится ко второй строке (можно напробоваться на 3К):
После создания платёжного аккаунта достаточно зайти в DataSphere и нажать большую синюю кнопку Создать проект. Открываем проект и ждём, пока рабочее пространство будет создано. Иногда нужно подождать около 1–2 минут. Далее откроется интерфейс:
По вкладкам с первой странички лучше сразу пройтись, чтобы подробнее понять рабочие моменты. Впрочем, всё важное и интересное разберём прямо здесь.

Перенос, запуск и хранение проекта

Для начала работы со своим проектом нужно было перенести один .ipynb и заархивированный датасет на 5 ГБ (всего для работы в DataSphere доступно 300 ГБ). В DataSphere работает drag'n'drop файлов (или можно подключить свой Яндекс.Диск), причём скорость загрузки по ощущениям значительно выше, чем у Google Colab. И дальше — распаковать архив. Т. к. консольного доступа к ОС в DataSphere нет, я сделал всё через Python.
По библиотекам — практически всё любимое ML-щиками (от tensorflow до opencv) имеется. Мне пришлось накатить лишь seaborn для красоты и imgaug для аугментаций. Pip работает через символ процента:
В первый день работы встретил одну проблему. Я люблю разные необычные слои в CNN. Например, мне нравится экспериментировать с SeparableConv2D, реализация которых доступна в tensorflow.keras.layers. Этот слой присутствовал и в архитектуре, которую я использовал здесь. При компиляции CNN я получил малопонятный DeserializationException:
Пришлось потратить 10 минут, последовательно упрощая архитектуру, чтобы понять, что лишним был как раз SeparableConv2D. Неприятно, но терпимо. На моем ПК с таким же окружением всё ок, как и на Google Colab. О возможных причинах в следующем пункте.

Аппаратные ресурсы

Тут внимание и следим за руками. Способ работы с конфигурациями у DataSphere — особенная фича. Любой проект DataSphere стартует в бессерверном режиме. Выбор мощностей происходит уже при исполнении конкретной ячейки. По умолчанию ячейки будут исполняться в самой простой 4-ядерной конфигурации. Всего конфигураций 5:
Чтобы выполнить ячейку кода на другом железе, в начале ячейки нужно указать номер аппаратного набора, например — #!g1.1. На выделение ресурсов уходит 20−30 секунд. Правда, когда я запускал первый раз, пришлось ждать ≈5 минут. Я даже подумал, что-то сломалось, но позже поддержка Яндекса объяснила, что я попал на пиковую нагрузку, с которой уже справились.
Attention: Видимо, сервис набирает обороты и активных клиентов и отчасти защищается от майнеров, поэтому с 20.06.2021 доступ к конфигурациям g1.1 ограничен. Для доступа необходимо пополнить баланс до суммы 500 ₽ или отправить в поддержку запрос с описанием задачи. Зато теперь конфигурации g1.1 будут с большей вероятностью доступны.
По доступности аппаратных наборов. За 5 дней моих экспериментов всегда всё было доступно и выделялось. Лишь один раз g1.1 были недоступны и DataSphere попросил меня подождать несколько минут. И правда — потом подключилось.
Совершенно нормально и приветствуется, что разные ячейки выполняются на разных аппаратных конфигурациях. Все переменные и состояния между ними удачно передадутся. Ну не вау ли!
Не совсем вау. Насчёт проблемы из предыдущего пункта. Я не шарю во внутренних реализациях DataSphere, но по traceback могу предположить, что как раз эта фича с переносом состояний и стала причиной неработающего SeparableConv2D в нашем проекте. Ведь эти состояния нужно сериализовать в одном аппаратном окружении и десериализовать в другом. Но возможно, это лишь единичная проблема или просто я не прав насчёт DeserializationException. С другими слоями проблем я не встретил.
Тем не менее я запустил обучение в окружении DataSphere и, к сожалению, никак не смог полностью загрузить V100. Даже отключая аугментацию и нацеливая CPU полностью на формирование батчей, я не смог добиться утилизации GPU более 5−10 %. Просто очень оверхедная мощность GPU для нашей небольшой CNN. А вот если бы мы решились обучать в облаке нашу YOLOv4.5, то V100 как раз был бы к месту.

Фоновые операции

Фича, которую просто невозможно обойти стороной. Мне её очень не хватало в работе с Google Colab. Иной раз поставишь в Google Colab обучаться модель, а сам кукуешь. Вроде хочется провести эксперименты над другими моделями или датасетом в это время. Но для этого нужно заводить другой ноутбук, заново ставить окружение — короче, неприятно.
А здесь идея простая — можно запускать долгие операции (например, обучение моделей) в фоновом режиме, т. е. асинхронно. При этом можно продолжать работу с ноутбуком. Однако стоит иметь в виду, что:
  1. Запуск операций в фоновом режиме не гарантирует немедленный запуск исполнения.
  2. Фоновые операции в общем случае могут выполняться дольше, чем обычные операции.
  3. Фоновые операции могут выполняться на прерываемых виртуальных машинах и ресурсах.
  4. Фоновые операции тарифицируются по другим правилам.
И если первые три пункта здесь не очень радуют, то четвёртый приятный (подробнее через несколько абзацев).
Для текущей задачи фоновые операции мне не понадобились, т. к. датасет уже плотно исследован и нет необходимости в каких-то отдельных экспериментах. Я лишь убедился, что обучение успешно запускается в фоне и ячейки ноутбука доступны к выполнению.

Версионирование

DataSphere интегрирован с системой контроля данных DVC и системой контроля версий Git. Связка с Git сделана очень плотно — можно управлять практически без консоли. В верхнем и левом тулбарах есть специальные меню и область для просмотра и управления ветками. Интерфейс Git здесь не самый привычный, но приятный и понятный:
Отдельно стоит упомянуть про чекпоинты — код ячеек, вывод и значения переменных в определённый момент времени. Для них слева в тулбаре тоже есть своё меню. В любой момент можно переключиться на одно из предыдущих сохранённых состояний. Сохранить состояние можно самостоятельно, или оно сохранится автоматически при бездействии ВМ. Просто необходимый и уникальный инструмент для воспроизводимости экспериментов в ML. Что круто, ими можно поделиться вместе с ноутбуком.
Для нашего проекта Git был не нужен, т. к. скрипт обучения умещается в одну портянку.ipynb. Поэтому я лишь погипнотизировал предоставляемый интерфейс. А вот сохранение чекпоинтов пригодилось и сыграло на руку. Можно удобно распарсить датасет в переменную и затем сохранить состояние в чекпоинте. И при перезапуске обучения нужно лишь вернуть состояние этого чекпоинта. В моём случае это экономит приятные 4−5 минут. Т. е. не нужно снова бежать по 23 папкам, изменять разрешение изображений и составлять список объектов.

Ценовая политика

Тут тоже интересный подход. При работе с сервисом DataSphere вы платите за фактическое использование вычислительных ресурсов — посекундно тарифицируется время вычисления. То есть если ячейка закончила свои вычисления и CPU/GPU больше не загружен, то вы не платите ни цента. Вычисление общей стоимости происходит с помощью юнитов. Чем мощнее конфигурация, тем больше юнитов в секунду будет назначено:
И чтобы посчитать общую стоимость, необходимо время работы умножить на количество юнитов и на стоимость одного юнита. Скажу проще. 1 час работы самой слабой конфигурации — это 10,8 ₽. А 1 час работы g1.1 — это 194,4 ₽.
Стоимость фоновых операций высчитывается тоже с помощью юнитов. Но стоит отметить, что их выполнение значительно выгоднее. 1 час работы самой слабой конфигурации — это 2,7 ₽. А 1 час работы g1.1 — это 40,5 ₽. Ну и стоит затронуть вопрос трафика. Входящий не тарифицируется. Исходящий не тарифицируется до 10 ГБ.
У меня на полное обучение одной CNN в такой загрузке ушло ≈4 часа и было потрачено ≈600 ₽. И тут мне подумалось, что хочется ещё конфигурацию подешевле с GPU попроще. Ну хотя бы T4 или K80, как у Colab. Ведь загрузить V100 на 100 % — это задачка совсем непростая. Особенно когда ты просто учишь небольшие CNN.

Сравнение с Google Colab

Составляя сравнительную табличку, я ещё раз убедился, что в двух этих сервисах проще перечислить общее, чем различия. Тем не менее я постарался выделить наиболее важные моменты:
Тема с корги и котиками, которой так не хватает в Yandex DataSphere
Тут ещё для сравнения ценообразования — у Google Colab есть подписка за 10 $, где даётся приоритетный доступ к GPU и время жизни ноутбуков увеличивается до 24 часов! (На восклицательный знак смотреть с иронией.) Понятно, что, учитывая специфику DataSphere, подписка нам обошлась бы сильно дороже. И оплата только фактического времени вычислений освобождает нас от необходимости бежать выключать ноутбук после конца обучения. Но для себя я пока не понял, какой тип тарификации мне больше нравится.
У каждого сервиса есть свой ряд плюсов. Google Colab проще для старта, бесплатен, имеет более гибкий набор GPU и тему с корги. А DataSphere более гибок в выборе CPU, имеет удобное рабочее пространство, версионирование из коробки, сохранение окружения и фоновые операции. Как итог сложно сказать, что лучше или хуже. Но можно разделить сферы применения.
Если тебе срочно нужен облачный Jupyter для учёбы или коротких экспериментов и ты не собираешься к нему часто возвращаться, то Google Colab будет достаточно. А если ты хочешь перенести важную часть своей работы в облако, проводить там большие ресёрчи, делиться ими с коллегами и не переживать за сохранность данных, то предпочтительнее окажется DataSphere.

Что я нашёл для себя в Yandex DataSphere

Изначально я думал, что будет просто аналог Colab, а получилось иначе/самобытно/вдохновляюще. Очень порадовали версионирование из коробки, сохранность окружения и фоновые операции. Огорчил ограниченный выбор GPU — мне кажется, не все учат BERT и кому-то тоже будет достаточно K80 или T4. В целом DataSphere привлёк и уже стал закладкой в моём браузере. В ближайшее время планирую продолжить эксперименты — хочу потестить устойчивость фоновых операций, доску TensorBoard и шеринг экспериментов.
P. S.
Я специалист по машинному обучению, а не писатель — и в моём посте что-то могло остаться непонятным. Поэтому буду рад ответить на вопросы в комментариях.

Комментарии 11

    +1

    Главный недостаток сферы для меня - только V100 на борту, нет тех же T4. Недавно выбирал лучшее облако для обучений, и лучшим ввариантом оказался пока что сырой, но очень удобный Saturn Cloud, во многом как раз из-за большего разброса видеокарт.

      0
      А как в Saturn Cloud остальные моменты? Pricing подпиской? На что больше похож в целом — Colab или DataSphere?
        0

        Не увидел комментарий. В сатурне цена за час работы ноутбука (одна т4 сейчас стоит $0.62/ч).

        Остальные моменты - после колаба прекрасная вещь. Интерфейс - классический юпитер-лаб на удалённом сервере (гугловский блокнот меня раздражал), видеокарта есть всегда и именно та, что ты взял, а также, что после колаба меня порадовало, в нём нормальная работа с файлами (в колабе 10к изображений с драйва читались около 1.5 часов, когда в сатурне секунд 15:) ).

        Из минусов - сыроватость сервиса, бывают падения и необычные ошибки, но всё обычно решается перезапуском сервера.

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

        0

        А для каких сценариев обучение используете T4, если не секрет?
        Мы думаем, чтобы добавить в ДатаСферу карты поменьше. T4 пока не факт, что получится. Пока думаем в сторону 1/7 карты A100.

          0

          Не увидел комментарий. На T4 я обучал YOLOv5m на своих данных, по цене выходит где-то около доллара за обучение, но это на минимальном тарифе, а на больших тарифах дешевле. Может, в сфере будет выгоднее (хотя и тут 70р много меньше стоимости часа работы датасаентиста), но меня в ней сразу отпугнул интерфейс расчёта цены.

          Проблема интерфейса в том, что когда ты хочешь арендовать видеокарту, то жмёшь "тарифы", как и на всех других сайтах. И когда ты выбираешь сервер с v100, то видишь цифру в 34тр/мес, а для небольших задач типа пары раз обучить ту же ёлу (не говоря о гораздо меньших сетках) этого слишком много.

          Я сейчас увидел, что информация по тарифам есть в документации, но она слишком глубоко и в ней надо сидеть и разбираться. Мой фидбек - хотелось бы кроме отличных от v100 плат ещё и более интуитивный и простой интерфейс. Как пример - тот же сатурн, где после нескольких нажатий у тебя появляется юпитер-лаб с 10 часами работы в нём и простых и понятных тарифов.

        +5

        Какая-то слишком радужная статья. У меня не такой позитивный опыт с датасферой.

        Во-первых очень часто вылазили ошибки такие: Execute error: Servant g1.1 not allocated: Internal Error. Абсолютно неинформативно - ты ждешь несколько минут пока запустится ячейка, потом раз - и эта ошибка. Причем это не ошибка в коде, потому что через какое-то время все работает на этой же ячейке.

        Во-вторых, непросто поставить дополнительные пакеты или что-то нестандартное. Если в Колабе просто вначале пишешь инициализацию со всеми зависимостями и пакетами, то тут такое не пройдет - у ячейки нет прав суперюзера и все ставится в пользовательское пространство, поэтому ставится не все как надо. Соответственно просто скопировать блокнот с Колаба не выйдет, если там ставится какие-то хитрые пакеты.

        Для решения второй проблемы придумана возможность создавать свое окружение при помощи Docker. Пишешь прямо в проекте свой Dockerfile со своими зависимостями, билдишь его и ставишь использовать по умолчанию. Интерфейс очень своеобразный - надо писать код dockerfile прямо в проекте, жать на кнопку Build и молиться что все соберется как надо.

        Может не собраться. В таком случае думаете можно отредактировать файл и запустить снова? Нет - редактировать нельзя, надо клонировать конфигурацию (у нее при этом на конце появляется посфикс "- clone") и редактировать-билдить заново.

        Еще может собраться, но не пройдут тесты - причем тесты могут не пройти просто так - пару раз у меня они не проходили просто потому что все были skipped, в другой раз один из тестов просто упал на ровном месте. В таком случае сборку перезапускаешь, а это процесс не быстрый (работает то сборка на самом базовом инстансе с1.4) и она со второго раза проходит нормально.

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

        То, что при сборке нельзя выбрать на каком виде инстансов будет производится сборка тоже нельзя - только на c1.4. Это особенно доставляет, потому что некоторые пакеты при сборке проверяют конфигурацию системы и не ставят модули для cuda, если не видят в системе GPU. Мне пришлось патчить установщик Deepspeed чтобы отключить эту проверку, а я тот еще питонист, так что это заняло немного дохрена времени.

        Кстати, если вы думаете, что сможете при сборке забрать файлы из проекта (в моем случае патченый DeepSpeed), удачи вам с этим - я так и не нашел как это провернуть, пришлось их куда-то выкладывать, откуда можно потом curlом скачивать в процессе сборки образа.

        "Что же ты там такое запускал" - недоуменно спросите вы?

        А я просто хотел запустить сберовский ruGPT3XL_generation.ipynb.

        "Ну и что же в итоге, получилось?"

        Да получилось, но сколько времени и нервов я на это потратил - вам лучше не знать

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

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

          0

          Круто, что у тебя есть такой опыт. Думаю, радужность, моего отзыва следуют как раз из недостаточно сложной задачи и окружения. Единственной проблемой для меня стал неподдерживаемый SEPARABLECONV2D, который потратил сравнимо меньше моих нервов. Значит, есть причина ещё раз задуматься о применимости DataSphere для больших проектов

            0
            Спасибо вам за подробный отзыв, правда очень полезно.

            Во-первых очень часто вылазили ошибки такие: Execute error: Servant g1.1 not allocated: Internal Error.

            Работаем с этим, боль постепенно решается.

            Во-вторых, непросто поставить дополнительные пакеты или что-то нестандартное.

            Дело в том, что Датасфера – не Колаб. Ради версионирования и serverless наша система имеет другие ограничения по сравнению с Колабом. Мы стараемся минимизировать их, но некоторые ограничения неизбежны.

            Может не собраться. В таком случае думаете можно отредактировать файл и запустить снова? Нет — редактировать нельзя, надо клонировать конфигурацию (у нее при этом на конце появляется посфикс "- clone") и редактировать-билдить заново.

            Мы негативно относимся к mutable сущностям. А вот UI имеет смысл допилить, чтобы выглядело как редактирование in-place.

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

            Такого фидбека мы не встречали, изучим. Да и acceptance тесты это не показывают. Попробуем сами массово пособирать образы.

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

            Звучит как баг, исследуем.

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

            Да, это понятная проблема. Должна решиться с переездом докеров в отдельное хранилище.

            То, что при сборке нельзя выбрать на каком виде инстансов будет производится сборка тоже нельзя — только на c1.4. Это особенно доставляет, потому что некоторые пакеты при сборке проверяют конфигурацию системы и не ставят модули для cuda, если не видят в системе GPU.

            Интересный фидбек, но разрешать сборку на g1.1 пока не планируем. Но будем за этим наблюдать. В идеале библиотека должна допускать конфигурацию, какие модули устанавливать, какие – нет.

            Кстати, если вы думаете, что сможете при сборке забрать файлы из проекта (в моем случае патченый DeepSpeed), удачи вам с этим

            Так было в самом начале. Сейчас доступны все данные с диска.

            В качестве благодарности за отзыв, мы будем рады дать вам грант на Датасферу, чтобы вы могли продолжить наблюдать, как мы становимся удобней и стабильней с каждым релизом. И дальше делиться наблюдениями, конечно, нам это важно. Напишите мне в личку, пожалуйста.
            0
            K80 в обычном. T4 и P100 в Pro. 2vCPU @2.2GHz
            Ну вообще-то нет, в бесплатной версии можно тоже получить T4/P100 (где-то год назад ещё были P4) — я весной на бесплатном регулярно получал P100. В Pro версии можно ещё получить V100 и запустить среду с большим объемом ОЗУ (в 2 раза больше, чем в обычной сессии), которая также ещё дает 4vCPU вместо 2vCPU.
              0

              А вы везунчик! Я ни разу не получал в простом Colab что-то из T4/P100. Так или иначе, для Pro выделение мощных GPU в приоритете и происходит чаще(о чем написано в официальной документации). В любом случае, несколько коробит такая ситуация, когда скорость обучения твоей сети зависит от воли случая. А про 4vCPU не знал, спасибо за замечание!

                0
                А вы везунчик! Я ни разу не получал в простом Colab что-то из T4/P100.
                Странно, когда я сидел на бесплатном Colab, то мне T4/P4/P100 чуть ли не чаще, чем K80 выпадали. Причем K80 начинали чаще падать ближе к приближению лимита по использованию ресурсов, а после того как «отдохнешь» дня 3, то опять топ карточки падают. Я одно время просто использовал несколько аккаунтов и чередовал их, похоже что Гугл это никак не трекает.

                Про приоритет — это да, так и есть. Добавлю, что сейчас ещё на Pro теперь падает либо P100, либо V100, а карты слабее — нет. Но это моё эмпирическое наблюдение, поскольку я с марта сижу на Pro версии и мне ещё ни разу не падало что-то кроме P100/V100.

                В любом случае, несколько коробит такая ситуация, когда скорость обучения твоей сети зависит от воли случая.
                Ну в какой-то мере согласен, но за $10 в месяц иметь доступ к машине с P100/V100 — это очень хорошее предложение, несмотря даже на все минусы, вроде 24-часового ограничения и возможного «кулдауна», если превысить ресурсные лимиты — а они на Pro весьма большие, я где-то 3-4 дня нон-стоп (ну без учета 24-часовых рестартов, естественно) тренировал сетки и меня не отключали. Если тренируешь часто, то предложение Колаба выглядит более привлекательным, чем у Яндекса, имхо.

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