Feast (FeatureStoreore) – это операционная система данных для управления и обслуживания функций машинного обучения в моделях, находящихся в производстве. Шаблон проектирования Feature Store упрощает управление и повторное использование функций в проектах, отделяя процесс создания функций от разработки моделей, использующих эти функции.

Проблемы в разработке функций в машинном обучении?

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

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

  • Специальные функции нелегко использовать повторно. Функции воссоздаются снова и снова, либо отдельными пользователями, либо внутри команд, либо никогда не покидают конвейеры (или блокноты), в которых они созданы. Это особенно проблематично для функций более высокого уровня, которые сложно вычислить. Это может быть связано с тем, что они получены с помощью дорогостоящих процессов, таких как предварительно обученный пользователь или встраивание элементов каталога. В других случаях это может быть связано с тем, что функции берутся из вышестоящих процессов, таких как бизнес-приоритеты, наличие контрактов или сегментация рынка. Еще одним источником сложности является то, что функции более высокого уровня, такие как количество заказов клиента за последний месяц, включают агрегирование во времени. Усилия и время тратятся на создание одних и тех же функций с нуля для каждого нового проекта.
  • Управление данными усложняется, если каждый проект машинного обучения по-разному вычисляет функции из конфиденциальных данных.
  • Специальные функции нелегко распределять между командами или проектами. Во многих организациях одни и те же необработанные данные используются несколькими командами, но отдельные команды могут по-разному определять функции, и доступ к документации по функциям затруднен. Это также препятствует эффективному взаимодействию команд, что приводит к разрозненной работе и излишнему дублированию усилий.
  • Специальные функции, используемые для обучения и обслуживания, несовместимы, т. е. перекос между обучением и обслуживанием. Обучение обычно выполняется с использованием исторических данных с пакетными функциями, которые создаются в автономном режиме. Однако обслуживание обычно осуществляется онлайн. Если конвейер функций для обучения вообще отличается от конвейера, используемого в производстве для обслуживания (например, другие библиотеки, код предварительной обработки или языки), то мы рискуем перекосом между обучением и обслуживанием.
  • Производить функции сложно. При переходе к рабочей среде не существует стандартизированной среды для обслуживания функций для онлайн-моделей машинного обучения и предоставления пакетных функций для обучения офлайн-моделей. Модели обучаются в автономном режиме с использованием функций, созданных в пакетных процессах, но при работе в рабочей среде эти функции часто создаются с упором на низкую задержку и в меньшей степени на высокую пропускную способность. Платформа для создания и хранения функций не является гибкой для обработки обоих этих сценариев.

Проблемы, которые решает праздник

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

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

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

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

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

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

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

Feast решает проблему утечки данных, обеспечивая правильный поиск объектов на определенный момент времени при экспорте наборов данных объектов для обучения модели.

Функции не используются повторно в разных проектах. Различные команды внутри организации часто не могут повторно использовать функции в разных проектах. Разрозненный характер разработки и монолитный дизайн комплексных систем машинного обучения способствуют дублированию создания и использования функций в командах и проектах.

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

Компромисс производительности Feast

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

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

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

Установка Kubeflow и Feast

ЧАСТЬ A. Kubeflow

~ Разверните AI Platform Pipelines с полным доступом к Google Cloud и перейдите по следующей ссылке https://cloud.google.com/ai-platform/pipelines/docs/setting-up.

~ После настройки платформы ИИ она создаст кластер, затем перейдет к кластеру Kubernetes и активирует облачную оболочку с помощью первой кнопки вверху справа и подключится к кластеру, нажав

~ Установите helm3 и выполните 3 команды ниже или перейдите по ссылке

curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3
chmod 700 get_helm.sh
./get_helm.sh

~ Установите Kubectl, выполнив следующие шаги по ссылке.

ЧАСТЬ B Пир

Добавьте репозиторий Feast Helm и загрузите последние диаграммы. Feast включает в себя диаграмму Helm, которая устанавливает все необходимые компоненты для запуска Feast Core, Feast Online Serving.

helm repo add feast-charts https://feast-helm-charts.storage.googleapis.com
helm repo update
helm install feast-release feast-charts/feast

Feast Core требует запуска Postgres, для чего требуется установить секрет в Kubernetes:

kubectl create secret generic feast-postgresql --from-literal=postgresql-password=password

Используйте оператор Kubernetes для Apache Spark

