1. Обзор
В этой лабораторной работе вы узнаете, как создавать и запускать конвейеры машинного обучения с помощью Vertex Pipelines .
Что вы узнаете
Вы узнаете, как:
- Используйте Kubeflow Pipelines SDK для создания масштабируемых конвейеров машинного обучения.
- Создайте и запустите трехэтапный вводный конвейер, который принимает ввод текста.
- Создайте и запустите конвейер, который обучает, оценивает и развертывает модель классификации AutoML.
- Используйте готовые компоненты для взаимодействия с сервисами Vertex AI, предоставляемыми через библиотеку
google_cloud_pipeline_components
- Запланируйте задание конвейера с помощью Cloud Scheduler
Общая стоимость запуска этой лаборатории в Google Cloud составляет около 25 долларов США .
2. Знакомство с Vertex AI
В этой лаборатории используются новейшие продукты искусственного интеллекта, доступные в Google Cloud. Vertex AI интегрирует предложения машинного обучения в Google Cloud в единый процесс разработки. Раньше модели, обученные с помощью AutoML, и пользовательские модели были доступны через отдельные сервисы. Новое предложение объединяет оба API в одном API, а также другие новые продукты. Вы также можете перенести существующие проекты на Vertex AI.
Помимо услуг по обучению и развертыванию моделей, Vertex AI также включает в себя множество продуктов MLOps, в том числе Vertex Pipelines (особое внимание в этой лабораторной работе), Model Monitoring, Feature Store и многое другое. Вы можете увидеть все предложения продуктов Vertex AI на диаграмме ниже.
Если у вас есть какие-либо отзывы, пожалуйста, посетите страницу поддержки .
Чем полезны конвейеры машинного обучения?
Прежде чем мы углубимся, давайте сначала поймем, почему вам нужно использовать конвейер. Представьте, что вы создаете рабочий процесс машинного обучения, который включает обработку данных, обучение модели, настройку гиперпараметров, оценку и развертывание модели. Каждый из этих шагов может иметь разные зависимости, которые могут стать громоздкими, если рассматривать весь рабочий процесс как монолит. Когда вы начнете масштабировать свой процесс машинного обучения, вы, возможно, захотите поделиться своим рабочим процессом машинного обучения с другими членами вашей команды, чтобы они могли запустить его и внести свой код. Без надежного и воспроизводимого процесса это может оказаться затруднительным. При использовании конвейеров каждый шаг процесса машинного обучения представляет собой отдельный контейнер. Это позволяет вам разрабатывать шаги независимо и отслеживать входные и выходные данные каждого шага воспроизводимым образом. Вы также можете запланировать или инициировать запуск вашего конвейера на основе других событий в вашей облачной среде, например запуск конвейера при появлении новых данных обучения.
Конвейеры tl;dr : помогают автоматизировать и воспроизвести рабочий процесс машинного обучения.
3. Настройка облачной среды
Для запуска этой лаборатории кода вам понадобится проект Google Cloud Platform с включенной оплатой. Чтобы создать проект, следуйте инструкциям здесь .
Шаг 1. Запустите Cloud Shell
В этой лабораторной работе вы будете работать в сеансе Cloud Shell , который представляет собой интерпретатор команд, размещенный на виртуальной машине, работающей в облаке Google. Вы также можете легко запустить этот раздел локально на своем компьютере, но использование Cloud Shell дает каждому доступ к воспроизводимому опыту в согласованной среде. После лабораторной работы вы можете повторить этот раздел на своем компьютере.
Активировать Cloud Shell
В правом верхнем углу Cloud Console нажмите кнопку ниже, чтобы активировать Cloud Shell :
Если вы никогда раньше не запускали Cloud Shell, вам будет представлен промежуточный экран (ниже сгиба) с описанием того, что это такое. В этом случае нажмите «Продолжить» (и вы больше никогда его не увидите). Вот как выглядит этот одноразовый экран:
Подготовка и подключение к Cloud Shell займет всего несколько минут.
Эта виртуальная машина оснащена всеми необходимыми инструментами разработки. Он предлагает постоянный домашний каталог объемом 5 ГБ и работает в Google Cloud, что значительно повышает производительность сети и аутентификацию. Большую часть, если не всю, работу в этой лаборатории кода можно выполнить с помощью просто браузера или Chromebook.
После подключения к Cloud Shell вы увидите, что вы уже прошли аутентификацию и что для проекта уже установлен ваш идентификатор проекта.
Выполните следующую команду в Cloud Shell, чтобы подтвердить, что вы прошли аутентификацию:
gcloud auth list
В выводе команды вы должны увидеть что-то вроде этого:
Выполните следующую команду в Cloud Shell, чтобы убедиться, что команда gcloud знает о вашем проекте:
gcloud config list project
Вывод команды
[core] project = <PROJECT_ID>
Если это не так, вы можете установить его с помощью этой команды:
gcloud config set project <PROJECT_ID>
Вывод команды
Updated property [core/project].
Cloud Shell имеет несколько переменных среды, включая GOOGLE_CLOUD_PROJECT
, которая содержит имя нашего текущего проекта Cloud. Мы будем использовать это в разных местах этой лабораторной работы. Вы можете увидеть это, запустив:
echo $GOOGLE_CLOUD_PROJECT
Шаг 2. Включите API
На последующих шагах вы увидите, где нужны эти службы (и почему), а пока запустите эту команду, чтобы предоставить вашему проекту доступ к службам Compute Engine, Container Registry и Vertex AI:
gcloud services enable compute.googleapis.com \
containerregistry.googleapis.com \
aiplatform.googleapis.com \
cloudbuild.googleapis.com \
cloudfunctions.googleapis.com
Это должно привести к успешному сообщению, похожему на это:
Operation "operations/acf.cc11852d-40af-47ad-9d59-477a12847c9e" finished successfully.
Шаг 3. Создайте сегмент облачного хранилища
Чтобы запустить задание обучения на Vertex AI, нам понадобится сегмент хранилища для хранения сохраненных ресурсов модели. Ведро должно быть региональным. Здесь мы используем us-central
, но вы можете использовать другой регион (просто замените его в ходе этой лабораторной работы). Если у вас уже есть ведро, вы можете пропустить этот шаг.
Выполните следующие команды в терминале Cloud Shell, чтобы создать корзину:
BUCKET_NAME=gs://$GOOGLE_CLOUD_PROJECT-bucket
gsutil mb -l us-central1 $BUCKET_NAME
Далее мы предоставим нашей учетной записи вычислительной службы доступ к этому сегменту. Это гарантирует, что Vertex Pipelines имеет необходимые разрешения для записи файлов в эту корзину. Запустите следующую команду, чтобы добавить это разрешение:
gcloud projects describe $GOOGLE_CLOUD_PROJECT > project-info.txt
PROJECT_NUM=$(cat project-info.txt | sed -nre 's:.*projectNumber\: (.*):\1:p')
SVC_ACCOUNT="${PROJECT_NUM//\'/}-compute@developer.gserviceaccount.com"
gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT --member serviceAccount:$SVC_ACCOUNT --role roles/storage.objectAdmin
Шаг 4. Создайте экземпляр Vertex AI Workbench.
В разделе Vertex AI облачной консоли нажмите Workbench:
Оттуда в блокнотах, управляемых пользователем , нажмите «Новый блокнот» :
Затем выберите тип экземпляра TensorFlow Enterprise 2.3 (с LTS) без графических процессоров :
Используйте параметры по умолчанию и нажмите «Создать» .
Шаг 5. Откройте свой блокнот
После создания экземпляра выберите «Открыть JupyterLab» :
4. Настройка вершинных конвейеров
Чтобы использовать Vertex Pipelines, нам необходимо установить несколько дополнительных библиотек:
- Kubeflow Pipelines : это SDK, который мы будем использовать для создания нашего конвейера. Vertex Pipelines поддерживает запуск конвейеров, созданных с помощью Kubeflow Pipelines или TFX.
- Компоненты Google Cloud Pipeline : эта библиотека предоставляет предварительно созданные компоненты, которые упрощают взаимодействие со службами Vertex AI на этапах вашего конвейера.
Шаг 1. Создайте блокнот Python и установите библиотеки.
Сначала в меню запуска экземпляра ноутбука создайте блокнот, выбрав Python 3 :
Вы можете получить доступ к меню запуска, щелкнув знак + в левом верхнем углу экземпляра блокнота.
Чтобы установить обе службы, которые мы будем использовать в этой лабораторной работе, сначала установите пользовательский флаг в ячейке блокнота:
USER_FLAG = "--user"
Затем запустите из своего блокнота следующее:
!pip3 install {USER_FLAG} google-cloud-aiplatform==1.7.0 --upgrade
!pip3 install {USER_FLAG} kfp==1.8.9 google-cloud-pipeline-components==0.2.0
После установки этих пакетов вам необходимо перезапустить ядро:
import os
if not os.getenv("IS_TESTING"):
# Automatically restart kernel after installs
import IPython
app = IPython.Application.instance()
app.kernel.do_shutdown(True)
Наконец, проверьте, правильно ли вы установили пакеты. Версия KFP SDK должна быть >=1,8:
!python3 -c "import kfp; print('KFP SDK version: {}'.format(kfp.__version__))"
!python3 -c "import google_cloud_pipeline_components; print('google_cloud_pipeline_components version: {}'.format(google_cloud_pipeline_components.__version__))"
Шаг 2. Установите идентификатор проекта и сегмент.
На протяжении всего практического занятия вы будете ссылаться на идентификатор своего облачного проекта и корзину, которую вы создали ранее. Далее мы создадим переменные для каждого из них.
Если вы не знаете идентификатор своего проекта, вы можете получить его, выполнив следующую команду:
import os
PROJECT_ID = ""
# Get your Google Cloud project ID from gcloud
if not os.getenv("IS_TESTING"):
shell_output=!gcloud config list --format 'value(core.project)' 2>/dev/null
PROJECT_ID = shell_output[0]
print("Project ID: ", PROJECT_ID)
В противном случае установите его здесь:
if PROJECT_ID == "" or PROJECT_ID is None:
PROJECT_ID = "your-project-id" # @param {type:"string"}
Затем создайте переменную для хранения имени вашего сегмента. Если вы создали его в этой лабораторной работе, будет работать следующее. В противном случае вам придется установить это вручную:
BUCKET_NAME="gs://" + PROJECT_ID + "-bucket"
Шаг 3. Импортируйте библиотеки
Добавьте следующее, чтобы импортировать библиотеки, которые мы будем использовать в этой лаборатории кода:
import kfp
from kfp.v2 import compiler, dsl
from kfp.v2.dsl import component, pipeline, Artifact, ClassificationMetrics, Input, Output, Model, Metrics
from google.cloud import aiplatform
from google_cloud_pipeline_components import aiplatform as gcc_aip
from typing import NamedTuple
Шаг 4: Определите константы
Последнее, что нам нужно сделать перед созданием нашего конвейера, — это определить некоторые постоянные переменные. PIPELINE_ROOT
— это путь к облачному хранилищу, куда будут записываться артефакты, созданные нашим конвейером. В качестве региона мы используем us-central1
, но если при создании сегмента вы использовали другой регион, обновите переменную REGION
в приведенном ниже коде:
PATH=%env PATH
%env PATH={PATH}:/home/jupyter/.local/bin
REGION="us-central1"
PIPELINE_ROOT = f"{BUCKET_NAME}/pipeline_root/"
PIPELINE_ROOT
После запуска приведенного выше кода вы должны увидеть напечатанный корневой каталог вашего конвейера. Это место в облачном хранилище, куда будут записываться артефакты из вашего конвейера. Он будет в формате gs://YOUR-BUCKET-NAME/pipeline_root/
5. Создание вашего первого конвейера
Чтобы ознакомиться с тем, как работают Vertex Pipelines, сначала создадим короткий конвейер с помощью KFP SDK. Этот конвейер не делает ничего, связанного с машинным обучением (не волнуйтесь, мы доберемся до цели!), мы используем его, чтобы научить вас:
- Как создавать пользовательские компоненты в KFP SDK
- Как запустить и контролировать конвейер в Vertex Pipelines
Мы создадим конвейер, который печатает предложение, используя два вывода: название продукта и описание смайлика. Этот трубопровод будет состоять из трех компонентов:
-
product_name
: этот компонент будет принимать название продукта (или любое существительное, которое вам действительно нужно) в качестве входных данных и возвращать эту строку в качестве выходных данных. -
emoji
: этот компонент возьмет текстовое описание смайлика и преобразует его в смайлик. Например, текстовый код ✨ — «блестки». Этот компонент использует библиотеку эмодзи, чтобы показать вам, как управлять внешними зависимостями в вашем конвейере. -
build_sentence
: этот последний компонент будет использовать выходные данные двух предыдущих для построения предложения, использующего смайлики. Например, результат может быть таким: «Вершинные конвейеры — это ✨».
Давайте начнем кодировать!
Шаг 1. Создайте компонент на основе функций Python
Используя KFP SDK, мы можем создавать компоненты на основе функций Python. Мы будем использовать это для трех компонентов в нашем первом конвейере. Сначала мы создадим компонент product_name
, который просто принимает строку в качестве входных данных и возвращает эту строку. Добавьте в свой блокнот следующее:
@component(base_image="python:3.9", output_component_file="first-component.yaml")
def product_name(text: str) -> str:
return text
Давайте подробнее рассмотрим синтаксис здесь:
- Декоратор
@component
компилирует эту функцию в компонент при запуске конвейера. Вы будете использовать это каждый раз, когда будете писать собственный компонент. - Параметр
base_image
указывает образ контейнера, который будет использовать этот компонент. - Параметр
output_component_file
является необязательным и указывает файл yaml, в который будет записываться скомпилированный компонент. После запуска ячейки вы должны увидеть этот файл, записанный в экземпляр вашего блокнота. Если вы хотите поделиться этим компонентом с кем-то, вы можете отправить ему сгенерированный файл yaml и попросить загрузить его со следующим:
product_name_component = kfp.components.load_component_from_file('./first-component.yaml')
-> str
после определения функции указывает тип вывода для этого компонента.
Шаг 2. Создайте два дополнительных компонента.
Чтобы завершить наш конвейер, мы создадим еще два компонента. Первый, который мы определим, принимает строку в качестве входных данных и преобразует эту строку в соответствующий смайлик, если таковой имеется. Он возвращает кортеж с переданным входным текстом и результирующим смайликом:
@component(packages_to_install=["emoji"])
def emoji(
text: str,
) -> NamedTuple(
"Outputs",
[
("emoji_text", str), # Return parameters
("emoji", str),
],
):
import emoji
emoji_text = text
emoji_str = emoji.emojize(':' + emoji_text + ':', language='alias')
print("output one: {}; output_two: {}".format(emoji_text, emoji_str))
return (emoji_text, emoji_str)
Этот компонент немного сложнее предыдущего. Давайте разберем, что нового:
- Параметр
packages_to_install
сообщает компоненту о любых зависимостях внешней библиотеки для этого контейнера. В данном случае мы используем библиотеку emoji . - Этот компонент возвращает
NamedTuple
с именемOutputs
. Обратите внимание, что каждая строка в этом кортеже имеет ключи:emoji_text
иemoji
. Мы будем использовать их в нашем следующем компоненте для доступа к выходным данным.
Последний компонент в этом конвейере будет использовать выходные данные первых двух и объединять их для возврата строки:
@component
def build_sentence(
product: str,
emoji: str,
emojitext: str
) -> str:
print("We completed the pipeline, hooray!")
end_str = product + " is "
if len(emoji) > 0:
end_str += emoji
else:
end_str += emojitext
return(end_str)
Вам может быть интересно: как этот компонент узнает, что нужно использовать выходные данные предыдущих шагов, которые вы определили? Хороший вопрос! На следующем этапе мы свяжем все это вместе.
Шаг 3. Объединение компонентов в конвейер
Определения компонентов, которые мы определили выше, создали фабричные функции, которые можно использовать в определении конвейера для создания шагов. Чтобы настроить конвейер, используйте декоратор @pipeline
, дайте конвейеру имя и описание, а также укажите корневой путь, куда должны быть записаны артефакты вашего конвейера. Под артефактами мы подразумеваем любые выходные файлы, созданные вашим конвейером. Этот вводный конвейер ничего не генерирует, но наш следующий конвейер будет.
В следующем блоке кода мы определяем функцию intro_pipeline
. Здесь мы указываем входные данные для наших начальных шагов конвейера и то, как шаги соединяются друг с другом:
-
product_task
принимает в качестве входных данных название продукта. Здесь мы передаем «Vertex Pipelines», но вы можете изменить это на все, что захотите. -
emoji_task
принимает на вход текстовый код смайлика. Вы также можете изменить это на все, что захотите. Например, «party_face» относится к смайлику 🥳. Обратите внимание: поскольку и этот компонент, и компонентproduct_task
не содержат никаких шагов, передающих в них входные данные, мы вручную указываем для них входные данные при определении нашего конвейера. - Последний шаг в нашем конвейере —
consumer_task
имеет три входных параметра:- Вывод
product_task
. Поскольку на этом шаге создается только один результат, мы можем ссылаться на него черезproduct_task.output
. - Результат
emoji
нашего шагаemoji_task
. См. компонентemoji
, определенный выше, где мы назвали выходные параметры. - Аналогично,
emoji_text
именует выходные данные компонентаemoji
. Если в наш конвейер передается текст, который не соответствует смайлику, он будет использовать этот текст для построения предложения.
- Вывод
@pipeline(
name="hello-world",
description="An intro pipeline",
pipeline_root=PIPELINE_ROOT,
)
# You can change the `text` and `emoji_str` parameters here to update the pipeline output
def intro_pipeline(text: str = "Vertex Pipelines", emoji_str: str = "sparkles"):
product_task = product_name(text)
emoji_task = emoji(emoji_str)
consumer_task = build_sentence(
product_task.output,
emoji_task.outputs["emoji"],
emoji_task.outputs["emoji_text"],
)
Шаг 4. Скомпилируйте и запустите конвейер.
Определив конвейер, вы готовы его скомпилировать. Следующее действие создаст файл JSON, который вы будете использовать для запуска конвейера:
compiler.Compiler().compile(
pipeline_func=intro_pipeline, package_path="intro_pipeline_job.json"
)
Затем создайте переменную TIMESTAMP
. Мы будем использовать это в нашем идентификаторе задания:
from datetime import datetime
TIMESTAMP = datetime.now().strftime("%Y%m%d%H%M%S")
Затем определите задание конвейера:
job = aiplatform.PipelineJob(
display_name="hello-world-pipeline",
template_path="intro_pipeline_job.json",
job_id="hello-world-pipeline-{0}".format(TIMESTAMP),
enable_caching=True
)
Наконец, запустите задание, чтобы создать новый конвейер выполнения:
job.submit()
После запуска этой ячейки вы должны увидеть журналы со ссылкой для просмотра запуска конвейера в вашей консоли:
Перейдите по этой ссылке. После завершения ваш конвейер должен выглядеть так:
Запуск этого конвейера займет 5-6 минут . По завершении вы можете щелкнуть компонент build-sentence
, чтобы увидеть окончательный результат:
Теперь, когда вы знакомы с тем, как работают KFP SDK и Vertex Pipelines, вы готовы создать конвейер, который создает и развертывает модель машинного обучения с использованием других сервисов Vertex AI. Давайте погрузимся!
6. Создание сквозного конвейера машинного обучения
Пришло время построить свой первый конвейер машинного обучения. В этом конвейере мы будем использовать набор данных UCI Machine Learning Dry Beans из: KOKLU, M. и OZKAN, IA, (2020), «Многоклассовая классификация сухих бобов с использованием методов компьютерного зрения и машинного обучения». В «Компьютерах и электронике в сельском хозяйстве», 174, 105507. DOI .
Это табличный набор данных, и в нашем конвейере мы будем использовать этот набор данных для обучения, оценки и развертывания модели AutoML, которая классифицирует bean-компоненты по одному из 7 типов на основе их характеристик.
Этот трубопровод будет:
- Создайте набор данных в
- Обучение табличной модели классификации с помощью AutoML
- Получите показатели оценки этой модели
- На основе метрик оценки решите, следует ли развертывать модель с использованием условной логики в Vertex Pipelines.
- Разверните модель в конечной точке с помощью прогнозирования вершин.
Каждый из описанных шагов будет компонентом. В большинстве этапов конвейера будут использоваться предварительно созданные компоненты для сервисов Vertex AI через библиотеку google_cloud_pipeline_components
, которую мы импортировали ранее в этой лаборатории кода. В этом разделе мы сначала определим один пользовательский компонент. Затем мы определим остальные этапы конвейера, используя предварительно созданные компоненты. Предварительно созданные компоненты упрощают доступ к сервисам Vertex AI, таким как обучение и развертывание моделей.
Шаг 1. Пользовательский компонент для оценки модели.
Пользовательский компонент, который мы определим, будет использоваться в конце нашего конвейера после завершения обучения модели. Этот компонент будет делать несколько вещей:
- Получите показатели оценки из обученной модели классификации AutoML.
- Анализируйте метрики и визуализируйте их в пользовательском интерфейсе Vertex Pipelines.
- Сравните показатели с пороговым значением, чтобы определить, следует ли развертывать модель.
Прежде чем определить компонент, давайте разберемся с его входными и выходными параметрами. В качестве входных данных этот конвейер принимает некоторые метаданные нашего облачного проекта, полученную обученную модель (мы определим этот компонент позже), метрики оценки модели и thresholds_dict_str
. thresholds_dict_str
— это то, что мы определим при запуске нашего конвейера. В случае этой модели классификации это будет область под значением кривой ROC, для которой нам следует развернуть модель. Например, если мы передаем значение 0,95, это означает, что мы хотим, чтобы наш конвейер развертывал модель только в том случае, если этот показатель превышает 95%.
Наш компонент оценки возвращает строку, указывающую, следует ли развертывать модель. Добавьте следующее в ячейку блокнота, чтобы создать этот пользовательский компонент:
@component(
base_image="gcr.io/deeplearning-platform-release/tf2-cpu.2-3:latest",
output_component_file="tabular_eval_component.yaml",
packages_to_install=["google-cloud-aiplatform"],
)
def classification_model_eval_metrics(
project: str,
location: str, # "us-central1",
api_endpoint: str, # "us-central1-aiplatform.googleapis.com",
thresholds_dict_str: str,
model: Input[Artifact],
metrics: Output[Metrics],
metricsc: Output[ClassificationMetrics],
) -> NamedTuple("Outputs", [("dep_decision", str)]): # Return parameter.
import json
import logging
from google.cloud import aiplatform as aip
# Fetch model eval info
def get_eval_info(client, model_name):
from google.protobuf.json_format import MessageToDict
response = client.list_model_evaluations(parent=model_name)
metrics_list = []
metrics_string_list = []
for evaluation in response:
print("model_evaluation")
print(" name:", evaluation.name)
print(" metrics_schema_uri:", evaluation.metrics_schema_uri)
metrics = MessageToDict(evaluation._pb.metrics)
for metric in metrics.keys():
logging.info("metric: %s, value: %s", metric, metrics[metric])
metrics_str = json.dumps(metrics)
metrics_list.append(metrics)
metrics_string_list.append(metrics_str)
return (
evaluation.name,
metrics_list,
metrics_string_list,
)
# Use the given metrics threshold(s) to determine whether the model is
# accurate enough to deploy.
def classification_thresholds_check(metrics_dict, thresholds_dict):
for k, v in thresholds_dict.items():
logging.info("k {}, v {}".format(k, v))
if k in ["auRoc", "auPrc"]: # higher is better
if metrics_dict[k] < v: # if under threshold, don't deploy
logging.info("{} < {}; returning False".format(metrics_dict[k], v))
return False
logging.info("threshold checks passed.")
return True
def log_metrics(metrics_list, metricsc):
test_confusion_matrix = metrics_list[0]["confusionMatrix"]
logging.info("rows: %s", test_confusion_matrix["rows"])
# log the ROC curve
fpr = []
tpr = []
thresholds = []
for item in metrics_list[0]["confidenceMetrics"]:
fpr.append(item.get("falsePositiveRate", 0.0))
tpr.append(item.get("recall", 0.0))
thresholds.append(item.get("confidenceThreshold", 0.0))
print(f"fpr: {fpr}")
print(f"tpr: {tpr}")
print(f"thresholds: {thresholds}")
metricsc.log_roc_curve(fpr, tpr, thresholds)
# log the confusion matrix
annotations = []
for item in test_confusion_matrix["annotationSpecs"]:
annotations.append(item["displayName"])
logging.info("confusion matrix annotations: %s", annotations)
metricsc.log_confusion_matrix(
annotations,
test_confusion_matrix["rows"],
)
# log textual metrics info as well
for metric in metrics_list[0].keys():
if metric != "confidenceMetrics":
val_string = json.dumps(metrics_list[0][metric])
metrics.log_metric(metric, val_string)
# metrics.metadata["model_type"] = "AutoML Tabular classification"
logging.getLogger().setLevel(logging.INFO)
aip.init(project=project)
# extract the model resource name from the input Model Artifact
model_resource_path = model.metadata["resourceName"]
logging.info("model path: %s", model_resource_path)
client_options = {"api_endpoint": api_endpoint}
# Initialize client that will be used to create and send requests.
client = aip.gapic.ModelServiceClient(client_options=client_options)
eval_name, metrics_list, metrics_str_list = get_eval_info(
client, model_resource_path
)
logging.info("got evaluation name: %s", eval_name)
logging.info("got metrics list: %s", metrics_list)
log_metrics(metrics_list, metricsc)
thresholds_dict = json.loads(thresholds_dict_str)
deploy = classification_thresholds_check(metrics_list[0], thresholds_dict)
if deploy:
dep_decision = "true"
else:
dep_decision = "false"
logging.info("deployment decision is %s", dep_decision)
return (dep_decision,)
Шаг 2. Добавление готовых компонентов Google Cloud
На этом этапе мы определим остальные компоненты нашего конвейера и посмотрим, как они все сочетаются друг с другом. Сначала определите отображаемое имя для запуска вашего конвейера, используя метку времени:
import time
DISPLAY_NAME = 'automl-beans{}'.format(str(int(time.time())))
print(DISPLAY_NAME)
Затем скопируйте следующее в новую ячейку блокнота:
@pipeline(name="automl-tab-beans-training-v2",
pipeline_root=PIPELINE_ROOT)
def pipeline(
bq_source: str = "bq://aju-dev-demos.beans.beans1",
display_name: str = DISPLAY_NAME,
project: str = PROJECT_ID,
gcp_region: str = "us-central1",
api_endpoint: str = "us-central1-aiplatform.googleapis.com",
thresholds_dict_str: str = '{"auRoc": 0.95}',
):
dataset_create_op = gcc_aip.TabularDatasetCreateOp(
project=project, display_name=display_name, bq_source=bq_source
)
training_op = gcc_aip.AutoMLTabularTrainingJobRunOp(
project=project,
display_name=display_name,
optimization_prediction_type="classification",
budget_milli_node_hours=1000,
column_transformations=[
{"numeric": {"column_name": "Area"}},
{"numeric": {"column_name": "Perimeter"}},
{"numeric": {"column_name": "MajorAxisLength"}},
{"numeric": {"column_name": "MinorAxisLength"}},
{"numeric": {"column_name": "AspectRation"}},
{"numeric": {"column_name": "Eccentricity"}},
{"numeric": {"column_name": "ConvexArea"}},
{"numeric": {"column_name": "EquivDiameter"}},
{"numeric": {"column_name": "Extent"}},
{"numeric": {"column_name": "Solidity"}},
{"numeric": {"column_name": "roundness"}},
{"numeric": {"column_name": "Compactness"}},
{"numeric": {"column_name": "ShapeFactor1"}},
{"numeric": {"column_name": "ShapeFactor2"}},
{"numeric": {"column_name": "ShapeFactor3"}},
{"numeric": {"column_name": "ShapeFactor4"}},
{"categorical": {"column_name": "Class"}},
],
dataset=dataset_create_op.outputs["dataset"],
target_column="Class",
)
model_eval_task = classification_model_eval_metrics(
project,
gcp_region,
api_endpoint,
thresholds_dict_str,
training_op.outputs["model"],
)
with dsl.Condition(
model_eval_task.outputs["dep_decision"] == "true",
name="deploy_decision",
):
endpoint_op = gcc_aip.EndpointCreateOp(
project=project,
location=gcp_region,
display_name="train-automl-beans",
)
gcc_aip.ModelDeployOp(
model=training_op.outputs["model"],
endpoint=endpoint_op.outputs["endpoint"],
dedicated_resources_min_replica_count=1,
dedicated_resources_max_replica_count=1,
dedicated_resources_machine_type="n1-standard-4",
)
Давайте посмотрим, что происходит в этом коде:
- Сначала, как и в предыдущем конвейере, мы определяем входные параметры, которые принимает этот конвейер. Нам нужно установить их вручную, поскольку они не зависят от результатов других шагов конвейера.
- Остальная часть конвейера использует несколько готовых компонентов для взаимодействия с сервисами Vertex AI:
-
TabularDatasetCreateOp
создает табличный набор данных в Vertex AI с учетом источника набора данных в Cloud Storage или BigQuery. В этом конвейере мы передаем данные через URL-адрес таблицы BigQuery. -
AutoMLTabularTrainingJobRunOp
запускает задание обучения AutoML для набора табличных данных. Мы передаем этому компоненту несколько параметров конфигурации, включая тип модели (в данном случае классификацию), некоторые данные о столбцах, продолжительность обучения и указатель на набор данных. Обратите внимание: чтобы передать набор данных этому компоненту, мы предоставляем выходные данные предыдущего компонента черезdataset_create_op.outputs["dataset"]
-
EndpointCreateOp
создает конечную точку в Vertex AI. Конечная точка, созданная на этом этапе, будет передана в качестве входных данных следующему компоненту. -
ModelDeployOp
развертывает заданную модель в конечной точке в Vertex AI. В этом случае мы используем конечную точку, созданную на предыдущем шаге. Доступны дополнительные параметры конфигурации, но здесь мы указываем тип и модель конечного компьютера, который мы хотим развернуть. Мы передаем модель, получая доступ к результатам этапа обучения в нашем конвейере.
-
- Этот конвейер также использует условную логику — функцию Vertex Pipelines, которая позволяет вам определять условие, а также различные ветки на основе результата этого условия. Помните, что когда мы определяли наш конвейер, мы передали параметр
thresholds_dict_str
. Это порог точности, который мы используем, чтобы определить, следует ли развертывать нашу модель в конечной точке. Для реализации этого мы используем классCondition
из KFP SDK. Условие, которое мы передаем, — это выходные данные пользовательского компонента eval, который мы определили ранее в этой лаборатории кода. Если это условие истинно, конвейер продолжит выполнение компонентаdeploy_op
. Если точность не соответствует нашему предопределенному порогу, конвейер остановится на этом этапе и не сможет развернуть модель.
Шаг 3. Скомпилируйте и запустите сквозной конвейер машинного обучения.
Когда наш полный конвейер определен, пришло время его скомпилировать:
compiler.Compiler().compile(
pipeline_func=pipeline, package_path="tab_classif_pipeline.json"
)
Далее определите задание:
ml_pipeline_job = aiplatform.PipelineJob(
display_name="automl-tab-beans-training",
template_path="tab_classif_pipeline.json",
pipeline_root=PIPELINE_ROOT,
parameter_values={"project": PROJECT_ID, "display_name": DISPLAY_NAME},
enable_caching=True
)
И, наконец, запустите задание:
ml_pipeline_job.submit()
Перейдите по ссылке, показанной в журналах, после запуска ячейки выше, чтобы увидеть свой конвейер в консоли. Для запуска этого трубопровода потребуется чуть больше часа. Большая часть времени уходит на этап обучения AutoML. Готовый конвейер будет выглядеть примерно так:
Если вы переключите кнопку «Развернуть артефакты» вверху, вы сможете увидеть подробную информацию о различных артефактах, созданных из вашего конвейера. Например, если вы щелкните артефакт dataset
, вы увидите подробную информацию о созданном наборе данных Vertex AI. Вы можете щелкнуть ссылку здесь, чтобы перейти на страницу этого набора данных:
Аналогичным образом, чтобы просмотреть полученные визуализации метрик из нашего пользовательского компонента оценки, щелкните артефакт под названием metricsc . В правой части панели управления вы увидите матрицу путаницы для этой модели:
Чтобы просмотреть модель и конечную точку, созданные в результате этого запуска конвейера, перейдите в раздел моделей и щелкните модель с именем automl-beans
Вы также можете получить доступ к этой странице, щелкнув артефакт конечной точки на графике конвейера.
Помимо просмотра графика конвейера в консоли, вы также можете использовать Vertex Pipelines для отслеживания происхождения . Под отслеживанием происхождения мы подразумеваем отслеживание артефактов, созданных на протяжении всего вашего конвейера. Это может помочь нам понять, где были созданы артефакты и как они используются в рабочем процессе ML. Например, чтобы просмотреть отслеживание происхождения набора данных, созданного в этом конвейере, щелкните артефакт набора данных, а затем выберите «Просмотреть происхождение» :
Это показывает нам все места, где используется этот артефакт:
Шаг 4. Сравнение показателей по всем запускам конвейера
Если вы запускаете этот конвейер несколько раз, возможно, вам захочется сравнить метрики между запусками. Вы можете использовать метод aiplatform.get_pipeline_df()
для доступа к метаданным запуска. Здесь мы получим метаданные для всех запусков этого конвейера и загрузим их в DataFrame Pandas:
pipeline_df = aiplatform.get_pipeline_df(pipeline="automl-tab-beans-training-v2")
small_pipeline_df = pipeline_df.head(2)
small_pipeline_df
На этом вы закончили лабораторию!
🎉Поздравляем! 🎉
Вы узнали, как использовать Vertex AI, чтобы:
- Используйте Kubeflow Pipelines SDK для создания комплексных конвейеров с использованием пользовательских компонентов.
- Запускайте свои конвейеры на Vertex Pipelines и запускайте запуск конвейеров с помощью SDK.
- Просмотр и анализ графика Vertex Pipelines в консоли.
- Используйте готовые компоненты конвейера для добавления сервисов Vertex AI в свой конвейер.
- Планирование повторяющихся заданий конвейера
Чтобы узнать больше о различных частях Vertex, ознакомьтесь с документацией .
7. Очистка
Чтобы с вас не взималась плата, рекомендуется удалить ресурсы, созданные в ходе этого практического занятия.
Шаг 1. Остановите или удалите экземпляр Notebooks
Если вы хотите продолжать использовать записную книжку, созданную в ходе этой лабораторной работы, рекомендуется выключать ее, когда она не используется. В пользовательском интерфейсе «Блокноты» в облачной консоли выберите блокнот и нажмите «Стоп» . Если вы хотите полностью удалить экземпляр, выберите «Удалить» :
Шаг 2. Удалите конечную точку
Чтобы удалить развернутую конечную точку, перейдите в раздел «Конечные точки» консоли Vertex AI и щелкните значок удаления:
Затем нажмите «Отменить развертывание» в следующем окне:
Наконец, перейдите в раздел «Модели» консоли, найдите эту модель и в трехточечном меню справа нажмите « Удалить модель» :
Шаг 3. Удалите корзину Cloud Storage.
Чтобы удалить сегмент хранилища, в меню навигации облачной консоли перейдите к разделу «Хранилище», выберите сегмент и нажмите «Удалить»: