Jupyter Notebook устарел и не годится для large scale аналитики
И какую альтернативу нам предлагает мир open-source?
0. Введение
Большинство читателей данного блога скорее всего начинали свой путь в данных с jupyter-ноутбука, который на протяжении почти 10 лет является синонимом работы с данными для ДС, дата-аналитиков и дата-журналистов, а также часто используется в академии. Если ты не знаешь что это, обратись к одному из источников — раз, два, три.
Jupyter Notebook (JN) основан на IPython Notebook, модуле проекта IPython. Сам по себе IPython предоставляет возможности для интерактивной работы с python, где помимо интероспекции есть дополнение кода и тд. Это удобно для итеративного типа работы, что важно при анализе данных: следующий кусок кода, который мы будем писать, зависит от вывода предыдущего.
Но запуск код на python — не всеобъемлющая часть анализа данных, ведь данные также нужно визуализировать, совмещать с другими инструментами, а также делиться результатами работы. Для этого в jupyter можно подключать т.н. кернелы для bash, R и тд, и строить визуализации с помощью различных библиотек. Для того, чтобы делиться результатами, рабочую книгу в jupyter (т.н. блокнот .ipynb) можно скачать одним self-contained файлом, содержащим в себе код, графики, а также отформатированный текст и формулы (markdown + LaTex). Такой формат обеспечивает повторяемость вывода, путем простого перезапуска блокнота.
Однако, бОльшая часть аналитиков и ДС работает внутри IT-корпораций, что накладывает определенные условия. Ниже мы разберем их подробнее и укажем, почему JN в первоначальном виде не удовлетворяет части из них (о чем уже много писали на medium), а также о том какие доработки (тюнинг) и альтернативы существуют.
1. Чем плох Jupyter notebook
Особенность корпоративного анализа данных — огромные датасеты, которые не помещаются в локальную память (тем более оперативную) рабочего компьютера. Jupyter имеет клиент-серверную архитектуру со специальным протоколом общения, благодаря чему является агностиком к ядру. В итоге сервер может исполняться на огромном кластере, и будет горизонтально масштабируемым. Это плюс.
Однако, в IT-компаниях дата-команды обычно состоит из более чем одного сотрудника, и коллеги читают код друг друга. Соответственно необходимо организовать доступ к ноутбукам разных контрибьютеров. Более того, обычно есть разделение ролей — дата-инженеры, аналитики, ДС и тд. Более подробное разделение обязанностей и примеры задач можно найти в примере Netflix. С одной стороны, они решают разные задачи в разных инструментах, с другой — концепция остается похожей. Нужно запустить код, сделать EDA, показать результаты и иногда задеплоить получивший пайплайн (суть деплоя заключается в автоматическом исполнение ноутбука планировщиком, в т.ч. с указанием доп-параметров).
Часто ноутбук выглядит так, как на картинке выше. Мы видим подключение к БД, SQL запрос к ней и построение графиков. Здесь сразу открывается несколько проблем. Во-первых, python является посредником для похода в БД. Код может поменяться и тогда придется править в нескольких ноутбуках. Конечно, можно сделать обертку в виде пакета python и ходить одной функцией, но это не исправит вторую проблему. Код на SQL является простой строкой, а значит не будет работать не то что авто-дополнение, но и подсветка синтаксиса. Во-вторых, непонятна актуальность графиков (возможно запуск был несколько месяцев назад). Кроме того, сама визуализация в python — не самая удобная и очень субъективная вещь. В-третьих, по умолчанию нет никакой версионности, и нужно придумывать какие-то костыли например с git.
Итого, мы имеем следующие хотелки для инструмента:
- Клиент-серверная архитектура, в которой в качества сервера выступает аналитический кластер компании, а клиенту желательно находиться в браузере.
- Наличие как приватного пространства, так и общедоступного.
- Возможность интерактивных отчетов с фильтрами.
- Возможность запуска по расписанию, в т.ч. параметризированного.
- Нативная поддержка SQL.
- Обмен объектами между разными языками (SQL/Python/Scala).
- Версионность.
- Удобный дебаггинг.
- Линейное исполнение??
2. Костыли с jupyter
Можно использовать локальные инструменты, например Spyder, немного упрощающие работы с визуализациями и зависимостями, что-то похоже на работу с IDE. Однако, он использует только локальные мощности. Поэтому, неплохо было бы использовать IDE, но с возможностью подключиться к работающему серверу jupyter.
Например, встроенная работа с ноутбуками есть в PyCharm. Также, VS Code не только поддерживает работу с ноутбуками, упрощая дебаггинг и интегрируя с git, но и позволяет использовать Github Copilot, всего лишь поставив доп. расширение. Использование данных инструментов решит часть проблем, например более удобную подсветку синтаксиса, работу с системами контроля версий, а также удобное подключение к БД и полноценная работа с ними.
Еще один продукт, упрощающий работу с ноутбуками — JupyterLab (JL). Он преставлен создателями jupyter довольно давно (в 2018 г.), и является прямым продолжение JN. Помимо основной работы с ноутбуками, полностью совместимыми с JN (можно даже перейти в старый интерфейс поменяв url, т.к. используется один и тот же сервер), JL позволяет кастомизировать интерфейс (аналогично RStudio), а также удобно просматривать и изменять разные форматы файлов (JSON, CSV, Vega, VegaLite). Помимо того, что продукт сам по себе open-source, он позволяет добавлять множество расширений. Например, визуальный дебаггер, рисование в draw.io, просмотр файлов Excel, а также новые magic’и.
Сам по себе JL убирает потребность в локальных IDE, поскольку помимо браузерной версии содержит версию JupyterLab Desktop, позволяющуя работать как с локальным железом, так и подключаться к удаленному серверу (в том числе под SSO). Для любителей, помимо десктопной версии с интерфейсом, локально можно работать с ноутбуками в том числе в терминале через nbterm. Однако, несмотря на все плюсы, поскольку JL является лишь продолжением JN, он также не поддерживает code-assist (хотя есть инспектор) и не решает проблемы 5–9. И ключевое, что необходимо понимать — данные инструменты все еще упрощают работу только одного контрибьютера, не решая проблемы 1–4 из списка выше. Еще одна из проблем jupyter, описанная выше — ненативный SQL. Не так давно появилось решение — Xeus, представляющее из себя kernel для работы с БД. Примеры работы с ним можно найти тут. Однако, он пока работает лишь с основными СУБД (Postgres, SQLite, MySQL) и не поддерживает современные аналитические. Поэтому большая компании, такие как Meta, делают свои SQL-ноутбуки.
К сожалению, перечисленные выше инструменты никак не решают проблему множества пользователей, поэтому будем изучать дальше.
3. Решение проблем
Многопользовательская работа
JupyterHub (JH) — это многопользовательская версия jupyter, работающая как со старой, так и с новой версией (JN и JL). Он работает как прокси, который принимает запросы и порождает single-user сервер jupyter с нужной аутентификацией. Подробную информацию можно найти в документации.
Главный плюс JH — это его гибкость. Он работает с несколькими интерфейсами: как с JupyterLab, так и с рассматриваемым далее nteract и с Visual Studio Code. В JH аутентификация настраивается удобным образом — через OAuth, GitHub, корпоративный SSO и тд. Также, JH хорошо масштрабируется: он может крутится как на одном сервере для небольшой команды, так и на тысячах под управлением Kubernetes. Это определяется т.н. spawner’ом, т.е. механизмом запуска нового сервера. Это легко решает проблему ресурсов — можно поставить spawner с ограничением по ресурсам, т.е. один пользователь не заберет всю мощность. Также можно отключать запущенные сервера по таймауту с помощью jupyterhub-idle-culler.
Шеринг
Одна из проблем, которую надо решить — это шеринг ноутбуков. Нужна как приватная зоны, так и общедоступная. Обычный JH позволяет это делать разве что созданием общей папки, куда можно копировать свои файлы. При этом есть всего 2 типа пользователей — админ и не-админ. Для по-командного разделения можно делать разные инстансы JH под разные команды, это же работает и для разделения ресурсов (подробнее разобрано в здесь).
Также, файлы .ipynb можно выкладывать в репо в GitHub/GitLab, где они будут красиво рендериться в ноутбуки с выводом, и в т.ч. нормально отображать diff’ы. Если ноутбук содержит интерактивные графики, можно открыть ноутбуки из открытых репозиториев в nbviewer, однако они все равно будут открываться лишь статическими html-файлами. Открытые репо с ноутбуками можно открыть в Binder, который под капотом создаст docker-образ с зависимостями из репо и откроет JL, в котором можно самому запускать ноутбуки из репо и изменять их (но в рамках этого образа, коммитов не будет). Кроме того, Binder является открытым репо, а значит можно поднять у себя в облаке BinderHub и шерить готовые интерактивные отчеты в виде ноутбуков.
Еще одним инструментом для упрощения шеринга может быть NBconvert. По его помощью можно превратить файл .ipynb в картинку, html и тд (можно делать слайды через RISE). А уже данные форматы можно перекладыать в хранилищ или интегрировать например с корпоративным вики.
В новой версии появилось расширение jupyter-collaboration, позволяющее работать совместоно как с гугл-доком. Также, есть облачные интрументы, которые позволяет делать публичную ссылку на ноутбук. Разберем их ниже.
Другим удобным инструментом является Voilà, позволяющий делать интерактивные визуалиции (дашборды) в отдельном веб-приложении, используя общую с nbconvert шаблонную систему. При этом kernel остается запущенным и может выполнять какие-то вычисления, необходимые для интерактивных графиков. Подробнее про отличии от nbconvert тут. В отличии от виджетов (обсудим их ниже), данный инструмент позволяет не выдавать доступ в jupyter на выполнение произвольного кода, а также на изменение текущего ноутбука.
Scheduling
C одной стороны это антипаттерн, т.к. jupyter является инструментом итеративной работы, а не отчетности или ETL. С другой — это прекрасно работает в маленьких командах. Исполненный по расписанию (например, из DAG’а) экземпляр ноутбука содержит в себе все нужные артефакты: конфиг, код, графики, логи исполнения (причем линейного), возможность посмотреть что уже исполнилось и перезапустить с нужного места. Это пригодиться как аналитикам/ДС для шаблонного анализа экспериментов, так и DE для автоматизации DQ-проверок.
Чтобы один ноутбук мог запускаться под разные даты (и другие параметры), обычно используется Papermill из проекта nteract для параметризации ноутбука. Например, из airflow прокидывается контекст, в котором среди прочего есть дата исполнения, и она подставляется в один из параметров (переменную) в ноутбуке. Простой пример можно найти на их github’е.
Сейчас в JupyterLab появилось расширение Jupyter Scheduler, позволяющей указать в панели инструментов ноутбука cron-выражение для его исполнения. В нужное время сервер сделает копию ноутбука с уникальным именем и исполнит его. Кроме того, интрумент из коробки поддерживает параметризацию.
Визуализации
Конечно, в jupyter можно и нужно использовать библиотеки для визуализации данных в python: matplotlib, plotly, Seaborn, Bokeh, тысячи их. Однако, для этого нужно выучить новую библиотеку, и для смены типа графика необходимо написать новый код. Это плохо ложится на итеративный стиль работы аналитика, когда хочется быстро крутить данные в разных форматах. И тем более такой вариант слабо подходит для интерактивных отчетов с фильтрами и тд.
В отличии от библиотек (tools) и дашбордов (applications) такие инструменты обычно называют automatic data visualization. Их особенность в том, что они созданы для циклической работы и не предполагают финального результата в виде фиксированной визуалиции или дашборда. Обычно для этого использует библиотеки, которые превращают ноутбук в некий аналог BI-системы с интуитивной настройкой визуализации. Один из таких вариантов — библиотека Lux.
Другим примером является Data Explorer от nteract — платформы, которую мы разберем в следующем разделе.
Основная проблема перечисленных выше решения — необходимость уставновки и настройки множества расширений, что требует дополнительных усилий и знаний от команды эксплуатации. Можно что-то проще?
4. Аналоги
Colab — это бесплатный JN-сервис от Google. Ноутбуки храняться как .ipynb файлы в Google Drive и ими можно делиться. Colab интегрирован с GitHub и позволяет удобн комитить через UI. Поддерживает Python, R, и SQL. Раньше colab использовали из-за возможности запуска кода на GPU (тем более что TensorFlow и PyTorch стоят по умолчанию), однако теперь это платная фича. При ограничение 20GB памяти на юзера раньше не было возможности докупить ресурсы, но теперь есть! Кроме ресурсов, есть ограничения по расширениям и настройке упомянутого выше тюнингу, а также привязке к сервисам гугла.
Еще одна альтернатива — kaggle notebooks, с возможность запускать код на GPU и TPU. Есть интеграция с Kaggle API, поддержка Git и возможность шаринга ноутбуков. Однако, это инструмент заточен под ML-соревнования и слабо подходит под корпоративную работу.
Также, есть и другие облачный платформы, такие как Microsoft Azure Notebooks, SageMathCloud, Nextjournal, JetBrains Datalore и др., подробный список можно найти в статье. В том числе, есть ноутбуки исключительно для SQL (evidence), и даже аналоги miro для SQL (см. count). Еще один пример ноутбука — BeakerX, также являющийся надстройкой на jupyter. Однако, они не обеспечивают уровень такой же контроля, как on-premise сервисы.
В desktop-версии лидероя является nteract. Это целая экосистема вокруг приложения с ноутбуками с приятным интерфейсом и использующее тот же формат .ipynb. Частью проекта является в том числе papermill. Блягодаря удобству в использовании, у данного проекта собралось комьюнити фанатов, которые пролобировали создание веб-версии — расширения для jupyter server со всеми плюшками ввиде drag-and-drop и тд. У nteract также был собственный интерфейс Hydrogen к редактору кода Atom, однако после покупки Github’а мелкомягкими редактор очевидно закрылся (дабы не конкурировать с Visual Studio Code). Одной из фишек экосистемы nteract является дополнение Data Explorer, позволяющее строить интерактивные визуализации в ноутбуке, в т.ч. работая с датасетом как с электронной таблицей. Другой проект для визуализации в nteract — Semiotic. В экосистеме есть проекты для версионирования ноутбуков bookstore, а также для их шеринга через сервер-эксплорер commuter. Главная фишка nteract — он полностью open-source, что позволяет большим корпорациям, таким как Netflix, дорабатывать под свои нужды с помощью components, о чем они писали в популярной статье.
3 года назад сотрудники Netflix, участвующие в разработках выше, решили создать свой продукт — Noteable. Он позволяет нативно использовать SQL (в т.ч. писать SQL по CSV и JSON файлам), делать простые интерактивные визуализации, версионировать через git, использовать как электронные таблицы. Ноутбуки поддерживают совместную работу, а также запуск по расписанию. С точки зрения эксплуатации, Noteable можно использовать как облачно, так и on-premise, удобно настраиваю оркестрацию и ресурс-менеджемент. И главное — облачная версия с большинством фич может использоваться бесплатно.
Похожую функциональность дает QueryBook, разработанный в недрах Pinterest. Это open-source продукт, нативно работающий с SQL (подстветка синтаксиса и тд) с приятным интерфейсом, что и было главной задачей инструмента. К сожалению, несмотря на интеграции с Presto/Hive/SparkSQL/СУБД, запускать обычный код на. Python/R интрумент не позволяет. Возможности: визуализация, планированное параметризированное (через Jinja2) исполнение, аутентификация и тд.
Еще одной облачной альтернативой является Deepnote . Помимо стандартного интерфейса ноутбука предоставляет также конекшены к популярным СУБД (в т.ч. Сlickhouse), а также другим источникам вроде Google Drive и Amazon S3. Ноутбуки можно как создавать в интерфейсе, так и импортировать через файлы .ipynb, а также из GitHub и Google Drive. Более подробный, но все еще краткий обзор можно найти тут. Из отличительных особенностей можно назвать удобный менеджемент среды (версия python и тд), совместная работа по аналогии с гугл-доками, а также простая no-code визуализация. Также у deepnote удобный эмбединг, поэтому примеры кода ниже сделаны в нем. Совсем недавно добавилась поддержка AI Copilot для SQL.
Главная проблема облачных сервисов в том, что обычно они работают поверх JN, а значит наследуют большинство из проблем и не удовлетворяют всем требованиям, перечисленным в первом разделе. При этом они или стоят денег (немаленьких), или сильно ограничены по мощностям.
5. Zeppelin
Одна из альтернатив, на которую стоит обратить внимание — это проект Apache Zeppelin, который позиционируется как jupyter для экосистемы Hadoop. Несмотря на это, его можно использовать и без данного стека, совмещая работу с СУБД и код на python. Краткий гайд по UI можно найти тут.
Zeppelin является java-приложением с простой установкой (можно воспользоваться также этим гайдом). Далее можно добавлять различные интерпретаторы (или kernel’ы в терминах jupyter), и использовать их в ноутбуках.
В отличии от jupyter, в Zeppelin интерпретатор прописывается в начале каждой ячейки. Например, после установки можно указать путь к бинарнику python, а также воспользоваться conda для установки библиотек. Для этого соответсвенно в начале ячейки указываем %python
или %python.conda
. При этом matplotlib автоматические конфигурируется inline с помощью pyplot
. Для документации также можно использовать интерпретатор для markdown, а для работы с БД можно подключить соотвествующие интепретаторы, при этом будет доступна подсветка синтаксиса. Кроме того, можно писать SQL поверх датафреймов в pandas.
В верхней части zeppelin находится панель инструментов, на которой расположены основные плюшки сервиса: из коробки работает версионность ноутбуков (второй блок с указателем HEAD на скрине) и запуск по cron (иконка с часами), однако запуск в параметрами невозможен.
В отличи от jupyter, здесь по умолчанию доступна многопользовательская работа, c настраиваемой LDAP/Active Directory аутентификацией и специально определенными группами безопасности. При нажатии на замок в правой части панели инструментов появляется окно с указанием логинов для доступа к чтению/записи/запуску ноутбука.
Т.к. zeppelin изначально создавался для big-data стека (Hadoop), у него есть встроенная интеграция с Apache Spark. Она решает задачу вызова контекстов (SparkContext и SQLContext) и загрузки jar-зависимостей из локальной файловой системы / репозитория maven во время выполнения задачи. Переменные контекста доступны под своими именами, более того, для одного юзера контекст будет общий, а это значит что можно переиспользовать структуры данных. В airflow это решалось с помощью спарковского REST-API — Livy (дока). Кроме того, ZeppelinContext
можно обмениваться переменными из разных языков.
Одна из главных плюшек zeppelin — доступная визуализация из коробки. “Выведенные в параграфе данные в виде нескольких базовых визуализаторов, работающих по принципу сводных диаграмм: в интерфейсе выбираются поля, по которым будут строиться оси и как будут агрегироваться выводимые значения” — из статьи. На картинке ниже видны кнопки выбора вида графика, а также выбор полей для графика (на пример для scatter-plot).
Получившиеся диаграммы кликабельны и позволяют с легкостью посмотреть данные в разных разрезах. Причем ячейки можно размещать не только друг под другом, но и на одной строке с помощью выбора ширины ячейки (сетка от 1 до 12).
Кроме того, отчеты могут быть экспортированы в формат CSV или TSV. Также zeppelin позволяет скрыть код, предоставляя читаемые интерактивные отчеты конечным пользователям, что делает из него мини-BI систему.
Однако, у zeppelin есть и минусы:
- Глюки и зависания на больших ноутбуках или загруженном кластере, а также загрузка множества оперативной памяти для интерактивного веб-интерфейса;
- По сравнению в jupyter, не такие гибкие возможности по настройке и кол-во предоставляемых от комьюнити инструментов;
- Все еще отсутствует автодополнение в редакторе.
Итог
Изначальная цель Jupyter — воспроизводимость кода, поэтому в отличии от обычного REPL (IPython) ноутбук сохраняет новую порцию кода в новой ячейке. Вопроизводимость важна не только при шеринге кода, но и самому автору — иногда трудно разобраться с тем что делал месяц назад. Но из-за итеративного характера работы часто ноутбук состоит из false starts, неупорядочных ячеек, старого неиспользуемого кода и тд. Следственно воспроизводимость страдает.
Обычно это разрешается путем очистки и повторного запуска блокнота после завершения определенного фрагмента анализа, чтобы получить чистый ноутбук. Так можно свести ноутбук к production-ready коду. Более того, Stitch Fix выпустили для этого специальное расширение Nodebook, которое делает ноутбук строго последовательно-выполняемым и автоматом перерасчитывает ячейки выше. Казалось бы, JN все еще нам подходит.
Однако, в отличии от академической среды, в IT-индустрии помимо воспроизводимости также важны автоматизация и командная работа. На первый взгляд jupyter из коробки предоставляет слабые возможности, о чем громко сказано в названии статьи. Однако, используя JupyterHub c расширениями Xeus, Data Explorer/Lux, Jupyter Scheduler/Papermill, NBconvert/Voilà и jupyter-collaboration можно превратить Jupyter во вполне годный инструмент. Для больших команд я бы рекомендовал этот вариант или облачные аналоги, разобранные выше. Но небольшим командам я бы посоветовал посмотреть в сторону Zeppelin, который хоть и не предоставляет таких возможностей по настройке и расширения, все же из коробки может покрыть большую часть вещей в простых дата-процессах.
P.S. (май 2024): в Jupyter Desktop наконец появилась возможность настраивать окна в UI (то, что было в RStudio уже лет 10). Зато подвелиз Zen-мод.
P.S.S.: Если тебе понравилась стать, в качестве благодарности можешь купить мне кофе на https://www.donationalerts.com/r/stats_data_ninja или https://buymeacoffee.com/koch.