Оператор Kubernetes для Apache Spark стремится сделать определение и запуск приложений Spark такими же простыми и идиоматичными, как выполнение других рабочих нагрузок в Kubernetes. Он использует пользовательские ресурсы Kubernetes для указания, запуска и отображения состояния приложений Spark.

Оператор состоит из:

  • контроллер SparkApplication, который отслеживает события создания, обновления и удаления объектов SparkApplication и действует в соответствии с событиями наблюдения,
  • обработчик отправки, который запускает spark-submit для отправки, полученной от контроллера,
  • монитор модуля Spark, который следит за модулями Spark и отправляет обновления состояния модуля на контроллер,
  • Мутирующий веб-перехватчик допуска, который обрабатывает настройки для модулей драйвера и исполнителя Spark на основе аннотаций модулей, добавленных контроллером,
  • а также инструмент командной строки под названием sparkctl для работы с оператором.

В частности, пользователь использует sparkctl (или kubectl) для создания объекта SparkApplication. SparkApplicationcontroller получает объект через наблюдателя с сервера API, создает представление, содержащее spark-submitarguments, и отправляет представление исполнителю отправки. Исполнитель отправки отправляет приложение для запуска и создает модуль драйвера приложения. При запуске модуль драйвера создает модули исполнителя. Во время работы приложения монитор модулей Spark наблюдает за модулями приложения и отправляет обновления состояния модулей обратно на контроллер, который затем соответствующим образом обновляет состояние приложения.

Перейдите по ссылке Github и выполните набор шагов из файла spark.md и активируйте Spark в кластере Kubernetes.

Далее выполните следующее. ниже, отредактируйте следующую команду и добавьте сервисные аккаунты в тег subjects.

kubectl edit clusterrolebinding spark-operatorsparkoperator-crb

Наконец, убедитесь, что учетная запись службы, используемая Feast, имеет разрешения на управление ресурсами приложения Spark. Это зависит от вашей настройки k8s, но обычно вам нужно настроить роль и привязку роли, как показано ниже:

kubectl edit clusterrolebinding spark-operatorsparkoperator-crb
kubectl apply -f role-binding.yaml -n spark-operator

Секрет Kubernetes для пространства имен по умолчанию

Чтобы подключиться к GCR из среды, отличной от GCP, вы добавляете поле ImagePullSecrets в конфигурацию учетной записи службы Kubernetes. Это тип секрета Kubernetes, который содержит учетную информацию.

Запустите следующие команды

### GCP KUBEFLOW
export SA_NAME=feastai
export NAMESPACE=default
export SECRETNAME=user-gcp-sa
PROJECT_ID=$(gcloud config list core/project --format='value(core.project)')
# Create service account
gcloud iam service-accounts create $SA_NAME \
--display-name $SA_NAME --project "$PROJECT_ID"
# Grant permissions to the service account by binding roles
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member=serviceAccount:$SA_NAME@$PROJECT_ID.iam.gserviceaccount.com \--role=roles/storage.admin
# Note that you can not bind multiple roles in one line.
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member=serviceAccount:$SA_NAME@$PROJECT_ID.iam.gserviceaccount.com \--role=roles/ml.admin
# Create credential for the service account
gcloud iam service-accounts keys create application_default_credentials.json --iam-account $SA_NAME@$PROJECT_ID.iam.gserviceaccount.com
# Attempt to create a k8s secret. If already exists, override.
kubectl create secret generic user-gcp-sa \
--from-file=user-gcp-sa.json=default.gcp.json \-n $NAMESPACE --dry-run -o yaml  |  kubectl apply -f -
kubectl create secret docker-registry $SECRETNAME -n $NAMESPACE \
--docker-server=https://gcr.io \
--docker-username=_json_key \
[email protected] \
--docker-password="$(cat application_default_credentials.json)"

Разоблачение внутренней DNS-службы Feast

Таким образом, служба, которая была развернута в пространстве имен Kubernetes по умолчанию, позволяет предоставлять их с аутентификацией в определенном пользователем пространстве имен, например. aniruddha-choudhury, чтобы клиент праздника мог получить доступ к таким сервисам, как Redis, Kafka, Feast Core, Feast Online и т. д.

Целью этого раздела является то, что наш конвейер Kubeflow будет работать в пространстве имен пользователя, а праздник — в пространстве имен по умолчанию.

Запустите следующую команду:

kubectl apply -f service-expose.yaml

