Compare commits

...
Author SHA1 Message Date
sasha-gitgandGitHub 707addff83 Merge branch 'main' into sasha-gitg-patch-3 2022-07-08 15:04:44 -04:00
Andrew FerlitschandGitHub c95f73c1a8 fix: bad link (#712)
* feat: notebook on model registry

* feat: notebook on model registry

* feat: workflow notebook

* feat: workflow notebook

* feat: workflow notebook

* fix: objective

* fix: objective

* fix: link

* fix: link
2022-07-07 12:51:14 -07:00
Andrew FerlitschandGitHub 9da033c887 Update README.md 2022-07-06 14:40:51 -07:00
Andrew FerlitschandGitHub f61f9bfdc2 feat: notebook for automl tabular workflow (#710)
* feat: notebook on model registry

* feat: notebook on model registry

* feat: workflow notebook

* feat: workflow notebook

* feat: workflow notebook
2022-07-06 14:26:45 -07:00
b2a17dfc83 inardini - New 20+ Pipeline Operators for BQML notebook (#706)
* google_cloud_pipeline_components_bqml_pipeline_demand_forecasting notebook

* linter test to check with andy

* google_cloud_pipeline_components_bqml_pipeline_demand_forecasting notebook

* linter test to check with andy

* merge

* linter test minor fails. check with andy

* add code owner

* minor changes

* remove components

* linter test passed

Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>
2022-07-06 08:38:28 -07:00
sasha-gitgandGitHub 7072219d8b Update build_model_experimentation_lineage_with_prebuild_code.ipynb (#703)
Switch to install from Pypi
2022-07-01 14:40:52 -07:00
Andrew FerlitschandGitHub 57db2f4014 Update README.md 2022-07-01 11:45:37 -07:00
Andrew FerlitschandGitHub 4604b0a0a9 Update README.md 2022-07-01 11:44:38 -07:00
Andrew FerlitschandGitHub c8c26a12ba fix: finish objective cell (#708)
* feat: notebook on model registry

* feat: notebook on model registry
2022-07-01 11:40:28 -07:00
Andrew FerlitschandGitHub 3a8fa3e312 feat: notebook for model registry (#707)
* update: refine experiment notebook

* update: refine experiment notebook

* update: new feature release

* update: new feature release

* update: new feature release

* update: new feature release

* feat: notebook on model registry

* feat: notebook on model registry
2022-07-01 11:25:20 -07:00
bbfba5aaaf add initial automl tables on vertex pipelines notebook (#694)
* add initial automl tables on vertex pipelines notebook

* apply template

* update bucket variable name

* reviewer requested changes

* update notebook with the updated API

* fix typo

* add stage_1_tuning_result_artifact_uri to skip architecture search pipeline

* update parameter for skip architecture search pipeline

* default evaluation to True; update data splits

* update dataset to gs://cloud-samples-data/vertex-ai/tabular-workflows/datasets/safe-driver/train.csv

Co-authored-by: Helin Wang <helin@google.com>
Co-authored-by: Ivan Cheung <ivans.mailbox@gmail.com>
2022-07-01 09:54:39 -07:00
Andrew FerlitschandGitHub e30b2182b0 Update get_started_with_vertex_endpoints.ipynb 2022-06-30 20:35:07 -07:00
4c4dade55a samples: Add Prediction CPR preprocess sample. (#662)
* samples: Add Prediction CPR preprocess sample.

* chore: Refined wording and used notebook template for CPR preprocessing
sample.

* samples: Fixed comments for CPR Preprocess sample.

* samples: Fixed wording.

Co-authored-by: Ivan Cheung <ivans.mailbox@gmail.com>
Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>
2022-06-30 20:14:35 -07:00
5690d50430 samples: Add Prediction CPR Triton sample. (#661)
* samples: Add Prediction CPR Triton sample.

* chore: Refined wording and used notebook template for CPR Triton sample.

* samples: Fixed comments for CPR Triton samples.

* samples: Fixed wording.

Co-authored-by: Ivan Cheung <ivans.mailbox@gmail.com>
Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>
2022-06-30 20:13:00 -07:00
Chun-Hsiang WangandGitHub 10c33f934f samples: Add Prediction CPR SDK sample. (#660)
* samples: Add Prediction CPR SDK sample.

* chore: Refined wording and used notebook template for CPR SDK sample.

* samples: Fixed comments for CPR SDK sample.

* samples: Fixed wording.
2022-06-30 20:07:29 -07:00
sasha-gitgandGitHub 75e4c80cb0 Merge branch 'main' into sasha-gitg-patch-3 2022-06-30 19:32:34 -04:00
Andrew FerlitschandGitHub 0c43cbd563 update: remove install from git branch 2022-06-30 16:24:20 -07:00
sasha-gitgandGitHub 6c22c0b177 Update comparing_pipeline_runs.ipynb 2022-06-30 18:53:03 -04:00
Andrew FerlitschandGitHub b640a8f545 update: new feature release (#702)
* update: refine experiment notebook

* update: refine experiment notebook

* update: new feature release

* update: new feature release

* update: new feature release

* update: new feature release
2022-06-30 11:57:50 -07:00
Ivan CheungandGitHub a575528b11 Tweaks to matching engine notebook (#701)
* Tweaks to notebook

* Ran linter

* More tweaks
2022-06-30 11:59:05 -04:00
Andrew FerlitschandGitHub 42a2c4d082 fix: doc link 2022-06-30 08:36:57 -07:00
Andrew FerlitschandGitHub 0bcf44e9fa Update get_started_bqml_training.ipynb 2022-06-30 08:33:06 -07:00
Andrew FerlitschandGitHub 9ac2774ece Update README.md 2022-06-29 21:25:19 -07:00
Andrew FerlitschandGitHub 975c9fe6bc update: refine experiments notebook (#699)
* update: refine experiment notebook

* update: refine experiment notebook
2022-06-29 21:14:11 -07:00
Andrew FerlitschandGitHub 417410f382 Fix: remove hardwired project number (#698)
* fix: remove hardwired project number

* fix: remove hardwired project number
2022-06-29 14:42:51 -07:00
Andrew FerlitschandGitHub 8fdfbe4e31 fix: link 2022-06-29 14:20:04 -07:00
Andrew FerlitschandGitHub 80f977546c fix: title 2022-06-29 09:54:29 -07:00
Ivan NardiniandGitHub c5fe281e32 inardini - experiments cuj2 notebook release (#637)
* experiments cuj2 notebook release

* add andy reviews

* linter test passed

* align notebooks

* linter test passed

* minor changes

* karl bug review fix

* linter test passed

* add -q to install

* linter test passed

* debug

* linter test passed

* PR build fix

* linter test passed. delete debug notebook

* import import tempfile

* linter test passed

* remove pandas install

* linter test passed

* add sklearn

* linter test passed

* test pandas dep

* linter test passed

* minor changes

* linter test passed

* ivan fix
2022-06-29 12:38:16 -04:00
49a2ddaf08 fix: removing TODOs from TabNet notebook (#652)
* moving REGION up

* moving REGION up and csv file name

* fix: changed bucket URL to console

* removing TODOs from Tabnet notebook

Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>
2022-06-28 07:26:01 -07:00
e9cba94bb4 inardini - experiments cuj3 notebook release (#638)
* experiments cuj3 notebook release

* add andy reviews

* linter test passed

* align notebooks

* linter test passed

* align notebooks

* linter test passed

* update CODEOWNERS

* sasha bug review fix

* linter test passed

* minor changes

* add -q to install

* linter test passed

* ivan dep fix

* linter test passed

Co-authored-by: Ivan Cheung <ivans.mailbox@gmail.com>
2022-06-27 19:15:13 -04:00
fc83cfcea5 samples: Add Prediction CPR PyTorch sample. (#659)
* samples: Add Prediction CPR PyTorch sample.

* chore: Refined wording and used notebook template for PyTorch sample.

* added missing bucket cleanup

Co-authored-by: Andrew Ferlitsch <aferlitsch@gmail.com>
Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>
2022-06-27 12:23:31 -07:00
e3aa9e8f35 samples: Add Prediction CPR handler sample. (#658)
* samples: Add Prediction CPR handler sample.

* chore: Refined wording and used notebook template.

* added missing bucket cleanup sequence

Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
Co-authored-by: Andrew Ferlitsch <aferlitsch@gmail.com>
Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>
2022-06-27 12:09:20 -07:00
Ivan CheungandGitHub 37c52abc11 Added a virtualenv to the notebook execution tests which should help with dependency issues (#693)
* Added a virtualenv

* Added a virtualenv for the single yaml

* Debug

* Fixed diff logic for all notebooks case

* Added missing -c
2022-06-26 13:31:52 -04:00
Ivan CheungandGitHub c8320c8764 Revert "Add notebook for co-hosting model (#666)" (#692)
This reverts commit aa5464151d.
2022-06-24 18:26:28 -04:00
b5d51e61b6 inardini - experiments cuj1 notebook release (#636)
* experiments cuj1 notebook release

* add andy reviews

* linter test passed

* align notebooks

* linter test passed

* minor changes

* linter test passed

* minor changes

* linter test passed

Co-authored-by: Ivan Cheung <ivans.mailbox@gmail.com>
2022-06-24 15:35:32 -04:00
Ziye XingandGitHub aa5464151d Add notebook for co-hosting model (#666)
* Add notebook for co-hosting model

* Add co-hosting model notebook codeowner
2022-06-24 10:36:26 -07:00
Andrew FerlitschandGitHub 386cecf4c2 upgrade: current notebook standard (#677)
* upgrade: notebook standard

* upgrade: notebook standard

* Update custom_model_training_and_batch_prediction.ipynb
2022-06-24 09:59:49 -07:00
dffdb15c17 Add default kernel_name for notebook execution (#497)
Currently, there is no kernel_name. Hence, the execution test cannot run for notebooks that don't have kernels defined in their .ipynb file.

Side-note: We should use lint to remove the kernel_name from .ipynb as well, as it could include info specific to the author's environment.

Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
2022-06-23 19:18:49 -04:00
Andrew FerlitschandGitHub 2f3691eb71 fix: workbench link 2022-06-23 13:55:29 -07:00
Andrew FerlitschandGitHub f456d86555 fix: open in workbench link 2022-06-23 13:52:39 -07:00
Andrew FerlitschandGitHub f534b4e7a5 upgrade: fine tune notebook standard 2022-06-23 13:28:00 -07:00
Andrew FerlitschandGitHub de247cd78b upgrade: current notebook standards (#681)
* upgrade: notebook standard

* upgrade: notebook standard

* fix: formatting
2022-06-23 12:03:55 -07:00
Andrew FerlitschandGitHub 22ad74eb8d Update README.md 2022-06-23 10:06:28 -07:00
Andrew FerlitschandGitHub baf69999fc update: fine-tuning notebook (#689)
* update: touchups

* update: touchups
2022-06-23 10:02:02 -07:00
Mohammad Al-AnsariandGitHub d5057da9bb Added new notebook that creates Vertex AI AutoML text entity extraction dataset from PDFs using Vision API (#683)
* Added new Stage 1 notebook to create unlabelled
Vertex AI AutoML text entity extraction dataset
from collection of PDF files on Google Cloud Storage

* Linted notebook

* Removed TODOs

* Updates per PR comments

* Revered to multiple imports per line
2022-06-23 08:38:14 -07:00
24904a5999 feat: adding code owners and updating graph_paysim (#645)
* adding code owners and updating graph_paysim

* formatted

Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
Co-authored-by: Ivan Cheung <ivans.mailbox@gmail.com>
2022-06-22 21:31:55 -05:00
Ivan CheungandGitHub 881a2b45c5 Improved git diff logic (#687) 2022-06-22 21:49:09 -04:00
35 changed files with 20675 additions and 934 deletions
@@ -17,6 +17,7 @@ import concurrent
import dataclasses
import datetime
import functools
import git
import operator
import os
import pathlib
@@ -232,20 +233,40 @@ def get_changed_notebooks(
# Find notebooks
notebooks = []
# Instantiate GitPython objects
repo = git.Repo(os.getcwd())
index = repo.index
if base_branch:
print(f"Looking for notebooks that changed from branch: {base_branch}")
notebooks = subprocess.check_output(
["git", "diff", "--name-only", f"origin/{base_branch}..."] + test_paths
)
# Get the point at which this branch branches off from main
branching_commits = repo.merge_base("HEAD", f"origin/{base_branch}")
if len(branching_commits) > 0:
branching_commit = branching_commits[0]
print(f"Looking for notebooks that changed from branch: {branching_commit}")
notebooks = [
diff.b_path
for diff in index.diff(branching_commit, paths=test_paths)
if diff.b_path is not None
]
else:
notebooks = []
else:
print(f"Looking for all notebooks.")
notebooks = subprocess.check_output(["git", "ls-files"] + test_paths)
notebooks = notebooks.decode("utf-8").split("\n")
notebooks = notebooks.decode("utf-8").split("\n")
notebooks = [notebook for notebook in notebooks if notebook.endswith(".ipynb")]
notebooks = [notebook for notebook in notebooks if len(notebook) > 0]
notebooks = [notebook for notebook in notebooks if pathlib.Path(notebook).exists()]
if len(notebooks) > 0:
print(f"Found {len(notebooks)} notebooks:")
for notebook in notebooks:
print(f"\t{notebook}")
return notebooks
@@ -10,19 +10,37 @@ steps:
entrypoint: /bin/sh
args:
- -c
- 'python3 .cloud-build/CheckPythonVersion.py'
# Install Python dependencies
- python3 .cloud-build/CheckPythonVersion.py
# Create a virtual environment
- name: ${_PYTHON_IMAGE}
entrypoint: /bin/sh
args:
- -c
- 'python3 -m pip install -U pip && python3 -m pip install -U --user -r .cloud-build/requirements.txt'
- python3 -m venv workspace/env
# Install Python dependencies
- name: ${_PYTHON_IMAGE}
entrypoint: /bin/sh
args:
- -c
- . workspace/env/bin/activate &&
python3 -m pip install -U pip &&
python3 -m pip install -U -r .cloud-build/requirements.txt
# pip freeze
- name: ${_PYTHON_IMAGE}
entrypoint: /bin/sh
args:
- -c
- |
. workspace/env/bin/activate &&
python3 -m pip freeze
# Install Python dependencies and run testing script
- name: ${_PYTHON_IMAGE}
entrypoint: /bin/sh
args:
- -c
- 'python3 -m pip install -U pip && python3 -m pip freeze && python3 .cloud-build/execute_notebook_cli.py --notebook_source "${_NOTEBOOK_GCS_URI}" --output_file_or_uri "${_NOTEBOOK_OUTPUT_GCS_URI}"'
- |
. workspace/env/bin/activate &&
python3 .cloud-build/execute_notebook_cli.py --notebook_source "${_NOTEBOOK_GCS_URI}" --output_file_or_uri "${_NOTEBOOK_OUTPUT_GCS_URI}"
env:
- 'IS_TESTING=1'
timeout: 86400s
@@ -4,32 +4,47 @@ steps:
entrypoint: /bin/sh
args:
- -c
- 'gcloud config list'
- gcloud config list
# Check the Python version
- name: ${_PYTHON_IMAGE}
entrypoint: /bin/sh
args:
- -c
- 'python3 .cloud-build/CheckPythonVersion.py'
# Fetch base branch if required
- python3 .cloud-build/CheckPythonVersion.py
# Fetch full repo for diff purposes
- name: gcr.io/cloud-builders/git
args: [fetch, --unshallow]
# Create a virtual environment
- name: ${_PYTHON_IMAGE}
entrypoint: /bin/sh
args:
- -c
- 'if [ -n "${_BASE_BRANCH}" ]; then git fetch origin "${_BASE_BRANCH}":refs/remotes/origin/"${_BASE_BRANCH}"; else echo "Skipping fetch."; fi'
- python3 -m venv workspace/env
# Install Python dependencies
- name: ${_PYTHON_IMAGE}
entrypoint: /bin/sh
args:
- -c
- . workspace/env/bin/activate &&
python3 -m pip install -U pip &&
python3 -m pip install -U -r .cloud-build/requirements.txt
# pip freeze
- name: ${_PYTHON_IMAGE}
entrypoint: /bin/sh
args:
- -c
- 'python3 -m pip install -U pip && python3 -m pip install -U --user -r .cloud-build/requirements.txt'
- |
. workspace/env/bin/activate &&
python3 -m pip freeze
# Install Python dependencies and run testing script
# TODO: Only pass in private_pool_id if it is set
- name: ${_PYTHON_IMAGE}
entrypoint: /bin/sh
args:
- -c
- 'python3 -m pip install -U pip && python3 -m pip freeze && python3 .cloud-build/execute_changed_notebooks_cli.py --test_paths_file "${_TEST_PATHS_FILE}" --base_branch "${_FORCED_BASE_BRANCH}" --container_uri ${_PYTHON_IMAGE} --staging_bucket ${_GCS_STAGING_BUCKET} --artifacts_bucket ${_GCS_STAGING_BUCKET}/executed_notebooks/PR_${_PR_NUMBER}/BUILD_${BUILD_ID} --variable_project_id ${PROJECT_ID} --variable_region ${_GCP_REGION} `if [ ! -z "${_PRIVATE_POOL_NAME}" ]; then echo "--private_pool_id ${_PRIVATE_POOL_NAME}"; fi`'
- |
. workspace/env/bin/activate &&
python3 .cloud-build/execute_changed_notebooks_cli.py --test_paths_file "${_TEST_PATHS_FILE}" --base_branch "${_FORCED_BASE_BRANCH}" --container_uri ${_PYTHON_IMAGE} --staging_bucket ${_GCS_STAGING_BUCKET} --artifacts_bucket ${_GCS_STAGING_BUCKET}/executed_notebooks/PR_${_PR_NUMBER}/BUILD_${BUILD_ID} --variable_project_id ${PROJECT_ID} --variable_region ${_GCP_REGION} `if [ ! -z "${_PRIVATE_POOL_NAME}" ]; then echo "--private_pool_id ${_PRIVATE_POOL_NAME}"; fi`
env:
- 'IS_TESTING=1'
timeout: 86400s
+1
View File
@@ -10,3 +10,4 @@ google-cloud-aiplatform
google-cloud-storage
google-cloud-build
ratemate
GitPython
+5 -1
View File
@@ -18,7 +18,11 @@
/sdk/pytorch_lightning_custom_container_training.ipynb @brianchunkang
/tensorboard @yfang1
/feature_store @nayaknishant @morgandu
/prediction @googleapis/vertex-prediction-team
/vertex_endpoints/tf_hub_obj_detection/deploy_tfhub_object_detection_on_vertex_endpoints.ipynb @entrpn
/vertex_endpoints/nvidia-triton/nvidia-triton-custom-container-prediction.ipynb @RajeshThallam
/vertex_endpoints/optimized_tensorflow_runtime @vlasenkoalexey
/notebooks/community/ml_ops/stage2/get_started_with_visionapi_and_automl.ipynb @mansari
/notebooks/community/ml_ops/stage2/get_started_with_visionapi_and_automl.ipynb @mansari
/notebooks/community/neo4j/graph_paysim.ipynb @benofben @laeg
/notebooks/community/ml_ops/stage1/get_started_with_visionapi_and_vertex_datasets.ipynb @mansari
/notebooks/community/pipelines/google_cloud_pipeline_components_bqml_pipeline_demand_forecasting.ipynb @inardini
@@ -97,11 +97,9 @@
"source": [
"## Before you begin\n",
"\n",
"* **Prepare a VPC network**. To reduce any network overhead that might lead to unnecessary increase in overhead latency, it is best to call the ANN endpoints from your VPC via a direct [VPC Peering](https://cloud.google.com/vertex-ai/docs/general/vpc-peering) connection. The following section describes how to setup a VPC Peering connection if you don't have one. This is a one-time initial setup task. You can also reuse existing VPC network and skip this section.\n",
"* **WARNING:** The MatchingIndexEndpoint.match method (to create online queries against your deployed index) has to be executed in a Vertex AI Workbench notebook instance that is created with the following requirements:\n",
" * **In the same region as where your ANN service is deployed** (for example, if you set `REGION = \"us-central1\"` as same as the tutorial, the notebook instance has to be in `us-central1`).\n",
" * **Make sure you select the VPC network you created for ANN service** (instead of using the \"default\" one). That is, you will have to create the VPC network below and then create a new notebook instance that uses that VPC. \n",
" * If you run it in the colab or a Vertex AI Workbench notebook instance in a different VPC network or region, the gRPC API will fail to peer the network (InactiveRPCError)."
"* **Prepare a VPC network**. To reduce any network overhead that might lead to unnecessary increase in overhead latency, it is best to call the ANN endpoints from your VPC via a direct [VPC Peering](https://cloud.google.com/vertex-ai/docs/general/vpc-peering) connection. \n",
" * The following section describes how to setup a VPC Peering connection if you don't have one. \n",
" * This is a one-time initial setup task. You can also reuse existing VPC network and skip this section."
]
},
{
@@ -112,11 +110,11 @@
},
"outputs": [],
"source": [
"PROJECT_ID = \"<your_project_id>\" # @param {type:\"string\"}\n",
"PROJECT_ID = \"python-docs-samples-tests\" # @param {type:\"string\"}\n",
"\n",
"NETWORK_NAME = \"my-vpc-network\" # @param {type:\"string\"}\n",
"NETWORK_NAME = \"ann-vpc-network\" # @param {type:\"string\"}\n",
"\n",
"PEERING_RANGE_NAME = \"my-haystack-range\""
"PEERING_RANGE_NAME = \"ann-haystack-range\""
]
},
{
@@ -143,6 +141,7 @@
"! gcloud compute addresses create {PEERING_RANGE_NAME} --global --prefix-length=16 --network={NETWORK_NAME} --purpose=VPC_PEERING --project={PROJECT_ID} --description=\"peering range\"\n",
"\n",
"# Set up peering with service networking\n",
"# Your account must have the \"Compute Network Admin\" role to run the following.\n",
"! gcloud services vpc-peerings connect --service=servicenetworking.googleapis.com --network={NETWORK_NAME} --ranges={PEERING_RANGE_NAME} --project={PROJECT_ID}"
]
},
@@ -155,6 +154,20 @@
"* Authentication: Rerun the `gcloud auth login` command in the Vertex AI Workbench notebook terminal when you are logged out and need the credential again."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "d5de53b31bf1"
},
"source": [
"## Make sure the following cells are run from inside the VPC network that you created in the previous step.\n",
"\n",
"* **WARNING:** The MatchingIndexEndpoint.match method (to create online queries against your deployed index) has to be executed in a Vertex AI Workbench notebook instance that is created with the following requirements:\n",
" * **In the same region as where your ANN service is deployed** (for example, if you set `REGION = \"us-central1\"` as same as the tutorial, the notebook instance has to be in `us-central1`).\n",
" * **Make sure you select the VPC network you created for ANN service** (instead of using the \"default\" one). That is, you will have to create the VPC network below and then create a new notebook instance that uses that VPC. \n",
" * If you run it in the colab or a Vertex AI Workbench notebook instance in a different VPC network or region, \"Create Online Queries\" section will fail."
]
},
{
"cell_type": "markdown",
"metadata": {
@@ -271,7 +284,7 @@
"source": [
"import os\n",
"\n",
"PROJECT_ID = \"\"\n",
"PROJECT_ID = \"python-docs-samples-tests\"\n",
"\n",
"# Get your Google Cloud project ID from gcloud\n",
"if not os.getenv(\"IS_TESTING\"):\n",
@@ -734,6 +747,28 @@
"INDEX_RESOURCE_NAME"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "0f1a9fbecabb"
},
"outputs": [],
"source": [
"Using the resource name, you can retrieve an existing MatchingEngineIndex."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "1ddb70647d98"
},
"outputs": [],
"source": [
"tree_ah_index = aiplatform.MatchingEngineIndex(INDEX_RESOURCE_NAME)"
]
},
{
"cell_type": "markdown",
"metadata": {
@@ -742,7 +777,7 @@
"source": [
"### Create Brute Force Index (for Ground Truth)\n",
"\n",
"The brute force index uses a naive brute force method to find the nearest neighbors. This method is not fast or efficient. Hence brute force indices are not recommended for production usage. They are to be used to find the \"ground truth\" set of neighbors, so that the \"ground truth\" set can be used to measure recall of the indices being tuned for production usage. To ensure an apples to apples comparison, the `distanceMeasureType` and `featureNormType`, `dimensions` of the brute force index should match those of the production indices being tuned.\n",
"The brute force index uses a naive brute force method to find the nearest neighbors. This method is not fast or efficient. Hence brute force indices are not recommended for production usage. They are to be used to find the \"ground truth\" set of neighbors, so that the \"ground truth\" set can be used to measure recall of the indices being tuned for production usage. To ensure an apples to apples comparison, the `distanceMeasureType` and `dimensions` of the brute force index should match those of the production indices being tuned.\n",
"\n",
"Create the brute force index configuration:"
]
@@ -777,6 +812,19 @@
"INDEX_BRUTE_FORCE_RESOURCE_NAME"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "865fcad494d7"
},
"outputs": [],
"source": [
"brute_force_index = aiplatform.MatchingEngineIndex(\n",
" \"projects/1012616486416/locations/us-central1/indexes/6738176690918260736\"\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
@@ -941,7 +989,7 @@
},
"outputs": [],
"source": [
"DEPLOYED_INDEX_ID = \"tree_ah_glove_deployed\""
"DEPLOYED_INDEX_ID = f\"tree_ah_glove_deployed_{TIMESTAMP}\""
]
},
{
@@ -976,7 +1024,7 @@
},
"outputs": [],
"source": [
"DEPLOYED_BRUTE_FORCE_INDEX_ID = \"glove_brute_force_deployed\""
"DEPLOYED_BRUTE_FORCE_INDEX_ID = f\"glove_brute_force_deployed_{TIMESTAMP}\""
]
},
{
@@ -1023,344 +1071,13 @@
"outputs": [],
"source": [
"# Test query\n",
"query = [\n",
" -0.11333,\n",
" 0.48402,\n",
" 0.090771,\n",
" -0.22439,\n",
" 0.034206,\n",
" -0.55831,\n",
" 0.041849,\n",
" -0.53573,\n",
" 0.18809,\n",
" -0.58722,\n",
" 0.015313,\n",
" -0.014555,\n",
" 0.80842,\n",
" -0.038519,\n",
" 0.75348,\n",
" 0.70502,\n",
" -0.17863,\n",
" 0.3222,\n",
" 0.67575,\n",
" 0.67198,\n",
" 0.26044,\n",
" 0.4187,\n",
" -0.34122,\n",
" 0.2286,\n",
" -0.53529,\n",
" 1.2582,\n",
" -0.091543,\n",
" 0.19716,\n",
" -0.037454,\n",
" -0.3336,\n",
" 0.31399,\n",
" 0.36488,\n",
" 0.71263,\n",
" 0.1307,\n",
" -0.24654,\n",
" -0.52445,\n",
" -0.036091,\n",
" 0.55068,\n",
" 0.10017,\n",
" 0.48095,\n",
" 0.71104,\n",
" -0.053462,\n",
" 0.22325,\n",
" 0.30917,\n",
" -0.39926,\n",
" 0.036634,\n",
" -0.35431,\n",
" -0.42795,\n",
" 0.46444,\n",
" 0.25586,\n",
" 0.68257,\n",
" -0.20821,\n",
" 0.38433,\n",
" 0.055773,\n",
" -0.2539,\n",
" -0.20804,\n",
" 0.52522,\n",
" -0.11399,\n",
" -0.3253,\n",
" -0.44104,\n",
" 0.17528,\n",
" 0.62255,\n",
" 0.50237,\n",
" -0.7607,\n",
" -0.071786,\n",
" 0.0080131,\n",
" -0.13286,\n",
" 0.50097,\n",
" 0.18824,\n",
" -0.54722,\n",
" -0.42664,\n",
" 0.4292,\n",
" 0.14877,\n",
" -0.0072514,\n",
" -0.16484,\n",
" -0.059798,\n",
" 0.9895,\n",
" -0.61738,\n",
" 0.054169,\n",
" 0.48424,\n",
" -0.35084,\n",
" -0.27053,\n",
" 0.37829,\n",
" 0.11503,\n",
" -0.39613,\n",
" 0.24266,\n",
" 0.39147,\n",
" -0.075256,\n",
" 0.65093,\n",
" -0.20822,\n",
" -0.17456,\n",
" 0.53571,\n",
" -0.16537,\n",
" 0.13582,\n",
" -0.56016,\n",
" 0.016964,\n",
" 0.1277,\n",
" 0.94071,\n",
" -0.22608,\n",
" -0.021106,\n",
"]\n",
"\n",
"response = my_index_endpoint.match(\n",
" deployed_index_id=DEPLOYED_INDEX_ID, queries=[query], num_neighbors=NUM_NEIGHBOURS\n",
" deployed_index_id=DEPLOYED_INDEX_ID, queries=test[:1], num_neighbors=NUM_NEIGHBOURS\n",
")\n",
"\n",
"response"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "_mNwdU9_B_Ez"
},
"source": [
"### Batch Query\n",
"\n",
"You can run multiple queries in a single match call:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "A0XL0PJ1GoM9"
},
"outputs": [],
"source": [
"# Test query\n",
"queries = [\n",
" [\n",
" -0.11333,\n",
" 0.48402,\n",
" 0.090771,\n",
" -0.22439,\n",
" 0.034206,\n",
" -0.55831,\n",
" 0.041849,\n",
" -0.53573,\n",
" 0.18809,\n",
" -0.58722,\n",
" 0.015313,\n",
" -0.014555,\n",
" 0.80842,\n",
" -0.038519,\n",
" 0.75348,\n",
" 0.70502,\n",
" -0.17863,\n",
" 0.3222,\n",
" 0.67575,\n",
" 0.67198,\n",
" 0.26044,\n",
" 0.4187,\n",
" -0.34122,\n",
" 0.2286,\n",
" -0.53529,\n",
" 1.2582,\n",
" -0.091543,\n",
" 0.19716,\n",
" -0.037454,\n",
" -0.3336,\n",
" 0.31399,\n",
" 0.36488,\n",
" 0.71263,\n",
" 0.1307,\n",
" -0.24654,\n",
" -0.52445,\n",
" -0.036091,\n",
" 0.55068,\n",
" 0.10017,\n",
" 0.48095,\n",
" 0.71104,\n",
" -0.053462,\n",
" 0.22325,\n",
" 0.30917,\n",
" -0.39926,\n",
" 0.036634,\n",
" -0.35431,\n",
" -0.42795,\n",
" 0.46444,\n",
" 0.25586,\n",
" 0.68257,\n",
" -0.20821,\n",
" 0.38433,\n",
" 0.055773,\n",
" -0.2539,\n",
" -0.20804,\n",
" 0.52522,\n",
" -0.11399,\n",
" -0.3253,\n",
" -0.44104,\n",
" 0.17528,\n",
" 0.62255,\n",
" 0.50237,\n",
" -0.7607,\n",
" -0.071786,\n",
" 0.0080131,\n",
" -0.13286,\n",
" 0.50097,\n",
" 0.18824,\n",
" -0.54722,\n",
" -0.42664,\n",
" 0.4292,\n",
" 0.14877,\n",
" -0.0072514,\n",
" -0.16484,\n",
" -0.059798,\n",
" 0.9895,\n",
" -0.61738,\n",
" 0.054169,\n",
" 0.48424,\n",
" -0.35084,\n",
" -0.27053,\n",
" 0.37829,\n",
" 0.11503,\n",
" -0.39613,\n",
" 0.24266,\n",
" 0.39147,\n",
" -0.075256,\n",
" 0.65093,\n",
" -0.20822,\n",
" -0.17456,\n",
" 0.53571,\n",
" -0.16537,\n",
" 0.13582,\n",
" -0.56016,\n",
" 0.016964,\n",
" 0.1277,\n",
" 0.94071,\n",
" -0.22608,\n",
" -0.021106,\n",
" ],\n",
" [\n",
" -0.99544,\n",
" -2.3651,\n",
" -0.24332,\n",
" -1.0321,\n",
" 0.42052,\n",
" -1.1817,\n",
" -0.16451,\n",
" -1.683,\n",
" 0.49673,\n",
" -0.27258,\n",
" -0.025397,\n",
" 0.34188,\n",
" 1.5523,\n",
" 1.3532,\n",
" 0.33297,\n",
" -0.0056677,\n",
" -0.76525,\n",
" 0.49587,\n",
" 1.2211,\n",
" 0.83394,\n",
" -0.20031,\n",
" -0.59657,\n",
" 0.38485,\n",
" -0.23487,\n",
" -1.0725,\n",
" 0.95856,\n",
" 0.16161,\n",
" -1.2496,\n",
" 1.6751,\n",
" 0.73899,\n",
" 0.051347,\n",
" -0.42702,\n",
" 0.16257,\n",
" -0.16772,\n",
" 0.40146,\n",
" 0.29837,\n",
" 0.96204,\n",
" -0.36232,\n",
" -0.47848,\n",
" 0.78278,\n",
" 0.14834,\n",
" 1.3407,\n",
" 0.47834,\n",
" -0.39083,\n",
" -1.037,\n",
" -0.24643,\n",
" -0.75841,\n",
" 0.7669,\n",
" -0.37363,\n",
" 0.52741,\n",
" 0.018563,\n",
" -0.51301,\n",
" 0.97674,\n",
" 0.55232,\n",
" 1.1584,\n",
" 0.73715,\n",
" 1.3055,\n",
" -0.44743,\n",
" -0.15961,\n",
" 0.85006,\n",
" -0.34092,\n",
" -0.67667,\n",
" 0.2317,\n",
" 1.5582,\n",
" 1.2308,\n",
" -0.62213,\n",
" -0.032801,\n",
" 0.1206,\n",
" -0.25899,\n",
" -0.02756,\n",
" -0.52814,\n",
" -0.93523,\n",
" 0.58434,\n",
" -0.24799,\n",
" 0.37692,\n",
" 0.86527,\n",
" 0.069626,\n",
" 1.3096,\n",
" 0.29975,\n",
" -1.3651,\n",
" -0.32048,\n",
" -0.13741,\n",
" 0.33329,\n",
" -1.9113,\n",
" -0.60222,\n",
" -0.23921,\n",
" 0.12664,\n",
" -0.47961,\n",
" -0.89531,\n",
" 0.62054,\n",
" 0.40869,\n",
" -0.08503,\n",
" 0.6413,\n",
" -0.84044,\n",
" -0.74325,\n",
" -0.19426,\n",
" 0.098722,\n",
" 0.32648,\n",
" -0.67621,\n",
" -0.62692,\n",
" ],\n",
"]"
]
},
{
"cell_type": "markdown",
"metadata": {
@@ -1369,7 +1086,7 @@
"source": [
"### Compute Recall\n",
"\n",
"Use deployed brute force Index as the ground truth to calculate the recall of ANN Index:"
"Use the deployed brute force Index as the ground truth to calculate the recall of ANN Index. Note that you can run multiple queries in a single match call."
]
},
{
@@ -1402,18 +1119,20 @@
"outputs": [],
"source": [
"# Calculate recall by determining how many neighbors were correctly retrieved as compared to the brute-force option.\n",
"correct_neighbors = 0\n",
"recalled_neighbors = 0\n",
"for tree_ah_neighbors, brute_force_neighbors in zip(\n",
" tree_ah_response_test, brute_force_response_test\n",
"):\n",
" tree_ah_neighbor_ids = [neighbor.id for neighbor in tree_ah_neighbors]\n",
" brute_force_neighbor_ids = [neighbor.id for neighbor in brute_force_neighbors]\n",
"\n",
" correct_neighbors += len(\n",
" recalled_neighbors += len(\n",
" set(tree_ah_neighbor_ids).intersection(brute_force_neighbor_ids)\n",
" )\n",
"\n",
"recall = correct_neighbors / (len(test) * NUM_NEIGHBOURS)\n",
"recall = recalled_neighbors / len(\n",
" [neighbor for neighbors in brute_force_response_test for neighbor in neighbors]\n",
")\n",
"\n",
"print(\"Recall: {}\".format(recall))"
]
@@ -88,6 +88,17 @@ The steps performed include:
- Cancel a data labeling job.
```
[Get Started with Vision API and Vertex AI Datasets](get_started_with_visionapi_and_vertex_datasets.ipynb)
```
The steps performed include:
- Using Vision API to perform Optical Character Recognition (OCR) to extract text from PDF files.
- Processing the results and saving them to text files.
- Generating a Vertex AI Dataset import file.
- Creating a new unlabelled text entity extraction Vertex AI Dataset resource in Vertex AI.
```
### E2E Stage Example
[Stage 1: Data Management](mlops_data_management.ipynb)
@@ -0,0 +1,994 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "copyright"
},
"outputs": [],
"source": [
"# 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",
"# You may obtain a copy of the License at\n",
"#\n",
"# https://www.apache.org/licenses/LICENSE-2.0\n",
"#\n",
"# Unless required by applicable law or agreed to in writing, software\n",
"# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
"# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
"# See the License for the specific language governing permissions and\n",
"# limitations under the License."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "4JIDiHvGasba"
},
"source": [
"This notebook was contributed by [Mohammad Al-Ansari](https://github.com/Mansari)."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "2xDiUNIZINWp"
},
"source": [
"# E2E ML on GCP: MLOps stage 1 : data management: create an unlabelled Vertex AI AutoML text entity extraction dataset from PDFs using Vision API\n",
"\n",
"<table align=\"left\">\n",
" <td>\n",
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage1/get_started_with_visionapi_and_vertex_datasets.ipynb\">\n",
" <img src=\"https://cloud.google.com/ml-engine/images/colab-logo-32px.png\" alt=\"Colab logo\"> Run in Colab\n",
" </a>\n",
" </td>\n",
" <td>\n",
" <a href=\"https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage1/get_started_with_visionapi_and_vertex_datasets.ipynb\">\n",
" <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>\n",
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://raw.githubusercontent.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage1/get_started_with_visionapi_and_vertex_datasets.ipynb\">\n",
" <img src=\"https://lh3.googleusercontent.com/UiNooY4LUgW_oTvpsNhPpQzsstV5W8F7rYgxgGBD85cWJoLmrOzhVs_ksK_vgx40SHs7jCqkTkCk=e14-rj-sc0xffffff-h130-w32\" alt=\"Vertex AI logo\">\n",
" Open in Vertex AI Workbench\n",
" </a>\n",
" </td>\n",
"</table>\n",
"<br/><br/><br/>"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "H0alLPo_A-LK"
},
"source": [
"## Overview\n",
"\n",
"This notebook will create an unlabelled `Vertex AI AutoML` text entity extraction dataset based on a collection of PDF files stored in a Cloud Storage bucket. \n",
"\n",
"The notebook can be modified to create different types of text datasets including sentiment analysis and classification."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "W4IBLTKOA5nl"
},
"source": [
"### Dataset\n",
"\n",
"The dataset used for this tutorial is the [Patent PDF Samples with Extracted Structured Data](https://console.cloud.google.com/marketplace/product/global-patents/labeled-patents) from Google Public Data Sets. \n",
"\n",
"This dataset includes data extracted from over 300 patent documents issued in the US and EU. The dataset includes links to Cloud Storage blobs for the first page of each patent, in addition to a number of extracted entities. \n",
"\n",
"The data is published as a [public dataset](https://cloud.google.com/bigquery/public-data) on `BigQuery`."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "3f8c2f702ccd"
},
"source": [
"### Objective\n",
"\n",
"In this tutorial, you learn to use `Vision API` to extract text from PDF files stored on a Cloud Storage bucket. You will then process the results and create an unlabelled `Vertex AI Dataset`, compatible with `AutoML`, for text entity extraction.\n",
"\n",
"You can then either use Google Cloud console to annotate / label the dataset, or create a labelling job as demonstrated in [this notebook](https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage1/get_started_with_data_labeling.ipynb).\n",
"\n",
"This tutorial uses the following Google Cloud services:\n",
"\n",
"- `Vision AI`\n",
"- `Vertex AI AutoML`\n",
"\n",
"The steps performed include:\n",
"\n",
"1. Using `Vision API` to perform Optical Character Recognition (OCR) to extract text from PDF files.\n",
"2. Processing the results and saving them to text files.\n",
"3. Generating a `Vertex AI Dataset` import file.\n",
"4. Creating a new unlabelled text entity extraction `Vertex AI Dataset` resource in `Vertex AI`."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "CgLDJ419LPJs"
},
"source": [
"### Costs\n",
"\n",
"This tutorial uses billable components of Google Cloud:\n",
"\n",
"* Vision API\n",
"* Vertex AI\n",
"* Cloud Storage\n",
"\n",
"Learn about [Vertex AI\n",
"pricing](https://cloud.google.com/vertex-ai/pricing), [Vision API pricing](https://cloud.google.com/vision/pricing), [Cloud Storage\n",
"pricing](https://cloud.google.com/storage/pricing), and use the [Pricing\n",
"Calculator](https://cloud.google.com/products/calculator/)\n",
"to generate a cost estimate based on your projected usage."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "va2g7m9wLTjA"
},
"source": [
"### Set up your local development environment\n",
"\n",
"If you are using Colab or Vertex AI Workbench Notebooks, your environment already meets all the requirements to run this notebook. You can skip this step.\n",
"\n",
"Otherwise, make sure your environment meets this notebook's requirements. You need the following:\n",
"\n",
"- The Vision API SDK\n",
"- The Vertex AI SDK\n",
"- The Cloud Storage SDK\n",
"- Git\n",
"- Python 3\n",
"- virtualenv\n",
"- Jupyter notebook running in a virtual environment with Python 3\n",
"\n",
"The Cloud Storage guide to [Setting up a Python development environment](https://cloud.google.com/python/setup) and the [Jupyter installation guide](https://jupyter.org/install) provide detailed instructions for meeting these requirements. The following steps provide a condensed set of instructions:\n",
"\n",
"1. [Install and initialize the SDKs](https://cloud.google.com/sdk/docs/).\n",
"\n",
"2. [Install Python 3](https://cloud.google.com/python/setup#installing_python).\n",
"\n",
"3. [Install virtualenv](https://cloud.google.com/python/setup#installing_and_using_virtualenv) and create a virtual environment that uses Python 3. Activate the virtual environment.\n",
"\n",
"4. To install Jupyter, run `pip3 install jupyter` on the command-line in a terminal shell.\n",
"\n",
"5. To launch Jupyter, run `jupyter notebook` on the command-line in a terminal shell.\n",
"\n",
"6. Open this notebook in the Jupyter Notebook Dashboard.\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "X2tZAmugAe6h"
},
"source": [
"## Installation\n",
"\n",
"Install the packages required for executing this notebook. You can ignore errors for the `pip` dependecy resolver as they do not impact this notebook."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "BQOsJ1hZAZu0"
},
"outputs": [],
"source": [
"import os\n",
"\n",
"# The Vertex AI Workbench Notebook product has specific requirements\n",
"IS_WORKBENCH_NOTEBOOK = os.getenv(\"DL_ANACONDA_HOME\")\n",
"IS_USER_MANAGED_WORKBENCH_NOTEBOOK = os.path.exists(\n",
" \"/opt/deeplearning/metadata/env_version\"\n",
")\n",
"\n",
"# Vertex AI Notebook requires dependencies to be installed with '--user'\n",
"USER_FLAG = \"\"\n",
"if IS_WORKBENCH_NOTEBOOK:\n",
" USER_FLAG = \"--user\"\n",
"\n",
"! pip3 install --upgrade google-cloud-storage google-cloud-vision google-cloud-aiplatform $USER_FLAG -q"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "yzvvcmCuAon3"
},
"source": [
"### Restart the kernel\n",
"\n",
"Once you've installed the additional packages, you need to restart the notebook kernel so it can find the packages."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "6qEonzbuAoI_"
},
"outputs": [],
"source": [
"import os\n",
"\n",
"if not os.getenv(\"IS_TESTING\"):\n",
" # Automatically restart kernel after installs\n",
" import IPython\n",
"\n",
" app = IPython.Application.instance()\n",
" app.kernel.do_shutdown(True)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "pGbbyN7rAuRM"
},
"source": [
"## Before you begin\n",
"\n",
"### GPU runtime\n",
"\n",
"*Make sure you're running this notebook in a GPU runtime if you have that option. In Colab, select* **Runtime > Change Runtime Type > GPU**\n",
"\n",
"### Set up your Google Cloud project\n",
"\n",
"**The following steps are required, regardless of your notebook environment.**\n",
"\n",
"1. [Select or create a Google Cloud project](https://console.cloud.google.com/cloud-resource-manager). When you first create an account, you get a $300 free credit towards your compute/storage costs.\n",
"\n",
"2. [Make sure that billing is enabled for your project.](https://cloud.google.com/billing/docs/how-to/modify-project)\n",
"\n",
"3. [Enable the following APIs: Vision API, Vertex AI APIs, Compute Engine APIs, and Cloud Storage.](https://console.cloud.google.com/flows/enableapi?apiid=vision.googleapis.com,aiplatform.googleapis.com,compute_component,storage-component.googleapis.com)\n",
"\n",
"4. If you are running this notebook locally, you will need to install the [Cloud SDK]((https://cloud.google.com/sdk)).\n",
"\n",
"5. Enter your project ID in the cell below. Then run the cell to make sure the\n",
"Cloud SDK uses the right project for all the commands in this notebook.\n",
"\n",
"**Note**: Jupyter runs lines prefixed with `!` as shell commands, and it interpolates Python variables prefixed with `$`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "AE97adtnAzrr"
},
"outputs": [],
"source": [
"PROJECT_ID = \"[your-project-id]\" # @param {type:\"string\"}"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "nWlzLu5ELxWd"
},
"outputs": [],
"source": [
"if PROJECT_ID == \"\" or PROJECT_ID is None or PROJECT_ID == \"[your-project-id]\":\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,
"metadata": {
"id": "GB5b27r0LxqE"
},
"outputs": [],
"source": [
"! gcloud config set project $PROJECT_ID"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "pMJdU1K5xG7D"
},
"source": [
"### Regions\n",
"\n",
"#### Vision AI\n",
"\n",
"You can now specify continent-level data storage and Optical Character Regonition (OCR) processing by setting the `VISION_AI_REGION` variable. You can select one of the following options:\n",
"\n",
"* USA country only: `us`\n",
"* The European Union: `eu`\n",
"\n",
"Learn more about [Vision AI regions for OCR](https://cloud.google.com/vision/docs/pdf#regionalization)\n",
"\n",
"#### Vertex AI\n",
"\n",
"You can also change the `VERTEX_AI_REGION` variable, which is used for operations throughout the rest of this notebook. Below are regions supported for Vertex AI. We recommend that you choose the region closest to you.\n",
"\n",
"- Americas: `us-central1`\n",
"- Europe: `europe-west4`\n",
"- Asia Pacific: `asia-east1`\n",
"\n",
"You may not use a multi-regional bucket for training with Vertex AI. Not all regions provide support for all Vertex AI services.\n",
"\n",
"Learn more about [Vertex AI regions](https://cloud.google.com/vertex-ai/docs/general/locations)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "5EhEAOK5xIKc"
},
"outputs": [],
"source": [
"VISION_AI_REGION = \"[your-region]\" # @param {type: \"string\"}\n",
"\n",
"if VISION_AI_REGION == \"[your-region]\":\n",
" VISION_AI_REGION = \"us\"\n",
"\n",
"VERTEX_AI_REGION = \"[your-region]\" # @param {type: \"string\"}\n",
"\n",
"if VERTEX_AI_REGION == \"[your-region]\":\n",
" VERTEX_AI_REGION = \"us-central1\""
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "xkgvWoXkxM1r"
},
"source": [
"### Timestamp\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 timestamp for each instance session, and append onto the name of resources which will be created in this tutorial."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "gr0HTpQZxNy4"
},
"outputs": [],
"source": [
"from datetime import datetime\n",
"\n",
"TIMESTAMP = datetime.now().strftime(\"%Y%m%d%H%M%S\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "AA-ns5CcBA9U"
},
"source": [
"### Vertex AI dataset import schema\n",
"\n",
"This constant tells Vertex AI the schema for importing the dataset. In this tutorial you are going to use the value for text extraction, but you can also change it to any of the values below for other use cases:\n",
"\n",
"- \n",
"`aiplatform.schema.dataset.ioformat.text.single_label_classification`\n",
"\n",
"- \n",
"`aiplatform.schema.dataset.ioformat.text.multi_label_classification`\n",
"\n",
"- \n",
"`aiplatform.schema.dataset.ioformat.text.extraction`\n",
"\n",
"- \n",
"`aiplatform.schema.dataset.ioformat.text.sentiment`\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "jnOb6Pp-4w5P"
},
"outputs": [],
"source": [
"from google.cloud import aiplatform\n",
"\n",
"DATASET_IMPORT_SCHEMA = aiplatform.schema.dataset.ioformat.text.extraction"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "ekbg-G7UA-bK"
},
"source": [
"### Authenticate your Google Cloud account\n",
"\n",
"**If you are using Vertex AI Workbench**, your environment is already authenticated. Skip this step. If you receive errors still, you may have to grant the service account that is your Workbench notebook is running under access to the services listed below.\n",
"\n",
"**If you are using Colab**, run the cell below and follow the instructions when prompted to authenticate your account via oAuth.\n",
"\n",
"**Otherwise**, follow these steps:\n",
"\n",
"In the Cloud Console, go to the [Create service account key](https://console.cloud.google.com/apis/credentials/serviceaccountkey) page.\n",
"\n",
"**Click Create service account**.\n",
"\n",
"In the **Service account name** field, enter a name, and click **Create**.\n",
"\n",
"In the **Grant this service account access to project** section, click the Role drop-down list. Type \"Vertex\" into the filter box, and select **Vertex AI Administrator**. Type \"Storage Object Admin\" into the filter box, and select **Storage Object Admin**.\n",
"\n",
"Click Create. A JSON file that contains your key downloads to your local environment.\n",
"\n",
"Enter the path to your service account key as the GOOGLE_APPLICATION_CREDENTIALS variable in the cell below and run the cell."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "lCRrULxKBAfa"
},
"outputs": [],
"source": [
"# If you are running this notebook in Colab, run this cell and follow the\n",
"# instructions to authenticate your GCP account. This provides access to your\n",
"# Cloud Storage bucket and lets you submit training jobs and prediction\n",
"# requests.\n",
"\n",
"import os\n",
"import sys\n",
"\n",
"# If on Vertex AI Workbench, then don't execute this code\n",
"IS_COLAB = \"google.colab\" in sys.modules\n",
"if not os.path.exists(\"/opt/deeplearning/metadata/env_version\") and not os.getenv(\n",
" \"DL_ANACONDA_HOME\"\n",
"):\n",
" if \"google.colab\" in sys.modules:\n",
" from google.colab import auth as google_auth\n",
"\n",
" google_auth.authenticate_user()\n",
"\n",
" # If you are running this notebook locally, replace the string below with the\n",
" # path to your service account key and run this cell to authenticate your GCP\n",
" # account.\n",
" elif not os.getenv(\"IS_TESTING\"):\n",
" %env GOOGLE_APPLICATION_CREDENTIALS ''"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "rHB6fbonMMbI"
},
"source": [
"### Create a Cloud Storage bucket\n",
"\n",
"**The following steps are required, regardless of your notebook environment.**\n",
"\n",
"When you initialize the Vertex AI SDK for Python, you specify a Cloud Storage staging bucket. The staging bucket is where all the data associated with your dataset and model resources are retained across sessions. This bucket will be also used to store the output of the Vision API SDK PDF-to-text conversion process.\n",
"\n",
"Set the name of your Cloud Storage bucket below. Bucket names must be globally unique across all Google Cloud projects, including those outside of your organization."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "ZSM5j0nfMOVK"
},
"outputs": [],
"source": [
"BUCKET_NAME = \"[your-bucket-name]\" # @param {type:\"string\"}\n",
"BUCKET_URI = f\"gs://{BUCKET_NAME}\""
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "i6H2iQX2MP-s"
},
"outputs": [],
"source": [
"if BUCKET_NAME == \"\" or BUCKET_NAME is None or BUCKET_NAME == \"[your-bucket-name]\":\n",
" BUCKET_NAME = PROJECT_ID + \"aip-\" + TIMESTAMP\n",
" BUCKET_URI = \"gs://\" + BUCKET_NAME"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "AOsnYE5cMQX4"
},
"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": "33RgSjhyMR6C"
},
"outputs": [],
"source": [
"! gsutil mb -l $VERTEX_AI_REGION -p $PROJECT_ID $BUCKET_URI"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "UpKfi0VfMTwe"
},
"source": [
"Finally, validate access to your Cloud Storage bucket by examining its contents:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "G9dMjMnkMVNt"
},
"outputs": [],
"source": [
"! gsutil ls -al $BUCKET_URI"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "k2qH7YCI0vnG"
},
"source": [
"### Set up variables\n",
"\n",
"Next, set up some variables used throughout the tutorial.\n",
"\n",
"### Import libraries and define constants"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "TB5-_2Xh01NH"
},
"outputs": [],
"source": [
"import os\n",
"\n",
"from google.cloud import aiplatform, storage, vision"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "-v7gY_KABIn8"
},
"source": [
"### Initialize Vision API SDK for Python\n",
"\n",
"Initialize the `Vision AI` SDK for Python for your project and region."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "DRbf--kWBLpx"
},
"outputs": [],
"source": [
"vision_client_options = {\n",
" \"quota_project_id\": PROJECT_ID,\n",
" \"api_endpoint\": f\"{VISION_AI_REGION}-vision.googleapis.com\",\n",
"}\n",
"vision_client = vision.ImageAnnotatorClient(client_options=vision_client_options)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "CA4nNVbBZ25d"
},
"source": [
"### Initialize Vertex AI SDK for Python\n",
"\n",
"Initialize the `Vertex AI` SDK for Python for your project, region and corresponding bucket."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "awWpNW1vZ6uV"
},
"outputs": [],
"source": [
"aiplatform.init(\n",
" project=PROJECT_ID, location=VERTEX_AI_REGION, staging_bucket=BUCKET_URI\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "debBBljMDqkM"
},
"source": [
"### Initialize Cloud Storage SDK for Python\n",
"\n",
"Initialize the `Cloud Storage` SDK for Python for your project."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "ZtzmI9tpDr4e"
},
"outputs": [],
"source": [
"storage_client = storage.Client(project=PROJECT_ID)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "mvD0BxVXMtJe"
},
"source": [
"## Tutorial\n",
"\n",
"Now you are ready to start creating an unlabelled `Vertex AI Dataset` text entity extraction dataset from PDF files."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "EurEFM3GBap9"
},
"source": [
"### Convert PDF files to text using Vision API\n",
"\n",
"First, you make a `Vision API` request to OCR to text the PDFs from the Patent samples stored in the Cloud Storage bucket.\n",
"\n",
"*Note:* `Visions API` only allows batches of 100 document submissions at a time."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "uXVPOvjTBeK3"
},
"outputs": [],
"source": [
"ORIGIN_BUCKET_NAME = \"gcs-public-data--labeled-patents\"\n",
"# You can add a path if needed\n",
"ORIGIN_BUCKET_PATH = \"\"\n",
"\n",
"DESTINATION_BUCKET_NAME = BUCKET_NAME\n",
"DESTINATION_BUCKET_PATH = \"ocr-output\"\n",
"\n",
"gcs_destination_uri = f\"gs://{DESTINATION_BUCKET_NAME}/{DESTINATION_BUCKET_PATH}\"\n",
"\n",
"# Specify the feature for the Vision API processor\n",
"feature = vision.Feature(type_=vision.Feature.Type.DOCUMENT_TEXT_DETECTION)\n",
"\n",
"# Retrieve a list of all files in the bucket and path\n",
"blobs = storage_client.list_blobs(\n",
" ORIGIN_BUCKET_NAME, prefix=ORIGIN_BUCKET_PATH, delimiter=\"/\"\n",
")\n",
"\n",
"# Create a collection of requests. The SDK requires a separate request per each\n",
"# file that we want to extract text from\n",
"async_requests = []\n",
"\n",
"# Visions API only supports processing up to 100 documents at a time\n",
"# so we will process the first 100 elements only\n",
"sliced_blob_list = list(blobs)[:100]\n",
"\n",
"# Loop through the source bucket and create a request for each file there\n",
"for blob in sliced_blob_list:\n",
" # Build input_config\n",
" # Ensure we are only processing PDF files\n",
" if blob.name.endswith(\".pdf\"):\n",
" gcs_source = vision.GcsSource(uri=f\"gs://{ORIGIN_BUCKET_NAME}/{blob.name}\")\n",
" input_config = vision.InputConfig(\n",
" gcs_source=gcs_source, mime_type=\"application/pdf\"\n",
" )\n",
"\n",
" # Build output config\n",
" # Get file name\n",
" file_name = os.path.splitext(os.path.basename(blob.name))[0]\n",
" gcs_destination = vision.GcsDestination(\n",
" uri=f\"{gcs_destination_uri}/{file_name}-\"\n",
" )\n",
" output_config = vision.OutputConfig(gcs_destination=gcs_destination)\n",
"\n",
" # Build request object and add to the collection\n",
" async_request = vision.AsyncAnnotateFileRequest(\n",
" features=[feature], input_config=input_config, output_config=output_config\n",
" )\n",
"\n",
" async_requests.append(async_request)\n",
"\n",
"print(f\"Created {len(async_requests)} requests\")\n",
"\n",
"# Submit the batch OCR job\n",
"\n",
"operation = vision_client.async_batch_annotate_files(requests=async_requests)\n",
"print(\"Submitting the batch OCR job\")\n",
"\n",
"print(\"Waiting for the operation to finish... this will take a short while\")\n",
"\n",
"response = operation.result(timeout=420)\n",
"\n",
"print(\"Completed!\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "7b15473e1937"
},
"source": [
"#### Quick peek at extracted annotated JSON files\n",
"\n",
"Next, you take a peek at the contents of one of the extracted JSON annotated files."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "4366442c1373"
},
"outputs": [],
"source": [
"json_files = ! gsutil ls {gcs_destination_uri}\n",
"\n",
"example = json_files[0]\n",
"! gsutil cat {example} | head -n 1"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "QWmeHWPIHako"
},
"source": [
"### Process results and build the import file\n",
"\n",
"The `Vision API` output is in JSON format, and contains detailed text extraction data. You only need the full text output, so you will processs the JSON results, extract the text output, and save it in new text files to be used later in the tutorial."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "WDLtiejKHug6"
},
"outputs": [],
"source": [
"import json\n",
"\n",
"print(\"Extracting text from Vision API output and saving it to text files\")\n",
"\n",
"ocr_blobs = storage_client.list_blobs(\n",
" DESTINATION_BUCKET_NAME, prefix=DESTINATION_BUCKET_PATH\n",
")\n",
"\n",
"output_bucket = storage_client.bucket(DESTINATION_BUCKET_NAME)\n",
"\n",
"# begin building the import file content\n",
"import_file_entries = []\n",
"\n",
"for ocr_blob in ocr_blobs:\n",
" # Only process .json files, in case we previously processed files and had .txt files\n",
" if ocr_blob.name.endswith(\".json\"):\n",
" print(f\"Extracting text from {ocr_blob.name}\")\n",
" # read each blob into a stream\n",
" contents = ocr_blob.download_as_string()\n",
" # load as JSON\n",
" json_object = json.loads(contents)\n",
" # extract text\n",
" full_text = \"\"\n",
" for response in json_object[\"responses\"]:\n",
" if response[\"fullTextAnnotation\"]:\n",
" full_text += response[\"fullTextAnnotation\"][\"text\"] + \"\\r\\n\"\n",
"\n",
" # save as a blob\n",
" output_blob_name = f\"{ocr_blob.name}.txt\"\n",
" import_file_blob = output_bucket.blob(output_blob_name)\n",
" import_file_blob.upload_from_string(full_text)\n",
"\n",
" # create import file listing\n",
" import_file_entry = {\n",
" \"textGcsUri\": f\"gs://{DESTINATION_BUCKET_NAME}/{output_blob_name}\"\n",
" }\n",
"\n",
" import_file_entries.append(import_file_entry)\n",
"\n",
"print(\"Extraction completed!\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "0a5aae0eab44"
},
"source": [
"#### Quick peek at extracted text files\n",
"\n",
"Next, you take a peek at the contents of one of the extracted text files."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "76ce5f57b1ae"
},
"outputs": [],
"source": [
"example = import_file_entries[0][\"textGcsUri\"]\n",
"\n",
"! gsutil cat {example}"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "hqTLS_AmLWQP"
},
"source": [
"### Generate and save import file to be used in `Vertex AI Dataset` resource\n",
"\n",
"You will now build the import file that will be used to create the `Vertex AI Dataset` resource."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "_xFvOdQ_LWne"
},
"outputs": [],
"source": [
"IMPORT_FILE_PATH = \"import_file\"\n",
"\n",
"# Convert import file entries to JSON Lines format\n",
"import_file_content = \"\"\n",
"for entry in import_file_entries:\n",
" import_file_content += json.dumps(entry) + \"\\n\"\n",
"\n",
"print(f\"Created import file based on {len(import_file_entries)} annotations\")\n",
"\n",
"# Upload content to GCS to be used in our next step\n",
"gcs_annotation_file_name = f\"{IMPORT_FILE_PATH}/import_file_{TIMESTAMP}.jsonl\"\n",
"import_file_blob = output_bucket.blob(gcs_annotation_file_name)\n",
"import_file_blob.upload_from_string(import_file_content)\n",
"\n",
"print(f\"Uploaded import file to {output_bucket.name}/{gcs_annotation_file_name}\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "6dVjFftOaKdw"
},
"source": [
"### Create an unlabelled `Vertex AI Dataset` resource\n",
"\n",
"Next, you create the `Dataset` resource using the `create` method for the `TextDataset` class, which takes the following parameters:\n",
"\n",
"- `display_name`: The human readable name for the `Dataset` resource.\n",
"- `gcs_source`: A list of one or more dataset index files to import the data items into the `Dataset` resource.\n",
"- `import_schema_uri`: The data labeling schema for the data items.\n",
"\n",
"This operation may take ten to twenty minutes."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "ciM9HLGCaOTJ"
},
"outputs": [],
"source": [
"print(\"Creating dataset ...\")\n",
"\n",
"dataset = aiplatform.TextDataset.create(\n",
" display_name=\"Text Dataset \" + TIMESTAMP,\n",
" gcs_source=[f\"gs://{output_bucket.name}/{gcs_annotation_file_name}\"],\n",
" import_schema_uri=DATASET_IMPORT_SCHEMA,\n",
")\n",
"\n",
"print(\"Completed!\")\n",
"\n",
"print(dataset.resource_name)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "2vagHf5T6Jd4"
},
"source": [
"**Congratulations, your dataset is now ready for annotations!**\n",
"\n",
"You have two options:\n",
"\n",
"* Use Google Cloud Console to manually annotate the dataset in `Vertex AI`. Checkout [this link](https://cloud.google.com/vertex-ai/docs/datasets/label-using-console#entity-extraction) for more details on how to do so.\n",
"* Create a labelling job to request data labelling. Check out [this link](https://cloud.google.com/vertex-ai/docs/datasets/data-labeling-job) and [this notebook](https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage1/get_started_with_data_labeling.ipynb) for more details and examples.\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "cleanup:migration,new"
},
"source": [
"# Cleaning up\n",
"\n",
"To clean up all GCP resources used in this project, you can [delete the GCP\n",
"project](https://cloud.google.com/resource-manager/docs/creating-managing-projects#shutting_down_projects) you used for the tutorial.\n",
"\n",
"Otherwise, you can delete the individual resources you created in this tutorial.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "aoJ18d8Y_jAy"
},
"outputs": [],
"source": [
"# Set this to true only if you'd like to delete your bucket\n",
"delete_bucket = False\n",
"\n",
"# Delete the dataset using the Vertex AI fully qualified identifier for the dataset\n",
"dataset.delete()\n",
"\n",
"# Delete the bucket created\n",
"if delete_bucket or os.getenv(\"IS_TESTING\"):\n",
" ! gsutil rm -r $BUCKET_URI"
]
}
],
"metadata": {
"accelerator": "GPU",
"colab": {
"collapsed_sections": [],
"name": "get_started_with_visionapi_and_vertex_datasets.ipynb",
"toc_visible": true
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
+24 -6
View File
@@ -35,18 +35,36 @@ The second stage in MLOps is experimenting in developing one or more baseline mo
### Get Started
[Get Started with Vertex Experiments and Vertex ML Metadata](get_started_vertex_experiments.ipynb)
[Get Started with Logging](get_started_with_logging.ipynb)
```
The steps performed include:
- Use Python logging to log training configuration/results locally.
- Use Google Cloud Logging to log training configuration/results in cloud storage.
- Create a Vertex AI `Experiment` resource.
- Instantiate an experiment run.
- Log parameters for the run.
- Log metrics for the run.
- Display the logged experiment run.
```
[Get Started with Vertex Experiments and Vertex ML Metadata](get_started_vertex_experiments.ipynb)
```
The steps performed include:
- Local (notebook) Training
- Create an experiment
- Create a first run in the experiment
- Log parameters and metrics
- Create artifact lineage
- Visualize the experiment results
- Execute a second run
- Compare the two runs in the experiment
- Cloud (`Vertex AI`) Training
- Within the training script:
- Create an experiment
- Log parameters and metrics
- Create artifact lineage
- Create a `Vertex AI Training` custom job
- Execute the custom job
- Visualize the experiment results
```
[Get Started with Vertex TensorBoard](get_started_vertex_tensorboard.ipynb)
@@ -40,7 +40,7 @@
" </td>\n",
" <td>\n",
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage2/get_started_bqml_training.ipynb\">\n",
" <img src=\"https://cloud.google.com/ml-engine/images/colab-logo-32px.png\\\" alt=\"Colab logo\"> Run in Colab\n",
" <img src=\"https://cloud.google.com/ml-engine/images/colab-logo-32px.png\" alt=\"Colab logo\"> Run in Colab\n",
" </a>\n",
" </td>\n",
" <td>\n",
@@ -1209,7 +1209,7 @@
"\n",
"You need to set some additional IAM permissions for BigQuery ML to automatically upload and register the model after training. Depending on your service account, the setting of the permissions below may fail. In this case, we recommend executing the permissions in a Cloud Shell.\n",
"\n",
"Learn more about [Setting permissions for Model Registry](https://cloud.devsite.corp.google.com/bigquery-ml/docs/managing-models-vertex\n"
"Learn more about [Setting permissions for Model Registry](https://cloud.google.com/bigquery-ml/docs/managing-models-vertex)\n"
]
},
{
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,684 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "copyright"
},
"outputs": [],
"source": [
"# 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",
"# You may obtain a copy of the License at\n",
"#\n",
"# https://www.apache.org/licenses/LICENSE-2.0\n",
"#\n",
"# Unless required by applicable law or agreed to in writing, software\n",
"# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
"# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
"# See the License for the specific language governing permissions and\n",
"# limitations under the License."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "title:generic,gcp"
},
"source": [
"# E2E ML on GCP: MLOps stage 2 : experimentation: get started with Logging\n",
"\n",
"<table align=\"left\">\n",
" <td>\n",
" <a href=\"https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage2/get_started_with_logging.ipynb\">\n",
" <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>\n",
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage2/get_started_with_logging.ipynb\">\n",
" <img src=\"https://cloud.google.com/ml-engine/images/colab-logo-32px.png\" alt=\"Colab logo\"> Run in Colab\n",
" </a>\n",
" </td>\n",
" <td>\n",
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://raw.githubusercontent.com/GoogleCloudPlatform/vertex-ai-samples/main/notebooks/community/ml_ops/stage2/get_started_with_logging.ipynb\">\n",
" <img src=\"https://lh3.googleusercontent.com/UiNooY4LUgW_oTvpsNhPpQzsstV5W8F7rYgxgGBD85cWJoLmrOzhVs_ksK_vgx40SHs7jCqkTkCk=e14-rj-sc0xffffff-h130-w32\" alt=\"Vertex AI logo\">\n",
" Open in Vertex AI Workbench\n",
" </a>\n",
" </td>\n",
"</table>\n",
"<br/><br/><br/>"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "overview:mlops"
},
"source": [
"## Overview\n",
"\n",
"\n",
"This tutorial demonstrates how to use Vertex AI for E2E MLOps on Google Cloud in production. This tutorial covers stage 2 : experimentation: get started with Logging."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "objective:mlops,stage2,get_started_vertex_experiments"
},
"source": [
"### Objective\n",
"\n",
"In this tutorial, you learn how to use Python and Cloud logging awhen training with `Vertex AI`.\n",
"\n",
"This tutorial uses the following Google Cloud ML services:\n",
"\n",
"- `Cloud Logging`\n",
"\n",
"The steps performed include:\n",
"\n",
"- Use Python logging to log training configuration/results locally.\n",
"- Use Google Cloud Logging to log training configuration/results in cloud storage."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "recommendation:mlops,stage2,logging"
},
"source": [
"### Recommendations\n",
"\n",
"When doing E2E MLOps on Google Cloud, the following are some of the best practices for logging data when experimenting or formally training a model.\n",
"\n",
"#### Python Logging\n",
"\n",
"Use Python's logging package when doing ad-hoc training locally.\n",
"\n",
"#### Cloud Logging\n",
"\n",
"Use `Google Cloud Logging` when doing training on the cloud.\n",
"\n",
"#### Experiments\n",
"\n",
"Use Vertex AI Experiments in conjunction with logging when performing experiments to compare results for different experiment configurations.\n",
"\n",
"### Costs\n",
"This tutorial uses billable components of Google Cloud:\n",
"\n",
"- Vertex AI\n",
"\n",
"Learn about [Vertex AI pricing](https://cloud.google.com/vertex-ai/pricing) and use the [Pricing Calculator](https://cloud.google.com/products/calculator/) to generate a cost estimate based on your projected usage."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "install_mlops"
},
"source": [
"## Installations\n",
"\n",
"Install the following packages for executing this notebook."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "install_mlops"
},
"outputs": [],
"source": [
"import os\n",
"\n",
"# The Vertex AI Workbench Notebook product has specific requirements\n",
"IS_WORKBENCH_NOTEBOOK = os.getenv(\"DL_ANACONDA_HOME\") and not os.getenv(\"VIRTUAL_ENV\")\n",
"IS_USER_MANAGED_WORKBENCH_NOTEBOOK = os.path.exists(\n",
" \"/opt/deeplearning/metadata/env_version\"\n",
")\n",
"\n",
"# Vertex AI Notebook requires dependencies to be installed with '--user'\n",
"USER_FLAG = \"\"\n",
"if IS_WORKBENCH_NOTEBOOK:\n",
" USER_FLAG = \"--user\"\n",
"\n",
"! pip3 install --upgrade google-cloud-logging $USER_FLAG -q"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "restart"
},
"source": [
"### Restart the kernel\n",
"\n",
"Once you've installed the additional packages, you need to restart the notebook kernel so it can find the packages."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "restart"
},
"outputs": [],
"source": [
"import os\n",
"\n",
"if not os.getenv(\"IS_TESTING\"):\n",
" # Automatically restart kernel after installs\n",
" import IPython\n",
"\n",
" app = IPython.Application.instance()\n",
" app.kernel.do_shutdown(True)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "project_id"
},
"source": [
"### Set up your Google Cloud project\n",
"\n",
"**The following steps are required, regardless of your notebook environment.**\n",
"\n",
"1. [Select or create a Google Cloud project](https://console.cloud.google.com/cloud-resource-manager). When you first create an account, you get a $300 free credit towards your compute/storage costs.\n",
"\n",
"1. [Make sure that billing is enabled for your project](https://cloud.google.com/billing/docs/how-to/modify-project).\n",
"\n",
"1. [Enable the Vertex AI, Compute Engine, Cloud Storage and Cloud Logging APIs](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com,compute_component,storage_component,logging).\n",
"\n",
"1. If you are running this notebook locally, you need to install the [Cloud SDK](https://cloud.google.com/sdk).\n",
"\n",
"1. Enter your project ID in the cell below. Then run the cell to make sure the\n",
"Cloud SDK uses the right project for all the commands in this notebook.\n",
"\n",
"**Note**: Jupyter runs lines prefixed with `!` as shell commands, and it interpolates Python variables prefixed with `$` into these commands.\n",
"\n",
"\n",
"#### Set your project ID\n",
"\n",
"**If you don't know your project ID**, you may be able to get your project ID using `gcloud`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "set_project_id"
},
"outputs": [],
"source": [
"PROJECT_ID = \"[your-project-id]\" # @param {type:\"string\"}"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "autoset_project_id"
},
"outputs": [],
"source": [
"if PROJECT_ID == \"\" or PROJECT_ID is None or PROJECT_ID == \"[your-project-id]\":\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,
"metadata": {
"id": "set_gcloud_project_id"
},
"outputs": [],
"source": [
"! gcloud config set project $PROJECT_ID"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "region"
},
"source": [
"#### Region\n",
"\n",
"You can also change the `REGION` variable, which is used for operations\n",
"throughout the rest of this notebook. Below are regions supported for Vertex AI. We recommend that you choose the region closest to you.\n",
"\n",
"- Americas: `us-central1`\n",
"- Europe: `europe-west4`\n",
"- Asia Pacific: `asia-east1`\n",
"\n",
"You may not use a multi-regional bucket for training with Vertex AI. Not all regions provide support for all Vertex AI services.\n",
"\n",
"Learn more about [Vertex AI regions](https://cloud.google.com/vertex-ai/docs/general/locations)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "region"
},
"outputs": [],
"source": [
"REGION = \"[your-region]\" # @param {type: \"string\"}\n",
"\n",
"if REGION == \"[your-region]\":\n",
" REGION = \"us-central1\""
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "timestamp"
},
"source": [
"#### Timestamp\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 timestamp for each instance session, and append the timestamp onto the name of resources you create in this tutorial."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "timestamp"
},
"outputs": [],
"source": [
"from datetime import datetime\n",
"\n",
"TIMESTAMP = datetime.now().strftime(\"%Y%m%d%H%M%S\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "f3bd8c0d0469"
},
"source": [
"### Authenticate your Google Cloud account\n",
"\n",
"**If you are using Vertex AI Workbench Notebooks**, your environment is already authenticated. Skip this step.\n",
"\n",
"**If you are using Colab**, run the cell below and follow the instructions when prompted to authenticate your account via oAuth.\n",
"\n",
"**Otherwise**, follow these steps:\n",
"\n",
"In the Cloud Console, go to the [Create service account key](https://console.cloud.google.com/apis/credentials/serviceaccountkey) page.\n",
"\n",
"1. **Click Create service account**.\n",
"\n",
"2. In the **Service account name** field, enter a name, and click **Create**.\n",
"\n",
"3. In the **Grant this service account access to project** section, click the Role drop-down list. Type \"Vertex AI\" into the filter box, and select **Vertex AI Administrator**. Type \"Storage Object Admin\" into the filter box, and select **Storage Object Admin**.\n",
"\n",
"4. Click Create. A JSON file that contains your key downloads to your local environment.\n",
"\n",
"5. Enter the path to your service account key as the GOOGLE_APPLICATION_CREDENTIALS variable in the cell below and run the cell."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "e0953a00668e"
},
"outputs": [],
"source": [
"# If you are running this notebook in Colab, run this cell and follow the\n",
"# instructions to authenticate your GCP account. This provides access to your\n",
"# Cloud Storage bucket and lets you submit training jobs and prediction\n",
"# requests.\n",
"\n",
"import os\n",
"import sys\n",
"\n",
"# If on Vertex AI Workbench, then don't execute this code\n",
"IS_COLAB = \"google.colab\" in sys.modules\n",
"if not os.path.exists(\"/opt/deeplearning/metadata/env_version\") and not os.getenv(\n",
" \"DL_ANACONDA_HOME\"\n",
"):\n",
" if \"google.colab\" in sys.modules:\n",
" from google.colab import auth as google_auth\n",
"\n",
" google_auth.authenticate_user()\n",
"\n",
" # If you are running this notebook locally, replace the string below with the\n",
" # path to your service account key and run this cell to authenticate your GCP\n",
" # account.\n",
" elif not os.getenv(\"IS_TESTING\"):\n",
" %env GOOGLE_APPLICATION_CREDENTIALS ''"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "setup_vars"
},
"source": [
"### Set up variables\n",
"\n",
"Next, set up some variables used throughout the tutorial.\n",
"### Import libraries"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "import_aip:mbsdk"
},
"outputs": [],
"source": [
"import logging\n",
"\n",
"import google.cloud.aiplatform as aiplatform"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "init_aip:mbsdk,region"
},
"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,region"
},
"outputs": [],
"source": [
"aiplatform.init(project=PROJECT_ID, location=REGION)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "python_logging"
},
"source": [
"## Python Logging\n",
"\n",
"The Python logging package is widely used for logging within Python scripts. Commonly used features:\n",
"\n",
"- Set logging levels.\n",
"- Send log output to console.\n",
"- Send log output to a file.\n",
"\n",
"### Logging Levels in Python Logging\n",
"\n",
"The logging levels in order (from least to highest) and each level inclusive of the previous level are :\n",
"\n",
"1. Informational\n",
"2. Warnings\n",
"3. Errors\n",
"4. Debugging\n",
"\n",
"By default, the logging level is set to error level.\n",
"\n",
"### Logging output to console\n",
"\n",
"By default, the Python logging package outputs to the console. Note, in the example the debug log message is not outputted since the default logging level is set to error."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "python_logging"
},
"outputs": [],
"source": [
"def logging_examples():\n",
" logging.info(\"Model training started...\")\n",
" logging.warning(\"Using older version of package ...\")\n",
" logging.error(\"Training was terminated ...\")\n",
" logging.debug(\"Hyperparameters were ...\")\n",
"\n",
"\n",
"logging_examples()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "python_logging_level"
},
"source": [
"### Setting logging level\n",
"\n",
"To set the logging level, you get the logging handler using `getLogger()`. You can have multiple logging handles. When `getLogger()` is called without any arguments, it gets the default handler named ROOT. With the handler, you set the logging level with the method `setLevel()`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "python_logging_level"
},
"outputs": [],
"source": [
"logging.getLogger().setLevel(logging.DEBUG)\n",
"\n",
"logging_examples()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "python_logging_remove"
},
"source": [
"### Clearing handlers\n",
"\n",
"At times, you may desire to reconfigure your logging. A common practice in this case is to first remove all existing logging handles for a fresh start."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "python_logging_remove"
},
"outputs": [],
"source": [
"for handler in logging.root.handlers[:]:\n",
" logging.root.removeHandler(handler)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "python_logging_file"
},
"source": [
"### Output to a local file\n",
"\n",
"You can preserve your logging output to a file that is local to where the Python script is running with the method `BasicConfig()`, that takes the following parameters:\n",
"\n",
"- `filename`: The file path to the local file to write the log output to.\n",
"- `level`: Sets the level of logging that is written to the logging file.\n",
"\n",
"*Note:* You cannot use a Cloud Storage bucket as the output file."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "python_logging_file"
},
"outputs": [],
"source": [
"logging.basicConfig(filename=\"mylog.log\", level=logging.DEBUG)\n",
"\n",
"logging_examples()\n",
"\n",
"! cat mylog.log"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "cloud_logging"
},
"source": [
"## Logging with Google Cloud Logging\n",
"\n",
"You can preserve and retrieve your logging output to `Google Cloud Logging` service. Commonly used features:\n",
"\n",
"- Set logging levels.\n",
"- Send log output to storage.\n",
"- Retrieve log output from storage.\n",
"\n",
"### Logging Levels in Cloud Logging\n",
"\n",
"The logging levels in order (from least to highest) are, with each level inclusive of the previous level:\n",
"\n",
"1. Informational\n",
"2. Warnings\n",
"3. Errors\n",
"4. Debugging\n",
"\n",
"By default, the logging level is set to warning level.\n",
"\n",
"### Configurable and storing log data.\n",
"\n",
"To use the `Google Cloud Logging` service, you do the following steps:\n",
"\n",
"1. Create a client to the service.\n",
"2. Obtain a handler for the service.\n",
"3. Create a logger instance and set logging level.\n",
"4. Attach logger instance to the service.\n",
"\n",
"Learn more about [Logging client libraries](https://cloud.google.com/logging/docs/reference/libraries)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "cloud_logging"
},
"outputs": [],
"source": [
"import google.cloud.logging\n",
"from google.cloud.logging.handlers import CloudLoggingHandler\n",
"\n",
"# Connect to the Cloud Logging service\n",
"cl_client = google.cloud.logging.Client(project=PROJECT_ID)\n",
"handler = CloudLoggingHandler(cl_client, name=\"mylog\")\n",
"\n",
"# Create a logger instance and logging level\n",
"cloud_logger = logging.getLogger(\"cloudLogger\")\n",
"cloud_logger.setLevel(logging.INFO)\n",
"\n",
"# Attach the logger instance to the service.\n",
"cloud_logger.addHandler(handler)\n",
"\n",
"# Log something\n",
"cloud_logger.error(\"bad news\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "cloud_logging_write"
},
"source": [
"### Logging output\n",
"\n",
"Logging output at specific levels is identical to Python logging with respect to method and method names. The only difference is that you use your instance of the cloud logger in place of logging."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "cloud_logging_write"
},
"outputs": [],
"source": [
"cloud_logger.info(\"Model training started...\")\n",
"cloud_logger.warning(\"Using older version of package ...\")\n",
"cloud_logger.error(\"Training was terminated ...\")\n",
"cloud_logger.debug(\"Hyperparameters were ...\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "cloud_logging_list"
},
"source": [
"### Get logging entries\n",
"\n",
"To get the logged output, you:\n",
"\n",
"1. Retrieve the log handle to the service.\n",
"2. Using the handle, call the method `list_entries()`.\n",
"3. Iterate through the entries."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "cloud_logging_list"
},
"outputs": [],
"source": [
"logger = cl_client.logger(\"mylog\")\n",
"\n",
"for entry in logger.list_entries():\n",
" timestamp = entry.timestamp.isoformat()\n",
" print(\"* {}: {}: {}\".format(timestamp, entry.severity, entry.payload))"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "cleanup:mbsdk"
},
"source": [
"# Cleaning up\n",
"\n",
"To clean up all Google Cloud resources used in this project, you can [delete the Google Cloud\n",
"project](https://cloud.google.com/resource-manager/docs/creating-managing-projects#shutting_down_projects) you used for the tutorial.\n",
"\n",
"Otherwise, you can delete the individual resources you created in this tutorial."
]
}
],
"metadata": {
"colab": {
"name": "get_started_with_logging.ipynb",
"toc_visible": true
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
@@ -177,6 +177,39 @@ The steps performed in this tutorial include:
- Execute the `Vertex AI Pipeline`.
```
[Get Started with Vertex AI Model Registry](get_started_with_model_registry.ipynb)
```
The steps performed in this tutorial include:
- Create and register a first version of a model to `Vertex AI Model Registry`
- Create and register a second version of a model to `Vertex AI Model Registry`
- List all versions of a `Model` resource.
- Change the default version of a `Model` resource`
- Deploy the default version of a `Model` resource.
- Delete a model version from a `Model` resource.
- Delete a `Model` resource along with all model versions.
```
[Get Started with AutoML Tabular Pipeline Workflow](get_started_with_automl_tabular_pipeline_workflow.ipynb)
```
The steps performed in this tutorial include:
- Define training specification.
- Dataset specification
- Hyperparameter overide specification
- machine specifications
- Construct tabular workflow pipeline.
- Compile and execute pipeline.
- View evaluation metrics artifact.
- Export AutoML model as an OSS TF model.
- Create `Endpoint` resource.
- Deploy exported OSS TF model.
- Make a prediction.
```
### E2E Stage Example
[Stage 3: Formalization](mlops_formalization.ipynb)
File diff suppressed because it is too large Load Diff
@@ -40,7 +40,7 @@
" </td>\n",
" <td>\n",
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage4/get_started_with_vertex_ml_metadata_and_automl.ipynb\">\n",
" <img src=\"https://cloud.google.com/ml-engine/images/colab-logo-32px.png\\\" alt=\"Colab logo\"> Run in Colab\n",
" <img src=\"https://cloud.google.com/ml-engine/images/colab-logo-32px.png\" alt=\"Colab logo\"> Run in Colab\n",
" </a>\n",
" </td>\n",
" <td>\n",
@@ -255,6 +255,30 @@
"! gcloud config set project $PROJECT_ID"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "23988890fef6"
},
"source": [
"#### Get your project number\n",
"\n",
"Now that the project ID is set, you get your corresponding project number."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "2d6950574e1d"
},
"outputs": [],
"source": [
"shell_output = ! gcloud projects list --filter=\"PROJECT_ID:'{PROJECT_ID}'\" --format='value(PROJECT_NUMBER)'\n",
"PROJECT_NUMBER = shell_output[0]\n",
"print(\"Project Number:\", PROJECT_NUMBER)"
]
},
{
"cell_type": "markdown",
"metadata": {
@@ -730,7 +754,7 @@
"\n",
"artifact_item = Artifact(\n",
" display_name=\"flowers_\" + TIMESTAMP,\n",
" uri=\"https://us-central1-aiplatform.googleapis.com/v1/\" + dataset.resource_name,\n",
" uri=f\"https://{REGION}-aiplatform.googleapis.com/v1/\" + dataset.resource_name,\n",
" name=dataset.resource_name,\n",
" schema_title=\"google.VertexDataset\",\n",
" metadata={\"data_type\": \"image\", \"annotation_type\": \"image classification\"},\n",
@@ -738,7 +762,7 @@
")\n",
"\n",
"artifact_dataset = clients[\"metadata\"].create_artifact(\n",
" parent=\"projects/759209241365/locations/us-central1/metadataStores/default\",\n",
" parent=f\"projects/{PROJECT_NUMBER}/locations/{REGION}/metadataStores/default\",\n",
" artifact=artifact_item,\n",
" artifact_id=dataset.resource_name.split(\"/\")[-1],\n",
")\n",
@@ -869,7 +893,7 @@
"source": [
"artifact_item = Artifact(\n",
" display_name=\"flowers_\" + TIMESTAMP,\n",
" uri=\"https://us-central1-aiplatform.googleapis.com/v1/\" + model.resource_name,\n",
" uri=f\"https://{REGION}-aiplatform.googleapis.com/v1/\" + model.resource_name,\n",
" name=model.resource_name,\n",
" schema_title=\"google.VertexModel\",\n",
" metadata={\"model_type\": \"image classification\"},\n",
@@ -877,7 +901,7 @@
")\n",
"\n",
"artifact_model = clients[\"metadata\"].create_artifact(\n",
" parent=\"projects/759209241365/locations/us-central1/metadataStores/default\",\n",
" parent=f\"projects/{PROJECT_NUMBER}/locations/{REGION}/metadataStores/default\",\n",
" artifact=artifact_item,\n",
" artifact_id=model.resource_name.split(\"/\")[-1],\n",
")\n",
@@ -941,7 +965,7 @@
"source": [
"artifact_item = Artifact(\n",
" display_name=\"flowers_\" + TIMESTAMP,\n",
" uri=\"https://us-central1-aiplatform.googleapis.com/v1/\"\n",
" uri=f\"https://{REGION}-aiplatform.googleapis.com/v1/\"\n",
" + model_evaluations[0].resource_name,\n",
" name=model_evaluations[0].resource_name,\n",
" schema_title=\"system.SlicedClassificationMetrics\",\n",
@@ -950,7 +974,7 @@
")\n",
"\n",
"artifact_metrics = clients[\"metadata\"].create_artifact(\n",
" parent=\"projects/759209241365/locations/us-central1/metadataStores/default\",\n",
" parent=f\"projects/{PROJECT_NUMBER}/locations/{REGION}/metadataStores/default\",\n",
" artifact=artifact_item,\n",
" artifact_id=model_evaluations[0].resource_name.split(\"/\")[-1],\n",
")\n",
@@ -1011,7 +1035,7 @@
"source": [
"artifact_item = Artifact(\n",
" display_name=\"flowers_\" + TIMESTAMP,\n",
" uri=\"https://us-central1-aiplatform.googleapis.com/v1/\" + endpoint.resource_name,\n",
" uri=f\"https://{REGION}-aiplatform.googleapis.com/v1/\" + endpoint.resource_name,\n",
" name=endpoint.resource_name,\n",
" schema_title=\"google.VertexEndpoint\",\n",
" metadata={\"param\": \"value\"},\n",
@@ -1019,7 +1043,7 @@
")\n",
"\n",
"artifact_endpoint = clients[\"metadata\"].create_artifact(\n",
" parent=\"projects/759209241365/locations/us-central1/metadataStores/default\",\n",
" parent=f\"projects/{PROJECT_NUMBER}/locations/{REGION}/metadataStores/default\",\n",
" artifact=artifact_item,\n",
" artifact_id=endpoint.resource_name.split(\"/\")[-1],\n",
")\n",
@@ -1058,7 +1082,7 @@
"from google.cloud.aiplatform_v1beta1.types import Execution\n",
"\n",
"execution = clients[\"metadata\"].create_execution(\n",
" parent=\"projects/759209241365/locations/us-central1/metadataStores/default\",\n",
" parent=f\"projects/{PROJECT_NUMBER}/locations/{REGION}/metadataStores/default\",\n",
" execution=Execution(\n",
" display_name=\"AutoML training and deployment\",\n",
" schema_title=\"system.ContainerExecution\",\n",
@@ -1157,7 +1181,7 @@
"from google.cloud.aiplatform_v1beta1.types import Context\n",
"\n",
"context = clients[\"metadata\"].create_context(\n",
" parent=\"projects/759209241365/locations/us-central1/metadataStores/default\",\n",
" parent=f\"projects/{PROJECT_NUMBER}/locations/{REGION}/metadataStores/default\",\n",
" context=Context(\n",
" display_name=\"flowers_\" + TIMESTAMP,\n",
" schema_title=\"system.Pipeline\",\n",
@@ -29,7 +29,7 @@
"id": "title"
},
"source": [
"# Vertex SDK: E2E ML on GCP: MLOps stage 4 : formalization: get started with Vertex AI Explanations\n",
"# Vertex SDK: E2E ML on GCP: MLOps stage 4 : evaluation: get started with Vertex AI Explanations\n",
"\n",
"<table align=\"left\">\n",
" <td>\n",
@@ -29,7 +29,7 @@
"id": "title:generic,gcp"
},
"source": [
"# E2E ML on GCP: MLOps stage 5 : Get started with Vertex AI Endpoints\n",
"# E2E ML on GCP: MLOps stage 5 : deployment: Get started with Vertex AI Endpoints\n",
"<table align=\"left\">\n",
" <td>\n",
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage5/get_started_with_vertex_endpoints.ipynb\">\n",
@@ -171,20 +171,6 @@
"! pip3 install --upgrade tensorflow $USER_FLAG -q"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "38379eb00a31"
},
"outputs": [],
"source": [
"# Temporary, until feature pushed to Pypi\n",
"! pip3 uninstall google-cloud-aiplatform -y\n",
"\n",
"! pip install --user git+https://github.com/googleapis/python-aiplatform.git@private-ep"
]
},
{
"cell_type": "markdown",
"metadata": {
+88 -103
View File
@@ -8,7 +8,7 @@
},
"outputs": [],
"source": [
"# 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",
@@ -42,6 +42,11 @@
" View on GitHub\n",
" </a>\n",
" </td>\n",
" <td>\n",
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://raw.githubusercontent.com/laeg/vertex-ai-samples/main/notebooks/community/neo4j/graph_paysim.ipynb\">\n",
" <img src=\"https://lh3.googleusercontent.com/UiNooY4LUgW_oTvpsNhPpQzsstV5W8F7rYgxgGBD85cWJoLmrOzhVs_ksK_vgx40SHs7jCqkTkCk=e14-rj-sc0xffffff-h130-w32\" alt=\"Vertex AI logo\">Open in Vertex AI Workbench\n",
" </a>\n",
"</td>\n",
"</table>"
]
},
@@ -143,7 +148,7 @@
},
"outputs": [],
"source": [
"!pip install --quiet --upgrade neo4j"
"!pip install --quiet --upgrade graphdatascience==1.0.0"
]
},
{
@@ -255,7 +260,7 @@
"outputs": [],
"source": [
"import pandas as pd\n",
"from neo4j import GraphDatabase"
"from graphdatascience import GraphDataScience"
]
},
{
@@ -266,7 +271,19 @@
},
"outputs": [],
"source": [
"driver = GraphDatabase.driver(DB_URL, auth=(DB_USER, DB_PASS))"
"# If you are connecting the client to an AuraDS instance, you can get the recommended non-default configuration settings of the Python Driver applied automatically. To achieve this, set the constructor argument aura_ds=True\n",
"gds = GraphDataScience(DB_URL, auth=(DB_USER, DB_PASS), aura_ds=True)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "f14915ddd1fb"
},
"outputs": [],
"source": [
"gds.set_database(DB_NAME)"
]
},
{
@@ -287,19 +304,16 @@
"outputs": [],
"source": [
"# node labels\n",
"with driver.session(database=DB_NAME) as session:\n",
" result = session.read_transaction(\n",
" lambda tx: tx.run(\n",
" \"\"\"\n",
" CALL db.labels() YIELD label\n",
" CALL apoc.cypher.run('MATCH (:`'+label+'`) RETURN count(*) as freq', {})\n",
" YIELD value\n",
" RETURN label, value.freq AS freq\n",
"result = gds.run_cypher(\n",
" \"\"\"\n",
" ).data()\n",
" )\n",
"df = pd.DataFrame(result)\n",
"display(df)"
"CALL db.labels() YIELD label\n",
"CALL apoc.cypher.run('MATCH (:`'+label+'`) RETURN count(*) as freq', {})\n",
"YIELD value\n",
"RETURN label, value.freq AS freq\n",
"\"\"\"\n",
")\n",
"\n",
"display(result)"
]
},
{
@@ -311,20 +325,17 @@
"outputs": [],
"source": [
"# relationship types\n",
"with driver.session(database=DB_NAME) as session:\n",
" result = session.read_transaction(\n",
" lambda tx: tx.run(\n",
" \"\"\"\n",
" CALL db.relationshipTypes() YIELD relationshipType as type\n",
" CALL apoc.cypher.run('MATCH ()-[:`'+type+'`]->() RETURN count(*) as freq', {})\n",
" YIELD value\n",
" RETURN type AS relationshipType, value.freq AS freq\n",
" ORDER by freq DESC\n",
" \"\"\"\n",
" ).data()\n",
" )\n",
"df = pd.DataFrame(result)\n",
"display(df)"
"result = gds.run_cypher(\n",
" \"\"\"\n",
"CALL db.relationshipTypes() YIELD relationshipType as type\n",
"CALL apoc.cypher.run('MATCH ()-[:`'+type+'`]->() RETURN count(*) as freq', {})\n",
"YIELD value\n",
"RETURN type AS relationshipType, value.freq AS freq\n",
"ORDER by freq DESC\n",
"\"\"\"\n",
")\n",
"\n",
"display(result)"
]
},
{
@@ -336,23 +347,20 @@
"outputs": [],
"source": [
"# transaction types\n",
"with driver.session(database=DB_NAME) as session:\n",
" result = session.read_transaction(\n",
" lambda tx: tx.run(\n",
" \"\"\"\n",
" MATCH (t:Transaction)\n",
" WITH sum(t.amount) AS globalSum, count(t) AS globalCnt\n",
" WITH *, 10^3 AS scaleFactor\n",
" UNWIND ['CashIn', 'CashOut', 'Payment', 'Debit', 'Transfer'] AS txType\n",
" CALL apoc.cypher.run('MATCH (t:' + txType + ')\n",
" RETURN sum(t.amount) as txAmount, count(t) AS txCnt', {})\n",
" YIELD value\n",
" RETURN txType,value.txAmount AS TotalMarketValue\n",
"result = gds.run_cypher(\n",
" \"\"\"\n",
" ).data()\n",
" )\n",
"df = pd.DataFrame(result)\n",
"display(df)"
" MATCH (t:Transaction)\n",
" WITH sum(t.amount) AS globalSum, count(t) AS globalCnt\n",
" WITH *, 10^3 AS scaleFactor\n",
" UNWIND ['CashIn', 'CashOut', 'Payment', 'Debit', 'Transfer'] AS txType\n",
" CALL apoc.cypher.run('MATCH (t:' + txType + ')\n",
" RETURN sum(t.amount) as txAmount, count(t) AS txCnt', {})\n",
" YIELD value\n",
" RETURN txType,value.txAmount AS TotalMarketValue\n",
" \"\"\"\n",
")\n",
"\n",
"display(result)"
]
},
{
@@ -375,18 +383,14 @@
},
"outputs": [],
"source": [
"with driver.session(database=DB_NAME) as session:\n",
" result = session.read_transaction(\n",
" lambda tx: tx.run(\n",
" \"\"\"\n",
" CALL gds.graph.create.cypher('client_graph', \n",
" 'MATCH (c:Client) RETURN id(c) as id, c.num_transactions as num_transactions, c.total_transaction_amnt as total_transaction_amnt, c.is_fraudster as is_fraudster',\n",
" 'MATCH (c:Client)-[:PERFORMED]->(t:Transaction)-[:TO]->(c2:Client) return id(c) as source, id(c2) as target, sum(t.amount) as amount, \"TRANSACTED_WITH\" as type ')\n",
" \"\"\"\n",
" ).data()\n",
" )\n",
"df = pd.DataFrame(result)\n",
"display(df)"
"# We get a tuple back with an object that represents the graph projection and the results of the GDS call\n",
"G, results = gds.graph.project.cypher(\n",
" \"client_graph\",\n",
" \"MATCH (c:Client) RETURN id(c) as id, c.num_transactions as num_transactions, c.total_transaction_amnt as total_transaction_amnt, c.is_fraudster as is_fraudster\",\n",
" 'MATCH (c:Client)-[:PERFORMED]->(t:Transaction)-[:TO]->(c2:Client) return id(c) as source, id(c2) as target, sum(t.amount) as amount, \"TRANSACTED_WITH\" as type ',\n",
")\n",
"\n",
"display(results)"
]
},
{
@@ -406,25 +410,19 @@
},
"outputs": [],
"source": [
"with driver.session(database=DB_NAME) as session:\n",
" result = session.read_transaction(\n",
" lambda tx: tx.run(\n",
" \"\"\"\n",
" CALL gds.fastRP.mutate('client_graph',{\n",
" relationshipWeightProperty:'amount',\n",
" iterationWeights: [0.0, 1.00, 1.00, 0.80, 0.60],\n",
" featureProperties: ['num_transactions', 'total_transaction_amnt'],\n",
" propertyRatio: 0.25, \n",
" nodeSelfInfluence: 0.15,\n",
" embeddingDimension: 16,\n",
" randomSeed: 1, \n",
" mutateProperty:'embedding'\n",
" })\n",
" \"\"\"\n",
" ).data()\n",
" )\n",
"df = pd.DataFrame(result)\n",
"display(df)"
"results = gds.fastRP.mutate(\n",
" G,\n",
" relationshipWeightProperty=\"amount\",\n",
" iterationWeights=[0.0, 1.00, 1.00, 0.80, 0.60],\n",
" featureProperties=[\"num_transactions\", \"total_transaction_amnt\"],\n",
" propertyRatio=0.25,\n",
" nodeSelfInfluence=0.15,\n",
" embeddingDimension=16,\n",
" randomSeed=1,\n",
" mutateProperty=\"embedding\",\n",
")\n",
"\n",
"display(result)"
]
},
{
@@ -444,19 +442,11 @@
},
"outputs": [],
"source": [
"with driver.session(database=DB_NAME) as session:\n",
" result = session.read_transaction(\n",
" lambda tx: tx.run(\n",
" \"\"\"\n",
" CALL gds.graph.streamNodeProperties\n",
" ('client_graph', ['embedding', 'num_transactions', 'total_transaction_amnt', 'is_fraudster'])\n",
" YIELD nodeId, nodeProperty, propertyValue\n",
" RETURN nodeId, nodeProperty, propertyValue\n",
" \"\"\"\n",
" ).data()\n",
" )\n",
"df = pd.DataFrame(result)\n",
"df.head()"
"node_properties = gds.graph.streamNodeProperties(\n",
" G, [\"embedding\", \"num_transactions\", \"total_transaction_amnt\", \"is_fraudster\"]\n",
")\n",
"\n",
"node_properties.head()"
]
},
{
@@ -476,7 +466,9 @@
},
"outputs": [],
"source": [
"x = df.pivot(index=\"nodeId\", columns=\"nodeProperty\", values=\"propertyValue\")\n",
"x = node_properties.pivot(\n",
" index=\"nodeId\", columns=\"nodeProperty\", values=\"propertyValue\"\n",
")\n",
"x = x.reset_index()\n",
"x.columns.name = None\n",
"x.head()"
@@ -699,8 +691,8 @@
"id": "ArK3cfKsdT1x"
},
"source": [
"## Train and deploy a model on GCP\n",
"We'll use the engineered features to train an AutoML Tables model, then deploy it to an endpoint"
"## Train and deploy a model with Vertex AI\n",
"We'll use the engineered features to train an AutoML Tabular Data, then deploy it to an endpoint"
]
},
{
@@ -782,8 +774,8 @@
"id": "-NnDaATyWY7z"
},
"source": [
"## Loading Data into GCP Feature Store\n",
"In this section, we'll take our dataframe with newly engineered features and load that into GCP feature store."
"## Loading Data into Vertex AI Feature Store\n",
"In this section, we'll take our dataframe with newly engineered features and load that into Vertex AI Feature Store."
]
},
{
@@ -1083,14 +1075,7 @@
},
"outputs": [],
"source": [
"with driver.session(database=DB_NAME) as session:\n",
" result = session.read_transaction(\n",
" lambda tx: tx.run(\n",
" \"\"\"\n",
" CALL gds.graph.drop('client_graph')\n",
" \"\"\"\n",
" ).data()\n",
" )"
"gds.graph.drop(G)"
]
},
{
+2
View File
@@ -12,6 +12,7 @@
/migration @aferlitsch
/explainabl_ai @aferlitsch
/pipelines @aferlitsch
/experiments @inardini
/model_monitoring/model_monitoring.ipynb @mco-gh
/ml_metadata/sdk-metric-parameter-tracking-for-custom-jobs.ipynb @jialuzh
@@ -23,3 +24,4 @@
/pipelines/google_cloud_pipeline_components_bqml_text.ipynb @inardini
/pipelines/google_cloud_pipelines_dataproc_tabular @inardini
/automl/automl_forecasting_bqml_arima_plus_comparison.ipynb @TheMichaelHu
/automl/automl_tabular_on_vertex_pipelines.ipynb @helinwang
@@ -43,7 +43,7 @@
" </a>\n",
" </td>\n",
" <td>\n",
" <a href=\"https://console.cloud.google.com/ai/platform/notebooks/deploy-notebook?download_url=https://github.com/GoogleCloudPlatform/vertex-ai-samples/tree/main/notebooks/official/automl/automl-text-classification.ipynb\">\n",
" <a href=\"https://console.cloud.google.com/ai/platform/notebooks/deploy-notebook?download_url=https://raw.githubusercontent.com/GoogleCloudPlatform/vertex-ai-samples/main/notebooks/official/automl/automl-text-classification.ipynb\">\n",
" <img src=\"https://lh3.googleusercontent.com/UiNooY4LUgW_oTvpsNhPpQzsstV5W8F7rYgxgGBD85cWJoLmrOzhVs_ksK_vgx40SHs7jCqkTkCk=e14-rj-sc0xffffff-h130-w32\" alt=\"Vertex AI logo\">\n",
" Open in Vertex AI Workbench\n",
" </a>\n",
@@ -61,7 +61,7 @@
"\n",
"## Overview\n",
"\n",
"This notebook walks you through the major phases of building and using a text classification model on [Vertex AI](https://cloud.google.com/vertex-ai/docs/). \n",
"This notebook walks you through the major phases of building and using an AutoML text classification model on [Vertex AI](https://cloud.google.com/vertex-ai/docs/). \n",
"\n",
"### Dataset\n",
"\n",
@@ -74,7 +74,7 @@
"This tutorial uses the following Google Cloud ML services:\n",
"\n",
"- `AutoML Training`\n",
"- `Vertex AI Model resource`\n",
"- `Vertex AI Model` resource\n",
"\n",
"The steps performed include:\n",
"\n",
@@ -192,7 +192,7 @@
"if IS_WORKBENCH_NOTEBOOK:\n",
" USER_FLAG = \"--user\"\n",
"\n",
"! pip3 install {USER_FLAG} --upgrade google-cloud-aiplatform google-cloud-storage jsonlines"
"! pip3 install {USER_FLAG} --upgrade google-cloud-aiplatform google-cloud-storage jsonlines -q"
]
},
{
@@ -536,7 +536,7 @@
"id": "32c971919605"
},
"source": [
"## Create a dataset and import your data\n",
"## Create a `Dataset` resource and import your data\n",
"\n",
"The notebook uses the 'Happy Moments' dataset for demonstration purposes. You can change it to another text classification dataset that [conforms to the data preparation requirements](https://cloud.google.com/vertex-ai/docs/datasets/prepare-text#classification).\n",
"\n",
@@ -584,7 +584,7 @@
"source": [
"## Train your text classification model\n",
"\n",
"Once your dataset has finished importing data, you are ready to train your model. To do this, you first need the full resource name of your dataset, where the full name has the format `projects/[YOUR_PROJECT]/locations/us-central1/datasets/[YOUR_DATASET_ID]`. If you don't have the resource name handy, you can list all of the datasets in your project using `TextDataset.list()`. \n",
"Once your dataset has finished importing data, you are ready to train your model. To do this, you first need the full resource name of your dataset, where the full name has the format `projects/[YOUR_PROJECT]/locations/[YOUR_REGIO)N]/datasets/[YOUR_DATASET_ID]`. If you don't have the resource name handy, you can list all of the datasets in your project using `TextDataset.list()`. \n",
"\n",
"As shown in the following code block, you can pass in the display name of your dataset in the call to `list()` to filter the results.\n"
]
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -33,20 +33,21 @@
"\n",
"<table align=\"left\">\n",
" <td>\n",
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/vertex-ai-samples/blob/master/notebooks/official/pipelines/custom_model_training_and_batch_prediction.ipynb\">\n",
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/official/pipelines/custom_model_training_and_batch_prediction.ipynb\">\n",
" <img src=\"https://cloud.google.com/ml-engine/images/colab-logo-32px.png\" alt=\"Colab logo\"> Run in Colab\n",
" </a>\n",
" </td>\n",
" <td>\n",
" <a href=\"https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/master/notebooks/official/pipelines/custom_model_training_and_batch_prediction.ipynb\">\n",
" <a href=\"https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/official/pipelines/custom_model_training_and_batch_prediction.ipynb\">\n",
" <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>\n",
" <a href=\"https://console.cloud.google.com/vertex-ai/notebooks/deploy-notebook?download_url=https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/master/notebooks/official/pipelines/custom_model_training_and_batch_prediction.ipynb\">\n",
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/official/pipelines/custom_model_training_and_batch_prediction.ipynb\">\n",
" <img src=\"https://lh3.googleusercontent.com/UiNooY4LUgW_oTvpsNhPpQzsstV5W8F7rYgxgGBD85cWJoLmrOzhVs_ksK_vgx40SHs7jCqkTkCk=e14-rj-sc0xffffff-h130-w32\" alt=\"Vertex AI logo\">\n",
" Open in Vertex AI Workbench\n",
" </a>\n",
" </a>\n",
" </td>\n",
"</table>\n",
"<br/><br/><br/>"
@@ -83,14 +84,25 @@
"source": [
"### Objective\n",
"\n",
"In this tutorial, you create a custom image classification model using Vertex AI Pipelines with pre-built Google Cloud Pipeline Components for custom training.\n",
"In this tutorial, you learn to use `Vertex AI Pipelines` and `Google Cloud Pipeline Components` to build a custom model.\n",
"\n",
"\n",
"This tutorial uses the following Google Cloud ML services:\n",
"\n",
"- `Vertex AI Pipelines`\n",
"- `Google Cloud Pipeline Components`\n",
"- `Vertex AI Training`\n",
"- `Vertex AI Model` resource\n",
"- `Vertex AI Endpoint` resource\n",
"\n",
"The steps performed include:\n",
"\n",
"- Train a custom model.\n",
"- Upload the trained model as a `Model` resource.\n",
"- Create an `Endpoint` resource.\n",
"- Deploy the `Model` resource to the `Endpoint` resource.\n",
"- Create a KFP pipeline:\n",
" - Train a custom model.\n",
" - Upload the trained model as a `Model` resource.\n",
" - Create an `Endpoint` resource.\n",
" - Deploy the `Model` resource to the `Endpoint` resource.\n",
" - Make a batch prediction request.\n",
"\n",
"Learn more about [Google Cloud Pipeline Components](https://cloud.google.com/vertex-ai/docs/pipelines/build-pipeline)."
]
@@ -123,7 +135,7 @@
"source": [
"### Set up your local development environment\n",
"\n",
"If you are using Colab or Google Cloud Notebook, your environment already meets all the requirements to run this notebook. You can skip this step.\n",
"If you are using Colab or Vertex AI Workbench Notebook, your environment already meets all the requirements to run this notebook. You can skip this step.\n",
"\n",
"Otherwise, make sure your environment meets this notebook's requirements. You need the following:\n",
"\n",
@@ -156,7 +168,7 @@
"source": [
"## Installation\n",
"\n",
"Install the latest version of Vertex AI SDK for Python."
"Install the packages required for executing this notebook."
]
},
{
@@ -169,63 +181,21 @@
"source": [
"import os\n",
"\n",
"# Google Cloud Notebook\n",
"if os.path.exists(\"/opt/deeplearning/metadata/env_version\") or os.getenv(\"IS_TESTING\"):\n",
"# The Vertex AI Workbench Notebook product has specific requirements\n",
"IS_WORKBENCH_NOTEBOOK = os.getenv(\"DL_ANACONDA_HOME\") and not os.getenv(\"VIRTUAL_ENV\")\n",
"IS_USER_MANAGED_WORKBENCH_NOTEBOOK = os.path.exists(\n",
" \"/opt/deeplearning/metadata/env_version\"\n",
")\n",
"\n",
"# Vertex AI Notebook requires dependencies to be installed with '--user'\n",
"USER_FLAG = \"\"\n",
"if IS_WORKBENCH_NOTEBOOK:\n",
" USER_FLAG = \"--user\"\n",
"else:\n",
" USER_FLAG = \"\"\n",
"\n",
"! pip3 install --upgrade google-cloud-aiplatform {USER_FLAG} -q\n",
"! pip3 install -U google-cloud-storage {USER_FLAG} -q\n",
"! pip3 install {USER_FLAG} kfp google-cloud-pipeline-components --upgrade -q\n",
"\n",
"! pip3 install --upgrade google-cloud-aiplatform $USER_FLAG"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "install_storage"
},
"source": [
"Install the latest GA version of *google-cloud-storage* library as well."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "install_storage"
},
"outputs": [],
"source": [
"! pip3 install -U google-cloud-storage $USER_FLAG"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "install_gcpc"
},
"source": [
"Install the latest GA version of *google-cloud-pipeline-components* library as well."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "install_gcpc"
},
"outputs": [],
"source": [
"! pip3 install kfp google-cloud-pipeline-components --upgrade $USER_FLAG"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "b12be5c73a33"
},
"outputs": [],
"source": [
"if os.getenv(\"IS_TESTING\"):\n",
" ! pip3 install --upgrade --force-reinstall $USER_FLAG tensorflow==2.5 kfp google-cloud-aiplatform google-cloud-storage google-cloud-pipeline-components"
]
@@ -389,23 +359,30 @@
"source": [
"### Authenticate your Google Cloud account\n",
"\n",
"**If you are using Google Cloud Notebook**, your environment is already authenticated. Skip this step.\n",
"**If you are using Vertex AI Workbench Notebook**, your environment is already authenticated. Skip this step.\n",
"\n",
"**If you are using Colab**, run the cell below and follow the instructions when prompted to authenticate your account via oAuth.\n",
"**If you are using Colab**, run the cell below and follow the instructions\n",
"when prompted to authenticate your account via oAuth.\n",
"\n",
"**Otherwise**, follow these steps:\n",
"\n",
"In the Cloud Console, go to the [Create service account key](https://console.cloud.google.com/apis/credentials/serviceaccountkey) page.\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",
"**Click Create service account**.\n",
"2. Click **Create service account**.\n",
"\n",
"In the **Service account name** field, enter a name, and click **Create**.\n",
"3. In the **Service account name** field, enter a name, and\n",
" click **Create**.\n",
"\n",
"In the **Grant this service account access to project** section, click the Role drop-down list. Type \"Vertex\" into the filter box, and select **Vertex Administrator**. Type \"Storage Object Admin\" into the filter box, and select **Storage Object Admin**.\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",
"Click Create. A JSON file that contains your key downloads to your local environment.\n",
"5. Click *Create*. A JSON file that contains your key downloads to your\n",
"local environment.\n",
"\n",
"Enter the path to your service account key as the GOOGLE_APPLICATION_CREDENTIALS variable in the cell below and run the cell."
"6. Enter the path to your service account key as the\n",
"`GOOGLE_APPLICATION_CREDENTIALS` variable in the cell below and run the cell."
]
},
{
@@ -424,8 +401,11 @@
"import os\n",
"import sys\n",
"\n",
"# If on Google Cloud Notebook, then don't execute this code\n",
"if not os.path.exists(\"/opt/deeplearning/metadata/env_version\"):\n",
"# If on Vertex AI Workbench, then don't execute this code\n",
"IS_COLAB = \"google.colab\" in sys.modules\n",
"if not os.path.exists(\"/opt/deeplearning/metadata/env_version\") and not os.getenv(\n",
" \"DL_ANACONDA_HOME\"\n",
"):\n",
" if \"google.colab\" in sys.modules:\n",
" from google.colab import auth as google_auth\n",
"\n",
@@ -473,8 +453,9 @@
},
"outputs": [],
"source": [
"if BUCKET_URI == \"\" or BUCKET_URI is None or BUCKET_URI == \"gs://[your-bucket-name]\":\n",
" BUCKET_URI = \"gs://\" + PROJECT_ID + \"aip-\" + TIMESTAMP"
"if BUCKET_NAME == \"\" or BUCKET_NAME is None or BUCKET_NAME == \"[your-bucket-name]\":\n",
" BUCKET_NAME = PROJECT_ID + \"aip-\" + TIMESTAMP\n",
" BUCKET_URI = \"gs://\" + BUCKET_NAME"
]
},
{
@@ -552,9 +533,16 @@
" or SERVICE_ACCOUNT is None\n",
" or SERVICE_ACCOUNT == \"[your-service-account]\"\n",
"):\n",
" # Get your GCP project id from gcloud\n",
" shell_output = !gcloud auth list 2>/dev/null\n",
" SERVICE_ACCOUNT = shell_output[2].strip()\n",
" # Get your service account from gcloud\n",
" if not IS_COLAB:\n",
" shell_output = !gcloud auth list 2>/dev/null\n",
" SERVICE_ACCOUNT = shell_output[2].replace(\"*\", \"\").strip()\n",
"\n",
" if IS_COLAB:\n",
" shell_output = ! gcloud projects describe $PROJECT_ID\n",
" project_number = shell_output[-1].split(\":\")[1].strip().replace(\"'\", \"\")\n",
" SERVICE_ACCOUNT = f\"{project_number}-compute@developer.gserviceaccount.com\"\n",
"\n",
" print(\"Service Account:\", SERVICE_ACCOUNT)"
]
},
@@ -602,7 +590,11 @@
},
"outputs": [],
"source": [
"import google.cloud.aiplatform as aip"
"import google.cloud.aiplatform as aip\n",
"import tensorflow as tf\n",
"from google_cloud_pipeline_components.experimental.custom_job import utils\n",
"from kfp.v2 import compiler, dsl\n",
"from kfp.v2.dsl import component"
]
},
{
@@ -627,29 +619,6 @@
"PIPELINE_ROOT = \"{}/pipeline_root/bikes_weather\".format(BUCKET_URI)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "additional_imports"
},
"source": [
"Additional imports."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "e3fca6d3"
},
"outputs": [],
"source": [
"import tensorflow as tf\n",
"from google_cloud_pipeline_components.experimental.custom_job import utils\n",
"from kfp.v2 import compiler, dsl\n",
"from kfp.v2.dsl import component"
]
},
{
"cell_type": "markdown",
"metadata": {
@@ -684,7 +653,7 @@
"\n",
"Set the variables `TRAIN_GPU/TRAIN_NGPU` and `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 Telsa K80 GPUs allocated to each VM, you would specify:\n",
"\n",
" (aip.AcceleratorType.NVIDIA_TESLA_K80, 4)\n",
" (aip.gapic.AcceleratorType.NVIDIA_TESLA_K80, 4)\n",
"\n",
"\n",
"Otherwise specify `(None, None)` to use a container image to run on a CPU.\n",
@@ -749,7 +718,7 @@
"if os.getenv(\"IS_TESTING_TF\"):\n",
" TF = os.getenv(\"IS_TESTING_TF\")\n",
"else:\n",
" TF = \"2-1\"\n",
" TF = \"2-5\"\n",
"\n",
"if TF[0] == \"2\":\n",
" if TRAIN_GPU:\n",
@@ -1389,8 +1358,9 @@
"batch_job = aip.BatchPredictionJob(batch_job_id)\n",
"batch_job.delete()\n",
"\n",
"# uncomment to delete your bucket\n",
"# ! gsutil rm -rf {BUCKET_URI}"
"delete_bucket = False\n",
"if delete_bucket or os.getenv(\"IS_TESTING\"):\n",
" ! gsutil rm -rf {BUCKET_URI}"
]
}
],
@@ -33,18 +33,18 @@
"\n",
"<table align=\"left\">\n",
" <td>\n",
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/vertex-ai-samples/blob/master/notebooks/official/pipelines/pipelines_intro_kfp.ipynb\">\n",
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/official/pipelines/pipelines_intro_kfp.ipynb\">\n",
" <img src=\"https://cloud.google.com/ml-engine/images/colab-logo-32px.png\" alt=\"Colab logo\"> Run in Colab\n",
" </a>\n",
" </td>\n",
" <td>\n",
" <a href=\"https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/master/notebooks/official/pipelines/pipelines_intro_kfp.ipynb\">\n",
" <a href=\"https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/official/pipelines/pipelines_intro_kfp.ipynb\">\n",
" <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>\n",
" <a href=\"https://console.cloud.google.com/vertex-ai/notebooks/deploy-notebook?download_url=https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/master/notebooks/official/pipelines/pipelines_intro_kfp.ipynb\">\n",
" <a href=\"https://console.cloud.google.com/vertex-ai/notebooks/deploy-notebook?download_url=https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/official/pipelines/pipelines_intro_kfp.ipynb\">\n",
" <img src=\"https://lh3.googleusercontent.com/UiNooY4LUgW_oTvpsNhPpQzsstV5W8F7rYgxgGBD85cWJoLmrOzhVs_ksK_vgx40SHs7jCqkTkCk=e14-rj-sc0xffffff-h130-w32\" alt=\"Vertex AI logo\">\n",
" Open in Vertex AI Workbench\n",
" </a>\n",
@@ -72,9 +72,15 @@
"source": [
"### Objective\n",
"\n",
"In this tutorial, you use the KFP SDK to build pipelines that generate evaluation metrics.\n",
"\n",
"This tutorial uses the following Google Cloud ML services:\n",
"\n",
"- `Vertex AI Pipelines`\n",
"\n",
"The steps performed include:\n",
"\n",
"- Define and compile a pipeline.\n",
"- Define and compile a `Vertex AI` pipeline.\n",
"- Schedule a recurring pipeline run.\n",
"- Specify which service account to use for a pipeline run."
]
@@ -111,7 +117,7 @@
"source": [
"### Set up your local development environment\n",
"\n",
"If you are using Colab or Google Cloud Notebook, your environment already meets all the requirements to run this notebook. You can skip this step.\n",
"If you are using Colab or Vertex AI Workbench Notebook, your environment already meets all the requirements to run this notebook. You can skip this step.\n",
"\n",
"Otherwise, make sure your environment meets this notebook's requirements. You need the following:\n",
"\n",
@@ -144,7 +150,7 @@
"source": [
"## Installation\n",
"\n",
"Install the latest version of Vertex AI SDK for Python."
"Install the packages required for executing this notebook."
]
},
{
@@ -157,53 +163,20 @@
"source": [
"import os\n",
"\n",
"# Google Cloud Notebook\n",
"if os.path.exists(\"/opt/deeplearning/metadata/env_version\"):\n",
" USER_FLAG = \"--user\"\n",
"else:\n",
" USER_FLAG = \"\"\n",
"# The Vertex AI Workbench Notebook product has specific requirements\n",
"IS_WORKBENCH_NOTEBOOK = os.getenv(\"DL_ANACONDA_HOME\") and not os.getenv(\"VIRTUAL_ENV\")\n",
"IS_USER_MANAGED_WORKBENCH_NOTEBOOK = os.path.exists(\n",
" \"/opt/deeplearning/metadata/env_version\"\n",
")\n",
"\n",
"! pip3 install --upgrade google-cloud-aiplatform $USER_FLAG"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "install_storage"
},
"source": [
"Install the latest GA version of *google-cloud-storage* library as well."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "Q9cY6x132Ouw"
},
"outputs": [],
"source": [
"! pip3 install -U google-cloud-storage $USER_FLAG"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "install_kfp"
},
"source": [
"Install the latest GA version of *KFP SDK* library as well."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "nbULuPjF2Oux"
},
"outputs": [],
"source": [
"! pip3 install $USER kfp --upgrade"
"# Vertex AI Notebook requires dependencies to be installed with '--user'\n",
"USER_FLAG = \"\"\n",
"if IS_WORKBENCH_NOTEBOOK:\n",
" USER_FLAG = \"--user\"\n",
"\n",
"! pip3 install --upgrade google-cloud-aiplatform {USER_FLAG} -q\n",
"! pip3 install -U google-cloud-storage {USER_FLAG} -q\n",
"! pip3 install {USER_FLAG} kfp google-cloud-pipeline-components --upgrade -q"
]
},
{
@@ -397,23 +370,30 @@
"source": [
"### Authenticate your Google Cloud account\n",
"\n",
"**If you are using Google Cloud Notebook**, your environment is already authenticated. Skip this step.\n",
"**If you are using Vertex AI Workbench Notebook**, your environment is already authenticated. Skip this step.\n",
"\n",
"**If you are using Colab**, run the cell below and follow the instructions when prompted to authenticate your account via oAuth.\n",
"**If you are using Colab**, run the cell below and follow the instructions\n",
"when prompted to authenticate your account via oAuth.\n",
"\n",
"**Otherwise**, follow these steps:\n",
"\n",
"In the Cloud Console, go to the [Create service account key](https://console.cloud.google.com/apis/credentials/serviceaccountkey) page.\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",
"**Click Create service account**.\n",
"2. Click **Create service account**.\n",
"\n",
"In the **Service account name** field, enter a name, and click **Create**.\n",
"3. In the **Service account name** field, enter a name, and\n",
" click **Create**.\n",
"\n",
"In the **Grant this service account access to project** section, click the Role drop-down list. Type \"Vertex\" into the filter box, and select **Vertex Administrator**. Type \"Storage Object Admin\" into the filter box, and select **Storage Object Admin**.\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",
"Click Create. A JSON file that contains your key downloads to your local environment.\n",
"5. Click *Create*. A JSON file that contains your key downloads to your\n",
"local environment.\n",
"\n",
"Enter the path to your service account key as the GOOGLE_APPLICATION_CREDENTIALS variable in the cell below and run the cell."
"6. Enter the path to your service account key as the\n",
"`GOOGLE_APPLICATION_CREDENTIALS` variable in the cell below and run the cell."
]
},
{
@@ -432,8 +412,11 @@
"import os\n",
"import sys\n",
"\n",
"# If on Google Cloud Notebook, then don't execute this code\n",
"if not os.path.exists(\"/opt/deeplearning/metadata/env_version\"):\n",
"# If on Vertex AI Workbench, then don't execute this code\n",
"IS_COLAB = \"google.colab\" in sys.modules\n",
"if not os.path.exists(\"/opt/deeplearning/metadata/env_version\") and not os.getenv(\n",
" \"DL_ANACONDA_HOME\"\n",
"):\n",
" if \"google.colab\" in sys.modules:\n",
" from google.colab import auth as google_auth\n",
"\n",
@@ -481,8 +464,9 @@
},
"outputs": [],
"source": [
"if BUCKET_URI == \"\" or BUCKET_URI is None or BUCKET_URI == \"gs://[your-bucket-name]\":\n",
" BUCKET_URI = \"gs://\" + PROJECT_ID + \"aip-\" + TIMESTAMP"
"if BUCKET_NAME == \"\" or BUCKET_NAME is None or BUCKET_NAME == \"[your-bucket-name]\":\n",
" BUCKET_NAME = PROJECT_ID + \"aip-\" + TIMESTAMP\n",
" BUCKET_URI = \"gs://\" + BUCKET_NAME"
]
},
{
@@ -560,12 +544,15 @@
" or SERVICE_ACCOUNT is None\n",
" or SERVICE_ACCOUNT == \"[your-service-account]\"\n",
"):\n",
" # Get your service account from gcloud\n",
" if not IS_COLAB:\n",
" shell_output = !gcloud auth list 2>/dev/null\n",
" SERVICE_ACCOUNT = shell_output[2].replace(\"*\", \"\").strip()\n",
"\n",
" # Get your GCP project id from gcloud\n",
"\n",
" shell_output = !gcloud auth list 2>/dev/null\n",
"\n",
" SERVICE_ACCOUNT = shell_output[2].replace(\"*\", \"\").strip()\n",
" if IS_COLAB:\n",
" shell_output = ! gcloud projects describe $PROJECT_ID\n",
" project_number = shell_output[-1].split(\":\")[1].strip().replace(\"'\", \"\")\n",
" SERVICE_ACCOUNT = f\"{project_number}-compute@developer.gserviceaccount.com\"\n",
"\n",
" print(\"Service Account:\", SERVICE_ACCOUNT)"
]
@@ -614,7 +601,12 @@
},
"outputs": [],
"source": [
"import google.cloud.aiplatform as aip"
"from typing import NamedTuple\n",
"\n",
"import google.cloud.aiplatform as aip\n",
"from kfp import dsl\n",
"from kfp.v2 import compiler\n",
"from kfp.v2.dsl import component"
]
},
{
@@ -664,30 +656,6 @@
"PIPELINE_ROOT = \"{}/pipeline_root/intro\".format(BUCKET_URI)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "additional_imports"
},
"source": [
"Additional imports."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "import_kfp:namedtuple"
},
"outputs": [],
"source": [
"from typing import NamedTuple\n",
"\n",
"from kfp import dsl\n",
"from kfp.v2 import compiler\n",
"from kfp.v2.dsl import component"
]
},
{
"cell_type": "markdown",
"metadata": {
@@ -1267,7 +1235,7 @@
"except Exception as e:\n",
" print(e)\n",
"\n",
"if delete_bucket and \"BUCKET_URI\" in globals():\n",
"if delete_bucket or os.getenv(\"IS_TESTING\"):\n",
" ! gsutil rm -r $BUCKET_URI"
]
}
@@ -155,7 +155,7 @@
"source": [
"### Install additional packages\n",
"\n",
"Install additional package dependencies not installed in your notebook environment, such as {XGBoost, AdaNet, or TensorFlow Hub TODO: Replace with relevant packages for the tutorial}. Use the latest major GA version of each package."
"Install additional package dependencies not installed in your notebook environment, such as XGBoost, AdaNet, or TensorFlow Hub. Use the latest major GA version of each package."
]
},
{
@@ -247,7 +247,7 @@
"\n",
"1. [Make sure that billing is enabled for your project](https://cloud.google.com/billing/docs/how-to/modify-project).\n",
"\n",
"1. [Enable the Vertex AI API](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com). {TODO: Update the APIs needed for your tutorial. Edit the API names, and update the link to append the API IDs, separating each one with a comma. For example, container.googleapis.com,cloudbuild.googleapis.com}\n",
"1. [Enable the Vertex AI API](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com).\n",
"\n",
"1. If you are running this notebook locally, you will need to install the [Cloud SDK](https://cloud.google.com/sdk).\n",
"\n",