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

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

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

Поскольку это был Spark, первое, что нужно сделать, это подождать несколько минут, чтобы кластер заработал, выбрать правильное количество рабочих процессов и выполнить некоторые настройки следующим образом:

С помощью Snowflake мы можем просто немедленно создавать виртуальные склады (без времени ожидания), сколь угодно маленькими или большими по мере необходимости. Мы также можем изменить размер любого склада без прерывания работы перед выполнением заданий или приостановить его, когда он больше не используется. Используя Snowpark, мы можем вызвать API use_warehouse, чтобы определить используемое хранилище или изменить его размер.

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

Мы хотим предсказать количество поездок для каждого идентификатора станции. В традиционной среде Spark требуется некоторая подготовка данных. Перетасовка Spark — дорогостоящая операция, но она необходима, поскольку Spark использует RDD для распределения данных, и их необходимо сгруппировать по идентификатору станции. Поэтому перед вызовом Pandas UDF данные будут распределены. Что-то вроде этого перед вызовом пользовательской функции station_train_predict_p_udf Pandas.

Snowflake предлагает Snowpark UDF и UDTF на Python. Это означает, что весь код, используемый для обучения и логического вывода, может быть написан и выполнен в Snowflake на предпочтительном для машинного обучения языке с использованием безопасной изолированной программной среды с доступом ко всем пакетам Anaconda. Мы можем определить нашу функцию следующим образом:

А затем зарегистрируйте его как один UDF в Snowflake:

После регистрации UDF при использовании Snowflake нет необходимости перемешивать или распределять данные. Это то, что делает Snowflake автоматически, и он будет использовать все доступные ресурсы в соответствии с размером определенного склада. В приведенном примере мы можем видеть, как сначала мы готовим фрейм данных с историческими данными и один с такими функциями, как прогнозы погоды и праздников, которые мы используем для прогнозирования новых поездок, поскольку они могут быть важным фактором принятия решения (я не люблю ездить под дождем ):

Здесь мы группируем по идентификатору станции при построении фрейма данных. Подумайте о сценарии использования розничной торговли, когда, возможно, они хотят прогнозировать по каждому магазину и разделу. Или каждый раздел или тип статьи. Нам просто нужно переписать способ создания фрейма данных, и Snowflake будет вызывать UDF Snowpark для каждой из тех групп, которые мы хотим предсказать. Код Snowpark UDF будет проще, потому что нет необходимости иметь дело с конкретными столбцами, которые мы хотим использовать для группировки. Это то, где Snowflake обеспечивает лучшую гибкость и гибкость с помощью фреймов данных и UDF.

В нашем примере мы можем просто объединить исторический и прогнозный кадр данных и вызвать UDF с необходимыми параметрами. Профилировщик запросов на уровне облачных служб создаст запрос и оптимизирует его выполнение в зависимости от используемого хранилища. Этот код создаст новую таблицу с прогнозами, и весь этот код будет выполняться в Snowflake:

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

Я могу изменить размер своего хранилища на XSMALL (то есть всего один узел) и выполнить его, чтобы получить базовый уровень. Весь процесс прогнозирования поездок для 522 станций занял 4 минуты 23 секунды.

И мы можем взглянуть на статистику выполнения 522 UDF:

Теперь я хочу масштабироваться либо потому, что у меня может быть больше магазинов для прогнозирования, либо потому, что я хочу сократить время, необходимое для выполнения моего запроса. Со Snowflake, в отличие от подготовки к работе, которая требовалась ранее с кластером Spark, это простая операция. Нам нужна всего одна строка кода или вызов API, чтобы изменить размер склада. Уровень облачных сервисов позаботится об оптимизации запроса и распределении рабочей нагрузки по всем доступным узлам в соответствии с новым размером. Увеличив размер хранилища до СРЕДНЕГО (4 узла), я вижу, как время выполнения сократилось до 1 минуты 31 секунды.

Если я взгляну на статистику UDF, они очень похожи, разница в сокращении общего времени заключается в том, что Snowflake распределила нагрузку по доступным узлам:

Функции Snowpark Python UDF и UDTF в сочетании с масштабируемостью и гибкостью Snowflake представляют собой очень эффективный способ внедрения некоторых операций машинного обучения в конвейеры данных. Нет необходимости перемещать данные из Snowflake, так как все выполнение выполняется внутри Snowflake и использует столько ресурсов, сколько необходимо, а платит только за то, что используется.

Имейте в виду, что на момент написания этого блога Snowpark Python находится в публичной предварительной версии. Это все личное мнение, а не мнение моего нынешнего работодателя (Снежинка)

Наслаждаться!