1. Набор функций Building Feast с подключением к клиенту

Данные хранятся в Feast с использованием FeatureSets. FeatureSet содержит схему данных и информацию об источнике данных, независимо от того, поступает ли она из фрейма данных pandas. FeatureSets — это то, как Feast узнает, где взять данные, необходимые для функции, как их получить, а также некоторые основные характеристики типов данных. Группы функций могут приниматься и храниться вместе, а наборы функций обеспечивают эффективное хранение и логическое пространство имен данных в этих хранилищах.

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

Шаги для загрузки функций в данные в Feast:

~ Подключитесь к развертыванию Feast, настроив клиент с помощью Python SDK и создав промежуточную корзину GCP.

import os,json
from feast import Client, Feature, Entity, ValueType, FeatureTable
from feast.data_source import FileSource, KafkaSource
from feast.data_format import ParquetFormat, AvroFormat
import random 
staging_bucket = f'gs://feast-staging-bucket-{random.randint(1000000, 10000000)}/'
!gsutil mb {staging_bucket}
staging_bucket
client = Client(core_url="feast-release-feast-core.aniruddha-choudhury.svc.cluster.local:6565",
    serving_url="feast-release-feast-online-serving.aniruddha-choudhury.svc.cluster.local:6566",
    spark_launcher="k8s",
    spark_staging_location=staging_bucket,
    spark_k8s_namespace="spark-operator",
    redis_host="feast-release-redis-headless.aniruddha-choudhury.svc.cluster.local:6379",
    historical_feature_output_location=f"{staging_bucket}historical",
)

~Entity определяет первичные ключи, связанные с одной или несколькими таблицами функций. Сущность должна быть зарегистрирована до объявления связанных таблиц функций. Сущности используются в качестве ключей для поиска значений функций и используются для объединения функций между различными наборами функций при создании наборов данных для обучения или обслуживания. Сущность служит идентификатором для любой соответствующей характеристики, имеющейся у вас в наборе данных. Это объект, который можно моделировать и хранить информацию.

driver_id = Entity(name="driver_id", description="Driver identifier", value_type=ValueType.INT64)
# Daily updated features 
acc_rate = Feature("acc_rate", ValueType.FLOAT)
conv_rate = Feature("conv_rate", ValueType.FLOAT)
avg_daily_trips = Feature("avg_daily_trips", ValueType.INT32)
fare_amount = Feature("fare_amount", ValueType.INT32)
sales_status = Feature("sales_status", ValueType.INT32)

~ Зарегистрируйте FeatureSet. Это создает именованный набор функций в Feast. Набор функций не содержит данных о функциях. Таблицы функций хранятся в системе корзин gcp и доступны из кластера Spark, batch_source определяющего, где хранятся исторические функции. Также возможно иметь необязательный stream_source, в котором значения характеристик доставляются непрерывно.

# Offline data will be stored in this location
demo_data_location = os.path.join(os.getenv(“FEAST_SPARK_STAGING_LOCATION”, staging_bucket), “test_data”)
driver_statistics_source_uri = os.path.join(demo_data_location, "driver_statistics")
driver_statistics = FeatureTable(
    name = "driver_statistics",
    entities = ["driver_id"],
    features = [
        acc_rate,
        conv_rate,
        avg_daily_trips,
        fare_amount,
        sales_status
    ],
    batch_source=FileSource(
        event_timestamp_column="datetime",
        created_timestamp_column="created",
        file_format=ParquetFormat(),
        file_url=driver_statistics_source_uri,
        date_partition_column="date"
    )
)

~Регистрация сущностей и таблиц функций в Feast Core

client.apply(driver_id)
client.apply(driver_statistics)
print(client.get_feature_table("driver_statistics").to_yaml())

~ Заполнение источника партии

Как для пакетных, так и для потоковых источников необходимы следующие конфигурации:

  • Столбец с временной меткой события: имя столбца, содержащего временную метку, когда произошли данные о событии. Используется во время присоединения значений признаков к временным меткам объекта.
  • Созданный столбец метки времени: имя столбца, содержащего метку времени при создании данных. Используется для дедупликации данных при приеме нескольких копий одного и того же ключа объекта.

Мы можем загрузить данные функции фрейма данных в Feast, используя client.ingest(..).

client.ingest(driver_statistics, stats_df)

2. Создание конвейера Feast для обучения и обслуживания с помощью Kubeflow

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

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

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

