Pengantar Vertex Pipelines

1. Ringkasan

Di lab ini, Anda akan mempelajari cara membuat dan menjalankan pipeline ML dengan Vertex Pipelines.

Yang Anda pelajari

Anda akan mempelajari cara:

  • Menggunakan Kubeflow Pipelines SDK untuk membangun pipeline ML yang skalabel
  • Membuat dan menjalankan pipeline pengantar 3 langkah yang menggunakan input teks
  • Membuat dan menjalankan pipeline yang melatih, mengevaluasi, dan men-deploy model klasifikasi AutoML
  • Menggunakan komponen bawaan untuk berinteraksi dengan layanan Vertex AI, yang disediakan melalui library google_cloud_pipeline_components
  • Menjadwalkan tugas pipeline dengan Cloud Scheduler

Total biaya untuk menjalankan lab ini di Google Cloud adalah sekitar $25.

2. Pengantar Vertex AI

Lab ini menggunakan penawaran produk AI terbaru yang tersedia di Google Cloud. Vertex AI mengintegrasikan penawaran ML di Google Cloud ke dalam pengalaman pengembangan yang lancar. Sebelumnya, model yang dilatih dengan AutoML dan model kustom dapat diakses melalui layanan terpisah. Penawaran baru ini menggabungkan kedua model ini menjadi satu API, beserta produk baru lainnya. Anda juga dapat memigrasikan project yang sudah ada ke Vertex AI.

Selain layanan deployment dan pelatihan model, Vertex AI juga mencakup berbagai produk MLOps, termasuk Vertex Pipelines (fokus lab ini), Pemantauan Model, Feature Store, dan banyak lagi. Anda dapat melihat semua penawaran produk Vertex AI pada diagram di bawah.

Ringkasan produk Vertex

Jika Anda memiliki masukan, harap lihat halaman dukungan.

Mengapa pipeline ML berguna?

Sebelum kita membahas lebih jauh, mari kita pahami terlebih dahulu mengapa Anda ingin menggunakan pipeline. Bayangkan Anda sedang membangun alur kerja ML yang mencakup pemrosesan data, melatih model, penyesuaian hyperparameter, evaluasi, dan deployment model. Masing-masing langkah ini mungkin memiliki dependensi yang berbeda, yang dapat menjadi berat jika Anda memperlakukan seluruh alur kerja sebagai monolit. Saat mulai menskalakan proses ML, Anda mungkin ingin membagikan alur kerja ML Anda kepada orang lain di tim Anda sehingga mereka dapat menjalankannya dan menyumbangkan kode. Tanpa proses yang dapat diandalkan dan dapat direproduksi, proses ini akan menjadi sulit. Dengan pipeline, setiap langkah dalam proses ML Anda adalah container-nya sendiri. Hal ini memungkinkan Anda mengembangkan langkah secara independen serta melacak input dan output dari setiap langkah dengan cara yang dapat direproduksi. Anda juga dapat menjadwalkan atau memicu pengoperasian pipeline berdasarkan peristiwa lain di lingkungan Cloud, seperti memulai operasi pipeline saat data pelatihan baru tersedia.

Pipeline tl;dr: membantu Anda mengotomatiskan dan mereproduksi alur kerja ML Anda.

3. Penyiapan lingkungan cloud

Anda memerlukan project Google Cloud Platform dengan penagihan yang diaktifkan untuk menjalankan codelab ini. Untuk membuat project, ikuti petunjuk di sini.

Langkah 1: Mulai Cloud Shell

Di lab ini, Anda akan mengerjakan sesi Cloud Shell, yang merupakan penafsir perintah yang dihosting oleh virtual machine yang berjalan di cloud Google. Anda dapat dengan mudah menjalankan bagian ini secara lokal di komputer sendiri, tetapi menggunakan Cloud Shell akan memberi semua orang akses ke pengalaman yang dapat diproduksi ulang dalam lingkungan yang konsisten. Setelah lab ini, Anda dapat mencoba lagi bagian ini di komputer Anda sendiri.

Mengizinkan Cloud Shell

Mengaktifkan Cloud Shell

Dari kanan atas Konsol Cloud, klik tombol di bawah untuk Activate Cloud Shell:

Mengaktifkan Cloud Shell

Jika belum pernah memulai Cloud Shell, Anda akan melihat layar perantara (di paruh bawah) yang menjelaskan apa itu Cloud Shell. Jika demikian, klik Lanjutkan (dan Anda tidak akan pernah melihatnya lagi). Berikut tampilan layar sekali-tampil tersebut:

Penyiapan Cloud Shell

Perlu waktu beberapa saat untuk penyediaan dan terhubung ke Cloud Shell.

Init Cloud Shell

Mesin virtual ini dimuat dengan semua alat pengembangan yang Anda butuhkan. Layanan ini menawarkan direktori beranda tetap sebesar 5 GB dan beroperasi di Google Cloud, sehingga sangat meningkatkan performa dan autentikasi jaringan. Sebagian besar pekerjaan Anda dalam codelab ini dapat dilakukan hanya dengan browser atau Chromebook.

Setelah terhubung ke Cloud Shell, Anda akan melihat bahwa Anda sudah diautentikasi dan project sudah ditetapkan ke project ID Anda.

Jalankan perintah berikut di Cloud Shell untuk mengonfirmasi bahwa Anda telah diautentikasi:

gcloud auth list

Anda akan melihat yang seperti ini dalam output perintah:

Output Cloud Shell

Jalankan perintah berikut di Cloud Shell untuk mengonfirmasi bahwa perintah gcloud mengetahui project Anda:

gcloud config list project

Output perintah

[core]
project = <PROJECT_ID>

Jika tidak, Anda dapat menyetelnya dengan perintah ini:

gcloud config set project <PROJECT_ID>

Output perintah

Updated property [core/project].

Cloud Shell memiliki beberapa variabel lingkungan, termasuk GOOGLE_CLOUD_PROJECT yang berisi nama project Cloud kita saat ini. Kita akan menggunakannya di berbagai tempat di lab ini. Anda dapat melihatnya dengan menjalankan:

echo $GOOGLE_CLOUD_PROJECT

Langkah 2: Aktifkan API

Pada langkah selanjutnya, Anda akan melihat di mana layanan ini diperlukan (dan alasannya). Namun, untuk saat ini, jalankan perintah ini agar project Anda dapat mengakses layanan Compute Engine, Container Registry, dan Vertex AI:

gcloud services enable compute.googleapis.com         \
                       containerregistry.googleapis.com  \
                       aiplatform.googleapis.com  \
                       cloudbuild.googleapis.com \
                       cloudfunctions.googleapis.com

Perintah di atas akan menampilkan pesan seperti berikut yang menandakan bahwa proses berhasil:

Operation "operations/acf.cc11852d-40af-47ad-9d59-477a12847c9e" finished successfully.

Langkah 3: Buat Bucket Cloud Storage

Untuk menjalankan tugas pelatihan pada Vertex AI, kita memerlukan bucket penyimpanan untuk menyimpan aset model tersimpan. Bucket harus bersifat regional. Kita menggunakan us-central di sini, tetapi Anda dapat menggunakan region lain (cukup ganti di seluruh lab ini). Jika sudah memiliki bucket, Anda dapat melewati langkah ini.

Jalankan perintah berikut di terminal Cloud Shell Anda untuk membuat bucket:

BUCKET_NAME=gs://$GOOGLE_CLOUD_PROJECT-bucket
gsutil mb -l us-central1 $BUCKET_NAME

Selanjutnya, kita akan memberi akun layanan komputasi akses ke bucket ini. Tindakan ini akan memastikan bahwa Vertex Pipelines memiliki izin yang diperlukan untuk menulis file ke bucket ini. Jalankan perintah berikut untuk menambahkan izin ini:

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

Langkah 4: Buat instance Vertex AI Workbench

Dari bagian Vertex AI di Cloud Console Anda, klik Workbench:

Menu Vertex AI

Dari sana, dalam Notebooks yang dikelola pengguna, klik Notebook Baru:

Buat notebook baru

Kemudian, pilih jenis instance TensorFlow Enterprise 2.3 (with LTS) tanpa GPU:

Instance TFE

Gunakan opsi default, lalu klik Create.

Langkah 5: Buka Notebook Anda

Setelah instance dibuat, pilih Open JupyterLab:

Buka Notebook

4. Penyiapan Vertex Pipelines

Ada beberapa library tambahan yang perlu kita instal agar dapat menggunakan Vertex Pipelines:

  • Kubeflow Pipelines: Ini adalah SDK yang akan kita gunakan untuk membangun pipeline. Vertex Pipelines mendukung pipeline yang berjalan yang dibangun dengan Kubeflow Pipelines atau TFX.
  • Komponen Pipeline Google Cloud: Library ini menyediakan komponen bawaan yang memudahkan interaksi dengan layanan Vertex AI dari langkah pipeline Anda.

Langkah 1: Membuat notebook Python dan menginstal library

Pertama, dari menu Peluncur di instance Notebook Anda, buat notebook dengan memilih Python 3:

Membuat notebook Python3

Anda dapat mengakses menu Peluncur dengan mengklik tanda + di kiri atas instance notebook Anda.

Untuk menginstal kedua layanan yang akan kita gunakan di lab ini, pertama-tama tetapkan flag pengguna dalam sel notebook:

USER_FLAG = "--user"

Kemudian jalankan perintah berikut dari notebook Anda:

!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

Setelah menginstal paket-paket ini, Anda harus memulai ulang kernel:

import os

if not os.getenv("IS_TESTING"):
    # Automatically restart kernel after installs
    import IPython

    app = IPython.Application.instance()
    app.kernel.do_shutdown(True)

Terakhir, periksa apakah Anda telah menginstal paket dengan benar. Versi KFP SDK harus >=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__))"

Langkah 2: Tetapkan project ID dan bucket

Sepanjang lab ini, Anda akan mereferensikan project ID Cloud dan bucket yang telah Anda buat sebelumnya. Selanjutnya kita akan membuat variabel untuk setiap variabel tersebut.

Jika tidak mengetahui project ID, Anda mungkin bisa mendapatkannya dengan menjalankan perintah berikut:

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)

Jika tidak, tetapkan di sini:

if PROJECT_ID == "" or PROJECT_ID is None:
    PROJECT_ID = "your-project-id"  # @param {type:"string"}

Kemudian, buat variabel untuk menyimpan nama bucket Anda. Jika Anda membuatnya di lab ini, berikut ini akan berfungsi. Jika tidak, Anda harus menyetelnya secara manual:

BUCKET_NAME="gs://" + PROJECT_ID + "-bucket"

Langkah 3: Impor library

Tambahkan kode berikut untuk mengimpor library yang akan kita gunakan di seluruh codelab ini:

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

Langkah 4: Menentukan konstanta

Hal terakhir yang perlu kita lakukan sebelum membangun pipeline adalah menentukan beberapa variabel konstan. PIPELINE_ROOT adalah jalur Cloud Storage tempat artefak yang dibuat oleh pipeline akan ditulis. Kita menggunakan us-central1 sebagai region di sini, tetapi jika Anda menggunakan region yang berbeda saat membuat bucket, perbarui variabel REGION pada kode di bawah:

PATH=%env PATH
%env PATH={PATH}:/home/jupyter/.local/bin
REGION="us-central1"

PIPELINE_ROOT = f"{BUCKET_NAME}/pipeline_root/"
PIPELINE_ROOT

Setelah menjalankan kode di atas, Anda akan melihat direktori root untuk pipeline Anda telah dicetak. Ini adalah lokasi Cloud Storage tempat artefak dari pipeline Anda akan ditulis. Formatnya adalah gs://YOUR-BUCKET-NAME/pipeline_root/

5. Membuat pipeline pertama Anda

Untuk memahami cara kerja Vertex Pipelines, pertama-tama kita akan membuat pipeline singkat menggunakan KFP SDK. Pipeline ini tidak melakukan apa pun yang terkait dengan ML (jangan khawatir, kami akan menggunakannya untuk mengajari Anda:

  • Cara membuat komponen kustom di KFP SDK
  • Cara menjalankan dan memantau pipeline di Vertex Pipelines

Kita akan membuat pipeline yang mencetak kalimat menggunakan dua output: nama produk dan deskripsi emoji. Pipeline ini akan terdiri dari tiga komponen:

  • product_name: Komponen ini akan menggunakan nama produk (atau kata benda yang benar-benar Anda inginkan) sebagai input, dan menampilkan string tersebut sebagai output
  • emoji: Komponen ini akan mengambil deskripsi teks emoji dan mengonversinya menjadi emoji. Misalnya, kode teks untuk ✨ adalah "sparkles". Komponen ini menggunakan library emoji untuk menunjukkan cara mengelola dependensi eksternal di pipeline Anda
  • build_sentence: Komponen akhir ini akan menggunakan output dari dua komponen sebelumnya untuk membuat kalimat yang menggunakan emoji. Misalnya, output yang dihasilkan mungkin adalah "Vertex Pipelines is ✨".

Mari kita mulai coding.

Langkah 1: Buat komponen berbasis fungsi Python

Dengan menggunakan KFP SDK, kita dapat membuat komponen berdasarkan fungsi Python. Kita akan menggunakannya untuk 3 komponen dalam pipeline pertama. Pertama-tama, kita akan membangun komponen product_name, yang hanya mengambil string sebagai input dan menampilkan string tersebut. Tambahkan kode berikut ke notebook Anda:

@component(base_image="python:3.9", output_component_file="first-component.yaml")
def product_name(text: str) -> str:
    return text

Mari kita pelajari lebih lanjut sintaksis berikut:

  • Dekorator @component mengompilasi fungsi ini ke komponen saat pipeline dijalankan. Anda akan menggunakan ini setiap kali menulis komponen kustom.
  • Parameter base_image menentukan image container yang akan digunakan komponen ini.
  • Parameter output_component_file bersifat opsional, dan menentukan file yaml yang menjadi tujuan penulisan komponen yang dikompilasi. Setelah menjalankan sel, Anda akan melihat file tersebut ditulis ke instance notebook. Jika ingin membagikan komponen ini kepada seseorang, Anda dapat mengirimkan file yaml yang dihasilkan dan meminta mereka memuatnya dengan kode berikut:
product_name_component = kfp.components.load_component_from_file('./first-component.yaml')
  • -> str setelah definisi fungsi menentukan jenis output untuk komponen ini.

Langkah 2: Buat dua komponen tambahan

Untuk menyelesaikan pipeline, kita akan membuat dua komponen lagi. Fungsi pertama yang akan kita tentukan menggunakan string sebagai input, dan mengonversi string ini menjadi emoji yang sesuai jika ada. Metode ini menampilkan tuple dengan teks input yang diteruskan, dan emoji yang dihasilkan:

@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)

Komponen ini sedikit lebih kompleks dari yang sebelumnya. Mari kita uraikan apa yang baru:

  • Parameter packages_to_install memberi tahu komponen tentang dependensi library eksternal apa pun untuk penampung ini. Dalam hal ini, kita menggunakan library yang disebut emoji.
  • Komponen ini menampilkan NamedTuple yang disebut Outputs. Perhatikan bahwa setiap string dalam tuple ini memiliki kunci: emoji_text dan emoji. Kita akan menggunakannya di komponen berikutnya untuk mengakses {i>output<i}.

Komponen akhir dalam pipeline ini akan menggunakan output dari dua komponen pertama dan menggabungkannya untuk menampilkan string:

@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)

Anda mungkin bertanya-tanya: bagaimana komponen ini tahu cara menggunakan output dari langkah sebelumnya yang Anda tentukan? Pertanyaan bagus. Kita akan menggabungkan semuanya di langkah berikutnya.

Langkah 3: Menggabungkan komponen ke dalam pipeline

Definisi komponen yang kami tentukan di atas membuat fungsi factory yang dapat digunakan dalam definisi pipeline untuk membuat langkah-langkah. Untuk menyiapkan pipeline, gunakan dekorator @pipeline, beri nama dan deskripsi pada pipeline, serta sediakan jalur root tempat artefak pipeline Anda harus ditulis. Yang kami maksud artefak adalah semua file {i>output<i} yang dihasilkan oleh pipeline Anda. Pipeline pengantar ini tidak menghasilkan apa pun, tetapi pipeline berikutnya akan melakukannya.

Pada blok kode berikutnya, kita menentukan fungsi intro_pipeline. Di sini kita akan menentukan input ke langkah pipeline awal dan cara langkah-langkah tersebut saling terhubung:

  • product_task menggunakan nama produk sebagai input. Di sini kita meneruskan "Vertex Pipelines" tetapi Anda dapat mengubahnya sesuai keinginan Anda.
  • emoji_task menggunakan kode teks untuk emoji sebagai input. Anda juga dapat mengubahnya sesuai keinginan. Misalnya, "party_face" lihat emoji 🥳. Perhatikan bahwa karena komponen ini dan komponen product_task tidak memiliki langkah yang memberikan input ke dalamnya, kita menentukan inputnya secara manual saat menentukan pipeline.
  • Langkah terakhir dalam pipeline - consumer_task memiliki tiga parameter input:
    • Output product_task. Karena langkah ini hanya menghasilkan satu output, kita dapat mereferensikannya melalui product_task.output.
    • Output emoji dari langkah emoji_task kita. Lihat komponen emoji yang ditentukan di atas, tempat parameter output diberi nama.
    • Demikian pula, output bernama emoji_text dari komponen emoji. Jika pipeline diteruskan teks yang tidak sesuai dengan emoji, teks ini akan digunakan untuk membuat kalimat.
@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"],
    )

Langkah 4: Mengompilasi dan menjalankan pipeline

Setelah menentukan pipeline, Anda siap untuk mengompilasinya. Berikut ini akan menghasilkan file JSON yang akan Anda gunakan untuk menjalankan pipeline:

compiler.Compiler().compile(
    pipeline_func=intro_pipeline, package_path="intro_pipeline_job.json"
)

Selanjutnya, buat variabel TIMESTAMP. Kita akan menggunakannya di ID tugas:

from datetime import datetime

TIMESTAMP = datetime.now().strftime("%Y%m%d%H%M%S")

Kemudian, tentukan tugas pipeline Anda:

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
)

Terakhir, jalankan tugas untuk membuat eksekusi pipeline baru:

job.submit()

Setelah menjalankan sel ini, Anda akan melihat log dengan link untuk melihat operasi pipeline yang dijalankan di konsol Anda:

Log tugas pipeline

Buka link tersebut. Pipeline Anda akan terlihat seperti ini setelah selesai:

Menyelesaikan pipeline pengantar

Pipeline ini akan memerlukan waktu 5-6 menit untuk dijalankan. Setelah selesai, Anda dapat mengklik komponen build-sentence untuk melihat output akhir:

Pengantar output pipeline

Setelah memahami cara kerja KFP SDK dan Vertex Pipelines, Anda siap membangun pipeline yang membuat dan men-deploy model ML menggunakan layanan Vertex AI lainnya. Ayo kita mulai!

6. Membuat pipeline ML menyeluruh

Saatnya membangun pipeline ML pertama Anda. Dalam pipeline ini, kita akan menggunakan set data Kacang kering Machine Learning UCI, dari: KOKLU, M. dan OZKAN, I.A., (2020), "Multiclass Classification of Dry Beans Using Computer Vision and Machine Learning Techniques." upayaIn Computers and Electronics in Agriculture, 174, 105507. DOI.

Ini adalah set data tabulasi, dan dalam pipeline kita, kita akan menggunakan set data untuk melatih, mengevaluasi, dan men-deploy model AutoML yang mengklasifikasikan biji kopi ke dalam salah satu dari 7 jenis berdasarkan karakteristiknya.

Pipeline ini akan:

  • Membuat Set data di
  • Melatih model klasifikasi tabel dengan AutoML
  • Dapatkan metrik evaluasi pada model ini
  • Berdasarkan metrik evaluasi, tentukan apakah akan men-deploy model menggunakan logika bersyarat di Vertex Pipelines
  • Men-deploy model ke endpoint menggunakan Vertex Prediction

Setiap langkah yang diuraikan akan menjadi komponen. Sebagian besar langkah pipeline akan menggunakan komponen bawaan untuk layanan Vertex AI melalui library google_cloud_pipeline_components yang telah kita impor sebelumnya dalam codelab ini. Di bagian ini, kita akan menentukan satu komponen kustom terlebih dahulu. Kemudian, kita akan menentukan langkah pipeline selanjutnya menggunakan komponen yang telah dibuat sebelumnya. Komponen bawaan memudahkan akses ke layanan Vertex AI, seperti pelatihan dan deployment model.

Langkah 1: Komponen kustom untuk evaluasi model

Komponen kustom yang akan kita tentukan akan digunakan di akhir pipeline setelah pelatihan model selesai. Komponen ini akan melakukan beberapa hal:

  • Mendapatkan metrik evaluasi dari model klasifikasi AutoML terlatih
  • Mengurai metrik dan merendernya di UI Vertex Pipelines
  • Bandingkan metrik dengan nilai minimum untuk menentukan apakah model harus di-deploy

