mirror of
https://github.com/GoogleCloudPlatform/vertex-ai-samples.git
synced 2026-09-26 14:42:04 +00:00
Compare commits
10
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3ebb74e97a | ||
|
|
15912adeaf | ||
|
|
a992a5530d | ||
|
|
35fdba7e1c | ||
|
|
f403fa9051 | ||
|
|
0d346b136e | ||
|
|
24e0e92f8d | ||
|
|
bc4ec36914 | ||
|
|
5387799f32 | ||
|
|
60d71d29cc |
+1859
-1683
File diff suppressed because it is too large
Load Diff
@@ -3,7 +3,6 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "d3069d95",
|
||||
"metadata": {
|
||||
"cellView": "form",
|
||||
"id": "d3069d95"
|
||||
@@ -11,7 +10,7 @@
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# @title Copyright & License (click to expand)\n",
|
||||
"# Copyright 2021 Google LLC\n",
|
||||
"# Copyright 2022 Google LLC\n",
|
||||
"#\n",
|
||||
"# Licensed under the Apache License, Version 2.0 (the \"License\");\n",
|
||||
"# you may not use this file except in compliance with the License.\n",
|
||||
@@ -28,7 +27,6 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "546c53de",
|
||||
"metadata": {
|
||||
"id": "546c53de"
|
||||
},
|
||||
@@ -46,13 +44,16 @@
|
||||
" <img src=\"https://cloud.google.com/ml-engine/images/github-logo-32px.png\" alt=\"GitHub logo\">\n",
|
||||
" View on GitHub\n",
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
" </td><td>\n",
|
||||
" <a href=\"https://console.cloud.google.com/ai-platform/notebooks/deploy-notebook?name=Model%20Monitoring&download_url=https%3A%2F%2Fraw.githubusercontent.com%2FGoogleCloudPlatform%2Fvertex-ai-samples%2Fmain%2Fnotebooks%2Fcommunity%2Fmodel_monitoring%2Fbatch_prediction_model_monitoring.ipynb\">\n",
|
||||
" <img src=\"https://www.gstatic.com/cloud/images/navigation/vertex-ai.svg\" alt=\"Google Cloud Notebooks\">Open in Workbench AI Notebook\n",
|
||||
" </a>\n",
|
||||
" </td> \n",
|
||||
"</table>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "53fd1070",
|
||||
"metadata": {
|
||||
"id": "53fd1070"
|
||||
},
|
||||
@@ -64,7 +65,6 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "8b26c855",
|
||||
"metadata": {
|
||||
"id": "8b26c855"
|
||||
},
|
||||
@@ -98,7 +98,6 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "d52ba95b",
|
||||
"metadata": {
|
||||
"id": "d52ba95b"
|
||||
},
|
||||
@@ -110,7 +109,6 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "e64fb18a",
|
||||
"metadata": {
|
||||
"id": "e64fb18a"
|
||||
},
|
||||
@@ -123,7 +121,6 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "9d839347",
|
||||
"metadata": {
|
||||
"id": "9d839347"
|
||||
},
|
||||
@@ -142,7 +139,6 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "738fce1f",
|
||||
"metadata": {
|
||||
"id": "738fce1f"
|
||||
},
|
||||
@@ -155,7 +151,6 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "4536fe4e",
|
||||
"metadata": {
|
||||
"id": "4536fe4e"
|
||||
},
|
||||
@@ -178,14 +173,13 @@
|
||||
" USER_FLAG = \"--user\"\n",
|
||||
"\n",
|
||||
"# Install Python package dependencies.\n",
|
||||
"! pip3 install -q tensorflow-data-validation $USER_FLAG\n",
|
||||
"! pip3 install -q google-api-core $USER_FLAG\n",
|
||||
"! pip3 install -q google-cloud-aiplatform $USER_FLAG"
|
||||
"! pip3 install -q {USER_FLAG} tensorflow-data-validation \\\n",
|
||||
" google-api-core \\\n",
|
||||
" google-cloud-aiplatform"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "6e98402b",
|
||||
"metadata": {
|
||||
"id": "6e98402b"
|
||||
},
|
||||
@@ -198,7 +192,6 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "9775c9ff",
|
||||
"metadata": {
|
||||
"id": "9775c9ff"
|
||||
},
|
||||
@@ -217,7 +210,6 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "d5737134",
|
||||
"metadata": {
|
||||
"id": "d5737134"
|
||||
},
|
||||
@@ -242,7 +234,6 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "cfb1a1d5",
|
||||
"metadata": {
|
||||
"id": "cfb1a1d5"
|
||||
},
|
||||
@@ -255,50 +246,33 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "cf8535e4",
|
||||
"metadata": {
|
||||
"id": "cf8535e4"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"PROJECT_ID = \"\"\n",
|
||||
"\n",
|
||||
"# Get your Google Cloud project ID from gcloud\n",
|
||||
"if not os.getenv(\"IS_TESTING\"):\n",
|
||||
" shell_output = ! gcloud config list --format 'value(core.project)' 2>/dev/null\n",
|
||||
" PROJECT_ID = shell_output[0]\n",
|
||||
" print(\"Project ID: \", PROJECT_ID)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "05a2d397",
|
||||
"metadata": {
|
||||
"id": "05a2d397"
|
||||
},
|
||||
"source": [
|
||||
"Otherwise, set your project ID here.\n"
|
||||
"PROJECT_ID = \"[your-project-id]\" # @param {type:\"string\"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "1c2be4bd",
|
||||
"metadata": {
|
||||
"id": "1c2be4bd"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"if PROJECT_ID == \"\" or PROJECT_ID is None:\n",
|
||||
" PROJECT_ID = \"python-docs-samples-tests\" # @param {type:\"string\"}"
|
||||
"if PROJECT_ID == \"\" or not PROJECT_ID or PROJECT_ID == \"[your-project-id]\":\n",
|
||||
" PROJECT_ID = \"[your-project-id]\" # @param {type:\"string\"}\n",
|
||||
" # Get your GCP project id from gcloud\n",
|
||||
" shell_output = ! gcloud config list --format 'value(core.project)' 2>/dev/null\n",
|
||||
" PROJECT_ID = shell_output[0]\n",
|
||||
" print(\"Project ID:\", PROJECT_ID)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "c129705c",
|
||||
"metadata": {
|
||||
"id": "c129705c"
|
||||
},
|
||||
@@ -309,32 +283,6 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "71404c9f",
|
||||
"metadata": {
|
||||
"id": "71404c9f"
|
||||
},
|
||||
"source": [
|
||||
"#### Set your email address\n",
|
||||
"This is used for delivering model monitoring notifications.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "4b1d2b69",
|
||||
"metadata": {
|
||||
"id": "4b1d2b69"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"EMAIL_ADDRESS = \"[your-email-address]\" # @param {type:\"string\"}\n",
|
||||
"if not EMAIL_ADDRESS or EMAIL_ADDRESS == \"[your-email-address]\":\n",
|
||||
" print(\"EMAIL_ADDRESS not specified, please correct before proceeding.\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "83340af4",
|
||||
"metadata": {
|
||||
"id": "83340af4"
|
||||
},
|
||||
@@ -356,18 +304,73 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "4814ea21",
|
||||
"metadata": {
|
||||
"id": "4814ea21"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"REGION = \"us-central1\" # @param {type: \"string\"}"
|
||||
"REGION = \"[your-region]\" # @param {type: \"string\"}\n",
|
||||
"\n",
|
||||
"if REGION == \"[your-region]\":\n",
|
||||
" REGION = \"us-central1\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "06571eb4063b"
|
||||
},
|
||||
"source": [
|
||||
"#### UUID\n",
|
||||
"\n",
|
||||
"If you are in a live tutorial session, you might be using a shared test account or project. To avoid name collisions between users on resources created, you create a uuid for each instance session, and append it onto the name of resources you create in this tutorial."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "4e166d927e36"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import random\n",
|
||||
"import string\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# Generate a uuid of a specifed length(default=8)\n",
|
||||
"def generate_uuid(length: int = 8) -> str:\n",
|
||||
" return \"\".join(random.choices(string.ascii_lowercase + string.digits, k=length))\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"UUID = generate_uuid()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "71404c9f"
|
||||
},
|
||||
"source": [
|
||||
"#### Set your email address\n",
|
||||
"This is used for delivering model monitoring notifications.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "4b1d2b69"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"EMAIL_ADDRESS = \"[your-email-address]\" # @param {type:\"string\"}\n",
|
||||
"if not EMAIL_ADDRESS or EMAIL_ADDRESS == \"[your-email-address]\":\n",
|
||||
" print(\"EMAIL_ADDRESS not specified, please correct before proceeding.\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "20a546c3",
|
||||
"metadata": {
|
||||
"id": "20a546c3"
|
||||
},
|
||||
@@ -375,16 +378,35 @@
|
||||
"### Authenticate your Google Cloud account\n",
|
||||
"\n",
|
||||
"**If you are using Vertex AI Workbench notebooks**, your environment is already\n",
|
||||
"authenticated. Skip this step.\n",
|
||||
"authenticated.\n",
|
||||
"\n",
|
||||
"**If you are using Colab**, run the cell below and follow the instructions\n",
|
||||
"when prompted to authenticate your account via oAuth.\n"
|
||||
"when prompted to authenticate your account via oAuth.\n",
|
||||
"\n",
|
||||
"**Otherwise**, follow these steps:\n",
|
||||
"\n",
|
||||
"1. In the Cloud Console, go to the [**Create service account key**\n",
|
||||
" page](https://console.cloud.google.com/apis/credentials/serviceaccountkey).\n",
|
||||
"\n",
|
||||
"2. Click **Create service account**.\n",
|
||||
"\n",
|
||||
"3. In the **Service account name** field, enter a name, and\n",
|
||||
" click **Create**.\n",
|
||||
"\n",
|
||||
"4. In the **Grant this service account access to project** section, click the **Role** drop-down list. Type \"Vertex AI\"\n",
|
||||
"into the filter box, and select\n",
|
||||
" **Vertex AI Administrator**. Type \"Storage Object Admin\" into the filter box, and select **Storage Object Admin**.\n",
|
||||
"\n",
|
||||
"5. Click **Create**. A JSON file that contains your key downloads to your\n",
|
||||
"local environment.\n",
|
||||
"\n",
|
||||
"6. Enter the path to your service account key as the\n",
|
||||
"`GOOGLE_APPLICATION_CREDENTIALS` variable in the cell below and run the cell."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "06c51076",
|
||||
"metadata": {
|
||||
"id": "06c51076"
|
||||
},
|
||||
@@ -421,73 +443,284 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "6b01af18",
|
||||
"metadata": {
|
||||
"id": "6b01af18"
|
||||
"id": "bucket:custom"
|
||||
},
|
||||
"source": [
|
||||
"### Upload the model\n",
|
||||
"### Create a Cloud Storage bucket\n",
|
||||
"\n",
|
||||
"The churn propensity model you'll be using in this notebook has been trained in BigQuery ML and exported to a Google Cloud Storage bucket. This illustrates how you can easily export a trained model and move a model from one cloud service to another. \n",
|
||||
"**The following steps are required, regardless of your notebook environment.**\n",
|
||||
"\n",
|
||||
"Next, import the model. **If you've already imported your model, you can skip this step.**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "9638ad2c",
|
||||
"metadata": {
|
||||
"id": "9638ad2c"
|
||||
},
|
||||
"source": [
|
||||
"<span id=\"papermill-error-cell\" style=\"color:red; font-family:Helvetica Neue, Helvetica, Arial, sans-serif; font-size:2em;\">Execution using papermill encountered an exception here and stopped:</span>"
|
||||
"Set the name of your Cloud Storage bucket below, which you use in this tutorial to upload the `input schema` for the monitoring service.\n",
|
||||
"\n",
|
||||
"Bucket names must be globally unique across all Google Cloud projects, including those outside of your organization."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "926e3ba8",
|
||||
"metadata": {
|
||||
"id": "926e3ba8"
|
||||
"id": "bucket"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from datetime import datetime\n",
|
||||
"import json\n",
|
||||
"import time\n",
|
||||
"import re\n",
|
||||
"import tensorflow as tf\n",
|
||||
"BUCKET_NAME = \"[your-bucket-name]\" # @param {type:\"string\"}\n",
|
||||
"BUCKET_URI = f\"gs://{BUCKET_NAME}\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "autoset_bucket"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"if BUCKET_NAME == \"\" or BUCKET_NAME is None or BUCKET_NAME == \"[your-bucket-name]\":\n",
|
||||
" BUCKET_NAME = PROJECT_ID + \"aip-\" + UUID\n",
|
||||
" BUCKET_URI = \"gs://\" + BUCKET_NAME"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "create_bucket"
|
||||
},
|
||||
"source": [
|
||||
"**Only if your bucket doesn't already exist**: Run the following cell to create your Cloud Storage bucket."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "create_bucket"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! gsutil mb -l $REGION $BUCKET_URI"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "validate_bucket"
|
||||
},
|
||||
"source": [
|
||||
"Finally, validate access to your Cloud Storage bucket by examining its contents:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "validate_bucket"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! gsutil ls -al $BUCKET_URI"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "a0d294ff6d10"
|
||||
},
|
||||
"source": [
|
||||
"### Import libraries"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "bd7a633296eb"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import google.cloud.aiplatform as aiplatform\n",
|
||||
"import tensorflow_data_validation as tfdv\n",
|
||||
"from tensorflow_data_validation.utils import io_util \n",
|
||||
"from tensorflow_metadata.proto.v0 import statistics_pb2\n",
|
||||
"\n",
|
||||
"MODEL_DISPLAY_NAME=f\"batch_prediction_monitoring_test_model_{datetime.now().strftime('%Y%m%d%H%M%S')}\"\n",
|
||||
"CONTAINER_IMAGE_URI=\"us-docker.pkg.dev/cloud-aiplatform/prediction/tf2-cpu.2-4:latest\"\n",
|
||||
"ARTIFACT_URI=\"gs://mco-mm/churn\"\n",
|
||||
"\n",
|
||||
"output = ! gcloud ai models upload \\\n",
|
||||
" --region=$REGION \\\n",
|
||||
" --display-name=$MODEL_DISPLAY_NAME \\\n",
|
||||
" --artifact-uri=$ARTIFACT_URI \\\n",
|
||||
" --container-image-uri=$CONTAINER_IMAGE_URI \\\n",
|
||||
" --format=\"value(model)\"\n",
|
||||
"MODEL_ID = output[1].split(\"/\")[5]\n",
|
||||
"print(f\"Model {MODEL_ID} created.\")"
|
||||
"from tensorflow_data_validation.utils import io_util\n",
|
||||
"from tensorflow_metadata.proto.v0 import statistics_pb2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "init_aip:mbsdk,all"
|
||||
},
|
||||
"source": [
|
||||
"### Initialize Vertex AI SDK for Python\n",
|
||||
"\n",
|
||||
"Initialize the Vertex AI SDK for Python for your project and corresponding bucket."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "init_aip:mbsdk,all"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"aiplatform.init(project=PROJECT_ID, location=REGION)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "accelerators:training,prediction"
|
||||
},
|
||||
"source": [
|
||||
"#### Set hardware accelerators\n",
|
||||
"\n",
|
||||
"You can set hardware accelerators for prediction (e.g., GPUs) or choose not to use any (CPU). Hardware accelertors lower the latency response for a prediction request. When choosing a hardware accelerators, consider the additional cost trade-off over latency.\n",
|
||||
"\n",
|
||||
"Set the variables `DEPLOY_GPU/DEPLOY_NGPU` to use a container image supporting a GPU and the number of GPUs allocated to the virtual machine (VM) instance. For example, to use a GPU container image with 4 Nvidia Tesla K80 GPUs allocated to each VM, you would specify:\n",
|
||||
"\n",
|
||||
" (aiplatform.gapic.AcceleratorType.NVIDIA_TESLA_K80, 4)\n",
|
||||
"\n",
|
||||
"See the [locations where accelerators are available](https://cloud.google.com/vertex-ai/docs/general/locations#accelerators).\n",
|
||||
"\n",
|
||||
"Otherwise specify `(None, None)` to use a container image to run on a CPU."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "xd5PLXDTlugv"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"GPU = False\n",
|
||||
"if GPU:\n",
|
||||
" DEPLOY_GPU, DEPLOY_NGPU = (aiplatform.gapic.AcceleratorType.NVIDIA_TESLA_K80, 1)\n",
|
||||
"else:\n",
|
||||
" DEPLOY_GPU, DEPLOY_NGPU = (None, None)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "container:training,prediction"
|
||||
},
|
||||
"source": [
|
||||
"#### Set pre-built containers\n",
|
||||
"\n",
|
||||
"Set the pre-built Docker container image for prediction.\n",
|
||||
"\n",
|
||||
"For the latest list, see [Pre-built containers for prediction](https://cloud.google.com/ai-platform-unified/docs/predictions/pre-built-containers)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "1u1mr18jlugv"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"if GPU:\n",
|
||||
" DEPLOY_VERSION = \"tf2-gpu.2-5\"\n",
|
||||
"else:\n",
|
||||
" DEPLOY_VERSION = \"tf2-cpu.2-5\"\n",
|
||||
"\n",
|
||||
"DEPLOY_IMAGE = \"{}-docker.pkg.dev/vertex-ai/prediction/{}:latest\".format(\n",
|
||||
" REGION.split(\"-\")[0], DEPLOY_VERSION\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"print(\"Deployment:\", DEPLOY_IMAGE, DEPLOY_GPU, DEPLOY_NGPU)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "machine:training,prediction"
|
||||
},
|
||||
"source": [
|
||||
"#### Set machine types\n",
|
||||
"\n",
|
||||
"Next, set the machine types to use for training and prediction.\n",
|
||||
"\n",
|
||||
"- Set the variable `DEPLOY_COMPUTE` to configure your compute resources for prediction.\n",
|
||||
" - `machine type`\n",
|
||||
" - `n1-standard`: 3.75GB of memory per vCPU\n",
|
||||
" - `n1-highmem`: 6.5GB of memory per vCPU\n",
|
||||
" - `n1-highcpu`: 0.9 GB of memory per vCPU\n",
|
||||
" - `vCPUs`: number of \\[2, 4, 8, 16, 32, 64, 96 \\]\n",
|
||||
"\n",
|
||||
"*Note: You may also use n2 and e2 machine types for training and deployment, but they do not support GPUs*."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "YAXwbqKKlugv"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"MACHINE_TYPE = \"n1-standard\"\n",
|
||||
"\n",
|
||||
"VCPU = \"4\"\n",
|
||||
"TRAIN_COMPUTE = MACHINE_TYPE + \"-\" + VCPU\n",
|
||||
"print(\"Train machine type\", TRAIN_COMPUTE)\n",
|
||||
"\n",
|
||||
"MACHINE_TYPE = \"n1-standard\"\n",
|
||||
"\n",
|
||||
"VCPU = \"4\"\n",
|
||||
"DEPLOY_COMPUTE = MACHINE_TYPE + \"-\" + VCPU\n",
|
||||
"print(\"Deploy machine type\", DEPLOY_COMPUTE)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "9bf06cd476e9"
|
||||
},
|
||||
"source": [
|
||||
"### Upload the model artifacts as a `Vertex AI Model` resource\n",
|
||||
"\n",
|
||||
"First, you upload the pre-trained custom tabular model artifacts as a `Vertex AI Model` resource using the `upload()` method, with the following parameters:\n",
|
||||
"\n",
|
||||
"- `display_name`: The human readable name for the `Model` resource.\n",
|
||||
"- `artifact_uri`: The Cloud Storage location of the model artifacts.\n",
|
||||
"- `serving_container_image`: The serving container image to use when the model is deployed to a `Vertex AI Endpoint` resource.\n",
|
||||
"- `sync`: Whether to wait for the process to complete, or return immediately (async)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "0193f247e216"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"MODEL_ARTIFACT_URI = \"gs://mco-mm/churn\"\n",
|
||||
"\n",
|
||||
"model = aiplatform.Model.upload(\n",
|
||||
" display_name=\"churn_\" + UUID,\n",
|
||||
" artifact_uri=MODEL_ARTIFACT_URI,\n",
|
||||
" serving_container_image_uri=DEPLOY_IMAGE,\n",
|
||||
" sync=True,\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"print(model)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "a4305ddf",
|
||||
"metadata": {
|
||||
"id": "a4305ddf"
|
||||
},
|
||||
"source": [
|
||||
"## Submit a batch prediction request with model monitoring enabled"
|
||||
"## Submit a batch prediction request with model monitoring enabled\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "053fde99",
|
||||
"metadata": {
|
||||
"id": "053fde99"
|
||||
},
|
||||
@@ -503,7 +736,6 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "b832ad31",
|
||||
"metadata": {
|
||||
"id": "b832ad31"
|
||||
},
|
||||
@@ -511,20 +743,17 @@
|
||||
"source": [
|
||||
"# Copy files to your projects gs bucket to avoid permission issues.\n",
|
||||
"# Ignore any error(s) for bucket already exists.\n",
|
||||
"OUTPUT_GS_PATH = f\"gs://{PROJECT_ID.replace('-', '_')}_bp_mm_output\"\n",
|
||||
"INPUT_GS_PATH = f\"gs://{PROJECT_ID.replace('-', '_')}_bp_mm_input\"\n",
|
||||
"OUTPUT_GS_PATH = f\"{BUCKET_URI}/bp_mm_output\"\n",
|
||||
"INPUT_GS_PATH = f\"{BUCKET_URI}/bp_mm_input\"\n",
|
||||
"PUBLIC_TRAINING_DATASET = \"gs://bp_mm_public_data/churn/churn_bp_insample.csv\"\n",
|
||||
"TRAINING_DATASET = f\"{INPUT_GS_PATH}/churn_bp_insample.csv\"\n",
|
||||
"TRAINING_DATASET_FORMAT = \"csv\"\n",
|
||||
"\n",
|
||||
"! gsutil mb -p {PROJECT_ID} -l {REGION} -b on {INPUT_GS_PATH}\n",
|
||||
"! gsutil mb -p {PROJECT_ID} -l {REGION} -b on {OUTPUT_GS_PATH}\n",
|
||||
"! gsutil copy $PUBLIC_TRAINING_DATASET $INPUT_GS_PATH"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "34c95126",
|
||||
"metadata": {
|
||||
"id": "34c95126"
|
||||
},
|
||||
@@ -541,21 +770,18 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "3a54368a",
|
||||
"metadata": {
|
||||
"id": "3a54368a"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"now = datetime.now()\n",
|
||||
"INPUT_URI = \"gs://bp_mm_public_data/churn/churn_bp_outsample.jsonl\"\n",
|
||||
"OUTPUT_URI = OUTPUT_GS_PATH\n",
|
||||
"INSTANCES_FORMAT = \"jsonl\"\n",
|
||||
"PREDICTIONS_FORMAT = \"jsonl\"\n",
|
||||
"JOB_NAME_PREFIX = \"bp_mm_demo\"\n",
|
||||
"MODEL_NAME = f\"projects/{PROJECT_ID}/locations/{REGION}/models/{MODEL_ID}\"\n",
|
||||
"MACHINE_TYPE = \"n1-standard-8\"\n",
|
||||
"BATCH_PREDICTION_JOB_NAME = JOB_NAME_PREFIX + \"_\" + now.strftime(\"%Y%m%d%H%M%S\")\n",
|
||||
"MODEL_NAME = model.resource_name\n",
|
||||
"BATCH_PREDICTION_JOB_NAME = JOB_NAME_PREFIX + \"_\" + UUID\n",
|
||||
"\n",
|
||||
"from google.cloud.aiplatform_v1beta1.types import (\n",
|
||||
" BatchDedicatedResources, BatchPredictionJob, GcsDestination, GcsSource,\n",
|
||||
@@ -573,7 +799,7 @@
|
||||
" gcs_destination=GcsDestination(output_uri_prefix=OUTPUT_URI),\n",
|
||||
" ),\n",
|
||||
" dedicated_resources=BatchDedicatedResources(\n",
|
||||
" machine_spec=MachineSpec(machine_type=MACHINE_TYPE),\n",
|
||||
" machine_spec=MachineSpec(machine_type=DEPLOY_COMPUTE),\n",
|
||||
" starting_replica_count=1,\n",
|
||||
" max_replica_count=1,\n",
|
||||
" ),\n",
|
||||
@@ -604,7 +830,6 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "cae39778",
|
||||
"metadata": {
|
||||
"id": "cae39778"
|
||||
},
|
||||
@@ -617,7 +842,6 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "bcdd4a47",
|
||||
"metadata": {
|
||||
"id": "bcdd4a47"
|
||||
},
|
||||
@@ -638,7 +862,6 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "49ec90a0",
|
||||
"metadata": {
|
||||
"id": "49ec90a0"
|
||||
},
|
||||
@@ -651,7 +874,6 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "c30496b5",
|
||||
"metadata": {
|
||||
"id": "c30496b5"
|
||||
},
|
||||
@@ -664,7 +886,6 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "831651c2",
|
||||
"metadata": {
|
||||
"id": "831651c2"
|
||||
},
|
||||
@@ -684,7 +905,6 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "a705c10b",
|
||||
"metadata": {
|
||||
"id": "a705c10b"
|
||||
},
|
||||
@@ -695,7 +915,6 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "2bbdddac",
|
||||
"metadata": {
|
||||
"id": "2bbdddac"
|
||||
},
|
||||
@@ -708,7 +927,6 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "f6c674e9",
|
||||
"metadata": {
|
||||
"id": "f6c674e9"
|
||||
},
|
||||
@@ -746,7 +964,6 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "233b1266",
|
||||
"metadata": {
|
||||
"id": "233b1266"
|
||||
},
|
||||
@@ -759,7 +976,6 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "4e8c00a7",
|
||||
"metadata": {
|
||||
"id": "4e8c00a7"
|
||||
},
|
||||
@@ -774,7 +990,6 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "497a0016",
|
||||
"metadata": {
|
||||
"id": "497a0016"
|
||||
},
|
||||
@@ -790,7 +1005,6 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "eabc3f81",
|
||||
"metadata": {
|
||||
"id": "eabc3f81"
|
||||
},
|
||||
@@ -806,7 +1020,6 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "0aa0219d",
|
||||
"metadata": {
|
||||
"id": "0aa0219d"
|
||||
},
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Copyright 2022 Google LLC\n",
|
||||
"# Copyright 2022 Google LLC.\n",
|
||||
"#\n",
|
||||
"# Licensed under the Apache License, Version 2.0 (the \"License\");\n",
|
||||
"# you may not use this file except in compliance with the License.\n",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -123,6 +123,7 @@
|
||||
"if IS_WORKBENCH_NOTEBOOK:\n",
|
||||
" USER_FLAG = \"--user\"\n",
|
||||
"\n",
|
||||
"! pip3 install google-vizier==0.0.4\n",
|
||||
"! pip3 install --upgrade google-cloud-aiplatform {USER_FLAG} -q"
|
||||
]
|
||||
},
|
||||
@@ -350,9 +351,9 @@
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import datetime\n",
|
||||
"import json\n",
|
||||
"\n",
|
||||
"from google.cloud import aiplatform"
|
||||
"from google.cloud import aiplatform\n",
|
||||
"from google.cloud.aiplatform.vizier import Study, pyvizier"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -384,11 +385,9 @@
|
||||
"# These will be automatically filled in.\n",
|
||||
"STUDY_DISPLAY_NAME = \"{}_study_{}\".format(\n",
|
||||
" PROJECT_ID.replace(\"-\", \"\"), datetime.datetime.now().strftime(\"%Y%m%d_%H%M%S\")\n",
|
||||
") # @param {type: 'string'}\n",
|
||||
"ENDPOINT = REGION + \"-aiplatform.googleapis.com\"\n",
|
||||
")\n",
|
||||
"PARENT = \"projects/{}/locations/{}\".format(PROJECT_ID, REGION)\n",
|
||||
"\n",
|
||||
"print(\"ENDPOINT: {}\".format(ENDPOINT))\n",
|
||||
"print(\"REGION: {}\".format(REGION))\n",
|
||||
"print(\"PARENT: {}\".format(PARENT))"
|
||||
]
|
||||
@@ -413,34 +412,21 @@
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Parameter Configuration\n",
|
||||
"\n",
|
||||
"param_r = {\"parameter_id\": \"r\", \"double_value_spec\": {\"min_value\": 0, \"max_value\": 1}}\n",
|
||||
"\n",
|
||||
"param_theta = {\n",
|
||||
" \"parameter_id\": \"theta\",\n",
|
||||
" \"double_value_spec\": {\"min_value\": 0, \"max_value\": 1.57},\n",
|
||||
"}\n",
|
||||
"problem = pyvizier.StudyConfig()\n",
|
||||
"problem.algorithm = pyvizier.Algorithm.RANDOM_SEARCH\n",
|
||||
"\n",
|
||||
"# Objective Metrics\n",
|
||||
"metric_y1 = {\"metric_id\": \"y1\", \"goal\": \"MINIMIZE\"}\n",
|
||||
"problem.metric_information.append(\n",
|
||||
" pyvizier.MetricInformation(name=\"y1\", goal=pyvizier.ObjectiveMetricGoal.MINIMIZE)\n",
|
||||
")\n",
|
||||
"problem.metric_information.append(\n",
|
||||
" pyvizier.MetricInformation(name=\"y2\", goal=pyvizier.ObjectiveMetricGoal.MAXIMIZE)\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Objective Metrics\n",
|
||||
"metric_y2 = {\"metric_id\": \"y2\", \"goal\": \"MAXIMIZE\"}\n",
|
||||
"\n",
|
||||
"# Put it all together in a study configuration\n",
|
||||
"study = {\n",
|
||||
" \"display_name\": STUDY_DISPLAY_NAME,\n",
|
||||
" \"study_spec\": {\n",
|
||||
" \"algorithm\": \"RANDOM_SEARCH\",\n",
|
||||
" \"parameters\": [\n",
|
||||
" param_r,\n",
|
||||
" param_theta,\n",
|
||||
" ],\n",
|
||||
" \"metrics\": [metric_y1, metric_y2],\n",
|
||||
" },\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"print(json.dumps(study, indent=2, sort_keys=True))"
|
||||
"# Defines the parameters configuration.\n",
|
||||
"root = problem.search_space.select_root()\n",
|
||||
"root.add_float_param(\"r\", 0, 1.0, scale_type=pyvizier.ScaleType.LINEAR)\n",
|
||||
"root.add_float_param(\"theta\", 0, 1.57, scale_type=pyvizier.ScaleType.LINEAR)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -462,10 +448,9 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"vizier_client = aiplatform.gapic.VizierServiceClient(\n",
|
||||
" client_options=dict(api_endpoint=ENDPOINT)\n",
|
||||
")\n",
|
||||
"study = vizier_client.create_study(parent=PARENT, study=study)\n",
|
||||
"aiplatform.init(project=PROJECT_ID, location=REGION)\n",
|
||||
"study = Study.create_or_load(display_name=STUDY_DISPLAY_NAME, problem=problem)\n",
|
||||
"\n",
|
||||
"STUDY_ID = study.name\n",
|
||||
"print(\"STUDY_ID: {}\".format(STUDY_ID))"
|
||||
]
|
||||
@@ -515,11 +500,12 @@
|
||||
" r, theta, y1, y2\n",
|
||||
" )\n",
|
||||
" )\n",
|
||||
" metric1 = {\"metric_id\": \"y1\", \"value\": y1}\n",
|
||||
" metric2 = {\"metric_id\": \"y2\", \"value\": y2}\n",
|
||||
" measurement = pyvizier.Measurement()\n",
|
||||
" measurement.metrics[\"y1\"] = y1\n",
|
||||
" measurement.metrics[\"y2\"] = y2\n",
|
||||
"\n",
|
||||
" # Return the results for this trial\n",
|
||||
" return [metric1, metric2]"
|
||||
" return measurement"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -545,11 +531,11 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"client_id = \"client1\" # @param {type: 'string'}\n",
|
||||
"suggestion_count_per_request = 5 # @param {type: 'integer'}\n",
|
||||
"max_trial_id_to_stop = 4 # @param {type: 'integer'}\n",
|
||||
"worker_id = \"worker1\" # @param {type: 'string'}\n",
|
||||
"suggestion_count_per_request = 3 # @param {type: 'integer'}\n",
|
||||
"max_trial_id_to_stop = 6 # @param {type: 'integer'}\n",
|
||||
"\n",
|
||||
"print(\"client_id: {}\".format(client_id))\n",
|
||||
"print(\"worker_id: {}\".format(worker_id))\n",
|
||||
"print(\"suggestion_count_per_request: {}\".format(suggestion_count_per_request))\n",
|
||||
"print(\"max_trial_id_to_stop: {}\".format(max_trial_id_to_stop))"
|
||||
]
|
||||
@@ -573,42 +559,17 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"trial_id = 0\n",
|
||||
"while int(trial_id) < max_trial_id_to_stop:\n",
|
||||
" suggest_response = vizier_client.suggest_trials(\n",
|
||||
" {\n",
|
||||
" \"parent\": STUDY_ID,\n",
|
||||
" \"suggestion_count\": suggestion_count_per_request,\n",
|
||||
" \"client_id\": client_id,\n",
|
||||
" }\n",
|
||||
" )\n",
|
||||
"while len(study.trials()) < max_trial_id_to_stop:\n",
|
||||
" trials = study.suggest(count=suggestion_count_per_request, worker=worker_id)\n",
|
||||
"\n",
|
||||
" for suggested_trial in suggest_response.result().trials:\n",
|
||||
" trial_id = suggested_trial.name.split(\"/\")[-1]\n",
|
||||
" trial = vizier_client.get_trial({\"name\": suggested_trial.name})\n",
|
||||
"\n",
|
||||
" if trial.state in [\"COMPLETED\", \"INFEASIBLE\"]:\n",
|
||||
" continue\n",
|
||||
"\n",
|
||||
" for param in trial.parameters:\n",
|
||||
" if param.parameter_id == \"r\":\n",
|
||||
" r = param.value\n",
|
||||
" elif param.parameter_id == \"theta\":\n",
|
||||
" theta = param.value\n",
|
||||
" print(\"Trial : r is {}, theta is {}.\".format(r, theta))\n",
|
||||
"\n",
|
||||
" vizier_client.add_trial_measurement(\n",
|
||||
" {\n",
|
||||
" \"trial_name\": suggested_trial.name,\n",
|
||||
" \"measurement\": {\n",
|
||||
" \"metrics\": CreateMetrics(suggested_trial.name, r, theta)\n",
|
||||
" },\n",
|
||||
" }\n",
|
||||
" for suggested_trial in trials:\n",
|
||||
" measurement = CreateMetrics(\n",
|
||||
" suggested_trial.name,\n",
|
||||
" suggested_trial.parameters[\"r\"].value,\n",
|
||||
" suggested_trial.parameters[\"theta\"].value,\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" response = vizier_client.complete_trial(\n",
|
||||
" {\"name\": suggested_trial.name, \"trial_infeasible\": False}\n",
|
||||
" )"
|
||||
" suggested_trial.add_measurement(measurement=measurement)\n",
|
||||
" suggested_trial.complete(measurement=measurement)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -630,8 +591,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"optimal_trials = vizier_client.list_optimal_trials({\"parent\": STUDY_ID})\n",
|
||||
"\n",
|
||||
"optimal_trials = study.optimal_trials()\n",
|
||||
"print(\"optimal_trials: {}\".format(optimal_trials))"
|
||||
]
|
||||
},
|
||||
@@ -655,7 +615,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"vizier_client.delete_study({\"name\": STUDY_ID})"
|
||||
"study.delete()"
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user