2.1 ПОЛУЧЕНИЕ ДАННЫХ ИЗ FEAST

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

import gcsfs
from pyarrow.parquet import ParquetDataset
from urllib.parse import urlparse
import os,json
from feast import Client, Feature, Entity, ValueType, FeatureTable
from feast.data_source import FileSource, KafkaSource
from feast.data_format import ParquetFormat, AvroFormat
features={"Features":[
        "driver_statistics:avg_daily_trips",
        "driver_statistics:conv_rate",
        "driver_statistics:acc_rate",
        "driver_statistics:fare_amount", 
    "driver_statistics:sales_status"
    ]}
entity_bucket="gs://feast_data_source/data/entity.csv"
entities_with_timestamp=pd.read_csv(entity_bucket)
entities_with_timestamp["event_timestamp"]=pd.to_datetime(entities_with_timestamp["event_timestamp"])
client = Client(
           core_url="feast-release-feast-core.aniruddha-    choudhury.svc.cluster.local:6565",
           serving_url="feast-release-feast-online-serving.aniruddha-choudhury.svc.cluster.local:6566",
          spark_launcher="k8s",
          spark_staging_location=staging_bucket,
          spark_k8s_namespace="spark-operator",
          redis_host="feast-release-redis-headless.aniruddha-choudhury.svc.cluster.local:6379",      historical_feature_output_location=f"{staging_bucket}historical")
job =
client.get_historical_features(feature_refs=features['Features'] ,entity_source= entities.stage_entities_to_fs(entity_source=entities_with_timestamp, staging_location=staging_bucket,config= Config))
# get_output_file_uri will block until the Spark job is completed.
output_file_uri = job.get_output_file_uri()
features_outcome=read_parquet(output_file_uri)

2.2 ТРУБОПРОВОД KUBEFLOW

Ниже приведен сервис компонента Feast Kubeflow для извлечения исторических функций для обучения.

import kfp.dsl as dsl
import yaml
from kubernetes import client as k8s
import kfp.gcp as gcp
from kfp import components
from string import Template
import json
from kubernetes import client as k8s_client
@dsl.pipeline(
  name='Feast Service pipeline',
  description='End to End pipeline for Feast training and serving'
)
def feast_training_pipeline(    feast_step_image="gcr.io/project_id/feast_kube/apachespark_job:v1",
        trainmodel_step_image="gcr.io/project_id/feast_kube/train_job:v1",
        evaluator_step_image="gcr.io/project_id/feast_kube/evals_job:v1",
json_bucket="gs://feast_data_source/data/features.json",
        entity_bucket="gs://feast_data_source/data/entity.csv",
        staging_bucket="gs://feast-staging-bucket-3670014/",  
        split_size=0.2,
        epochs=5,
        learning_rate=.001,
        batch_size=64,
        shuffle_size=1000,
        target_name="driver_statistics__sales_status",
        tensorboard_gcs_logs="gs://feast_data_source/taxi/logs",
        gcs_path="gs://feast_data_source/taxi/model",        gcs_path_confusion="gs://feast_data_source/taxi/",
        mode="gcs",
        probability=0.5,
        serving_name="kfserving-feast-serving",
        serving_namespace="default",
        image="gcr.io/<project_id/feast_kubeflow/serving_job:v1"
        
    ):
"""
    Pipeline
    """
    # PVC : PersistentVolumeClaim volume
    vop = dsl.VolumeOp(
      name='my-pvc',
      resource_name="my-pvc",
      modes=dsl.VOLUME_MODE_RWO,
      size="1Gi"
    )
# feast
    feast_step = dsl.ContainerOp(
        name='Feast Service',
        image=feast_step_image,
        command="python",
        arguments=[
            "/app/feast_service.py",
            "--staging-bucket", staging_bucket,
            "--json-bucket", json_bucket,
            "--entity-bucket", entity_bucket,
            "--target-name",target_name
        ],
        pvolumes={"/mnt": vop.volume}
    ).apply(gcp.use_gcp_secret("user-gcp-sa"))