Sebelum menentukan komponen, mari kita pahami parameter input dan outputnya. Sebagai input, pipeline ini mengambil beberapa metadata pada project Cloud, model terlatih yang dihasilkan (kita akan menentukan komponen ini nanti), metrik evaluasi model, dan thresholds_dict_str. thresholds_dict_str adalah sesuatu yang akan kita tentukan saat menjalankan pipeline. Dalam kasus model klasifikasi ini, area ini adalah area di bawah nilai kurva ROC yang harus kita deploy modelnya. Misalnya, jika kita meneruskan 0,95, itu berarti kita hanya ingin pipeline kita men-deploy model jika metrik ini di atas 95%.

Komponen evaluasi menampilkan string yang menunjukkan apakah model akan di-deploy atau tidak. Tambahkan baris berikut dalam sel notebook untuk membuat komponen kustom ini:

@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,)

Langkah 2: Menambahkan komponen siap pakai Google Cloud

Pada langkah ini, kita akan menentukan komponen pipeline lainnya dan melihat bagaimana semuanya saling melengkapi. Pertama, tentukan nama tampilan untuk proses pipeline Anda menggunakan stempel waktu:

import time
DISPLAY_NAME = 'automl-beans{}'.format(str(int(time.time())))
print(DISPLAY_NAME)

Kemudian, salin kode berikut ke sel notebook baru:

@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",
        )

Mari kita lihat apa yang terjadi dalam kode ini:

  • Pertama, seperti pada pipeline sebelumnya, kita menentukan parameter input yang diperlukan oleh pipeline ini. Kita perlu menyetelnya secara manual karena tidak bergantung pada output dari langkah lain dalam pipeline.
  • Pipeline lainnya menggunakan beberapa komponen bawaan untuk berinteraksi dengan layanan Vertex AI:
    • TabularDatasetCreateOp membuat set data tabulasi di Vertex AI berdasarkan sumber set data di Cloud Storage atau BigQuery. Di pipeline ini, kita meneruskan data melalui URL tabel BigQuery
    • AutoMLTabularTrainingJobRunOp memulai tugas pelatihan AutoML untuk set data tabel. Kita meneruskan beberapa parameter konfigurasi ke komponen ini, termasuk jenis model (dalam hal ini, klasifikasi), beberapa data di kolom, berapa lama kita ingin menjalankan pelatihan, dan pointer ke set data. Perhatikan bahwa untuk meneruskan set data ke komponen ini, kita memberikan output dari komponen sebelumnya melalui dataset_create_op.outputs["dataset"]
    • EndpointCreateOp membuat endpoint di Vertex AI. Endpoint yang dibuat dari langkah ini akan diteruskan sebagai input ke komponen berikutnya
    • ModelDeployOp men-deploy model tertentu ke endpoint di Vertex AI. Dalam hal ini, kita menggunakan endpoint yang dibuat dari langkah sebelumnya. Ada opsi konfigurasi tambahan yang tersedia, tetapi di sini kita menyediakan jenis mesin endpoint dan model yang ingin kita deploy. Kita meneruskan model dengan mengakses output dari langkah pelatihan di pipeline
  • Pipeline ini juga menggunakan logika bersyarat, sebuah fitur Vertex Pipelines yang memungkinkan Anda menentukan kondisi, beserta cabang yang berbeda berdasarkan hasil kondisi tersebut. Perlu diingat bahwa saat menentukan pipeline, kita meneruskan parameter thresholds_dict_str. Ini adalah batas akurasi yang kita gunakan untuk menentukan apakah akan men-deploy model ke endpoint. Untuk menerapkannya, kita menggunakan class Condition dari KFP SDK. Kondisi yang kita teruskan adalah output komponen eval kustom yang telah kita tentukan sebelumnya dalam codelab ini. Jika kondisi ini benar, pipeline akan terus menjalankan komponen deploy_op. Jika akurasi tidak memenuhi batas yang telah ditentukan, pipeline akan berhenti di sini dan tidak akan men-deploy model.

Langkah 3: Kompilasi dan jalankan pipeline ML menyeluruh

Setelah pipeline lengkap kita ditentukan, saatnya untuk mengompilasinya:

compiler.Compiler().compile(
    pipeline_func=pipeline, package_path="tab_classif_pipeline.json"
)

Selanjutnya, tentukan tugas:

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
)

Terakhir, jalankan tugas:

ml_pipeline_job.submit()

Buka link yang ditampilkan dalam log setelah menjalankan sel di atas untuk melihat pipeline Anda di konsol. Pipeline ini akan membutuhkan waktu lebih dari satu jam untuk berjalan. Sebagian besar waktu dihabiskan dalam langkah pelatihan AutoML. Pipeline yang sudah selesai akan terlihat seperti ini:

Pipeline AutoML selesai

Jika Anda mengaktifkan tombol "Luaskan artefak" di bagian atas, Anda akan melihat detail untuk berbagai artefak yang dibuat dari pipeline. Misalnya, jika mengklik artefak dataset, Anda akan melihat detail set data Vertex AI yang dibuat. Anda dapat mengeklik tautan di sini untuk masuk ke halaman {i>dataset<i} tersebut:

Set data pipeline

Demikian pula, untuk melihat visualisasi metrik yang dihasilkan dari komponen evaluasi kustom kami, klik artefak yang disebut metricsc. Di sisi kanan dasbor, Anda akan melihat matriks konfusi untuk model ini:

Visualisasi metrik

Untuk melihat model dan endpoint yang dibuat dari pipeline ini, buka bagian model lalu klik model bernama automl-beans. Di sana, Anda akan melihat model ini di-deploy ke endpoint:

Endpoint model

Anda juga dapat mengakses halaman ini dengan mengklik artefak endpoint di grafik pipeline Anda.

Selain melihat grafik pipeline di konsol, Anda juga dapat menggunakan Vertex Pipelines untuk Lineage Tracking. Yang kami maksud dengan pelacakan silsilah adalah melacak artefak yang dibuat di seluruh pipeline Anda. Hal ini dapat membantu kita memahami tempat artefak dibuat dan bagaimana artefak tersebut digunakan di sepanjang alur kerja ML. Misalnya, untuk melihat pelacakan silsilah untuk set data yang dibuat di pipeline ini, klik artefak set data, lalu klik Lihat Lineage:

Lihat silsilah

Kode ini menunjukkan semua tempat artefak ini digunakan:

Detail silsilah

Langkah 4: Membandingkan metrik di berbagai proses pipeline

Jika Anda menjalankan pipeline ini beberapa kali, sebaiknya bandingkan metrik di semua operasi. Anda dapat menggunakan metode aiplatform.get_pipeline_df() untuk mengakses metadata operasi. Di sini, kita akan mendapatkan metadata untuk semua proses pipeline ini dan memuatnya ke dalam DataFrame Pandas:

pipeline_df = aiplatform.get_pipeline_df(pipeline="automl-tab-beans-training-v2")
small_pipeline_df = pipeline_df.head(2)
small_pipeline_df

Dengan begitu, kamu sudah menyelesaikan lab!

🎉 Selamat! 🎉

Anda telah mempelajari cara menggunakan Vertex AI untuk:

  • Menggunakan Kubeflow Pipelines SDK untuk membangun pipeline end-to-end dengan komponen kustom
  • Menjalankan pipeline di Vertex Pipelines dan memulai operasi pipeline dengan SDK
  • Melihat dan menganalisis grafik Vertex Pipelines di konsol
  • Menggunakan komponen pipeline yang telah dibangun sebelumnya untuk menambahkan layanan Vertex AI ke pipeline Anda
  • Menjadwalkan tugas pipeline berulang

Untuk mempelajari lebih lanjut berbagai bagian Vertex, lihat dokumentasinya.

7. Pembersihan

Agar Anda tidak dikenai biaya, sebaiknya hapus resource yang dibuat di lab ini.

Langkah 1: Hentikan atau hapus instance Notebooks Anda

Jika ingin terus menggunakan notebook yang Anda buat di lab ini, sebaiknya nonaktifkan notebook tersebut saat tidak digunakan. Dari UI Notebooks di Konsol Cloud, pilih notebook, lalu pilih Stop. Jika Anda ingin menghapus instance secara keseluruhan, pilih Hapus:

Hentikan instance

Langkah 2: Hapus endpoint Anda

Untuk menghapus endpoint yang di-deploy, buka bagian Endpoint di konsol Vertex AI, lalu klik ikon hapus:

Menghapus endpoint

Selanjutnya, klik Batalkan deployment dari perintah berikut:

Batalkan deployment model

Terakhir, buka bagian Models pada konsol Anda, temukan model tersebut, dan dari menu tiga titik di sebelah kanan, klik Hapus model:

Hapus model

Langkah 3: Hapus bucket Cloud Storage

Untuk menghapus Bucket Penyimpanan menggunakan menu Navigasi di Cloud Console, jelajahi Penyimpanan, pilih bucket Anda, lalu klik Hapus:

Hapus penyimpanan