Привет, меня зовут Максим Гуляев, я продуктовый менеджер в команде ML Space Notebooks в Cloud.ru. Раньше я был техлидом этой команды, поэтому глубоко понимаю всю внутреннюю кухню.

В статье расскажу, какие ноутбуки мы используем, зачем они нужны и как сделать себе такие же. Упомяну, почему нам потребовалось вносить изменения в привычные ноутбуки на базе JupyterLab. Затем объясню, что нужно, чтобы прийти к крутым образам. И напоследок поделюсь нашей новой архитектурой и методом ее создания.

Что делает команда ML Space Notebooks

Cloud.ru ML Space — платформа полного цикла для работы с данными. Она включает в себя хранение, перенос, обработку данных, а после завершения этих этапов переходит к обучению моделей.

Обучение может происходить как в распределенной системе, так и на одной машине, но гораздо важнее — мониторинг моделей. Мы следим за метриками во время обучения, анализируем метрики качества и функцию потерь (loss function): например, кросс-энтропию, F1-score, полноту, точность и другие. Не замерять метрики — всё равно, что пытаться работать за выключенным монитором.

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

Ноутбук — это сердце нашей платформы. Пользователи хотят работать в едином интерфейсе, не переключаясь между разными приложениями. Поэтому важно, чтобы ноутбук поддерживал все этапы работы: от анализа данных до мониторинга моделей и проведения экспериментов. Такие инструменты как TensorBoard, ML Flow и VS Code интегрированы в ноутбук, что обеспечивает комфортную среду для ML и DS-специалистов.

Инструменты, которые мы интегрировали в наши ноутбуки
Инструменты, которые мы интегрировали в наши ноутбуки

А теперь — к тому, как мы подошли к созданию решения и какие шаги предприняли.

Общая архитектура нашего сервиса ноутбуков и с чего все началось

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

Ноутбук сам по себе мало полезен, если он изолирован. Пользователю нужны разные способы взаимодействия: веб-интерфейс (Web-UI) или SSH. Мы предоставляем оба варианта. 

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

А для тех, кто считает, что SSH слишком сложен, и предпочитает простой и удобный Web-UI, мы внедряем ролевую систему, чтобы контролировать доступ к ноутбуку при работе через веб-интерфейс. Благодаря этому попасть в проект могут только авторизованные пользователи.

Общая схема архитектуры сервиса ноутбуков
Общая схема архитектуры сервиса ноутбуков

Мы используем IAM Cloud True для управления правами доступа (аналогичное решение — Keycloak). Также добавили прокси-сервер, который помогает идентифицировать пользователей и назначать им соответствующие роли.

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

Почему мы выбрали Kubeflow

Есть несколько вариантов построения инфраструктуры для сервиса ноутбуков. Один из самых популярных — JupyterHub, однако он нам не подошел. Почему? Во-первых, высокие требования к правам доступа. Для запуска контейнеров в JupyterHub нужны root-права — это серьезные риски с точки зрения безопасности. Во-вторых, нужно писать свой спаунер, что добавляет работы и усложняет разработку.

В качестве альтернативы выбрали Kubeflow. Его преимущества:

  1. Контроллер прямо из коробки для работы с ноутбуками.

  2. Возможность удаления и создания ноутбуков.

  3. Гибкость в плане функциональности — по мере необходимости можно что-то переписать.

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

Проблемы Docker-образов ноутбуков первого поколения

Один из важнейших аспектов любого сервиса ноутбуков — образы. Как обычно происходит их сборка? ML-специалист просит девопса собрать образ. Тот устанавливает драйверы и убирает root-доступ, зная, что предоставление root-прав в контейнере — не лучшая идея. Все выглядит замечательно, но тут приходит ML- или DS-специалист и говорит: «Версия не та, нужно пересобирать».

Обновления таких библиотек, как PyTorch, выходят часто, нужно постоянно поддерживать их актуальность. Бывают случаи, когда нужно установить OpenCV, но без root-доступа не получится поставить build-essential или CMake. Мы снова идем к девопсу, просим его пересобрать образ. И так каждый раз, когда нужно обновить библиотеку, что очевидно неудобно.

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

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

Проблемы Docker-образов, которые нам предстояло решить
Проблемы Docker-образов, которые нам предстояло решить

Как мы решили проблемы в образах нового поколения