#trainmodel
    train_model_step = dsl.ContainerOp(
        name='train_model',
        image=trainmodel_step_image,
        command="python",
        arguments=[
            "/app/train.py",
            "--epochs",epochs,
            "--batch-size",batch_size,
            "--learning-rate",learning_rate,
            "--tensorboard-gcs-logs",tensorboard_gcs_logs,
            "--gcs-path", gcs_path,
            "--mode", mode,
          
        ],
        file_outputs={"mlpipeline-ui-metadata": "/mlpipeline-ui-metadata.json"
        },
        pvolumes={"/mnt": feast_step.pvolume}
    ).apply(gcp.use_gcp_secret("user-gcp-sa")) 
   
    #evaluationmodel
    evaluation_model_step = dsl.ContainerOp(
        name='evaluation_model',
        image=evaluator_step_image,
        command="python",
        arguments=[
            "/app/evaluator.py",
            "--probability",probability,
            "--gcs-path", gcs_path,
            "--gcs-path-confusion", gcs_path_confusion,
          
        ],file_outputs={"mlpipeline-metrics":"/mlpipeline-metrics.json","mlpipeline-ui-metadata": "/mlpipeline-ui-metadata.json"
        },
        pvolumes={"/mnt": train_model_step.pvolume}
    ).apply(gcp.use_gcp_secret("user-gcp-sa"))
kfserving_template = Template("""{
                              "apiVersion": "serving.kubeflow.org/v1alpha2",
                              "kind": "InferenceService",
                              "metadata": {
                                "labels": {
                                  "controller-tools.k8s.io": "1.0"
                                },
                                "name": "$name",
                                "namespace": "$namespace"
                              },
                              "spec": {
                                "default": {
                                  "predictor": {
                                    "custom": {
                                      "container": {
                                        "image": "$image"
                                      }
                                    }
                                  }
                                }
                              }
                            }""")
kfservingjson = kfserving_template.substitute({ 'name': str(serving_name),
                                'namespace': str(serving_namespace),
                                'image': str(image)})
kfservingdeployment = json.loads(kfservingjson)
serve = dsl.ResourceOp(
        name="serve",
        k8s_resource=kfservingdeployment,
        action="apply",
        success_condition="status.url"
    )
    serve.after(evaluation_model_step)
    
    
if __name__ == '__main__':
    import kfp.compiler as compiler
    pipeline_func = feast_training_pipeline
    pipeline_filename = pipeline_func.__name__ + '.pipeline.zip'
    compiler.Compiler().compile(pipeline_func,pipeline_filename)
  • @dsl.pipeline является обязательным украшением, включая свойства name и description.
  • Входные аргументы отображаются как параметры конвейера в пользовательском интерфейсе Kubeflow Pipelines. По правилу Python сначала появляются позиционные аргументы, за которыми следуют аргументы ключевого слова.
  • Каждый аргумент функции имеет тип dsl.PipelineParam. Все значения по умолчанию должны относиться к этому типу. Значения по умолчанию отображаются в пользовательском интерфейсе Kubeflow Pipelines, но пользователь может их переопределить. Скомпилируйте конвейер и загрузите его в пользовательский интерфейс kubeflow.

2.3 ПРАЗДНИКИ И МОНИТОРИНГ УСЛУГ

Компоненты Feast экспортируют метрики, которые могут дать представление о поведении Feast. Задание Feast Ingestion Job можно настроить для отправки показателей Ingestion в экземпляр StatsD. Экспорт метрик в StatsD для задания загрузки настраивается в контроллере заданий.

kubectl port-forward — namespace knative-monitoring $(kubectl get pod — namespace knative-monitoring — selector=”app=grafana” — output jsonpath=’{.items[0].metadata.name}’) 8080:3000

Подключитесь к Grafana и проверьте метрики и телеметрию. Метрики приема в Prometheus или какой-либо другой серверной части метрик, используйте пересылку метрик для пересылки метрик приема из StatsD в выбранную серверную часть метрик. (т.е. используйте prometheus-statsd-exporter для пересылки метрик в Prometheus.

**Вывод**

Этот пост демонстрирует хранилище функций с открытым исходным кодом для машинного обучения, разработанное Google Cloud и Gojek. Он построен на основе Облачных сервисов Google с использованием Big Query для обучения моделей в автономном режиме и Redis для онлайн-обслуживания с малой задержкой. Apache Beam используется для создания функций, что позволяет использовать согласованные конвейеры данных как для пакетной, так и для потоковой передачи. И шаги из конца в конец. И скоро мы поделимся ссылкой на Github со всей настройкой.

**Дополнительная ссылка**

https://docs.feast.dev/

Автор

Анируддха Чоудхури
Старший специалист по данным

Не стесняйтесь обращаться ко мне на Github Linkedin Электронная почта Веб-сайт