Что стало ключевым изменением? Мы внедрили Conda — менеджер виртуальных окружений, который позволяет создавать изолированные среды. Это уже почти наполовину решило проблему с обновлениями, так как теперь можно устанавливать любые пакеты в Runtime, не вызывая каждый раз девопса.

Кроме того, мы создали ML Space SDK — он значительно упрощает работу с окружениями. Теперь можно выполнять такие операции, как создание, удаление, получение списка окружений, а также их версионирование.

Образы нового поколения. Добавили сюда поддержку Conda и ML Space SDK
Образы нового поколения. Добавили сюда поддержку Conda и ML Space SDK
Что под капотом у ML Space SDK и как он помог в создании окружения

У ML Space SDK много полезных фич, и этот функционал продолжает расти. Приведу небольшую часть возможностей и расскажу, как ML Space SDK устроен в рамках создания окружения.

Создание окружения с пакетами для JupyterLab, установкой ML Space SDK и, по необходимости, CUDA
Создание окружения с пакетами для JupyterLab, установкой ML Space SDK и, по необходимости, CUDA

Когда вы создаете окружение, вы фактически создаете среду, в которой будете работать. Что же важно туда включить? Для начала — IPython Kernel, Python-библиотеки и Conda NB Pack. Это все нужно, чтобы Jupyter умел работать с Conda и правильно создавать тетрадки.

После этого устанавливаем в созданное окружение ML Space SDK. Но вот вопрос —зачем? Рассказываю. Без ML Space SDK будет сложно найти нужный инструмент. Например, пользователь открывает тетрадку прямо в JupyterLab, через восклицательный знак, а она не открывается. Он бежит в поддержку, думая, что что-то сломалось. Но на самом деле проблема в том, что выбран неправильный kernel. 

Именно для этого важно установить ML Space SDK — чтобы сделать процессы прозрачными. Вы получите четкое понимание, как работает система, и избежите ситуаций, когда что-то идет не так.

И самое важное, что еще умеет платформа, — ставить CUDA. Иногда на его установку может уходить неделя, а с ML Space SDK это время можно сэкономить.

При таком подходе уменьшается объем образа. Для сравнения: в начале, когда мы создавали 82-й образ, мы добавляли в него все что можно, чтобы он заработал. Новый TensorFlow, PyTorch, CUDA... Получался слишком жирный образ, который плохо и медленно стартовал. А недавно вышел 98-й образ, и с ML Space SDK мы создаем ноутбуки на 50% быстрее.

Почему это важно? Может возникнуть ситуация, когда вы захотите попробовать нестабильный релиз PyTorch или другую библиотеку, но не захотите ломать рабочее окружение. Благодаря версионированию окружений будет возможность вернуться к контрольной точке, восстановиться, если что-то пойдет не так.

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

Также в рамках одного кластера есть NFS (Network File System), поэтому при создании ноутбука можно не переживать, что там не будет вашего рабочего окружения.

Как мы пришли к новой архитектуре ноутбуков и какие вопросы решили

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

Отчасти это связано с тем, что JupyterLab — это open source проект, а open source код порой собирается по принципу «с миру по нитке». Например, JupyterLab синкает файлы где-то каждые 20 секунд, считает хэши для некоторых измененных файлов, иногда считает хэши полностью. А самое важное — JupyterLab плохо справляется с листингом. Представьте, как пойдет работа, если в директории 6 миллионов файлов, их надо синкать каждые 20 секунд, да еще и отсортировывать на фронте.

А теперь — о том, как мы решили эти проблемы.

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

На сколько сократилось время открытия ноутбуков благодаря прямому трафику
На сколько сократилось время открытия ноутбуков благодаря прямому трафику

Улучшили отзывчивость интерфейса за счет разделения фронта и бэка. Да, ноутбуки стали запускаться быстрее, но интерфейс все равно зависал. Обучать крутую модель на таком устройстве — задача со звездочкой. Эту проблему решили тем, что разделили фронт и бэк.

В JupyterLab не предусмотрено, чтобы его кто-то разделял, поэтому для этой цели существует механизм kernel-gateway — он появился с JupyterLab 4. Изначально мы искали другие варианты: например, попробовали ограничить приоритеты, но это не сработало. Поэтому взяли kernel-gateway, который позволяет запускать kernel удаленно на другом устройстве.

К какой архитектуре ноутбуков мы пришли
К какой архитектуре ноутбуков мы пришли

Казалось бы, вот она — success story, но на этом всё не закончилось.

Внедрение Cloud.ru Jupyterlab extension вместо плагинов

Хотя механизм kernel gateway позволяет запускать ядра на других машинах, мы столкнулись с техническими ограничениями. Например, kernel не умеет прокидывать переменные окружения, что вызывает сложности при синхронизации данных. Также kernel не поддерживает передачу отдельных файлов, что может приводить к ошибкам при передаче данных. Нужна была система плагинов, которая бы помогла это всё починить.

Но и с плагинами есть загвоздка — JupyterLab изначально не был спроектирован для работы с удаленными ядрами. Это означает, что некоторые плагины (например, TensorBoard) не могут корректно функционировать. Для исправления ситуации нужен разработчик, чтобы он вручную настроил интеграцию плагинов с удаленными ядрами для нормальной работы.

В качестве основного решения этой ситуации мы внедрили экстеншн, и всё прекрасно заработало.

Cloud.ru Jupyterlab extension
Cloud.ru Jupyterlab extension

Возможности extension в Jupyterlab 

Весомый плюс JupyterLab — возможность покрыть экстеншнами все что угодно. Можно переписать практически весь JupyterLab, при этом не форкая его. Таким способом можно решить проблемы:

  • healthcheck;

  • уведомлений;

  • переменных окружения в remote kernels;

  • большого количества файлов, которые могут уронить ноутбук.

Healthcheck. Важно, чтобы при работе системы один из компонентов не выходил из строя, когда остальные продолжают работать. Например, в ситуации с фронтом и бэком мы не хотели, чтобы что-то из них упало. А если недостаточно ресурсов, OM-киллер может отключить часть системы — например, если батч не влез в объем памяти GPU. Пользователям нужно понимать, что делать в таких ситуациях и как получить уведомление о проблеме, чтобы своевременно сохранить изменения.

Нам нужно, чтобы при возникновении проблем в бэке мы получали об этом уведомление, а фронт при этом не падал. Мол, сервер что-то упал, но сейчас поднимется и все будет круто. Такие уведомления — это важно, чтобы была возможность сохраниться. В работе ML, DS-специалистов непременно нужно нажать «Ctrl + S», чтобы ничего не потерять.

Уведомления. Мы также улучшили систему уведомлений в JupyterLab. Они есть в формате release notes, но если покопаться в настройках, оповещения можно расширить — использовать специальный менеджер уведомлений.

Переменные окружения в remote kernels. Как я упомянул выше, для решения проблемы выбрали экстеншены, так как в JupyterLab могут неправильно работать нужные плагины — например, TensorBoard.

Большое количество файлов. Существует отдельный open source проект JupyterLab, который обеспечивает поддержку кода. Команда Jupyter пока не предложила решение вопроса с большим количеством файлов, поэтому мы находимся в ожидании. В качестве временной меры ограничили объем данных, возвращаемых с бэкэнда, чтобы файлы не положили ноутбуки.

Итоги и планы на будущее

Год, что мы работали над созданием ноутбуков, выдался насыщенным. Мы решили массу задач:

  • При разработке новой архитектуры ноутбуков внедрили Kubeflow и ML Space SDK. Это позволило версионировать окружения и передавать их версии другим сотрудникам.

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

  • Решили проблемы с NVML error, о которой много говорят.

  • Подключили SSH портал.

  • Создали мультирутовый браузер, которого пока что нет у Jupyter.

В этом году мы планируем показать новые эластичные ноутбуки, которые смогут останавливаться по триггерам. В качестве триггеров будут метрики нагрузки либо заданный интервал времени жизни — время, когда устройство должно выключиться. Это позволит не платить за простой.

Для создания доступны индивидуальные (приватные) ноутбуки. Пилот уже проведен, мы реализовали возможность запустить индивидуальный Jupyter Server и подключиться к нему через интерфейс ML Space. 

Продолжим развивать MLflow, ML Space SDK, добавим новые образы. Будем работать над удобством интерфейса, чтобы пользователь мог работать в ноутбуке и не покидать его. И, конечно, вложимся в оптимизацию внутренних сервисов, чтобы ноутбуки по итогу были и на нашей платформе Cloud.ru ML Space, и на Сloud.ru Evolution ?

Комментарии (0)