Compare commits

...
Author SHA1 Message Date
Andrew FerlitschandGitHub f2371b4f7d Merge branch 'main' into update_model_eval 2022-04-21 11:36:37 -07:00
Andrew Ferlitsch 20cb46cc29 feat: improve notebook for metric compare 2022-04-21 18:34:55 +00:00
Andrew Ferlitsch db1827cb74 feat: improve notebook for metric compare 2022-04-21 18:33:55 +00:00
0137cd106e adds Colab part and minor changes to ml_ops/stage2/get_started_vertex_experiments notebook in community folder (#493)
* updates the get-started-vertex-experiments notebook in the community folder

* ran linter test

* adds the costs section

* ran linter test

* adds colab part and minor changes

* ran linter test

Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>
2022-04-21 09:20:29 -07:00
8b3b63d714 Adds Colab part and minor changes to ml_ops/stage2/get_started_automl_training notebook (#492)
* updates the get-started-automl-training notebook

* ran linter test

* adds --user flag during installation step

* ran linter test

* updates the clean up step

* ran linter test

* adds colab part and minor changes

* ran linter test

Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>
Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
2022-04-21 09:19:34 -07:00
bf79916f29 Adds Colab part to ml_ops/stage1/get_started_bq_datasets notebook (#490)
* adds the updated mlops-stage1-get_started_bq_datasets notebook to the official branch and removes it from the community branch

* removes second instance of create_bigquery_dataset() function

* ran linter test successfully

* adds costs section

* ran linter test successfully

* updates the dependency installation step and GCS bucket explanation

* ran linter test

* adds pyarrow to the installations

* ran linter test

* removes unnecessary installations + adds silent install + moves the notebook back from official to community folder + adds IS_TESTING condition during clean-up

* ran linter test

* resolves the move up?? comment and builtin comment

* ran linter test

* updates textual content about package installation

* ran linter test

* resolves the future-tense and  dependency installations comments

* ran linter test

* updates the header according to template

* ran linter test

* adds Colab part and minor changes

* ran linter test

* updates the enable apis step in setup project section

* ran linter test

* changes vertex to vertex ai

* ran linter test

* moves temporary BQ table deletion outside the delete_storage condition

* ran linter test

Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>
2022-04-21 09:17:49 -07:00
6bf462f79d Notebook fix to handle GCS outputs and resolve (AutoML Tabular Forecasting notebook error: no row field 'name' #453) (#477)
* notebook fix to handle gcs output

* linter test

* minor bug fix and markup added

* linter test

Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>
2022-04-21 09:13:52 -07:00
Andrew FerlitschandGitHub 106cdee495 feat: update model eval metrics for comparison (#498)
* feat: improve notebook for metric compare

* feat: improve notebook for metric compare

* feat: improve notebook for metric compare
2022-04-20 19:21:23 -07:00
Andrew Ferlitsch b702bf3a9e feat: improve notebook for metric compare 2022-04-20 22:17:18 +00:00
Andrew Ferlitsch 36ea560aad feat: improve notebook for metric compare 2022-04-20 22:16:57 +00:00
Andrew Ferlitsch 48e744d004 feat: improve notebook for metric compare 2022-04-20 22:15:55 +00:00
dfb7301733 Inardini - feature store demo blog review (#484)
* review for blog

* linter code passed

Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>
2022-04-18 15:17:17 -07:00
da707b2cbc Made minor changes to custom-tabular-bq-managed-dataset file (#473)
* modified notebook

* modified file

* ran linter test

Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>
2022-04-18 15:07:07 -07:00
873ba9dde9 Made minor changes to get_started_with_rapid_prototyping_bqml_automl file (#459)
* modified file

* made linter changes

* made changes

* linter test issues resolved

* ran linter test

Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>
2022-04-18 15:06:27 -07:00
Andrew FerlitschandGitHub 15c452f39d fix: Issue 451, add db-dtypes to requirements (#458)
* fix: issue 451

* fix: issue 451
2022-04-18 12:14:56 -07:00
Andrew FerlitschandGitHub be7111815b fix: getting SERVICE ACCOUNT 2022-04-18 10:59:44 -07:00
17db1a952b Tabnet - Add serving (#482)
* Start a new branch for TabNet tutorial.

* Clean version Created using Colaboratory

* Created using Colaboratory

* Remove unused import

* format lint

* Remove unused import

* Created using Colaboratory

* Remove unused import

* Fix the first iteration of reviewing except the image location

* add import

* Update the image to vertex

* Force delete the BQ to avoid waiting

* Add codeowner for TabNet

* Remove - from folder name

* Add deployment in Vertex AI

* Add delete the resource

Co-authored-by: Long Le <longtle@google.com>
Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>
2022-04-15 12:51:55 -07:00
Andrew FerlitschandGitHub 455143d0f0 Update README.md 2022-04-15 12:26:06 -07:00
Andrew FerlitschandGitHub f0892852cb Update README.md 2022-04-15 12:24:39 -07:00
Andrew FerlitschandGitHub ca48556d0c feat: add tabnet notebook (#483)
* feat: add BQML+MR example

* feat: add BQML+MR example

* feat: add TFE optimizzed

* feat: add TFE optimizzed

* feat: add raw predict example

* feat: add raw predict example

* feat: add tabnet notebook

* feat: add tabnet notebook
2022-04-15 12:21:51 -07:00
Aleksey VlasenkoandGitHub f961aa3174 Minor updates basing on team feedback (#481) 2022-04-15 10:56:46 -07:00
64c8eca7df Refresh of Distributed Hyperparameter Tuning for Colab (#461)
* notebook refresh from vertex ai sdk project

* linter test

Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>
2022-04-15 08:49:36 -07:00
b3332c1742 minro changes to get_started_with_hpt_pipeline_components (#465)
* minor changes made to notebook

* ran lintertest

* added coment

* ran lintertest

* made changes sujjested in git review

* ran linter test

* changes done as per review

* ran lintertest

Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>
2022-04-14 17:02:23 -07:00
Aleksey VlasenkoandGitHub b35f697a75 Adding samples for Vertex AI Prediction optimized TensorFlow runtime (#475)
* adding Vertex AI optimized TensorFlow runtime samples

* updated URLs, added code to import benchmark.py

* fixed 'Open in Vertex AI Workbench' links

* final cleanup

* added @vlasesnkoalexey as an owner of notebooks/community/vertex_endpoints/optimized_tensorflow_runtime

* rerun linter
2022-04-14 10:14:27 -07:00
3bc32a1d48 Adds Colab part to the ml_ops/stage3/get_started_with_automl_pipelines notebook (#472)
* updates the get-started-automl-pipelines in the mlops/stage3 folder inside community folder

* replaces the unused variable deploy_op with _

* removes the unused Model import

* adds the costs section

* ran linter test

* adds Colab part to the notebook

* ran linter test

Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>
2022-04-12 11:52:06 -07:00
d66f851554 Adds Colab part to the ml_ops/stage3/get_started_with_kubeflow_pipelines notebook (#471)
* updates the mlops/stage3/get_started_with_kubeflow_pipelines.ipynb notebook

* fixes unused variables

* fixes conflicting function names

* ran linter test

* adds colab changes

* ran linter test

Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>
2022-04-12 11:51:34 -07:00
d733f107e1 Made minor changes to get_started_with_custom_training_pipeline_components file (#470)
* added colab related content

* ran linter test

Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>
2022-04-12 11:51:01 -07:00
805e2e1c83 Made minor changes to get_started_with_bqml_pipeline_components file (#469)
* made colab related changes

* ran linter test

Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>
2022-04-12 11:50:18 -07:00
03dc17d9d7 updates ml_ops/stage3/get_started_with_dataproc_serverless_pipelines notebook (adds delete-batch code + adds colab part + updates textual content) in community folder (#464)
* updates: adds delete-batch code  + adds colab part + updates textual content

* sets delete_bucket to False as default

* ran linter test

Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>
2022-04-12 11:49:26 -07:00
a4909f823e Adds changes for Colab support to the ml_ops/stage2/get-started-with-vertex-featstore notebook (#462)
* updates get-started-featurestore notebook in mlops/stage2

* ran linter test

* adds the colab changes and minor textual changes

* ran linter test

* adds the colab changes to the notebook and minor textual changes

* ran linter test

Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>
2022-04-12 11:48:58 -07:00
e91b259595 Made minor changes to file get_started_vertex_training_xgboost.ipynb (#436)
* modified file

* run linter test

* run in colab

* added coment

* run lintertest

* changed as per review coments

* ran lintertest

Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>
2022-04-12 10:08:04 -07:00
14284046e4 Made minor changes to get_started_vertex_tensorboard (#437)
* Adding a notebook

* Ran linter test

* Added Colab

* Ran the linter test

Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>
2022-04-12 10:07:24 -07:00
59a9a5e6ba Notebook Refresh E2E ML on GCP: MLOps stage 2 : experimentation: get started with Vertex Distributed Training (#434)
* notebook refresh from vertex ai sdk project

* update with linter test changes

* linter fix

* linter issue

* notebook colab workbench links

* linter test

* linter fix

* linter test

Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>
2022-04-12 10:06:01 -07:00
Andrew FerlitschandGitHub f3b0a9e0c0 Update README.md 2022-04-11 18:56:52 -07:00
Andrew FerlitschandGitHub 92b572a364 feat: add raw predict example (#468)
* feat: add BQML+MR example

* feat: add BQML+MR example

* feat: add TFE optimizzed

* feat: add TFE optimizzed

* feat: add raw predict example

* feat: add raw predict example
2022-04-11 18:53:45 -07:00
014be9b530 Made minor changes to get_started_with_data_labeling_2 (#463)
* added colab link and made colab related changes

* ran linter test

Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>
2022-04-11 16:07:13 -07:00
fa675e0082 inardini real time churn feature store demo fixes (#455)
* add new notebook version

* linter test done. passed

* simple fix

* add images

* linter test done

* fix image name

* fix file name in the notebook

* linter code run. done

* linter code run. done

* name fixes. linter code done. passed.

* fix project id and region

* test done

* format

* linter test done.

Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>
2022-04-11 16:01:27 -07:00
Andrew FerlitschandGitHub 113cbb9709 Update README.md 2022-04-11 14:54:27 -07:00
Andrew FerlitschandGitHub b72bdc8112 Update README.md 2022-04-11 12:31:03 -07:00
Andrew FerlitschandGitHub 0842fa8354 Update README.md 2022-04-11 12:30:38 -07:00
Andrew FerlitschandGitHub 4e4f3f4095 Ml ops 7v6 (#467)
* feat: add BQML+MR example

* feat: add BQML+MR example

* feat: add TFE optimizzed

* feat: add TFE optimizzed
2022-04-11 12:16:47 -07:00
Andrew FerlitschandGitHub d014febeb9 Update README.md 2022-04-11 11:37:42 -07:00
Andrew FerlitschandGitHub a3264df643 feat: add BQML + MR example (#466)
* feat: add BQML+MR example

* feat: add BQML+MR example
2022-04-11 11:36:50 -07:00
f0208e3e37 Made minor changes to get_started_with_custom_training_pipeline_components (#456)
* modified file

* modified notebook

* ran linter test

Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>
2022-04-08 09:31:37 -07:00
f84e1b9cbc Updates ml_ops/stage3/get-started-kubeflow-pipeline-notebook in the community folder (#449)
* updates the mlops/stage3/get_started_with_kubeflow_pipelines.ipynb notebook

* fixes unused variables

* fixes conflicting function names

* ran linter test

Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>
2022-04-08 09:31:05 -07:00
16b2086031 Made minor changes to get_started_with_bqml_pipeline_components (#444)
* modified notebook

* linter modifications made

Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>
2022-04-08 09:30:20 -07:00
0e24ba565d Updates ml_ops/stage3/get-started-automl-pipeline-notebook in the community folder (#440)
* updates the get-started-automl-pipelines in the mlops/stage3 folder inside community folder

* replaces the unused variable deploy_op with _

* removes the unused Model import

* adds the costs section

* ran linter test

Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>
2022-04-08 09:29:37 -07:00
49718b02a5 Made minor changes to get_started_with_bq_tfdv_pipeline_components (#439)
* modified notebook

* linter test issues resolved

* ran linter test

* added colab option

* ran linter test

Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>
2022-04-08 09:29:03 -07:00
63031ed364 Updates ml_ops/stage2/get_started_vertex_featurestore notebook in community folder. (#426)
* updates get-started-featurestore notebook in mlops/stage2

* ran linter test

Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>
2022-04-08 09:26:57 -07:00
9fd325e25b Made minor changes to file get_started_with_data_labeling (#425)
* modified notebook

* ran linter test

Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>
2022-04-08 09:22:12 -07:00
93af43419c Updates Mlops/stage2/get-started-automl-training notebook in the community folder (#409)
* updates the get-started-automl-training notebook

* ran linter test

* adds --user flag during installation step

* ran linter test

* updates the clean up step

* ran linter test

Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>
Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
2022-04-07 13:03:29 -07:00
c8f0cdb74a Refresh of Distributed Hyperparameter Tuning Notebook (#454)
* notebook refresh

* linter test

* notebook refresh added corrected cleanup

* linter test

* notebook refresh added corrected cleanup

* linter test

Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
2022-04-07 14:07:47 -05:00
19368fe5cc inardini google cloud pipelines dataproc tabular (#445)
* add dataproc components tabular notebook

* add src package

* add codeowner

* linter test done. almost ok except for the flake8 E231. need to follow up with andy

* fix typos based on andy review

* linter test done. review with andy

* hyperparameter_tuning_op fix

* project name

* add delete repo

* fix image

* linter test done

* fix image reference

* fix typo image reference

* minor fixes

* karl fixes

* karl fixes on links

Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
2022-04-07 10:10:33 -07:00
6a05e0eb6c inardini real time churn feature store demo (#448)
* add new notebook version

* linter test done. passed

* simple fix

* add images

* linter test done

* fix image name

* fix file name in the notebook

* linter code run. done

* linter code run. done

Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
2022-04-07 10:21:22 -05:00
40d643f11c Change bq://bigquery-public-data:iowa_liquor_sales_forecasting.2021_sales_predict for PREDICTION_DATASET_BQ_PATH (#423)
Co-authored-by: Jungwoon Lee <jungwoonlee@google.com>
Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
2022-04-07 09:10:10 -05:00
Andrew FerlitschandGitHub 72009cd21b fix: misspelling of BigQuery 2022-04-06 20:15:07 -07:00
Andrew FerlitschandGitHub cc9a50f40b Update get_started_with_vertex_private_endpoints.ipynb 2022-04-06 19:56:51 -07:00
Andrew FerlitschandGitHub e3135e8875 Update README.md 2022-04-06 17:42:45 -07:00
Andrew FerlitschandGitHub 59eb297151 feat: add notebook for private endpoints (#450)
* feat: add notebook for FastAPI server

* feat: add notebook for FastAPI server

* feat: add notebook for FastAPI server

* feat: notebook for private endpoints

* feat: notebook for private endpoints
2022-04-06 17:41:10 -07:00
32b0c1c89e Mco mvmm (#420) - move model monitoring notebook from community to official
* license tweak

* remove unused import json

* fixed a missing import

* add sleep(300) to test my theory

* add missing newline

* put sleep behind a conditional

* revert new notebook name to previous name for compatibility with extant links

* fix quoting syntax error

* reformatted due to relint

Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
2022-04-06 22:37:53 +01:00
3328a8190d Adding sample to use (auto) scaling config for Feature Store online store (#367)
* Add example using auto scale

* Format with nbqa

* Complete sentence

* Give the sample for CreateFeaturestoreRequest only, instead of actual call to create FS to avoid duplicate resource or extra cleanup.

* Remove unused import

* Remove version pinning

* Add try block to avoid error when test was not cleanup properly.

* Lint

* Fix import

* Merge print lro result with the call in the same try block

* Fix typo

Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
Co-authored-by: Morgan Du <morgandu@google.com>
2022-04-05 17:02:49 -07:00
7aa6acdca6 fix UnboundLocalError in TF-Agents Bandits Guide (#446)
In "Step by Step Guide to Building Reinforcement Learning Applications using Vertex AI", the replay_buffer was unbound if training_data_spec_transformation_fn was provided to the train() function

Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
2022-04-05 16:30:40 -05:00
Andrew FerlitschandGitHub 7926ff1264 Update README.md 2022-04-05 11:10:12 -07:00
Andrew FerlitschandGitHub 67b926dfb4 feat: add notebook for FastAPI server (#447)
* feat: add notebook for FastAPI server

* feat: add notebook for FastAPI server

* feat: add notebook for FastAPI server
2022-04-05 11:08:09 -07:00
327f9e7a4b Fix typo in notebook heading. (#443)
* Fix typo in notebook heading.

* Fix linting issues.

Co-authored-by: Win Woo <wwoo@google.com>
2022-04-05 08:43:47 -05:00
Andrew FerlitschandGitHub 8be220d089 fix missing + 2022-04-04 14:40:27 -07:00
Andrew FerlitschandGitHub 2dad40f49f bucket setting fine-tuning 2022-04-04 14:39:45 -07:00
Andrew FerlitschandGitHub 99b724028f Update README.md 2022-04-04 13:51:43 -07:00
Andrew FerlitschandGitHub 909fbcb0d4 feat: notebook for TF Serving binary (#442)
* update: more details to objective on endpoint notebook

* update: more details to objective on endpoint notebook

* update: more details to objective on endpoint notebook

* update: more details to objective on endpoint notebook

* update: workaround for blocking issue

* update: workaround for blocking issue

* fix: reconfigure endpoint

* fix: reconfigure endpoint

* feat: add get started with TF serving functions

* feat: add get started with TF serving functions

* feat: notebook for TF Serving

* feat: notebook for TF Serving
2022-04-04 13:49:39 -07:00
Andrew FerlitschandGitHub 351fc3e4d3 fix: remove unused print_op 2022-04-04 09:05:33 -07:00
252b3d31a3 Inardini bqml components pipeline official blog (#416)
* bqml pipeline notebook for official blog

* add notebook to CODEOWNERS

* add author name

* requirements commenting fix

* linter test done

* unpin the maintenance version for kfp

* fix: install conflicts

* Update google_cloud_pipeline_components_bqml_text.ipynb

* add karl fix

* lint test done

* add andy fixes

* linter test done

* flip order of the special METADATA fix

Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>
Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
Co-authored-by: Andrew Ferlitsch <aferlitsch@gmail.com>
2022-04-04 09:00:17 -07:00
Andrew FerlitschandGitHub bfdfaab38c Update README.md 2022-04-01 16:11:28 -07:00
Andrew FerlitschandGitHub 21a5963f84 feat: notebook for tf serving functions (#438)
* update: more details to objective on endpoint notebook

* update: more details to objective on endpoint notebook

* update: more details to objective on endpoint notebook

* update: more details to objective on endpoint notebook

* update: workaround for blocking issue

* update: workaround for blocking issue

* fix: reconfigure endpoint

* fix: reconfigure endpoint

* feat: add get started with TF serving functions

* feat: add get started with TF serving functions
2022-04-01 16:09:39 -07:00
9452249dce Added a new section called "Grant Dataproc roles to the Service Account" (#433)
* Ml ops 7v2 (#429)

* update: more details to objective on endpoint notebook

* update: more details to objective on endpoint notebook

* update: more details to objective on endpoint notebook

* update: more details to objective on endpoint notebook

* Update README.md

* Add files via upload

* Update README.md

* Delete stage6b.png

* Delete stage6c.png

* Add files via upload

* Delete stage6b.png

* Delete stage6c.png

* Add files via upload

* Delete stage6b.png

* feat: new notebook on endpoints (#430)

* update: more details to objective on endpoint notebook

* update: more details to objective on endpoint notebook

* update: more details to objective on endpoint notebook

* update: more details to objective on endpoint notebook

* update: workaround for blocking issue

* update: workaround for blocking issue

* wrong location

* Create README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* fix: links

* fix: title

* fix: example for reconfiguring the traffic split (#431)

* update: more details to objective on endpoint notebook

* update: more details to objective on endpoint notebook

* update: more details to objective on endpoint notebook

* update: more details to objective on endpoint notebook

* update: workaround for blocking issue

* update: workaround for blocking issue

* fix: reconfigure endpoint

* fix: reconfigure endpoint

* Add section on granting Dataproc IAM roles.

Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>
Co-authored-by: Andrew Ferlitsch <aferlitsch@gmail.com>
Co-authored-by: Win Woo <wwoo@google.com>
2022-03-31 20:14:16 -07:00
Andrew FerlitschandGitHub 49a9df058f fix: example for reconfiguring the traffic split (#431)
* update: more details to objective on endpoint notebook

* update: more details to objective on endpoint notebook

* update: more details to objective on endpoint notebook

* update: more details to objective on endpoint notebook

* update: workaround for blocking issue

* update: workaround for blocking issue

* fix: reconfigure endpoint

* fix: reconfigure endpoint
2022-03-31 15:27:27 -07:00
Andrew FerlitschandGitHub f99b7e5d17 fix: title 2022-03-31 12:28:15 -07:00
Andrew FerlitschandGitHub ac03c57a94 fix: links 2022-03-31 12:27:47 -07:00
Andrew FerlitschandGitHub 2e4cf648c5 Update README.md 2022-03-31 12:27:01 -07:00
Andrew FerlitschandGitHub f000baa328 Update README.md 2022-03-31 12:26:35 -07:00
Andrew FerlitschandGitHub 113f89604a Update README.md 2022-03-31 12:26:01 -07:00
Andrew FerlitschandGitHub 5019a004ce Update README.md 2022-03-31 12:25:42 -07:00
Andrew FerlitschandGitHub a577f3844a Create README.md 2022-03-31 12:25:31 -07:00
Andrew FerlitschandGitHub 88c7f0f690 wrong location 2022-03-31 12:24:20 -07:00
Andrew FerlitschandGitHub a18792499a feat: new notebook on endpoints (#430)
* update: more details to objective on endpoint notebook

* update: more details to objective on endpoint notebook

* update: more details to objective on endpoint notebook

* update: more details to objective on endpoint notebook

* update: workaround for blocking issue

* update: workaround for blocking issue
2022-03-31 12:23:22 -07:00
Andrew FerlitschandGitHub 0b5fc8bb3c Delete stage6b.png 2022-03-30 19:34:52 -07:00
Andrew FerlitschandGitHub 1f77410fda Add files via upload 2022-03-30 19:34:31 -07:00
Andrew FerlitschandGitHub 45fb57f29c Delete stage6c.png 2022-03-30 19:34:11 -07:00
Andrew FerlitschandGitHub 3380b394eb Delete stage6b.png 2022-03-30 19:34:03 -07:00
Andrew FerlitschandGitHub 1286cc5044 Add files via upload 2022-03-30 19:33:20 -07:00
Andrew FerlitschandGitHub 1ce1af791c Delete stage6c.png 2022-03-30 19:31:24 -07:00
Andrew FerlitschandGitHub 2587e329ee Delete stage6b.png 2022-03-30 19:31:15 -07:00
Andrew FerlitschandGitHub 37d4816051 Update README.md 2022-03-30 19:30:19 -07:00
Andrew FerlitschandGitHub d9dff882b8 Add files via upload 2022-03-30 19:29:41 -07:00
Andrew FerlitschandGitHub 26cc2c5278 Update README.md 2022-03-30 19:21:49 -07:00
Andrew FerlitschandGitHub 69aff1bdc4 Ml ops 7v2 (#429)
* update: more details to objective on endpoint notebook

* update: more details to objective on endpoint notebook

* update: more details to objective on endpoint notebook

* update: more details to objective on endpoint notebook
2022-03-30 19:20:41 -07:00
Andrew FerlitschandGitHub 567994f2b1 fix: add missing details to objective in endpoint notebooks (#428)
* update: more details to objective on endpoint notebook

* update: more details to objective on endpoint notebook
2022-03-30 19:16:02 -07:00
Andrew FerlitschandGitHub e316c7b8aa Update README.md 2022-03-30 17:31:59 -07:00
Andrew FerlitschandGitHub c07a059a8b Update README.md 2022-03-30 17:30:46 -07:00
Andrew FerlitschandGitHub 7b4bbffc41 feat: add endpoint notebook (#427)
* feat: add data labeling notebook

* feat: add data labeling notebook

* update: details on dsl.Condition

* update: details on dsl.Condition

* feat: add TFHub model example

* feat: add TFHub model example

* feat: add endpoint notebook

* feat: add endpoint notebook
2022-03-30 15:44:54 -07:00
bdc011ef34 Made some minor changes to get_started_vertex_training_pytorch (#406)
* Added notebook

* Ran linter test

Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
2022-03-30 08:21:22 -05:00
Andrew FerlitschandGitHub 44ea0d7c61 Update README.md 2022-03-28 17:00:01 -07:00
Andrew FerlitschandGitHub aa950e5ee4 feat: add TFHub model example (#422)
* feat: add data labeling notebook

* feat: add data labeling notebook

* update: details on dsl.Condition

* update: details on dsl.Condition

* feat: add TFHub model example

* feat: add TFHub model example
2022-03-28 16:57:04 -07:00
Andrew FerlitschandGitHub 247906e50e fix: WORKDIR in Dockerfile 2022-03-28 15:52:28 -07:00
81b2493a44 Made minor changes to get_started_vertex_training_r (#417)
* addd file

* modified file

* ran linter test

Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>
2022-03-28 13:26:54 -07:00
WhiteSource RenovateandGitHub 97b0edb222 chore(deps): update dependency black to v22.3.0 (#421) 2022-03-28 14:23:25 -05:00
sudarshan-SpringMLandGitHub f0a9e4b9fe added mlops folder to tested_folders file (#418) 2022-03-28 10:37:21 -05:00
Andrew FerlitschandGitHub f35bbcaec5 update: details on dsl.Condition (#415)
* feat: add data labeling notebook

* feat: add data labeling notebook

* update: details on dsl.Condition

* update: details on dsl.Condition
2022-03-26 09:51:01 -07:00
Andrew FerlitschandGitHub 2822061dc9 Update README.md 2022-03-25 16:00:46 -07:00
Andrew FerlitschandGitHub be481c8d17 feat: add data labeling notebook (#414)
* feat: add data labeling notebook

* feat: add data labeling notebook
2022-03-25 15:56:22 -07:00
Andrew FerlitschandGitHub 605a972122 fix: testing issues (#413)
* fix: testing issues

* fix: testing issues
2022-03-25 13:26:53 -07:00
Andrew FerlitschandGitHub 66d98d9fe7 fix: testing issues (#412)
* fix: test failures

* fix: test failures
2022-03-25 10:58:39 -07:00
Krishna Chaitanya MovvaandGitHub 6445ed37c9 Updates the Mlops/stage2/ get-started-vertex-experiments notebook in the community folder (#410)
* updates the get-started-vertex-experiments notebook in the community folder

* ran linter test

* adds the costs section

* ran linter test
2022-03-25 10:52:21 -05:00
Andrew FerlitschandGitHub ca745aeee8 fix: better cleanup (#407)
* update: for official

* update: for official

* cleanup: add deleting model/endpoint created from pipeline

* cleanup: add deleting model/endpoint created from pipeline

* feat: add dataproc notebook

* feat: add dataproc notebook

* fix: better cleanup

* fix: better cleanup
2022-03-24 18:58:43 -07:00
f806b4927b Adds updated Mlops/stage1/get-started-bq notebook to the community folder (#392)
* adds the updated mlops-stage1-get_started_bq_datasets notebook to the official branch and removes it from the community branch

* removes second instance of create_bigquery_dataset() function

* ran linter test successfully

* adds costs section

* ran linter test successfully

* updates the dependency installation step and GCS bucket explanation

* ran linter test

* adds pyarrow to the installations

* ran linter test

* removes unnecessary installations + adds silent install + moves the notebook back from official to community folder + adds IS_TESTING condition during clean-up

* ran linter test

* resolves the move up?? comment and builtin comment

* ran linter test

* updates textual content about package installation

* ran linter test

* resolves the future-tense and  dependency installations comments

* ran linter test

* updates the header according to template

* ran linter test

Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
2022-03-24 14:16:51 -05:00
2942eb5d7f minor changes on Sdk automl tabular regression online bq1 (#369)
* add automl tabular regression online bq with minor changes

* Run Linter

* Fix errors from the CLA test

* run linter

* resolve issue.

* run Linter

* Merge

* test lint

* fix for linter test

* add automl tabular regression online bq with minor changes

* Run Linter

* Fix errors from the CLA test

* run linter

* resolve issue.

* run Linter

* Merge

* test lint

* fix for linter test

* Fix Bucket name variable

* run linter

Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
2022-03-24 14:16:30 -05:00
2a5d6650ee Adds updated Mlops/stage2/get-started-bqml-training notebook to the community folder (#397)
* adds the ml_ops/stage2/get_Started_bqml_training notebook to official and removes the same from community folder

* ran linter test

* updates the textual content

* ran linter test

* moves the updated stage2/get-started-bqml notebook back to the communit folder

* ran linter test

* updates the header according to the template

* ran linter test

Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
2022-03-24 14:11:01 -05:00
Andrew FerlitschandGitHub 43e971f57a Update README.md 2022-03-24 11:38:17 -07:00
Andrew FerlitschandGitHub 785779613b feat: add dataproc notebook (#405)
* update: for official

* update: for official

* cleanup: add deleting model/endpoint created from pipeline

* cleanup: add deleting model/endpoint created from pipeline

* feat: add dataproc notebook

* feat: add dataproc notebook
2022-03-23 15:43:53 -07:00
Andrew FerlitschandGitHub 481193f0ca cleanup: delete created resources in the pipeline (#404)
* update: for official

* update: for official

* cleanup: add deleting model/endpoint created from pipeline

* cleanup: add deleting model/endpoint created from pipeline
2022-03-23 14:06:58 -07:00
Karl WeinmeisterandGitHub 2cb3cccd14 Fix: Linting issues in two tower notebook (#402) 2022-03-22 16:08:12 -05:00
7c16766994 minor changes in sdk automl image object detection batch (#370)
* Add minor changes to automl image object detection

* run linter

* Correct the milli nodes hours

* fix errors

* fix getenv

* Run linter

* remove tabular notebook, wrongly added

* Correct the bucket varible and minor changes to text

* Run linter

Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>
2022-03-22 13:18:27 -07:00
Andrew FerlitschandGitHub 448d18deca update: for official (#401)
* update: for official

* update: for official
2022-03-22 09:26:34 -07:00
97022b0733 Feat: Add Pluto on Workbench tutorial (#399)
* Initial commit

* Undo master commit

* Initial commit

* Update CODEOWNERS

* Add links to resolve PR comments

Co-authored-by: Ward K Harold <wkh@google.com>
Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
2022-03-22 10:10:46 -05:00
c2a3e2d4cd deprecate: gapic XAI notebooks replaced by SDK notebooks (#394)
* deprecate: replaced by SDK notebook

* deprecate: replaced by SDK notebook

* deprecate: replaced by SDK notebook

* deprecate: replaced by SDK notebook

Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
2022-03-22 09:46:47 -05:00
manuelamunateguiandGitHub b2dfcf17c8 E2E ML on GCP: MLOps stage 2 : experimentation: get started with Vertex Training for Scikit-Learn (#398)
* notebook refresh

* linter test after refresh
2022-03-22 09:37:09 -05:00
Andrew FerlitschandGitHub d061f09281 fix: replace os.environ with os.getenv - 2nd batch (#396)
* fix: replace os.environ with os.getenv

* fix: replace os.environ with os.getenv

* fix: replace os.environ with os.getenv

* fix: replace os.environ with os.getenv

* fix: replace os.environ with os.getenv

* fix: replace os.environ with os.getenv

* fix: replace os.environ with os.getenv

* fix: replace os.environ with os.getenv

* fix: replace os.environ with os.getenv
2022-03-19 12:02:47 -05:00
daa64efd40 fix: replace os.environ with os.getenv (#393)
* fix: use os.getenv()

* fix: use os.getenv()

* fix: use os.getenv()

* fix: use os.getenv()

* fix: use os.getenv()

Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
2022-03-18 16:44:34 -05:00
Andrew FerlitschandGitHub a37deabe27 Update README.md 2022-03-18 13:15:34 -07:00
Andrew FerlitschandGitHub 6009ef0def Update README.md 2022-03-18 13:14:34 -07:00
Andrew FerlitschandGitHub edc644b0d0 Update README.md 2022-03-18 13:13:15 -07:00
Andrew FerlitschandGitHub 1297af8baf Create README.md 2022-03-18 13:11:38 -07:00
Andrew FerlitschandGitHub b8b1b6675b Update README.md 2022-03-18 13:09:51 -07:00
Andrew FerlitschandGitHub 7d3b7abc44 fix: review updates (#395)
* feat: add CPR notebook

* feat: add CPR notebook

* feat: add CPR notebook

* feat: add CPR notebook

* feat: finalize CPR notebook

* feat: finalize CPR notebook

* feat: notebook for bqml+automl

* feat: notebook for bqml+automl

* review: edits per Erwin review

* review: edits per Erwin review
2022-03-18 12:09:53 -07:00
Rajesh ThallamandGitHub 9a572f298e [community-content] Notebook to demo NVIDIA Triton Inference Server on Vertex AI Prediction (#391)
* Add NVIDIA Triton on Vertex AI Prediction official notebook

* Add NVIDIA Triton on Vertex AI Prediction official notebook

* Add NVIDIA Triton on Vertex AI Prediction official notebook

* Add NVIDIA Triton on Vertex AI Prediction community notebook

* Add NVIDIA Triton on Vertex AI Prediction community notebook

* Add NVIDIA Triton on Vertex AI Prediction community notebook

* Fixes based on feedback to NVIDIA Triton on Vertex AI Prediction community notebook
2022-03-18 11:31:01 -05:00
b53ca9e678 Tabnet (#375)
* Start a new branch for TabNet tutorial.

* Clean version Created using Colaboratory

* Created using Colaboratory

* Remove unused import

* format lint

* Remove unused import

* Created using Colaboratory

* Remove unused import

* Fix the first iteration of reviewing except the image location

* add import

* Update the image to vertex

* Force delete the BQ to avoid waiting

* Add codeowner for TabNet

* Remove - from folder name

Co-authored-by: Long Le <longtle@google.com>
Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
2022-03-17 17:20:01 -05:00
Andrew FerlitschandGitHub 9aceec161a Update README.md 2022-03-17 14:50:24 -07:00
Andrew FerlitschandGitHub 98b186ed55 feat: notebook for bqml+automl combined (#390)
* feat: add CPR notebook

* feat: add CPR notebook

* feat: add CPR notebook

* feat: add CPR notebook

* feat: finalize CPR notebook

* feat: finalize CPR notebook

* feat: notebook for bqml+automl

* feat: notebook for bqml+automl
2022-03-17 14:46:29 -07:00
sudarshan-SpringMLandGitHub f23ee1b5a8 Made small changes to Get started vertex vizier notebook (#389)
* modified notebook

* ran linter test

* modified notebook changed copyright licence year

* ran linter test
2022-03-17 10:03:19 -05:00
c6d779f1fc Featurestore colab update (#387)
* update featurestore colab comment

* delete some changes

* delete some changes 2

Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
2022-03-16 21:31:22 -05:00
Andrew FerlitschandGitHub 8908b27b08 feat: finish CPR notebook (#388)
* feat: add CPR notebook

* feat: add CPR notebook

* feat: add CPR notebook

* feat: add CPR notebook

* feat: finalize CPR notebook

* feat: finalize CPR notebook
2022-03-16 14:00:03 -07:00
Andrew FerlitschandGitHub 8947c9b116 feat: more CPR (#385)
* feat: add CPR notebook

* feat: add CPR notebook

* feat: add CPR notebook

* feat: add CPR notebook
2022-03-15 11:56:29 -07:00
Andrew FerlitschandGitHub 9464caac6e Update README.md 2022-03-14 17:40:15 -07:00
Andrew FerlitschandGitHub 98ce91c575 feat: add CPR notebook (#384)
* feat: add CPR notebook

* feat: add CPR notebook
2022-03-14 17:38:47 -07:00
Andrew FerlitschandGitHub 07f8feda3d Update README.md 2022-03-14 11:19:31 -07:00
Andrew FerlitschandGitHub a4e0496ff5 feat: CMEK training (#383)
* feat: add FS from panda

* feat: add FS from panda

* feat: add CMEK example

* feat: add CMEK example
2022-03-14 11:15:35 -07:00
cf162c02c8 chore(deps): update dependency pyupgrade to v2.31.1 (#381)
Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
2022-03-14 09:34:58 -05:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>Karl Weinmeister
831aae94df build(deps): bump pillow (#378)
Bumps [pillow](https://github.com/python-pillow/Pillow) from 9.0.0 to 9.0.1.
- [Release notes](https://github.com/python-pillow/Pillow/releases)
- [Changelog](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst)
- [Commits](https://github.com/python-pillow/Pillow/compare/9.0.0...9.0.1)

---
updated-dependencies:
- dependency-name: pillow
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
2022-03-14 09:33:36 -05:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>Karl Weinmeister
3fd9f28778 build(deps): bump pillow (#379)
Bumps [pillow](https://github.com/python-pillow/Pillow) from 9.0.0 to 9.0.1.
- [Release notes](https://github.com/python-pillow/Pillow/releases)
- [Changelog](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst)
- [Commits](https://github.com/python-pillow/Pillow/compare/9.0.0...9.0.1)

---
updated-dependencies:
- dependency-name: pillow
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
2022-03-14 09:32:20 -05:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
a656e8e2a8 build(deps): bump pillow (#380)
Bumps [pillow](https://github.com/python-pillow/Pillow) from 9.0.0 to 9.0.1.
- [Release notes](https://github.com/python-pillow/Pillow/releases)
- [Changelog](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst)
- [Commits](https://github.com/python-pillow/Pillow/compare/9.0.0...9.0.1)

---
updated-dependencies:
- dependency-name: pillow
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-14 09:30:19 -05:00
Morgan DuandGitHub 2f02152703 fix: pip install google-cloud-aiplatform (#376) 2022-03-10 12:00:08 -06:00
9d08f8ce67 Using BQML 1st-party components and upgrading to 1.0.0 of google-cloud-pipeline-components (#372)
* Using BQML 1st-party components and 1.0.0 of google-cloud-pipeline-components

* Using BQML 1st-party components and upgrading to 1.0.0 of google-cloud-pipeline-components

* Using BQML 1st-party components and upgrading to 1.0.0 of google-cloud-pipeline-components

* Using BQML 1st-party components and upgrading to 1.0.0 of google-cloud-pipeline-components

* Using BQML components and upgrade to 1.0.0 of GCPC

Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
2022-03-09 13:34:12 -06:00
ec6d508793 adds automl-text-sentiment-analysis-online notebook (#293)
* adds automl-text-sentiment-analysis-online notebook

* adds the cleaned up automl-text-sentiment-analysis notebook after running linter test

* adds textual content on what the dataset predicts in the dataset section

* ran the linter test after the update

* adds textual content on what the dataset predicts in the dataset section

* ran the linter test after the update

* corrects the IMPORT_FILE parameter in the notebook

* ran linter test after update

* deletes the source file from the community/sdk folder

* updates the colab, git & workbench links in the notebook

* ran linter test

* updates the license year to 2022 and simplifies the clean-up step for bucket-deletion

* ran linter test

* adds TESTING env condition while deleting the buckets

* ran linter test successfully

Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>
Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
2022-03-09 13:09:10 -06:00
WhiteSource RenovateandGitHub 772e35ea75 chore(deps): update dependency nbqa to v1.3.1 (#374) 2022-03-09 08:24:16 -06:00
Andrew FerlitschandGitHub 1d28f886c8 feat: add example of FS values from dataframe (#373)
* feat: add FS from panda

* feat: add FS from panda
2022-03-08 17:44:59 -08:00
Andrew FerlitschandGitHub d3dc8aeb9a fix: missing create dataset schema (#371)
* fix: missing dataset create

* fix: missing dataset create
2022-03-07 11:53:39 -08:00
WhiteSource RenovateandGitHub a07d762934 chore(deps): update dependency nbqa to v1.3.0 (#368) 2022-03-07 09:53:42 -06:00
Andrew FerlitschandGitHub 85ac9e127d update: v1 (#366)
* fix: v1 upgrades

* fix: v1 upgrades

* fix: v1 upgrades

* fix: v1 upgrades

* update: v1

* update: v1
2022-03-04 17:47:56 -08:00
Gal ZahaviandGitHub 011c2823ff Update CODEOWNERS (#361) 2022-03-04 22:43:10 +02:00
Karl WeinmeisterandGitHub f28a94f03f docs: Add visualization of repo structure to README.md (#364) 2022-03-04 12:46:26 -06:00
5ecfc80cb9 Adds minor changes(license year and clean-up step) to Sdk automl video action recognition batch notebook (#355)
* adds the automl-video-action-recognition-notebook

* ran linter test

* fixes the dag variable by replacing with job

* ran linter test

* fixes the dag variable by replacing with job

* ran linter test

* corrects the IMPORT_FILE parameter in the notebook

* ran linter test after update

* updates the colab, git & vertex-ai links

* ran linter test

* updates the license year to 2022 and simplifies the lean-up step for bucket created

* ran linter test

* removes the file from the community folder

* adds the TESTING env condition while deleting the buckets

* ran linter test successfully

* adds TESTING env condition while deleting the bucket

* ran linter test successfully

Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>
Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
2022-03-04 12:44:39 -06:00
Andrew FerlitschandGitHub e5e36ba050 fix: upgrades to v1 (#360)
* fix: v1 upgrades

* fix: v1 upgrades

* fix: v1 upgrades

* fix: v1 upgrades
2022-03-03 20:05:36 -08:00
Andrew FerlitschandGitHub 0ad9116d6a fix: v1 upgrades (#359)
* fix: v1 upgrades

* fix: v1 upgrades
2022-03-03 17:49:45 -08:00
0516032443 Update CODEOWNERS (#354)
* Update CODEOWNERS

* Update CODEOWNERS

Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
2022-03-03 10:23:19 -06:00
95d211c90f Fixing minor issues in sdk_automl_text_entity_extraction_online.ipynb (#329)
* modified colab,github,vertexAI links and added vertex logo

* ran linter

* resolved comments

* ran linter

Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
2022-03-03 10:17:48 -06:00
12d6a75ef7 Fixing minor issues in sdk_automl_video_object_tracking_batch.ipynb (#328)
* changed master to main for links and added vertex AI logo

* ran linter

* resolved comments

* ran linter

Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
2022-03-03 10:07:50 -06:00
Andrew FerlitschandGitHub 06153dc373 Update README.md 2022-03-02 11:45:01 -08:00
Andrew FerlitschandGitHub 02afa91fc3 Ml ops 6v3 (#352)
* fix: eval comp improvement

* fix: eval comp improvement

* feat: add to KFP get started
2022-03-02 10:38:42 -08:00
Karl WeinmeisterandGitHub c8b212789f Revert "ci: Apply filter to format_and_lint_job (#348)" (#351)
This reverts commit 95256d3fcf.
2022-03-02 09:44:03 -06:00
Karl WeinmeisterandGitHub 95256d3fcf ci: Apply filter to format_and_lint_job (#348)
* ci: Apply filter to format_and_lint_job

Only run when PR contains a notebook file

* Minor fix
2022-03-02 09:29:38 -06:00
Karl WeinmeisterandGitHub 8a6d174c99 Create README.md for notebooks folder 2022-03-01 19:44:41 -06:00
WhiteSource RenovateandGitHub d36cf7f662 chore(deps): update actions/setup-python action to v3 (#337) 2022-03-01 19:04:32 -06:00
WhiteSource RenovateandGitHub 1b02a542c8 chore(deps): update actions/checkout action to v3 (#347) 2022-03-01 19:02:39 -06:00
Ivan CheungandGitHub 45430bb010 Fixed minor issues (#345) 2022-03-01 14:56:50 -06:00
Ivan CheungandGitHub be2a139ade Delete notebooks/community/feature_store/assets directory 2022-02-28 20:21:17 -05:00
70d77b24f6 feature store e2e with assets (#343)
* A notebook that shows Vertex AI feature store capabilities in a real-world scenario (#296)

* A notebook that shows Vertex AI feature store capabilities in a real-world scenario

* new notebook version

* fix CODEOWNERS

* comment to the feature store monitoring api

* format notebook

* fix CODEOWNERS

* fix CODEOWNERS as required

* new version

* new notebook version

* notebook cleaning

* new update

* add fix to pass lint test

* resolve conflict

* import libraries fix

* update image

* update notebook

* fix comment

* new notebook version

* new notebook and assets

Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>

* Added files in their old folder

* Deleted unneeded file

* Ran linter

* Fixed CODEOWNERS

Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>
Co-authored-by: ivanmkc <ivans.mailbox@gmail.com>
2022-02-28 19:23:15 -05:00
Ivan CheungandGitHub 50c25d6d7b Revert "A notebook that shows Vertex AI feature store capabilities in a real-world scenario (#296)" (#338)
This reverts commit 5bcdc0bc64.
2022-02-28 11:01:39 -05:00
5bcdc0bc64 A notebook that shows Vertex AI feature store capabilities in a real-world scenario (#296)
* A notebook that shows Vertex AI feature store capabilities in a real-world scenario

* new notebook version

* fix CODEOWNERS

* comment to the feature store monitoring api

* format notebook

* fix CODEOWNERS

* fix CODEOWNERS as required

* new version

* new notebook version

* notebook cleaning

* new update

* add fix to pass lint test

* resolve conflict

* import libraries fix

* update image

* update notebook

* fix comment

* new notebook version

* new notebook and assets

Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>
2022-02-28 07:47:26 -08:00
eff0f95b58 Automl links fix (#330)
* fixing links to open notebook - main and images

* linter test changes

Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
2022-02-27 15:57:25 -06:00
50b53d31bd Jfacevedo endpoints tfhub obj detect (#319)
* Deploying TF Hub object detection model using Vertex endpoints

* Add user to codeowners

* fix path in CODEOWNERS

* clear all outputs

* run linter

* manual lint fix

* fix more linting errors

* order imports in alphabetical order

* run linter

* made changes requested on feedback

* automate fetching endpoint model id

* fix hardcoded value in bash command

* generalize region endpoint and project in bash cell

* retrieve endpoint and model ids programatically

* fix formatting

* run linter

* Remove pipfile

Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
2022-02-27 15:55:54 -06:00
Andrew FerlitschandGitHub b5a56852f3 fix: automl eval component improvement (#333)
* fix: eval comp improvement

* fix: eval comp improvement
2022-02-25 12:07:06 -08:00
b7486e34ad Sdk automl video action recognition batch (#310)
* adds the automl-video-action-recognition-notebook

* ran linter test

* fixes the dag variable by replacing with job

* ran linter test

* fixes the dag variable by replacing with job

* ran linter test

* corrects the IMPORT_FILE parameter in the notebook

* ran linter test after update

* updates the colab, git & vertex-ai links

* ran linter test

Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>
Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
2022-02-25 11:31:19 -06:00
3edc5f1425 Notebook template (#326)
* modified vertex AI link

* minor change

* changed master to main and added vertex logo

* ran lint

Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
2022-02-25 10:16:34 -06:00
65b4b73cb5 Add google_cloud_pipeline_components_model_upload_predict_evaluate notebook (#288)
* Add google_cloud_pipeline_components_model_upload_predict_evaluate notebook.ipynb

* format with linter

* add import for tensorflow when in the testing environment

* linter

* fix dependency issues for testing env

* address comments

* eval component  does not output gcp_resources yet, still in experimental

* added location to aip.init

* add deletion for model and batch prediction jobs

* typo, missed a comma.

* linter

* Remove tensorflow import + use gsutil to check if artifacts exist.

Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>
Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
2022-02-24 15:36:35 -08:00
Ivan CheungandGitHub 186c08e8c3 Update sdk_matching_engine_for_indexing.ipynb 2022-02-24 17:47:53 -05:00
Ivan CheungandGitHub 7721aa0def Added matching engine with SDK notebook (#327)
* Matching engine

* Added notebook

* Updated CODEOWNERS

* Fixed links

* Added logo

* Renamed Workbench
2022-02-24 14:57:16 -05:00
4987c60e03 updating gcloud usage because a flag was renamed (#320)
Co-authored-by: Yicheng Fang <yichengfang@google.com>
Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
2022-02-24 09:33:33 -06:00
Andrew FerlitschandGitHub cd845f7fdd feat: start on model eval notebook (#325)
* fix: bqml export format

* fix: bqml export format

* feat: start on custom model eval

* feat: start on custom model eval
2022-02-23 12:56:01 -08:00
Andrew FerlitschandGitHub 9e84d9e782 fix: bqml doc for exporting model (#324)
* fix: bqml export format

* fix: bqml export format
2022-02-23 12:44:43 -08:00
nayaknishantandGitHub 23c7fcc97f fix: changed bucket URL from pantheon to console (#323)
* moving REGION up

* moving REGION up and csv file name

* fix: changed bucket URL to console
2022-02-23 13:17:12 -06:00
e4024efbc7 feat: add community notebook for Vertex AI SDK Feature Store with Pandas (#311)
* feat: add sdk-feature-store-pandas notebook

* fix: add ldap to codeowners

* feat: add sdk-feature-store-pandas notebook

* fix: add ldap to codeowners

* fix: lint

* fix: addressed feedback

* fix: format

* fix: lint

* Linted

Co-authored-by: Karl Weinmeister <11586922+kweinmeister@users.noreply.github.com>
Co-authored-by: Andrew Ferlitsch <aferlitsch@google.com>
Co-authored-by: ivanmkc <ivans.mailbox@gmail.com>
2022-02-23 10:22:28 -08:00
Ivan CheungandGitHub c4d53108af Matching Engine: Updated location for data (#322)
Switched to gs://cloud-samples-data/vertex-ai/matching_engine/glove-100-angular.hdf5
2022-02-23 12:03:48 -05:00
119 changed files with 50675 additions and 17673 deletions
+1
View File
@@ -1,2 +1,3 @@
notebooks/official
notebooks/notebook_template.ipynb
notebooks/community/ml_ops
+2 -2
View File
@@ -7,9 +7,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Set up Python
uses: actions/setup-python@v2
uses: actions/setup-python@v3
- name: Fetch pull request branch
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Fetch base main branch
+3 -3
View File
@@ -2,8 +2,8 @@ git+https://github.com/tensorflow/docs
ipython
jupyter
nbconvert
black==22.1.0
pyupgrade==2.31.0
black==22.3.0
pyupgrade==2.31.1
isort==5.10.1
flake8==4.0.1
nbqa==1.2.3
nbqa==1.3.1
+13 -1
View File
@@ -6,7 +6,19 @@ Welcome to the Google Cloud [Vertex AI](https://cloud.google.com/vertex-ai/docs/
## Overview
The repository contains [Notebooks](https://github.com/GoogleCloudPlatform/vertex-ai-samples/tree/master/notebooks) and [Community Content](https://github.com/GoogleCloudPlatform/vertex-ai-samples/tree/master/community-content) that demonstrate how to develop and manage ML workflows using Google Cloud Vertex AI.
The repository contains [notebooks](https://github.com/GoogleCloudPlatform/vertex-ai-samples/tree/master/notebooks) and [community content](https://github.com/GoogleCloudPlatform/vertex-ai-samples/tree/master/community-content) that demonstrate how to develop and manage ML workflows using Google Cloud Vertex AI.
## Repository structure
```bash
├── community-content - Sample code and tutorials contributed by the community
├── notebooks
│ ├── community - Notebooks contributed by the community
│ ├── official - Notebooks demonstrating use of each Vertex AI service
│ │ ├── automl
│ │ ├── custom
│ │ ├── ...
```
## Contributing
+1
View File
@@ -3,3 +3,4 @@
/pytorch_text_classification_using_vertex_sdk_and_gcloud @RajeshThallam
/pytorch_text_classification_using_vertex_sdk_and_gcloud @RajeshThallam @ultrons
/sklearn_text_classification_from_script_using_vertex_sdk @maxhardt
/pluto_on_workbench @wkharold
@@ -0,0 +1,52 @@
# Overview
*Pluto* is a programming environment for Julia, designed to be interactive and helpful. It provides a familiar notebook interface but it is not a Jupyter notebook. The biggest difference is that Pluto notebooks are reactive, changing a variable or function in one cell causes the cells that depend on that variable or function to be reevaluated. Pluto also provides useful interaction mechanisms that allow users to dynamically interact with the notebooks computation state.
The JuliaCon 2020 presentation: [Interactive notebooks ~ Pluto.jl]() provides a good introduction to Pluto. The source is at [fonsp/Pluto.jl]()
# Install Pluto
## Create a Vertex AI JupyterLab Instance
1. From the [GCP console](https://console.cloud.google.com) "hamburger menu"
select Vertex AI > Workbench
2. Click NEW NOTEBOOK
* Choose Python 3 if you won't be using a GPU
* Choose Python 3 (CUDA Toolkit xx.y) if you do want use a GPU
3. Give the notebook an appropriate name
4. Edit Notebook properties if you have special requirements otherwise accept the defaults and click CREATE
5. When the notebook instance is ready click OPEN JUPYTERLAB
## Configure JupyterLab
1. Open a terminal by clicking the Terminal icon.
1. Install the plutoserver
pip3 install git+https://github.com/fonsp/pluto-on-jupyterlab.git
1. In a browser go to [julialang.org/downloads](https://julialang.org/downloads/)
1. In the Current stable release right click on the `Generic Linux on x86 / 64-bit (glibc)` link
Select copy link address
1. Back in the terminal switch to root via
sudo -i
1. Download the release to /opt and install julia in /usr/local/bin
```bash
cd /opt
wget <paste the release link address>
tar xf <name of the downloaded tar file>
ln -s /opt/<julia-x.y.z>/bin/julia /usr/local/bin
^d
```
1. Add the Pluto package to Julia
```bash
julia
julia> ]add Pluto
julia> bksp
julia> using Pluto
julia> ^d
```
1. From the JupyterLab menu bar select File > Shut Down
# Start Pluto
1. Click OPEN JUPYTERLAB in the Workbench
1. In the Notebook section of the Launcher click Pluto.jl
1. The welcome to Pluto.jl screen should appear
@@ -1,4 +1,4 @@
google-cloud-bigquery==2.20.0
tensorflow==2.5.3
pillow==9.0.0
pillow==9.0.1
tf-agents==0.8.0
@@ -1,4 +1,4 @@
google-cloud-pubsub==2.5.0
pillow==9.0.0
pillow==9.0.1
tf-agents==0.8.0
tensorflow==2.5.3
@@ -1,5 +1,5 @@
dataclasses==0.6
google-cloud-aiplatform==1.8.1
tensorflow==2.5.3
pillow==9.0.0
pillow==9.0.1
tf-agents==0.8.0
@@ -706,8 +706,8 @@
" else:\n",
" data_spec = training_data_spec_transformation_fn(\n",
" agent.policy.trajectory_spec)\n",
" replay_buffer = trainer.get_replay_buffer(data_spec, environment.batch_size,\n",
" steps_per_loop)\n",
" replay_buffer = trainer.get_replay_buffer(data_spec, environment.batch_size,\n",
" steps_per_loop)\n",
"\n",
" # `step_metric` records the number of individual rounds of bandit interaction;\n",
" # that is, (number of trajectories) * batch_size.\n",
@@ -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",
@@ -113,8 +113,8 @@
},
"outputs": [],
"source": [
"! gcloud beta ai custom-jobs local-run \\\n",
" --base-image=$BASE_IMAGE_URI \\\n",
"! gcloud ai custom-jobs local-run \\\n",
" --executor-image-uri=$BASE_IMAGE_URI \\\n",
" --script=$SCRIPT_PATH \\\n",
" --output-image-uri=$OUTPUT_IMAGE_NAME \\\n",
" -- \\\n",
+5
View File
@@ -0,0 +1,5 @@
The [official](https://github.com/GoogleCloudPlatform/vertex-ai-samples/tree/main/notebooks/official) folder contains notebooks organized by Google Cloud product.
The [community](https://github.com/GoogleCloudPlatform/vertex-ai-samples/tree/main/notebooks/community) folder contains notebooks that aren't officially supported by Google.
Contributions to the repo should use the [notebook template](https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/notebook_template.ipynb) as a starting point.
+13 -12
View File
@@ -3,19 +3,20 @@
# @global-owner1 and @global-owner2 will be requested for
# review when someone opens a pull request.
/sdk/sdk_* @aferlitsch
/gapic @aferlitsch
/ml_ops @aferlitsch
/model_monitoring/* @mco
/sdk/sdk_* @andrewferlitsch
/gapic @andrewferlitsch
/ml_ops @andrewferlitsch
/model_monitoring/* @mco-gh
/structured_data/rapid_prototyping_* @rafael-carvalho
/managed_notebooks/ @notebooks-team
/sdk/SDK_FBProphet_Forecasting_Online.ipynb @brianchunkang
/managed_notebooks/
/sdk/SDK_FBProphet_Forecasting_Online.ipynb @brianchunkang
/pipelines/google_cloud_pipeline_components_TPU_model_train_upload_deploy.ipynb @brianchunkang
/sdk/SDK_AutoML_Forecasting_Model_Training_Example.ipynb @thehardikv
/sdk/sdk_automl_forecasting_evaluating_a_model.ipynb @thehardikv
/matching_engine @yinghsienwu
/neo4j @benofben @htappen
/matching_engine/sdk_matching_engine_for_indexing.ipynb @ivanmkc
/matching_engine/matching_engine_for_indexing.ipynb @yinghsienwu
/sdk/pytorch_lightning_custom_container_training.ipynb @brianchunkang
/tensorboard @yfang1 @wattli
/feature_store @nayaknishant
/tensorboard @yfang1
/feature_store @nayaknishant @morgandu
/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
Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

File diff suppressed because it is too large Load Diff
@@ -180,7 +180,7 @@
},
"outputs": [],
"source": [
"! pip install {USER_FLAG} --upgrade git+https://github.com/googleapis/python-aiplatform.git@main"
"! pip install {USER_FLAG} --upgrade google-cloud-aiplatform"
]
},
{
@@ -742,7 +742,7 @@
"source": [
"### Source Data Format and Layout\n",
"\n",
"BigQuery table/Avro/CSV are supported as input data types. No matter what format you are using, each imported entity *must* have an ID; also, each entity can *optionally* have a timestamp, specifying when the feature values are generated. This Colab uses Avro as an input, located at this public [bucket](https://pantheon.corp.google.com/storage/browser/cloud-samples-data-us-central1/vertex-ai/feature-store/datasets). The Avro schemas are as follows:\n",
"BigQuery table/Avro/CSV are supported as input data types. No matter what format you are using, each imported entity *must* have an ID; also, each entity can *optionally* have a timestamp, specifying when the feature values are generated. This Colab uses Avro as an input, located at this public [bucket](https://console.cloud.google.com/storage/browser/cloud-samples-data-us-central1/vertex-ai/feature-store/datasets). The Avro schemas are as follows:\n",
"\n",
"**For the Users entity**:\n",
"```\n",
File diff suppressed because it is too large Load Diff
@@ -459,7 +459,7 @@
},
"outputs": [],
"source": [
"! gsutil cp gs://cloud-samples-data/ai-platform-unified/matching_engine/glove-100-angular.hdf5 ."
"! gsutil cp gs://cloud-samples-data/vertex-ai/matching_engine/glove-100-angular.hdf5 ."
]
},
{
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -12,7 +12,7 @@ The purpose of this set of notebooks and markdown files is to demonstrate Google
2. [Experimentation](stage2)
3. [Formalization](stage3)
4. [Evaluation](stage4)
5. Deployment
6. Serving
5. [Deployment](stage5)
6. [Serving](stage6)
7. Monitoring
8. Continuous Training
@@ -76,6 +76,18 @@ The steps performed include:
- image data
```
[Get Started with Data Labeling](get_started_data_labeling.ipynb)
```
The steps performed include:
- Create a Specialist Pool for data labelers.
- Create a data labeling job.
- Submit the data labeling job.
- List data labeling jobs.
- Cancel a data labeling job.
```
### E2E Stage Example
[Stage 1: Data Management](mlops_data_management.ipynb)
@@ -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",
@@ -38,9 +38,15 @@
" 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/stage1/get_started_bq_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://console.cloud.google.com/ai/platform/notebooks/deploy-notebook?download_url=https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage1/get_started_bq_datasets.ipynb\">\n",
" Open in Google Cloud Notebooks\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/community/ml_ops/stage1/get_started_bq_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",
@@ -67,7 +73,7 @@
"source": [
"### Dataset\n",
"\n",
"The dataset used for this tutorial is the GSOD dataset from [BigQuery public datasets](https://cloud.google.com/bigquery/public-data). The version of the dataset you use only the fields year, month and day to predict the value of mean daily temperature (mean_temp)."
"The dataset used for this tutorial is the GSOD dataset from [BigQuery public datasets](https://cloud.google.com/bigquery/public-data). In this version of the dataset you consider the fields year, month and day to predict the value of mean daily temperature (mean_temp)."
]
},
{
@@ -104,7 +110,7 @@
"source": [
"### Recommendations\n",
"\n",
"When doing E2E MLOps on Google Cloud, the following best practices with structured (tabular) data in BigQuery:\n",
"When doing E2E MLOps on Google Cloud, following are the best practices when dealing with structured (tabular) data in BigQuery:\n",
"\n",
"- For AutoML training:\n",
" - Create a managed dataset with Vertex AI `TabularDataset`.\n",
@@ -124,7 +130,7 @@
" - Within the generator (upstream)\n",
" - Within the model (downstream)\n",
" - XGBoost model training:\n",
" - Use BigQuery ML builtin XGBoost training.\n",
" - Use BigQuery ML built-in XGBoost training.\n",
" - Alternatively, create a DMatrix generator from CSV files extracted from BigQuery table.\n",
" - Pytorch model training:\n",
" - Extract the BigQuery to a pandas dataframe.\n",
@@ -132,10 +138,19 @@
" - Create a DataLoader generator from the pandas dataframe.\n",
"\n",
"\n",
"- Alternately:\n",
"- Alternatively:\n",
" - Extract the BigQuery table to CSV files.\n",
" - Preprocess the CSV files.\n",
" - Create a tf.data.Dataset generator from the CSV files."
" - Create a tf.data.Dataset generator from the CSV files.\n",
" \n",
"### Costs\n",
"This tutorial uses billable components of Google Cloud:\n",
"\n",
"- Vertex AI\n",
"- Cloud Storage\n",
"- BigQuery\n",
"\n",
"Learn about [Vertex AI pricing](https://cloud.google.com/vertex-ai/pricing), [Cloud Storage pricing](https://cloud.google.com/storage/pricing) and [BigQuery pricing](https://cloud.google.com/bigquery/pricing) and use the [Pricing Calculator](https://cloud.google.com/products/calculator/) to generate a cost estimate based on your projected usage."
]
},
{
@@ -146,7 +161,7 @@
"source": [
"## Installations\n",
"\n",
"Install *one time* the packages for executing the MLOps notebooks."
"Install the following packages to execute this notebook."
]
},
{
@@ -157,40 +172,22 @@
},
"outputs": [],
"source": [
"ONCE_ONLY = False\n",
"if ONCE_ONLY:\n",
" ! pip3 install -U tensorflow==2.5 $USER_FLAG\n",
" ! pip3 install -U tensorflow-data-validation==1.2 $USER_FLAG\n",
" ! pip3 install -U tensorflow-transform==1.2 $USER_FLAG\n",
" ! pip3 install -U tensorflow-io==0.18 $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-aiplatform[tensorboard] $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-pipeline-components $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-bigquery $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-logging $USER_FLAG\n",
" ! pip3 install --upgrade apache-beam[gcp] $USER_FLAG\n",
" ! pip3 install --upgrade pyarrow $USER_FLAG\n",
" ! pip3 install --upgrade cloudml-hypertune $USER_FLAG\n",
" ! pip3 install --upgrade kfp $USER_FLAG"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "install_xgboost"
},
"source": [
"Install the latest GA version of *XGBoost* library as well."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "install_xgboost"
},
"outputs": [],
"source": [
"! pip3 install -U xgboost $USER_FLAG"
"import os\n",
"\n",
"# The Google Cloud Notebook product has specific requirements\n",
"IS_GOOGLE_CLOUD_NOTEBOOK = os.path.exists(\"/opt/deeplearning/metadata/env_version\")\n",
"\n",
"# Google Cloud Notebook requires dependencies to be installed with '--user'\n",
"USER_FLAG = \"\"\n",
"if IS_GOOGLE_CLOUD_NOTEBOOK:\n",
" USER_FLAG = \"--user\"\n",
"\n",
"# Install the packages\n",
"! pip3 install --upgrade pyarrow $USER_FLAG\n",
"! pip3 install --upgrade google-cloud-bigquery $USER_FLAG\n",
"! pip3 install --upgrade google-cloud-aiplatform[tensorboard] $USER_FLAG\n",
"! pip3 install -U xgboost $USER_FLAG\n",
"! pip3 install -U tensorflow-io==0.18 $USER_FLAG"
]
},
{
@@ -222,6 +219,39 @@
" app.kernel.do_shutdown(True)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "a47846030fef"
},
"source": [
"## Before you begin"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "84cd83853240"
},
"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, BigQuery, Compute Engine and Cloud Storage APIs](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com,bigquery,compute_component,storage_component).\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."
]
},
{
"cell_type": "markdown",
"metadata": {
@@ -298,7 +328,10 @@
},
"outputs": [],
"source": [
"REGION = \"us-central1\" # @param {type: \"string\"}"
"REGION = \"[your-region]\" # @param {type: \"string\"}\n",
"\n",
"if REGION == \"[your-region]\":\n",
" REGION = \"us-central1\""
]
},
{
@@ -325,6 +358,66 @@
"TIMESTAMP = datetime.now().strftime(\"%Y%m%d%H%M%S\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "77c385f0db59"
},
"source": [
"### Authenticate your Google Cloud account\n",
"\n",
"**If you are using Google Cloud 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": "535223fa4b84"
},
"outputs": [],
"source": [
"import os\n",
"import sys\n",
"\n",
"# 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",
"# The Google Cloud Notebook product has specific requirements\n",
"IS_GOOGLE_CLOUD_NOTEBOOK = os.path.exists(\"/opt/deeplearning/metadata/env_version\")\n",
"\n",
"# If on Google Cloud Notebooks, then don't execute this code\n",
"if not IS_GOOGLE_CLOUD_NOTEBOOK:\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": {
@@ -335,12 +428,7 @@
"\n",
"**The following steps are required, regardless of your notebook environment.**\n",
"\n",
"When you submit a custom training job using the Vertex SDK, you upload a Python package\n",
"containing your training code to a Cloud Storage bucket. Vertex AI runs\n",
"the code from this package. In this tutorial, Vertex AI also saves the\n",
"trained model that results from your job in the same bucket. You can then\n",
"create an `Endpoint` resource based on this output in order to serve\n",
"online predictions.\n",
"When you create a dataset resource using the Vertex SDK, you can provide a Cloud Storage bucket that contains the data. Vertex AI creates the dataset resource from the data. In this tutorial, Vertex AI also creates a dataset resource from your data in the Cloud Storage bucket.\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."
]
@@ -353,7 +441,7 @@
},
"outputs": [],
"source": [
"BUCKET_NAME = \"gs://[your-bucket-name]\" # @param {type:\"string\"}"
"BUCKET_URI = \"gs://[your-bucket-name]\" # @param {type:\"string\"}"
]
},
{
@@ -364,8 +452,8 @@
},
"outputs": [],
"source": [
"if BUCKET_NAME == \"\" or BUCKET_NAME is None or BUCKET_NAME == \"gs://[your-bucket-name]\":\n",
" BUCKET_NAME = \"gs://\" + PROJECT_ID + \"aip-\" + TIMESTAMP"
"if BUCKET_URI == \"\" or BUCKET_URI is None or BUCKET_URI == \"gs://[your-bucket-name]\":\n",
" BUCKET_URI = \"gs://\" + PROJECT_ID + \"aip-\" + TIMESTAMP"
]
},
{
@@ -385,7 +473,7 @@
},
"outputs": [],
"source": [
"! gsutil mb -l $REGION $BUCKET_NAME"
"! gsutil mb -l $REGION $BUCKET_URI"
]
},
{
@@ -405,7 +493,7 @@
},
"outputs": [],
"source": [
"! gsutil ls -al $BUCKET_NAME"
"! gsutil ls -al $BUCKET_URI"
]
},
{
@@ -414,9 +502,6 @@
"id": "setup_vars"
},
"source": [
"### Set up variables\n",
"\n",
"Next, set up some variables used throughout the tutorial.\n",
"### Import libraries and define constants"
]
},
@@ -428,75 +513,12 @@
},
"outputs": [],
"source": [
"import google.cloud.aiplatform as aip"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "import_bq"
},
"source": [
"#### Import BigQuery\n",
"\n",
"Import the BigQuery package into your Python environment."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "import_bq"
},
"outputs": [],
"source": [
"import google.cloud.aiplatform as aiplatform\n",
"import pandas as pd\n",
"import xgboost as xgb\n",
"from google.cloud import bigquery"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "import_xgboost"
},
"source": [
"#### Import XGBoost\n",
"\n",
"Import the XGBoost package into your Python environment."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "import_xgboost"
},
"outputs": [],
"source": [
"import xgboost as xgb"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "import_pandas"
},
"source": [
"#### Import pandas\n",
"\n",
"Import the pandas package into your Python environment."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "import_pandas"
},
"outputs": [],
"source": [
"import pandas as pd"
]
},
{
"cell_type": "markdown",
"metadata": {
@@ -516,7 +538,7 @@
},
"outputs": [],
"source": [
"aip.init(project=PROJECT_ID, location=REGION)"
"aiplatform.init(project=PROJECT_ID, location=REGION)"
]
},
{
@@ -538,7 +560,7 @@
},
"outputs": [],
"source": [
"bqclient = bigquery.Client()"
"bqclient = bigquery.Client(project=PROJECT_ID)"
]
},
{
@@ -549,7 +571,7 @@
"source": [
"#### Location of BigQuery training data.\n",
"\n",
"Now set the variable `IMPORT_FILE` to the location of the data table in BigQuery."
"Now, set the variable `IMPORT_FILE` to the location of the data table in BigQuery and `BQ_TABLE` with the table id."
]
},
{
@@ -591,10 +613,10 @@
},
"outputs": [],
"source": [
"dataset = aip.TabularDataset.create(\n",
"dataset = aiplatform.TabularDataset.create(\n",
" display_name=\"NOAA historical weather data\" + \"_\" + TIMESTAMP,\n",
" bq_source=[IMPORT_FILE],\n",
" labels={\"user_metadata\": BUCKET_NAME[5:]},\n",
" labels={\"user_metadata\": BUCKET_URI[5:]},\n",
")\n",
"\n",
"label_column = \"mean_temp\"\n",
@@ -610,7 +632,7 @@
"source": [
"### Copy the dataset to Cloud Storage\n",
"\n",
"Next, you make a copy of the BigQuery dataset, as a CSV file, to Cloud Storage using the BigQuery extract command.\n",
"Next, you make a copy of the BigQuery table as a CSV file, to Cloud Storage using the BigQuery extract command.\n",
"\n",
"Learn more about [BigQuery command line interface](https://cloud.google.com/bigquery/docs/reference/bq-cli-reference)."
]
@@ -626,9 +648,9 @@
"comps = BQ_TABLE.split(\".\")\n",
"BQ_PROJECT_DATASET_TABLE = comps[0] + \":\" + comps[1] + \".\" + comps[2]\n",
"\n",
"! bq --location=us extract --destination_format CSV $BQ_PROJECT_DATASET_TABLE $BUCKET_NAME/mydata*.csv\n",
"! bq --location=us extract --destination_format CSV $BQ_PROJECT_DATASET_TABLE $BUCKET_URI/mydata*.csv\n",
"\n",
"IMPORT_FILES = ! gsutil ls $BUCKET_NAME/mydata*.csv\n",
"IMPORT_FILES = ! gsutil ls $BUCKET_URI/mydata*.csv\n",
"\n",
"print(IMPORT_FILES)\n",
"\n",
@@ -664,15 +686,12 @@
},
"outputs": [],
"source": [
"if \"IMPORT_FILES\" in globals():\n",
" gcs_source = IMPORT_FILES\n",
"else:\n",
" gcs_source = [IMPORT_FILE]\n",
"gcs_source = IMPORT_FILES\n",
"\n",
"dataset = aip.TabularDataset.create(\n",
"dataset = aiplatform.TabularDataset.create(\n",
" display_name=\"NOAA historical weather data\" + \"_\" + TIMESTAMP,\n",
" gcs_source=gcs_source,\n",
" labels={\"user_metadata\": BUCKET_NAME[5:]},\n",
" labels={\"user_metadata\": BUCKET_URI[5:]},\n",
")\n",
"\n",
"\n",
@@ -694,6 +713,30 @@
"Learn more about [Creating BigQuery views](https://cloud.google.com/bigquery/docs/views)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "7dc142433e50"
},
"outputs": [],
"source": [
"# Set dataset name and view name in BigQuery\n",
"BQ_MY_DATASET = \"[your-dataset-name]\"\n",
"BQ_MY_TABLE = \"[your-view-name]\"\n",
"\n",
"# Otherwise, use the default names\n",
"if (\n",
" BQ_MY_DATASET == \"\"\n",
" or BQ_MY_DATASET is None\n",
" or BQ_MY_DATASET == \"[your-dataset-name]\"\n",
"):\n",
" BQ_MY_DATASET = \"mlops_dataset_\" + TIMESTAMP\n",
"\n",
"if BQ_MY_TABLE == \"\" or BQ_MY_TABLE is None or BQ_MY_TABLE == \"[your-view-name]\":\n",
" BQ_MY_TABLE = \"mlops_view_\" + TIMESTAMP"
]
},
{
"cell_type": "code",
"execution_count": null,
@@ -702,8 +745,7 @@
},
"outputs": [],
"source": [
"BQ_MY_DATASET = 'mydataset'\n",
"BQ_MY_TABLE = 'myview'\n",
"# Create the resources\n",
"! bq --location=US mk -d \\\n",
"$PROJECT_ID:$BQ_MY_DATASET\n",
"\n",
@@ -744,8 +786,8 @@
},
"outputs": [],
"source": [
"# Download a table.\n",
"table = bigquery.TableReference.from_string(\"bigquery-public-data.samples.gsod\")\n",
"# Download the table.\n",
"table = bigquery.TableReference.from_string(BQ_TABLE)\n",
"\n",
"rows = bqclient.list_rows(\n",
" table,\n",
@@ -1031,22 +1073,6 @@
"TABLE_ID = \"gsod\"\n",
"\n",
"\n",
"def create_bigquery_dataset(dataset_id):\n",
" dataset = bigquery.Dataset(\n",
" bigquery.dataset.DatasetReference(PROJECT_ID, dataset_id)\n",
" )\n",
" dataset.location = \"us\"\n",
"\n",
" try:\n",
" dataset = bqclient.create_dataset(dataset) # API request\n",
" return True\n",
" except Exception as err:\n",
" print(err)\n",
" if err.code != 409: # http_client.CONFLICT\n",
" raise\n",
" return False\n",
"\n",
"\n",
"def load_data_into_bigquery(url, dataset_id, table_id):\n",
" create_bigquery_dataset(dataset_id)\n",
" dataset = bqclient.dataset(dataset_id)\n",
@@ -1079,13 +1105,11 @@
"source": [
"### Read BigQuery table into XGboost DMatrix\n",
"\n",
"Currently, there is no direct data feeding connector between BigQuery and the open source XGBoost.\n",
"Currently, there is no direct data feeding connector between BigQuery and the open source XGBoost. The BigQuery ML service has a built-in XGBoost training module.\n",
"\n",
"The BigQuery ML service has XGBoost training builtin.\n",
"Alernatively, you extract the data either as a pandas dataframe or as CSV files. The extracted data is then given as an input to a `DMatrix` object when training the model.\n",
"\n",
"Alernatively, you extract the data either as a pandas dataframe or as CSV files. The extracted data is then inputted to a `DMatrix` object when training the model.\n",
"\n",
"Learn more about [Getting started with builtin XGBoost](https://cloud.google.com/ai-platform/training/docs/algorithms/xgboost-start)"
"Learn more about [Getting started with built-in XGBoost](https://cloud.google.com/ai-platform/training/docs/algorithms/xgboost-start)."
]
},
{
@@ -1096,7 +1120,7 @@
"source": [
"### Read pandas table into XGboost DMatrix\n",
"\n",
"Next, you load the pandas dataframe into a `DMatrix` object. XGBoost does not support non-numeric inputs. Any column that is categorical will need to be one-hot encoded prior to loading the dataframe."
"Next, you load the pandas dataframe into a `DMatrix` object. XGBoost does not support non-numeric inputs. Any column that is categorical need to be one-hot encoded prior to loading the dataframe."
]
},
{
@@ -1122,7 +1146,7 @@
"source": [
"### Read CSV files into XGboost DMatrix\n",
"\n",
"Currently, there is no Cloud Storage support in XGBoost. If you use CSV files for input, you will need to download them locally."
"Currently, there is no Cloud Storage support in XGBoost. If you use CSV files for input, you need to download them locally."
]
},
{
@@ -1144,87 +1168,41 @@
"id": "cleanup:mbsdk"
},
"source": [
"# Cleaning up\n",
"# Clean 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:\n",
"\n",
"- Dataset\n",
"- Pipeline\n",
"- Model\n",
"- Endpoint\n",
"- AutoML Training Job\n",
"- Batch Job\n",
"- Custom Job\n",
"- Hyperparameter Tuning Job\n",
"- Cloud Storage Bucket"
"- Vertex AI Dataset resource\n",
"- Cloud Storage Bucket\n",
"- BigQuery Dataset\n",
"\n",
"Set `delete_storage` to _True_ to delete the storage resources used in this notebook."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "cleanup:mbsdk"
"id": "47ad926d84e8"
},
"outputs": [],
"source": [
"delete_all = True\n",
"import os\n",
"\n",
"if delete_all:\n",
" # Delete the dataset using the Vertex dataset object\n",
" try:\n",
" if \"dataset\" in globals():\n",
" dataset.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"# Delete the dataset using the Vertex dataset object\n",
"dataset.delete()\n",
"# Delete the temporary BigQuery dataset\n",
"! bq rm -r -f $PROJECT_ID:$DATASET_ID\n",
"\n",
" # Delete the model using the Vertex model object\n",
" try:\n",
" if \"model\" in globals():\n",
" model.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the endpoint using the Vertex endpoint object\n",
" try:\n",
" if \"endpoint\" in globals():\n",
" endpoint.undeploy_all()\n",
" endpoint.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the AutoML or Pipeline training job\n",
" try:\n",
" if \"dag\" in globals():\n",
" dag.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the custom training job\n",
" try:\n",
" if \"job\" in globals():\n",
" job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the batch prediction job using the Vertex batch prediction object\n",
" try:\n",
" if \"batch_predict_job\" in globals():\n",
" batch_predict_job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the hyperparameter tuning job using the Vertex hyperparameter tuning object\n",
" try:\n",
" if \"hpt_job\" in globals():\n",
" hpt_job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" if \"BUCKET_NAME\" in globals():\n",
" ! gsutil rm -r $BUCKET_NAME"
"delete_storage = False\n",
"if delete_storage or os.getenv(\"IS_TESTING\"):\n",
" # Delete the created GCS bucket\n",
" ! gsutil rm -r $BUCKET_URI\n",
" # Delete the created BigQuery datasets\n",
" ! bq rm -r -f $PROJECT_ID:$BQ_MY_DATASET"
]
}
],
@@ -676,6 +676,31 @@
"dataframe[\"station_number\"] = pd.to_numeric(dataframe[\"station_number\"])"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "bqml_create_dataset"
},
"source": [
"### Create BQ dataset resource\n",
"\n",
"First, you create an empty dataset resource in your project."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "bqml_create_dataset"
},
"outputs": [],
"source": [
"BQ_MY_DATASET = 'samples'\n",
"BQ_MY_TABLE = 'gsod'\n",
"! bq --location=US mk -d \\\n",
"$PROJECT_ID:$BQ_MY_DATASET"
]
},
{
"cell_type": "code",
"execution_count": null,
File diff suppressed because it is too large Load Diff
+62 -7
View File
@@ -153,12 +153,13 @@ The steps performed include:
```
The steps performed include:
- Create a local BQ table in your project.
- Train a BQML model.
- Evaluate the BQML model.
- Export the BQML model as a cloud model.
- Upload the exported model as a Vertex AI Model resource.
- Hyperparameter tune a BQML model with Vertex AI Vizier.
- Create a local BigQuery table in your project
- Train a BQML model
- Evaluate the BQML model
- Export the BQML model as a cloud model
- Upload the exported model as a `Vertex AI Model` resource
- Hyperparameter tune a BQML model with `Vertex AI Vizier`
- Automatically register a BQML model to `Vertex AI Model Registry`
```
[Get Started with Vertex Feature Store](get_started_vertex_feature_store.ipynb)
@@ -169,11 +170,65 @@ The steps performed include:
- Creating a Vertex AI `Featurestore` resource.
- Creating `EntityType` resources for the `Featurestore` resource.
- Creating `Feature` resources for each `EntityType` resource.
- Import feature values (entity data items) into `Featurestore` resource.
- Import feature values (entity data items) into `Featurestore` resource from Cloud Storage.
- Import feature values (entity data items) into `Featurestore` resource from pandas DataFrame.
- Perform online serving from a `Featurestore` resource.
- Perform batch serving from a `Featurestore` resource.
```
[Get Started with Google CMEK Training](get_started_with_cmek_training.ipynb)
```
The steps performed include:
- Creating a customer managed encryption key.
- Creating an image dataset with CMEK encryption.
- Train an AutoML model with CMEK encryption.
```
[Get Started with TensorFlow Hub models](get_started_with_tfhub_models.ipynb)
```
The steps performed include:
- Download a TensorFlow Hub prebuilt model.
- Add the task component as a classifier for the CIFAR-10 dataset.
- Fine tune locally the model with transfer learning training.
- Construct a custom training script:
- Get training data from TensorFlow Datasets
- Get model architecture from TensorFlow Hub
- Train then model
- Save model artifacts and upload as Vertex AI Model resource.
```
[Get Started with Vertex AI TabNet builtin algorithm](get_started_with_tabnet.ipynb)
```
The steps performed include:
- Get the training data.
- Configure training parameters for the Vertex AI TabNet container.
- Train the model using Vertex AI Training using CSV data.
- Upload the model as a Vertex AI Model resource.
- Deploy the Vertex AI Model resource to a Vertex AI Endpoint resource.
- Make a prediction with the deployed model.
- Hyperparameter tuning the Vertex AI TabNet model.
- Train the model using Vertex AI Training using BigQuery table.
```
[Get Started with Vertex AI TabNet builtin algorithm](get_started_with_tabnet.ipynb)
```
The steps performed include:
- Get the training data.
- Configure training parameters for the Vertex AI TabNet container.
- Train the model using Vertex AI Training using CSV data.
- Upload the model as a Vertex AI Model resource.
- Deploy the Vertex AI Model resource to a Vertex AI Endpoint resource.
- Make a prediction with the deployed model.
- Hyperparameter tuning the Vertex AI TabNet model.
- Train the model using Vertex AI Training using BigQuery table.
```
### E2E Stage Example
[Stage 2: Experimentation](mlops_experimentation.ipynb)
@@ -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",
@@ -38,9 +38,15 @@
" 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_automl_training.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/ai/platform/notebooks/deploy-notebook?download_url=https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage2/get_started_automl_training.ipynb\">\n",
" Open in Google Cloud Notebooks\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/community/ml_ops/stage2/get_started_automl_training.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",
@@ -65,9 +71,11 @@
"id": "dataset:flowers,icn"
},
"source": [
"### Dataset\n",
"### Datasets\n",
"\n",
"The dataset used for this tutorial is the [Flowers dataset](https://www.tensorflow.org/datasets/catalog/tf_flowers) from [TensorFlow Datasets](https://www.tensorflow.org/datasets/catalog/overview). The version of the dataset you will use in this tutorial is stored in a public Cloud Storage bucket. The trained model predicts the type of flower an image is from a class of five flowers: daisy, dandelion, rose, sunflower, or tulip."
"#### Image\n",
"\n",
"The image dataset used for this tutorial is the [Flowers dataset](https://www.tensorflow.org/datasets/catalog/tf_flowers) from [TensorFlow Datasets](https://www.tensorflow.org/datasets/catalog/overview). The version of the dataset you will use in this tutorial is stored in a public Cloud Storage bucket. The trained model predicts the type of flower in a given image from a class of five flowers: daisy, dandelion, rose, sunflower, or tulip."
]
},
{
@@ -76,9 +84,9 @@
"id": "dataset:gsod,lrg"
},
"source": [
"### Dataset\n",
"#### Tabular\n",
"\n",
"The dataset used for this tutorial is the GSOD dataset from [BigQuery public datasets](https://cloud.google.com/bigquery/public-data). The version of the dataset you use only the fields year, month and day to predict the value of mean daily temperature (mean_temp)."
"The tabular dataset used for this tutorial is the GSOD dataset from [BigQuery public datasets](https://cloud.google.com/bigquery/public-data). The version of the dataset you use only the fields year, month and day to predict the value of mean daily temperature (mean_temp)."
]
},
{
@@ -87,9 +95,20 @@
"id": "dataset:happydb,tcn"
},
"source": [
"### Dataset\n",
"#### Text\n",
"\n",
"The dataset used for this tutorial is the [Happy Moments dataset](https://www.kaggle.com/ritresearch/happydb) from [Kaggle Datasets](https://www.kaggle.com/ritresearch/happydb). The version of the dataset you will use in this tutorial is stored in a public Cloud Storage bucket."
"The text dataset used for this tutorial is the [Happy Moments dataset](https://www.kaggle.com/ritresearch/happydb) from [Kaggle Datasets](https://www.kaggle.com/ritresearch/happydb). The version of the dataset you will use in this tutorial is stored in a public Cloud Storage bucket."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "98eb93ec6faa"
},
"source": [
"#### Video\n",
"\n",
"The video dataset used for this tutorial is the golf swing recognition portion of the [Human Motion dataset](https://todo) from [MIT](http://cbcl.mit.edu/publications/ps/Kuehne_etal_iccv11.pdf). The version of the dataset you will use in this tutorial is stored in a public Cloud Storage bucket. The trained model will predict the start frame where a golf swing begins."
]
},
{
@@ -108,11 +127,12 @@
"\n",
"The steps performed include:\n",
"\n",
"- Train an image model.\n",
"- Export the image model as an edge model.\n",
"- Train a tabular model.\n",
"- Export the tabular model as a cloud model.\n",
"- Train a text model."
"- Train an image model\n",
"- Export the image model as an edge model\n",
"- Train a tabular model\n",
"- Export the tabular model as a cloud model\n",
"- Train a text model\n",
"- Train a video model"
]
},
{
@@ -125,9 +145,24 @@
"\n",
"When doing E2E MLOps on Google Cloud, the following are best practices for when to use AutoML:\n",
"\n",
"**You have a limited amount of training data**\n",
"* **You have a limited amount of training data**\n",
"\n",
"**You want to establish a baseline metric before experimenting with a custom model**"
"* **You want to establish a baseline metric before experimenting with a custom model**"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "fb3451ce8e47"
},
"source": [
"### Costs\n",
"This tutorial uses billable components of Google Cloud:\n",
"\n",
"- Vertex AI\n",
"- Cloud Storage\n",
"\n",
"Learn about [Vertex AI pricing](https://cloud.google.com/vertex-ai/pricing) and [Cloud Storage pricing](https://cloud.google.com/storage/pricing) and use the [Pricing Calculator](https://cloud.google.com/products/calculator/) to generate a cost estimate based on your projected usage."
]
},
{
@@ -138,7 +173,7 @@
"source": [
"## Installations\n",
"\n",
"Install *one time* the packages for executing the MLOps notebooks."
"Install the following packages for executing the MLOps notebooks."
]
},
{
@@ -149,20 +184,18 @@
},
"outputs": [],
"source": [
"ONCE_ONLY = False\n",
"if ONCE_ONLY:\n",
" ! pip3 install -U tensorflow==2.5 $USER_FLAG\n",
" ! pip3 install -U tensorflow-data-validation==1.2 $USER_FLAG\n",
" ! pip3 install -U tensorflow-transform==1.2 $USER_FLAG\n",
" ! pip3 install -U tensorflow-io==0.18 $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-aiplatform[tensorboard] $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-pipeline-components $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-bigquery $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-logging $USER_FLAG\n",
" ! pip3 install --upgrade apache-beam[gcp] $USER_FLAG\n",
" ! pip3 install --upgrade pyarrow $USER_FLAG\n",
" ! pip3 install --upgrade cloudml-hypertune $USER_FLAG\n",
" ! pip3 install --upgrade kfp $USER_FLAG"
"import os\n",
"\n",
"# The Google Cloud Notebook product has specific requirements\n",
"IS_GOOGLE_CLOUD_NOTEBOOK = os.path.exists(\"/opt/deeplearning/metadata/env_version\")\n",
"\n",
"# Google Cloud Notebook requires dependencies to be installed with '--user'\n",
"USER_FLAG = \"\"\n",
"if IS_GOOGLE_CLOUD_NOTEBOOK:\n",
" USER_FLAG = \"--user\"\n",
"\n",
"! pip3 install --upgrade google-cloud-aiplatform $USER_FLAG\n",
"! pip3 install --upgrade google-cloud-storage $USER_FLAG"
]
},
{
@@ -200,6 +233,23 @@
"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 and Cloud Storage APIs](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com,compute_component,storage_component).\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",
"#### 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`."
@@ -270,7 +320,10 @@
},
"outputs": [],
"source": [
"REGION = \"us-central1\" # @param {type: \"string\"}"
"REGION = \"[your-region]\" # @param {type: \"string\"}\n",
"\n",
"if REGION == \"[your-region]\":\n",
" REGION = \"us-central1\""
]
},
{
@@ -297,6 +350,63 @@
"TIMESTAMP = datetime.now().strftime(\"%Y%m%d%H%M%S\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "3ffa6b6c7cdb"
},
"source": [
"### Authenticate your Google Cloud account\n",
"\n",
"**If you are using Google Cloud 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": "2b72272258fc"
},
"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 Google Cloud Notebook, then don't execute this code\n",
"if not os.path.exists(\"/opt/deeplearning/metadata/env_version\"):\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": {
@@ -320,7 +430,8 @@
},
"outputs": [],
"source": [
"BUCKET_NAME = \"gs://[your-bucket-name]\" # @param {type:\"string\"}"
"BUCKET_NAME = \"[your-bucket-name]\" # @param {type:\"string\"}\n",
"BUCKET_URI = f\"gs://{BUCKET_NAME}\""
]
},
{
@@ -331,8 +442,9 @@
},
"outputs": [],
"source": [
"if BUCKET_NAME == \"\" or BUCKET_NAME is None or BUCKET_NAME == \"gs://[your-bucket-name]\":\n",
" BUCKET_NAME = \"gs://\" + PROJECT_ID + \"aip-\" + TIMESTAMP"
"if BUCKET_URI == \"\" or BUCKET_URI is None or BUCKET_URI == \"gs://[your-bucket-name]\":\n",
" BUCKET_NAME = PROJECT_ID + \"aip-\" + TIMESTAMP\n",
" BUCKET_URI = \"gs://\" + BUCKET_NAME"
]
},
{
@@ -352,7 +464,7 @@
},
"outputs": [],
"source": [
"! gsutil mb -l $REGION $BUCKET_NAME"
"! gsutil mb -l $REGION $BUCKET_URI"
]
},
{
@@ -372,7 +484,7 @@
},
"outputs": [],
"source": [
"! gsutil ls -al $BUCKET_NAME"
"! gsutil ls -al $BUCKET_URI"
]
},
{
@@ -395,7 +507,7 @@
},
"outputs": [],
"source": [
"import google.cloud.aiplatform as aip"
"import google.cloud.aiplatform as aiplatform"
]
},
{
@@ -417,7 +529,7 @@
},
"outputs": [],
"source": [
"aip.init(project=PROJECT_ID, staging_bucket=BUCKET_NAME)"
"aiplatform.init(project=PROJECT_ID, staging_bucket=BUCKET_URI)"
]
},
{
@@ -448,7 +560,7 @@
"source": [
"## AutoML image models\n",
"\n",
"AutoML can train the following types of models:\n",
"AutoML can train the following types of image models:\n",
"\n",
"- classification\n",
"- objection detection\n",
@@ -504,10 +616,7 @@
},
"outputs": [],
"source": [
"if \"IMPORT_FILES\" in globals():\n",
" FILE = IMPORT_FILES[0]\n",
"else:\n",
" FILE = IMPORT_FILE\n",
"FILE = IMPORT_FILE\n",
"\n",
"count = ! gsutil cat $FILE | wc -l\n",
"print(\"Number of Examples\", int(count[0]))\n",
@@ -545,10 +654,10 @@
},
"outputs": [],
"source": [
"dataset = aip.ImageDataset.create(\n",
" display_name=\"Happy Moments\" + \"_\" + TIMESTAMP,\n",
"dataset = aiplatform.ImageDataset.create(\n",
" display_name=\"flowers_\" + TIMESTAMP,\n",
" gcs_source=[IMPORT_FILE],\n",
" import_schema_uri=aip.schema.dataset.ioformat.image.single_label_classification,\n",
" import_schema_uri=aiplatform.schema.dataset.ioformat.image.single_label_classification,\n",
")\n",
"\n",
"print(dataset.resource_name)"
@@ -593,8 +702,8 @@
},
"outputs": [],
"source": [
"dag = aip.AutoMLImageTrainingJob(\n",
" display_name=\"happydb_\" + TIMESTAMP,\n",
"dag = aiplatform.AutoMLImageTrainingJob(\n",
" display_name=\"flowers_\" + TIMESTAMP,\n",
" prediction_type=\"classification\",\n",
" multi_label=False,\n",
" model_type=\"MOBILE_TF_LOW_LATENCY_1\",\n",
@@ -612,14 +721,14 @@
"source": [
"#### Run the training pipeline\n",
"\n",
"Next, you run the DAG to start the training job by invoking the method `run`, with the following parameters:\n",
"Next, you run the created DAG to start the training job by invoking the method `run`, with the following parameters:\n",
"\n",
"- `dataset`: The `Dataset` resource to train the model.\n",
"- `model_display_name`: The human readable name for the trained model.\n",
"- `training_fraction_split`: The percentage of the dataset to use for training.\n",
"- `test_fraction_split`: The percentage of the dataset to use for test (holdout data).\n",
"- `validation_fraction_split`: The percentage of the dataset to use for validation.\n",
"- `budget_milli_node_hours`: (optional) Maximum training time specified in unit of millihours (1000 = hour).\n",
"- `budget_milli_node_hours`: (optional) Maximum training time specified in unit of milli node-hours (1000 = node-hour).\n",
"- `disable_early_stopping`: If `True`, training maybe completed before using the entire budget if the service believes it cannot further improve on the model objective measurements.\n",
"\n",
"The `run` method when completed returns the `Model` resource.\n",
@@ -637,7 +746,7 @@
"source": [
"model = dag.run(\n",
" dataset=dataset,\n",
" model_display_name=\"happydb_\" + TIMESTAMP,\n",
" model_display_name=\"flowers_\" + TIMESTAMP,\n",
" training_fraction_split=0.8,\n",
" validation_fraction_split=0.1,\n",
" test_fraction_split=0.1,\n",
@@ -653,7 +762,7 @@
},
"source": [
"## Review model evaluation scores\n",
"After your model has finished training, you can review the evaluation scores for it.\n",
"After your model training has finished, you can review the evaluation scores for it.\n",
"\n",
"First, you need to get a reference to the new model. As with datasets, you can either use the reference to the model variable you created when you deployed the model or you can list all of the models in your project."
]
@@ -667,11 +776,13 @@
"outputs": [],
"source": [
"# Get model resource ID\n",
"models = aip.Model.list(filter=\"display_name=happydb_\" + TIMESTAMP)\n",
"models = aiplatform.Model.list(filter=\"display_name=flowers_\" + TIMESTAMP)\n",
"\n",
"# Get a reference to the Model Service client\n",
"client_options = {\"api_endpoint\": f\"{REGION}-aiplatform.googleapis.com\"}\n",
"model_service_client = aip.gapic.ModelServiceClient(client_options=client_options)\n",
"model_service_client = aiplatform.gapic.ModelServiceClient(\n",
" client_options=client_options\n",
")\n",
"\n",
"model_evaluations = model_service_client.list_model_evaluations(\n",
" parent=models[0].resource_name\n",
@@ -721,7 +832,7 @@
"source": [
"### Get test item\n",
"\n",
"You will use an arbitrary example out of the dataset as a test item. Don't be concerned that the example was likely used in training the model -- we just want to demonstrate how to make a prediction."
"You will use an arbitrary example out of the dataset as a test item. Don't be concerned that the example was likely used in training the model. You are just looking at how to make a prediction."
]
},
{
@@ -753,7 +864,7 @@
"\n",
"#### Request\n",
"\n",
"Since in this example your test item is in a Cloud Storage bucket, you open and read the contents of the image using `tf.io.gfile.Gfile()`. To pass the test data to the prediction service, you encode the bytes into base64 -- which makes the content safe from modification while transmitting binary data over the network.\n",
"Since your test item is in a public Cloud Storage bucket in this example, you copy it to your bucket and read the contents of the image using `Cloud Storage SDK`. To pass the test data to the prediction service, you encode the bytes into base64 which makes the content safe from modification while transmitting binary data over the network.\n",
"\n",
"The format of each instance is:\n",
"\n",
@@ -775,32 +886,66 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "predict_request:mbsdk,icn"
"id": "1c1d53e89beb"
},
"outputs": [],
"source": [
"import base64\n",
"\n",
"import tensorflow as tf\n",
"from google.cloud import storage\n",
"\n",
"with tf.io.gfile.GFile(test_item, \"rb\") as f:\n",
" content = f.read()\n",
"# Copy the test image to the Cloud storage bucket as \"test.jpg\"\n",
"test_image_local = \"{}/test.jpg\".format(BUCKET_URI)\n",
"! gsutil cp $test_item $test_image_local\n",
"\n",
"# Download the test image in bytes format\n",
"storage_client = storage.Client(project=PROJECT_ID)\n",
"bucket = storage_client.bucket(bucket_name=BUCKET_NAME)\n",
"test_content = bucket.get_blob(\"test.jpg\").download_as_bytes()\n",
"\n",
"# The format of each instance should conform to the deployed model's prediction input schema.\n",
"instances = [{\"content\": base64.b64encode(content).decode(\"utf-8\")}]\n",
"instances = [{\"content\": base64.b64encode(test_content).decode(\"utf-8\")}]\n",
"\n",
"prediction = endpoint.predict(instances=instances)\n",
"\n",
"print(prediction)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "3b1b67898533"
},
"source": [
"#### Alternate method using [GFile](https://www.tensorflow.org/api_docs/python/tf/io/gfile/GFile)\n",
"\n",
"Alternatively, [GFile](https://www.tensorflow.org/api_docs/python/tf/io/gfile/GFile) method from tensorflow-io library can be used to read the data from Cloud storage directly. The following code snippet does the same :\n",
"\n",
"```\n",
"import base64\n",
"import tensorflow as tf\n",
"\n",
"# Read the test file using GFile\n",
"with tf.io.gfile.GFile(test_item, \"rb\") as f:\n",
" content = f.read()\n",
"\n",
"# The format of each instance should conform to the deployed model's prediction input schema.\n",
"instances = [{\"content\": base64.b64encode(content).decode(\"utf-8\")}]\n",
"\n",
"prediction = endpoint.predict(instances=instances)\n",
"\n",
"print(prediction)\n",
"```\n",
"Nevertheless, `tf.io.gfile.GFile` supports multiple file system implementations, including local files, Google Cloud Storage (using a gs:// prefix), and HDFS (using an hdfs:// prefix)."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "undeploy_model:mbsdk"
},
"source": [
"## Undeploy the model\n",
"#### Undeploy the model\n",
"\n",
"When you are done doing predictions, you undeploy the model from the `Endpoint` resouce. This deprovisions all compute resources and ends billing for the deployed model."
]
@@ -846,7 +991,7 @@
"outputs": [],
"source": [
"response = model.export_model(\n",
" artifact_destination=BUCKET_NAME, export_format_id=\"tflite\", sync=True\n",
" artifact_destination=BUCKET_URI, export_format_id=\"tflite\", sync=True\n",
")\n",
"\n",
"model_package = response[\"artifactOutputUri\"]"
@@ -987,10 +1132,10 @@
},
"outputs": [],
"source": [
"dataset = aip.TabularDataset.create(\n",
" display_name=\"Happy Moments\" + \"_\" + TIMESTAMP,\n",
"dataset = aiplatform.TabularDataset.create(\n",
" display_name=\"gsod_\" + TIMESTAMP,\n",
" bq_source=[IMPORT_FILE],\n",
" labels={\"user_metadata\": BUCKET_NAME[5:]},\n",
" labels={\"user_metadata\": BUCKET_NAME},\n",
")\n",
"\n",
"label_column = \"mean_temp\"\n",
@@ -1046,9 +1191,7 @@
" - regression:\n",
" - `minimize-rmse`\n",
" - `minimize-mae`\n",
" - `minimize-rmsle`\n",
"\n",
"The instantiated object is the DAG (directed acyclic graph) for the training pipeline."
" - `minimize-rmsle`"
]
},
{
@@ -1059,8 +1202,8 @@
},
"outputs": [],
"source": [
"dag = aip.AutoMLTabularTrainingJob(\n",
" display_name=\"happydb_\" + TIMESTAMP,\n",
"dag = aiplatform.AutoMLTabularTrainingJob(\n",
" display_name=\"gsod_\" + TIMESTAMP,\n",
" optimization_prediction_type=\"regression\",\n",
" optimization_objective=\"minimize-rmse\",\n",
" column_transformations=TRANSFORMATIONS,\n",
@@ -1077,7 +1220,7 @@
"source": [
"#### Run the training pipeline\n",
"\n",
"Next, you run the DAG to start the training job by invoking the method `run`, with the following parameters:\n",
"Next, you run the created DAG to start the training job by invoking the method `run`, with the following parameters:\n",
"\n",
"- `dataset`: The `Dataset` resource to train the model.\n",
"- `model_display_name`: The human readable name for the trained model.\n",
@@ -1103,7 +1246,7 @@
"source": [
"model = dag.run(\n",
" dataset=dataset,\n",
" model_display_name=\"happydb_\" + TIMESTAMP,\n",
" model_display_name=\"gsod_\" + TIMESTAMP,\n",
" training_fraction_split=0.8,\n",
" validation_fraction_split=0.1,\n",
" test_fraction_split=0.1,\n",
@@ -1134,11 +1277,13 @@
"outputs": [],
"source": [
"# Get model resource ID\n",
"models = aip.Model.list(filter=\"display_name=happydb_\" + TIMESTAMP)\n",
"models = aiplatform.Model.list(filter=\"display_name=gsod_\" + TIMESTAMP)\n",
"\n",
"# Get a reference to the Model Service client\n",
"client_options = {\"api_endpoint\": f\"{REGION}-aiplatform.googleapis.com\"}\n",
"model_service_client = aip.gapic.ModelServiceClient(client_options=client_options)\n",
"model_service_client = aiplatform.gapic.ModelServiceClient(\n",
" client_options=client_options\n",
")\n",
"\n",
"model_evaluations = model_service_client.list_model_evaluations(\n",
" parent=models[0].resource_name\n",
@@ -1177,7 +1322,7 @@
"id": "undeploy_model:mbsdk"
},
"source": [
"## Undeploy the model\n",
"#### Undeploy the model\n",
"\n",
"When you are done doing predictions, you undeploy the model from the `Endpoint` resouce. This deprovisions all compute resources and ends billing for the deployed model."
]
@@ -1218,7 +1363,7 @@
"outputs": [],
"source": [
"response = model.export_model(\n",
" artifact_destination=BUCKET_NAME, export_format_id=\"tf-saved-model\", sync=True\n",
" artifact_destination=BUCKET_URI, export_format_id=\"tf-saved-model\", sync=True\n",
")\n",
"\n",
"model_package = response[\"artifactOutputUri\"]"
@@ -1350,10 +1495,7 @@
},
"outputs": [],
"source": [
"if \"IMPORT_FILES\" in globals():\n",
" FILE = IMPORT_FILES[0]\n",
"else:\n",
" FILE = IMPORT_FILE\n",
"FILE = IMPORT_FILE\n",
"\n",
"count = ! gsutil cat $FILE | wc -l\n",
"print(\"Number of Examples\", int(count[0]))\n",
@@ -1391,10 +1533,10 @@
},
"outputs": [],
"source": [
"dataset = aip.TextDataset.create(\n",
" display_name=\"Happy Moments\" + \"_\" + TIMESTAMP,\n",
"dataset = aiplatform.TextDataset.create(\n",
" display_name=\"happydb_\" + TIMESTAMP,\n",
" gcs_source=[IMPORT_FILE],\n",
" import_schema_uri=aip.schema.dataset.ioformat.text.single_label_classification,\n",
" import_schema_uri=aiplatform.schema.dataset.ioformat.text.single_label_classification,\n",
")\n",
"\n",
"print(dataset.resource_name)"
@@ -1420,9 +1562,7 @@
" - `sentiment`: A text sentiment analysis model.\n",
" - `extraction`: A text entity extraction model.\n",
"- `multi_label`: If a classification task, whether single (False) or multi-labeled (True).\n",
"- `sentiment_max`: If a sentiment analysis task, the maximum sentiment value.\n",
"\n",
"The instantiated object is the DAG (directed acyclic graph) for the training pipeline."
"- `sentiment_max`: If a sentiment analysis task, the maximum sentiment value.\n"
]
},
{
@@ -1433,7 +1573,7 @@
},
"outputs": [],
"source": [
"dag = aip.AutoMLTextTrainingJob(\n",
"dag = aiplatform.AutoMLTextTrainingJob(\n",
" display_name=\"happydb_\" + TIMESTAMP,\n",
" prediction_type=\"classification\",\n",
" multi_label=False,\n",
@@ -1450,7 +1590,7 @@
"source": [
"#### Run the training pipeline\n",
"\n",
"Next, you run the DAG to start the training job by invoking the method `run`, with the following parameters:\n",
"Next, you run the created DAG to start the training job by invoking the method `run`, with the following parameters:\n",
"\n",
"- `dataset`: The `Dataset` resource to train the model.\n",
"- `model_display_name`: The human readable name for the trained model.\n",
@@ -1501,11 +1641,13 @@
"outputs": [],
"source": [
"# Get model resource ID\n",
"models = aip.Model.list(filter=\"display_name=happydb_\" + TIMESTAMP)\n",
"models = aiplatform.Model.list(filter=\"display_name=happydb_\" + TIMESTAMP)\n",
"\n",
"# Get a reference to the Model Service client\n",
"client_options = {\"api_endpoint\": f\"{REGION}-aiplatform.googleapis.com\"}\n",
"model_service_client = aip.gapic.ModelServiceClient(client_options=client_options)\n",
"model_service_client = aiplatform.gapic.ModelServiceClient(\n",
" client_options=client_options\n",
")\n",
"\n",
"model_evaluations = model_service_client.list_model_evaluations(\n",
" parent=models[0].resource_name\n",
@@ -1542,7 +1684,7 @@
"id": "undeploy_model:mbsdk"
},
"source": [
"## Undeploy the model\n",
"#### Undeploy the model\n",
"\n",
"When you are done doing predictions, you undeploy the model from the `Endpoint` resouce. This deprovisions all compute resources and ends billing for the deployed model."
]
@@ -1686,10 +1828,7 @@
},
"outputs": [],
"source": [
"if \"IMPORT_FILES\" in globals():\n",
" FILE = IMPORT_FILES[0]\n",
"else:\n",
" FILE = IMPORT_FILE\n",
"FILE = IMPORT_FILE\n",
"\n",
"count = ! gsutil cat $FILE | wc -l\n",
"print(\"Number of Examples\", int(count[0]))\n",
@@ -1726,10 +1865,10 @@
},
"outputs": [],
"source": [
"dataset = aip.VideoDataset.create(\n",
" display_name=\"Happy Moments\" + \"_\" + TIMESTAMP,\n",
"dataset = aiplatform.VideoDataset.create(\n",
" display_name=\"human_motion_\" + TIMESTAMP,\n",
" gcs_source=[IMPORT_FILE],\n",
" import_schema_uri=aip.schema.dataset.ioformat.video.classification,\n",
" import_schema_uri=aiplatform.schema.dataset.ioformat.video.classification,\n",
")\n",
"\n",
"print(dataset.resource_name)"
@@ -1753,9 +1892,7 @@
"- `prediction_type`: The type task to train the model for.\n",
" - `classification`: A video classification model.\n",
" - `object_tracking`: A video object tracking model.\n",
" - `action_recognition`: A video action recognition model.\n",
"\n",
"The instantiated object is the DAG (directed acyclic graph) for the training pipeline."
" - `action_recognition`: A video action recognition model."
]
},
{
@@ -1766,8 +1903,8 @@
},
"outputs": [],
"source": [
"dag = aip.AutoMLVideoTrainingJob(\n",
" display_name=\"happydb_\" + TIMESTAMP,\n",
"dag = aiplatform.AutoMLVideoTrainingJob(\n",
" display_name=\"human_motion_\" + TIMESTAMP,\n",
" prediction_type=\"classification\",\n",
")\n",
"\n",
@@ -1782,7 +1919,7 @@
"source": [
"#### Run the training pipeline\n",
"\n",
"Next, you run the DAG to start the training job by invoking the method `run`, with the following parameters:\n",
"Next, you run the created DAG to start the training job by invoking the method `run`, with the following parameters:\n",
"\n",
"- `dataset`: The `Dataset` resource to train the model.\n",
"- `model_display_name`: The human readable name for the trained model.\n",
@@ -1804,7 +1941,7 @@
"source": [
"model = dag.run(\n",
" dataset=dataset,\n",
" model_display_name=\"happydb_\" + TIMESTAMP,\n",
" model_display_name=\"human_motion_\" + TIMESTAMP,\n",
" training_fraction_split=0.8,\n",
" test_fraction_split=0.2,\n",
")"
@@ -1831,11 +1968,13 @@
"outputs": [],
"source": [
"# Get model resource ID\n",
"models = aip.Model.list(filter=\"display_name=happydb_\" + TIMESTAMP)\n",
"models = aiplatform.Model.list(filter=\"display_name=human_motion_\" + TIMESTAMP)\n",
"\n",
"# Get a reference to the Model Service client\n",
"client_options = {\"api_endpoint\": f\"{REGION}-aiplatform.googleapis.com\"}\n",
"model_service_client = aip.gapic.ModelServiceClient(client_options=client_options)\n",
"model_service_client = aiplatform.gapic.ModelServiceClient(\n",
" client_options=client_options\n",
")\n",
"\n",
"model_evaluations = model_service_client.list_model_evaluations(\n",
" parent=models[0].resource_name\n",
@@ -1899,16 +2038,7 @@
"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:\n",
"\n",
"- Dataset\n",
"- Pipeline\n",
"- Model\n",
"- Endpoint\n",
"- Batch Job\n",
"- Custom Job\n",
"- Hyperparameter Tuning Job\n",
"- Cloud Storage Bucket"
"Otherwise, you can delete the individual resources you created in this tutorial.\n"
]
},
{
@@ -1919,66 +2049,11 @@
},
"outputs": [],
"source": [
"delete_dataset = True\n",
"delete_pipeline = True\n",
"delete_model = True\n",
"delete_endpoint = True\n",
"delete_batchjob = True\n",
"delete_customjob = True\n",
"delete_hptjob = True\n",
"delete_bucket = True\n",
"# 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 fully qualified identifier for the dataset\n",
"try:\n",
" if delete_dataset and \"dataset_id\" in globals():\n",
" clients[\"dataset\"].delete_dataset(name=dataset_id)\n",
"except Exception as e:\n",
" print(e)\n",
"\n",
"# Delete the training pipeline using the Vertex fully qualified identifier for the pipeline\n",
"try:\n",
" if delete_pipeline and \"pipeline_id\" in globals():\n",
" clients[\"pipeline\"].delete_training_pipeline(name=pipeline_id)\n",
"except Exception as e:\n",
" print(e)\n",
"\n",
"# Delete the model using the Vertex fully qualified identifier for the model\n",
"try:\n",
" if delete_model and \"model_to_deploy_id\" in globals():\n",
" clients[\"model\"].delete_model(name=model_to_deploy_id)\n",
"except Exception as e:\n",
" print(e)\n",
"\n",
"# Delete the endpoint using the Vertex fully qualified identifier for the endpoint\n",
"try:\n",
" if delete_endpoint and \"endpoint_id\" in globals():\n",
" clients[\"endpoint\"].delete_endpoint(name=endpoint_id)\n",
"except Exception as e:\n",
" print(e)\n",
"\n",
"# Delete the batch job using the Vertex fully qualified identifier for the batch job\n",
"try:\n",
" if delete_batchjob and \"batch_job_id\" in globals():\n",
" clients[\"job\"].delete_batch_prediction_job(name=batch_job_id)\n",
"except Exception as e:\n",
" print(e)\n",
"\n",
"# Delete the custom job using the Vertex fully qualified identifier for the custom job\n",
"try:\n",
" if delete_customjob and \"job_id\" in globals():\n",
" clients[\"job\"].delete_custom_job(name=job_id)\n",
"except Exception as e:\n",
" print(e)\n",
"\n",
"# Delete the hyperparameter tuning job using the Vertex fully qualified identifier for the hyperparameter tuning job\n",
"try:\n",
" if delete_hptjob and \"hpt_job_id\" in globals():\n",
" clients[\"job\"].delete_hyperparameter_tuning_job(name=hpt_job_id)\n",
"except Exception as e:\n",
" print(e)\n",
"\n",
"if delete_bucket and \"BUCKET_NAME\" in globals():\n",
" ! gsutil rm -r $BUCKET_NAME"
"if delete_bucket or os.getenv(\"IS_TESTING\"):\n",
" ! gsutil rm -r $BUCKET_URI"
]
}
],
@@ -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",
@@ -39,8 +39,9 @@
" </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/blob/main/notebooks/community/ml_ops/stage2/get_started_bqml_training.ipynb\">\n",
" Open in Google Cloud Notebooks\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/community/ml_ops/stage2/get_started_bqml_training.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",
@@ -67,7 +68,7 @@
"source": [
"### Dataset\n",
"\n",
"The dataset used for this tutorial is the Penguins dataset from [BigQuery public datasets](https://cloud.google.com/bigquery/public-data). The version of the dataset predicts the species."
"The dataset used for this tutorial is the Penguins dataset from [BigQuery public datasets](https://cloud.google.com/bigquery/public-data). This version of the dataset is used to predict the species of penguins from the available features like culmen-length, flipper-depth etc."
]
},
{
@@ -84,16 +85,26 @@
"\n",
"- `BigQueryML Training`\n",
"- `Vertex AI Model resource`\n",
"- `Vertex AI Vizier.\n",
"- `Vertex AI Vizier`\n",
"\n",
"The steps performed include:\n",
"\n",
"- Create a local BQ table in your project.\n",
"- Train a BQML model.\n",
"- Evaluate the BQML model.\n",
"- Export the BQML model as a cloud model.\n",
"- Upload the exported model as a Vertex AI Model resource.\n",
"- Hyperparameter tune a BQML model with Vertex AI Vizier."
"- Create a local BigQuery table in your project\n",
"- Train a BQML model\n",
"- Evaluate the BQML model\n",
"- Export the BQML model as a cloud model\n",
"- Upload the exported model as a `Vertex AI Model` resource\n",
"- Hyperparameter tune a BQML model with `Vertex AI Vizier`\n",
"- Automatically register a BQML model to `Vertex AI Model Registry`\n",
"\n",
"### Costs\n",
"This tutorial uses billable components of Google Cloud:\n",
"\n",
"- Vertex AI\n",
"- Cloud Storage\n",
"- BigQuery\n",
"\n",
"Learn about [Vertex AI pricing](https://cloud.google.com/vertex-ai/pricing), [Cloud Storage pricing](https://cloud.google.com/storage/pricing) and [BigQuery pricing](https://cloud.google.com/bigquery/pricing) and use the [Pricing Calculator](https://cloud.google.com/products/calculator/) to generate a cost estimate based on your projected usage."
]
},
{
@@ -104,7 +115,7 @@
"source": [
"## Installations\n",
"\n",
"Install *one time* the packages for executing the MLOps notebooks."
"Install the following packages for executing this notebook."
]
},
{
@@ -115,20 +126,20 @@
},
"outputs": [],
"source": [
"ONCE_ONLY = False\n",
"if ONCE_ONLY:\n",
" ! pip3 install -U tensorflow==2.5 $USER_FLAG\n",
" ! pip3 install -U tensorflow-data-validation==1.2 $USER_FLAG\n",
" ! pip3 install -U tensorflow-transform==1.2 $USER_FLAG\n",
" ! pip3 install -U tensorflow-io==0.18 $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-aiplatform[tensorboard] $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-pipeline-components $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-bigquery $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-logging $USER_FLAG\n",
" ! pip3 install --upgrade apache-beam[gcp] $USER_FLAG\n",
" ! pip3 install --upgrade pyarrow $USER_FLAG\n",
" ! pip3 install --upgrade cloudml-hypertune $USER_FLAG\n",
" ! pip3 install --upgrade kfp $USER_FLAG"
"import os\n",
"\n",
"# The Google Cloud Notebook product has specific requirements\n",
"IS_GOOGLE_CLOUD_NOTEBOOK = os.path.exists(\"/opt/deeplearning/metadata/env_version\")\n",
"\n",
"# Google Cloud Notebook requires dependencies to be installed with '--user'\n",
"USER_FLAG = \"\"\n",
"if IS_GOOGLE_CLOUD_NOTEBOOK:\n",
" USER_FLAG = \"--user\"\n",
"\n",
"# Install the packages\n",
"! pip3 install --upgrade pyarrow $USER_FLAG\n",
"! pip3 install --upgrade google-cloud-aiplatform $USER_FLAG\n",
"! pip3 install --upgrade google-cloud-bigquery $USER_FLAG"
]
},
{
@@ -236,7 +247,10 @@
},
"outputs": [],
"source": [
"REGION = \"us-central1\" # @param {type: \"string\"}"
"REGION = \"[your-region]\" # @param {type: \"string\"}\n",
"\n",
"if REGION == \"[your-region]\":\n",
" REGION = \"us-central1\""
]
},
{
@@ -347,9 +361,6 @@
"id": "setup_vars"
},
"source": [
"### Set up variables\n",
"\n",
"Next, set up some variables used throughout the tutorial.\n",
"### Import libraries and define constants"
]
},
@@ -361,28 +372,7 @@
},
"outputs": [],
"source": [
"import google.cloud.aiplatform as aip"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "import_bq"
},
"source": [
"#### Import BigQuery\n",
"\n",
"Import the BigQuery package into your Python environment."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "import_bq"
},
"outputs": [],
"source": [
"import google.cloud.aiplatform as aiplatform\n",
"from google.cloud import bigquery"
]
},
@@ -392,7 +382,7 @@
"id": "init_aip:mbsdk"
},
"source": [
"### Initialize Vertex AI SDK for Python\n",
"### Initialize Vertex AI and BigQuery SDKs for Python\n",
"\n",
"Initialize the Vertex AI SDK for Python for your project and corresponding bucket."
]
@@ -405,7 +395,7 @@
},
"outputs": [],
"source": [
"aip.init(project=PROJECT_ID, staging_bucket=BUCKET_NAME)"
"aiplatform.init(project=PROJECT_ID, staging_bucket=BUCKET_NAME)"
]
},
{
@@ -414,8 +404,6 @@
"id": "init_bq"
},
"source": [
"### Create BigQuery client\n",
"\n",
"Create the BigQuery client."
]
},
@@ -427,7 +415,7 @@
},
"outputs": [],
"source": [
"bqclient = bigquery.Client()"
"bqclient = bigquery.Client(project=PROJECT_ID)"
]
},
{
@@ -436,17 +424,17 @@
"id": "accelerators:prediction,mbsdk"
},
"source": [
"#### Set hardware accelerators\n",
"### Set hardware accelerators\n",
"\n",
"You can set hardware accelerators for prediction.\n",
"\n",
"Set the variable `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",
" (aiplatform.AcceleratorType.NVIDIA_TESLA_K80, 4)\n",
"\n",
"Otherwise specify `(None, None)` to use a container image to run on a CPU.\n",
"\n",
"Learn more [here](https://cloud.google.com/vertex-ai/docs/general/locations#accelerators) hardware accelerator support for your region"
"Learn more [here](https://cloud.google.com/vertex-ai/docs/general/locations#accelerators) hardware accelerator support for your region."
]
},
{
@@ -457,13 +445,15 @@
},
"outputs": [],
"source": [
"import os\n",
"\n",
"if os.getenv(\"IS_TESTING_DEPLOY_GPU\"):\n",
" DEPLOY_GPU, DEPLOY_NGPU = (\n",
" aip.gapic.AcceleratorType.NVIDIA_TESLA_K80,\n",
" aiplatform.gapic.AcceleratorType.NVIDIA_TESLA_K80,\n",
" int(os.getenv(\"IS_TESTING_DEPLOY_GPU\")),\n",
" )\n",
"else:\n",
" DEPLOY_GPU, DEPLOY_NGPU = (aip.gapic.AcceleratorType.NVIDIA_TESLA_K80, 1)"
" DEPLOY_GPU, DEPLOY_NGPU = (aiplatform.gapic.AcceleratorType.NVIDIA_TESLA_K80, 1)"
]
},
{
@@ -472,7 +462,7 @@
"id": "container:prediction"
},
"source": [
"#### Set pre-built containers\n",
"### Set pre-built containers\n",
"\n",
"Set the pre-built Docker container image for prediction.\n",
"\n",
@@ -519,11 +509,11 @@
"id": "machine:prediction"
},
"source": [
"#### Set machine type\n",
"### Set machine type\n",
"\n",
"Next, set the machine type to use for prediction.\n",
"\n",
"- Set the variable `DEPLOY_COMPUTE` to configure the compute resources for the VM you will use for prediction.\n",
"- Set the variable `DEPLOY_COMPUTE` to configure the compute resources for the VM which is used for prediction.\n",
" - `machine type`\n",
" - `n1-standard`: 3.75GB of memory per vCPU.\n",
" - `n1-highmem`: 6.5GB of memory per vCPU\n",
@@ -557,7 +547,7 @@
"id": "bqml_intro"
},
"source": [
"## Bigquery ML introduction\n",
"## BigQuery ML introduction\n",
"\n",
"BigQuery ML (BQML) provides the capability to train ML tabular models, such as classification and regression, in BigQuery using SQL syntax.\n",
"\n",
@@ -582,9 +572,9 @@
"id": "bqml_create_dataset"
},
"source": [
"### Create BQ dataset/model resource\n",
"### Create BQ dataset resource\n",
"\n",
"First, you create a empty dataset/model resource in your project."
"First, you create an empty dataset resource in your project."
]
},
{
@@ -659,7 +649,7 @@
"id": "bqml_eval_model"
},
"source": [
"### Evaluate the BQML trained model\n",
"### Evaluate the trained BQML model\n",
"\n",
"Next, retrieve the model evaluation for the trained BQML model.\n",
"\n",
@@ -694,7 +684,7 @@
"source": [
"### Export the model from BQML\n",
"\n",
"The model you trained in BQML is a TensorFlow model. Next, you will export the TensorFlow model artifacts in TF.SavedModel format."
"The model you trained in BQML is a TensorFlow model. Next, you export the TensorFlow model artifacts in TF.SavedModel format."
]
},
{
@@ -718,9 +708,25 @@
"id": "upload_bqml_model"
},
"source": [
"## Upload the BQML model to a Model resource\n",
"## Upload the BigQuery ML model to a Vertex AI Model resource\n",
"\n",
"Finally, now that you have the BQML model exported as a TF.SavedModel format, you upload the model artifacts to Vertex AI Model resource, in the same way as if you were uploading a custom trained model."
"Finally, now that you have the BigQuery ML model exported, you upload the model artifacts to Vertex AI Model resource, in the same way as if you were uploading a custom trained model.\n",
"\n",
"Below is a partial list of mapping BigQuery ML model types to their corresponding exported model format:\n",
"\n",
"'LINEAR_REG'<br/>\n",
"'LOGISTIC_REG' --> TensorFlow SavedFormat\n",
"\n",
"'AUTOML_CLASSIFIER'<br/>\n",
"'AUTOML_REGRESSOR' --> TensorFlow SavedFormat\n",
"\n",
"'BOOSTED_TREE_CLASSIFIER'<br/>\n",
"'BOOSTED_TREE_REGRESSOR' --> XGBoost format\n",
"\n",
"'DNN_CLASSIFIER'<br/>\n",
"'DNN_REGRESSOR'<br/>\n",
"'DNN_LINEAR_COMBINED_CLASSIFIER'<br/>\n",
"'DNN_LINEAR_COMBINED_REGRESSOR' --> TensorFlow Estimator"
]
},
{
@@ -731,7 +737,7 @@
},
"outputs": [],
"source": [
"model = aip.Model.upload(\n",
"model = aiplatform.Model.upload(\n",
" display_name=\"penguins_\" + TIMESTAMP,\n",
" artifact_uri=MODEL_DIR,\n",
" serving_container_image_uri=DEPLOY_IMAGE,\n",
@@ -752,7 +758,7 @@
"- `deployed_model_display_name`: A human readable name for the deployed model.\n",
"- `traffic_split`: Percent of traffic at the endpoint that goes to this model, which is specified as a dictionary of one or more key/value pairs.\n",
"If only one model, then specify as { \"0\": 100 }, where \"0\" refers to this model being uploaded and 100 means 100% of the traffic.\n",
"If there are existing models on the endpoint, for which the traffic will be split, then use model_id to specify as { \"0\": percent, model_id: percent, ... }, where model_id is the model id of an existing model to the deployed endpoint. The percents must add up to 100.\n",
"If there are existing models on the endpoint, for which the traffic needs to be split, then use model_id to specify as { \"0\": percent, model_id: percent, ... }, where model_id is the model id of an existing model to the deployed endpoint. The percents must add up to 100.\n",
"- `machine_type`: The type of machine to use for training.\n",
"- `accelerator_type`: The hardware accelerator type.\n",
"- `accelerator_count`: The number of accelerators to attach to a worker replica.\n",
@@ -801,7 +807,7 @@
"id": "undeploy_model:mbsdk"
},
"source": [
"## Undeploy the model\n",
"#### Undeploy the model\n",
"\n",
"When you are done doing predictions, you undeploy the model from the `Endpoint` resouce. This deprovisions all compute resources and ends billing for the deployed model."
]
@@ -825,7 +831,7 @@
"source": [
"#### Delete the model\n",
"\n",
"The method 'delete()' will delete the model."
"The method 'delete()' deletes the model."
]
},
{
@@ -847,7 +853,7 @@
"source": [
"### Hyperparameter Tune and train a BQML model\n",
"\n",
"Next, you train a BQML tabular classification model with hyperparameter tuning using the Vertex AI Vizier service. The hyperparameter settings are specified in the `OPTIONS` statement as follows:\n",
"Next, you train a BQML tabular classification model with hyperparameter tuning using the `Vertex AI Vizier` service. The hyperparameter settings are specified in the `OPTIONS` statement as follows:\n",
"\n",
"- `HPARAM_TUNING_ALGORITHM`: The algorithm for selecting the next trial parameters.\n",
"- `num_trials`: The number of trials.\n",
@@ -902,7 +908,7 @@
"source": [
"### Evaluate the BQML trained model\n",
"\n",
"Next, retrieve the model evaluation for the trained BQML model.\n",
"Next, retrieve the model evaluation results for the trained BQML model.\n",
"\n",
"Learn more about [The ML.EVALUATE function](https://cloud.google.com/bigquery-ml/docs/reference/standard-sql/bigqueryml-syntax-evaluate)."
]
@@ -976,6 +982,116 @@
"print(\"{} created in {}\".format(tblname, job.ended - job.started))"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "1bb996026c94"
},
"source": [
"## Model Registry\n",
"\n",
"Alternatively, you can implicitly upload your BigQuery ML model as a `Vertex AI Model` resource with exporting and importing the model artifacts. In this method, you add additional options when training the model that tells BigQuery ML to automatically upload and register the trained model as a `Model` resource.\n",
"\n",
"### Setting permissions to automatically register the model\n",
"\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."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "eaaf24146aad"
},
"outputs": [],
"source": [
"! gcloud projects add-iam-policy-binding $PROJECT_ID \\\n",
" --member='serviceAccount:cloud-dataengine@system.gserviceaccount.com' \\\n",
" --role='roles/aiplatform.admin'\n",
"\n",
"! gcloud projects add-iam-policy-binding $PROJECT_ID \\\n",
" --member='user:cloud-dataengine@prod.google.com' \\\n",
" --role='roles/aiplatform.admin'"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "8bfc0b26155f"
},
"source": [
"### Training and registering the model\n",
"\n",
"Next, you train the model and automatically register the model to the `Vertex AI Model Registry`, by adding the following parameters as options:\n",
"\n",
"- `model_registry`: Set to \"vertex_ai\" to indicate automatic registation to `Vertex AI Model Registry`.\n",
"- `vertex_ai_model_id`: The human readable display name for the registered model.\n",
"- `vertex_ai_model_version_aliases`: Alternate names for the model."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "3ff1d4ef4df2"
},
"outputs": [],
"source": [
"MODEL_NAME = \"penguins\"\n",
"MODEL_QUERY = f\"\"\"\n",
"CREATE OR REPLACE MODEL `{BQ_DATASET_NAME}.{MODEL_NAME}`\n",
"OPTIONS(\n",
" model_type='DNN_CLASSIFIER',\n",
" labels = ['species'],\n",
" model_registry=\"vertex_ai\",\n",
" vertex_ai_model_id=\"bqml_model_{TIMESTAMP}\", \n",
" vertex_ai_model_version_aliases=[\"1\"]\n",
" )\n",
"AS\n",
"SELECT *\n",
"FROM `{BQ_TABLE}`\n",
"\"\"\"\n",
"\n",
"job = bqclient.query(MODEL_QUERY)\n",
"print(job.errors, job.state)\n",
"\n",
"while job.running():\n",
" from time import sleep\n",
"\n",
" sleep(30)\n",
" print(\"Running ...\")\n",
"print(job.errors, job.state)\n",
"\n",
"tblname = job.ddl_target_table\n",
"tblname = \"{}.{}\".format(tblname.dataset_id, tblname.table_id)\n",
"print(\"{} created in {}\".format(tblname, job.ended - job.started))"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "a243d86f9d22"
},
"source": [
"### Find the model in the `Vertex Model Registry`\n",
"\n",
"Finally, you can use the `Vertex AI Model` list() method with a filter query to find the automatically registered model."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "4fd9a143d900"
},
"outputs": [],
"source": [
"models = aiplatform.Model.list(filter=\"display_name=bqml_model_\" + TIMESTAMP)\n",
"model = models[0]\n",
"\n",
"print(model.gca_resource)"
]
},
{
"cell_type": "markdown",
"metadata": {
@@ -989,14 +1105,9 @@
"\n",
"Otherwise, you can delete the individual resources you created in this tutorial:\n",
"\n",
"- Dataset\n",
"- Pipeline\n",
"- Model\n",
"- Endpoint\n",
"- AutoML Training Job\n",
"- Batch Job\n",
"- Custom Job\n",
"- Hyperparameter Tuning Job\n",
"- Dataset\n",
"- Cloud Storage Bucket"
]
},
@@ -1008,61 +1119,21 @@
},
"outputs": [],
"source": [
"delete_all = True\n",
"# Delete the endpoint using the Vertex endpoint object\n",
"endpoint.undeploy_all()\n",
"endpoint.delete()\n",
"\n",
"if delete_all:\n",
" # Delete the dataset using the Vertex dataset object\n",
" try:\n",
" if \"dataset\" in globals():\n",
" dataset.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"# Delete the model using the Vertex model object\n",
"try:\n",
" model.delete()\n",
"except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the model using the Vertex model object\n",
" try:\n",
" if \"model\" in globals():\n",
" model.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the endpoint using the Vertex endpoint object\n",
" try:\n",
" if \"endpoint\" in globals():\n",
" endpoint.undeploy_all()\n",
" endpoint.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the AutoML or Pipeline training job\n",
" try:\n",
" if \"dag\" in globals():\n",
" dag.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the custom training job\n",
" try:\n",
" if \"job\" in globals():\n",
" job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the batch prediction job using the Vertex batch prediction object\n",
" try:\n",
" if \"batch_predict_job\" in globals():\n",
" batch_predict_job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the hyperparameter tuning job using the Vertex hyperparameter tuning object\n",
" try:\n",
" if \"hpt_job\" in globals():\n",
" hpt_job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" if \"BUCKET_NAME\" in globals():\n",
" ! gsutil rm -r $BUCKET_NAME"
"if os.getenv(\"IS_TESTING\"):\n",
" # Delete the created GCS bucket\n",
" ! gsutil rm -r $BUCKET_NAME\n",
" # Delete the created BigQuery dataset\n",
" ! bq rm -r -f $PROJECT_ID:$BQ_DATASET_NAME"
]
}
],
@@ -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",
@@ -32,6 +32,11 @@
"# E2E ML on GCP: MLOps stage 2 : experimentation: get started with Vertex Distributed Training\n",
"\n",
"<table align=\"left\">\n",
" <td>\n",
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/vertex-ai-samples/blob/master/notebooks/community/ml_ops/stage2/get_started_vertex_distributed_training.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/stage2/get_started_vertex_distributed_training.ipynb\">\n",
" <img src=\"https://cloud.google.com/ml-engine/images/github-logo-32px.png\" alt=\"GitHub logo\">\n",
@@ -39,8 +44,9 @@
" </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/blob/main/notebooks/community/ml_ops/stage2/get_started_vertex_distributed_training.ipynb\">\n",
" Open in Google Cloud Notebooks\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/community/ml_ops/stage2/get_started_vertex_distributed_training.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",
@@ -56,7 +62,7 @@
"## 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 Vertex Distributed Training."
"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 Vertex Distributed Training. Please note: There are incompatibilities between Colab and Docker and the Docker section may not work until resolved by the platform."
]
},
{
@@ -100,6 +106,15 @@
"id": "recommendation:mlops,stage2,vertex,distributed_training"
},
"source": [
"### Costs\n",
" \n",
"This tutorial uses billable components of Google Cloud:\n",
"\n",
"Vertex AI\n",
"Cloud Storage\n",
"\n",
"Learn about [Vertex AI pricing](https://cloud.google.com/vertex-ai/pricing) and [Cloud Storage pricing](https://cloud.google.com/storage/pricing), and use the [Pricing Calculator](https://cloud.google.com/products/calculator/),\n",
" to generate a cost estimate based on your projected usage.\n",
"### Recommendations\n",
"\n",
"When doing E2E MLOps on Google Cloud, the following are best practices for when to use Vertex AI Distributed Training:\n",
@@ -126,59 +141,64 @@
{
"cell_type": "markdown",
"metadata": {
"id": "install_mlops"
"id": "XkYpRvOQyVYb"
},
"source": [
"## Installations\n",
"### Install additional packages\n",
"\n",
"Install *one time* the packages for executing the MLOps notebooks."
"Install the latest version of Vertex SDK for Python."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "install_mlops"
"id": "xs_Kt8RcyXTC"
},
"outputs": [],
"source": [
"ONCE_ONLY = False\n",
"if ONCE_ONLY:\n",
" ! pip3 install -U tensorflow==2.5 $USER_FLAG\n",
" ! pip3 install -U tensorflow-data-validation==1.2 $USER_FLAG\n",
" ! pip3 install -U tensorflow-transform==1.2 $USER_FLAG\n",
" ! pip3 install -U tensorflow-io==0.18 $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-aiplatform[tensorboard] $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-pipeline-components $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-bigquery $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-logging $USER_FLAG\n",
" ! pip3 install --upgrade apache-beam[gcp] $USER_FLAG\n",
" ! pip3 install --upgrade pyarrow $USER_FLAG\n",
" ! pip3 install --upgrade cloudml-hypertune $USER_FLAG\n",
" ! pip3 install --upgrade kfp $USER_FLAG\n",
" ! pip3 install --upgrade torchvision $USER_FLAG\n",
" ! pip3 install --upgrade rpy2 $USER_FLAG"
"import os\n",
"\n",
"# The Google Cloud Notebook product has specific requirements\n",
"IS_GOOGLE_CLOUD_NOTEBOOK = os.path.exists(\"/opt/deeplearning/metadata/env_version\")\n",
"\n",
"# Google Cloud Notebook requires dependencies to be installed with '--user'\n",
"USER_FLAG = \"\"\n",
"if IS_GOOGLE_CLOUD_NOTEBOOK:\n",
" USER_FLAG = \"--user\""
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "TjOXHg2VyajN"
},
"outputs": [],
"source": [
"! pip3 install {USER_FLAG} --upgrade google-cloud-aiplatform"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "restart"
"id": "oQhwq1iozAxh"
},
"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."
"After you install 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"
"id": "zo3YFZXLzCRJ"
},
"outputs": [],
"source": [
"# Automatically restart kernel after installs\n",
"import os\n",
"\n",
"if not os.getenv(\"IS_TESTING\"):\n",
@@ -208,6 +228,8 @@
},
"outputs": [],
"source": [
"import os\n",
"\n",
"PROJECT_ID = \"[your-project-id]\" # @param {type:\"string\"}"
]
},
@@ -261,7 +283,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "region"
"id": "qohAA9fJulvP"
},
"outputs": [],
"source": [
@@ -283,7 +305,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "timestamp"
"id": "8NKwwe7aulvQ"
},
"outputs": [],
"source": [
@@ -292,6 +314,81 @@
"TIMESTAMP = datetime.now().strftime(\"%Y%m%d%H%M%S\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "poKeKYG8ulvQ"
},
"source": [
"### Authenticate your Google Cloud account\n",
"\n",
"**If you are using Google Cloud Notebooks**, your environment is already\n",
"authenticated. Skip this step."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "MIpJGzF9ulvQ"
},
"source": [
"**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",
"1. In the Cloud Console, go to the [**Create service account key**\n",
" page](https://console.cloud.google.com/apis/credentials/serviceaccountkey).\n",
"\n",
"2. Click **Create service account**.\n",
"\n",
"3. In the **Service account name** field, enter a name, and\n",
" click **Create**.\n",
"\n",
"4. In the **Grant this service account access to project** section, click the **Role** drop-down list. Type \"Vertex AI\"\n",
"into the filter box, and select\n",
" **Vertex AI Administrator**. Type \"Storage Object Admin\" into the filter box, and select **Storage Object Admin**.\n",
"\n",
"5. Click *Create*. A JSON file that contains your key downloads to your\n",
"local environment.\n",
"\n",
"6. Enter the path to your service account key as the\n",
"`GOOGLE_APPLICATION_CREDENTIALS` variable in the cell below and run the cell."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "Vh6KDXB5ulvQ"
},
"outputs": [],
"source": [
"import os\n",
"import sys\n",
"\n",
"# 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",
"# The Google Cloud Notebook product has specific requirements\n",
"IS_GOOGLE_CLOUD_NOTEBOOK = os.path.exists(\"/opt/deeplearning/metadata/env_version\")\n",
"\n",
"# If on Google Cloud Notebooks, then don't execute this code\n",
"if not IS_GOOGLE_CLOUD_NOTEBOOK:\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": {
@@ -343,7 +440,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "create_bucket"
"id": "Moosy2rOulvR"
},
"outputs": [],
"source": [
@@ -363,7 +460,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "validate_bucket"
"id": "56irx2CvulvS"
},
"outputs": [],
"source": [
@@ -408,7 +505,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "init_aip:mbsdk"
"id": "wbvYPSTDulvS"
},
"outputs": [],
"source": [
@@ -441,7 +538,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "accelerators:training,prediction,ngpu,mbsdk"
"id": "PryARdnoulvT"
},
"outputs": [],
"source": [
@@ -483,7 +580,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "container:training,prediction"
"id": "LhhUFw2nulvT"
},
"outputs": [],
"source": [
@@ -551,7 +648,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "machine:training"
"id": "vytMaukeulvT"
},
"outputs": [],
"source": [
@@ -613,7 +710,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "create_custom_pp_training_job:mbsdk"
"id": "mhw34XoOulvU"
},
"outputs": [],
"source": [
@@ -662,7 +759,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "examine_training_package"
"id": "IAaZpZyyulvU"
},
"outputs": [],
"source": [
@@ -711,7 +808,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "taskpy_contents:mirrored,boston"
"id": "zKzddzl6ulvV"
},
"outputs": [],
"source": [
@@ -767,6 +864,13 @@
" strategy = tf.distribute.MultiWorkerMirroredStrategy()\n",
" logging.info(\"Multi-worker Strategy distributed training\")\n",
" logging.info('TF_CONFIG = {}'.format(os.environ.get('TF_CONFIG', 'Not found')))\n",
" # Single Machine, multiple TPU devices\n",
"elif args.distribute == 'tpu':\n",
" cluster_resolver = tf.distribute.cluster_resolver.TPUClusterResolver(tpu=\"local\")\n",
" tf.config.experimental_connect_to_cluster(cluster_resolver)\n",
" tf.tpu.experimental.initialize_tpu_system(cluster_resolver)\n",
" strategy = tf.distribute.TPUStrategy(cluster_resolver)\n",
" print(\"All devices: \", tf.config.list_logical_devices('TPU'))\n",
"\n",
"logging.info('num_replicas_in_sync = {}'.format(strategy.num_replicas_in_sync))\n",
"\n",
@@ -825,8 +929,11 @@
" else:\n",
" task_type, task_id = None, None\n",
"\n",
" if args.distribute==\"tpu\":\n",
" save_locally = tf.saved_model.SaveOptions(experimental_io_device='/job:localhost')\n",
" model.save(args.model_dir, options=save_locally)\n",
" # single, mirrored or primary for multiworker\n",
" if _is_chief(task_type, task_id):\n",
" elif _is_chief(task_type, task_id):\n",
" model.save(args.model_dir)\n",
" # non-primary workers for multi-workers\n",
" else:\n",
@@ -860,7 +967,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "tarball_training_script"
"id": "LFUHioqTulvV"
},
"outputs": [],
"source": [
@@ -885,7 +992,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "run_custom_pp_training_job:mirrored"
"id": "LnUX0UkvulvV"
},
"outputs": [],
"source": [
@@ -920,7 +1027,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "delete_job"
"id": "iUWHFpPoulvW"
},
"outputs": [],
"source": [
@@ -942,7 +1049,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "model_delete:mbsdk"
"id": "-0gqCUTEulvW"
},
"outputs": [],
"source": [
@@ -1027,7 +1134,7 @@
{
"cell_type": "markdown",
"metadata": {
"id": "create_custom_pp_training_job:mbsdk"
"id": "aXvPN8P6ulvX"
},
"source": [
"### Create and run custom training job\n",
@@ -1053,7 +1160,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "create_custom_pp_training_job:mbsdk"
"id": "kYcFsVSEulvX"
},
"outputs": [],
"source": [
@@ -1084,7 +1191,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "run_custom_pp_training_job:multiworker"
"id": "GHRxPU32ulvX"
},
"outputs": [],
"source": [
@@ -1111,7 +1218,7 @@
{
"cell_type": "markdown",
"metadata": {
"id": "delete_job"
"id": "92D_hbuVulvX"
},
"source": [
"### Delete a custom training job\n",
@@ -1123,7 +1230,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "delete_job"
"id": "CqrfWkB3ulvX"
},
"outputs": [],
"source": [
@@ -1175,14 +1282,13 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "write_docker_file:training,multiworker"
"id": "pGI2viDAulvY"
},
"outputs": [],
"source": [
"%%writefile custom/Dockerfile\n",
"\n",
"FROM gcr.io/deeplearning-platform-release/tf2-gpu.2-5\n",
"WORKDIR /root\n",
"\n",
"WORKDIR /\n",
"\n",
@@ -1208,7 +1314,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "name_container:training"
"id": "7P8cdlFtulvY"
},
"outputs": [],
"source": [
@@ -1228,7 +1334,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "build_container:training"
"id": "jmw5cakNulvY"
},
"outputs": [],
"source": [
@@ -1250,7 +1356,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "test_container:training"
"id": "jJGLjU-TulvZ"
},
"outputs": [],
"source": [
@@ -1272,7 +1378,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "register_container:training"
"id": "GAXGjae7ulvZ"
},
"outputs": [],
"source": [
@@ -1296,7 +1402,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "worker_pool_primary"
"id": "CEAnXBzCulvZ"
},
"outputs": [],
"source": [
@@ -1339,7 +1445,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "worker_pool_training"
"id": "6dchPSfNulvZ"
},
"outputs": [],
"source": [
@@ -1375,7 +1481,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "custom_job:worker_pool"
"id": "m2VgmqEOulva"
},
"outputs": [],
"source": [
@@ -1399,7 +1505,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "run_custom_job:multiworker"
"id": "hg8vnI_Wulva"
},
"outputs": [],
"source": [
@@ -1413,7 +1519,7 @@
{
"cell_type": "markdown",
"metadata": {
"id": "delete_job"
"id": "WT76Sc-culva"
},
"source": [
"### Delete a custom training job\n",
@@ -1425,7 +1531,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "delete_job"
"id": "I_IxVfuDulva"
},
"outputs": [],
"source": [
@@ -1474,7 +1580,7 @@
{
"cell_type": "markdown",
"metadata": {
"id": "custom_job:worker_pool"
"id": "L8Av8ATVulvb"
},
"source": [
"### Create CustomJob with worker pool specifications\n",
@@ -1490,7 +1596,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "custom_job:worker_pool"
"id": "TUWEP1Lmulvb"
},
"outputs": [],
"source": [
@@ -1502,7 +1608,7 @@
{
"cell_type": "markdown",
"metadata": {
"id": "run_custom_job:multiworker"
"id": "_95FH8jeulvb"
},
"source": [
"### Run the CustomJob\n",
@@ -1514,7 +1620,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "run_custom_job:multiworker"
"id": "IEbrY05Gulvb"
},
"outputs": [],
"source": [
@@ -1528,7 +1634,7 @@
{
"cell_type": "markdown",
"metadata": {
"id": "delete_job"
"id": "8R2Bnmwmulvb"
},
"source": [
"### Delete a custom training job\n",
@@ -1540,7 +1646,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "delete_job"
"id": "s1geVE3Lulvb"
},
"outputs": [],
"source": [
@@ -1583,14 +1689,14 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "docker_write:tpu"
"id": "nQVPtknpulvb"
},
"outputs": [],
"source": [
"%%writefile custom/Dockerfile\n",
"FROM python:3.8\n",
"\n",
"WORKDIR /root\n",
"WORKDIR /\n",
"\n",
"# Copies the trainer code to the docker image.\n",
"COPY trainer /trainer\n",
@@ -1622,11 +1728,11 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "docker_push:tpu"
"id": "J_d_zEXUulvc"
},
"outputs": [],
"source": [
"TRAIN_IMAGE = f\"gcr.io/\" + PROJECT_ID + \"/tpu-train:latest\"\n",
"TRAIN_IMAGE = \"gcr.io/\" + PROJECT_ID + \"/tpu-train:latest\"\n",
"\n",
"os.chdir(\"custom\")\n",
"! docker build --quiet --tag={TRAIN_IMAGE} .\n",
@@ -1653,7 +1759,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "worker_pool_tpu"
"id": "d514eU7lulvc"
},
"outputs": [],
"source": [
@@ -1701,7 +1807,7 @@
{
"cell_type": "markdown",
"metadata": {
"id": "custom_job:worker_pool"
"id": "RruSqNfrulvc"
},
"source": [
"### Create CustomJob with worker pool specifications\n",
@@ -1717,7 +1823,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "custom_job:worker_pool"
"id": "2QvSqbbHulvc"
},
"outputs": [],
"source": [
@@ -1729,7 +1835,7 @@
{
"cell_type": "markdown",
"metadata": {
"id": "run_custom_job:multiworker"
"id": "Iw4L3UIfulvd"
},
"source": [
"### Run the CustomJob\n",
@@ -1741,7 +1847,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "run_custom_job:multiworker"
"id": "zmqCNS78ulvd"
},
"outputs": [],
"source": [
@@ -1755,7 +1861,7 @@
{
"cell_type": "markdown",
"metadata": {
"id": "delete_job"
"id": "gWZoH9QKulvd"
},
"source": [
"### Delete a custom training job\n",
@@ -1767,7 +1873,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "delete_job"
"id": "Lt8BJ4iBulvd"
},
"outputs": [],
"source": [
@@ -1787,13 +1893,7 @@
"\n",
"Otherwise, you can delete the individual resources you created in this tutorial:\n",
"\n",
"- Dataset\n",
"- Pipeline\n",
"- Model\n",
"- Endpoint\n",
"- Batch Job\n",
"- Custom Job\n",
"- Hyperparameter Tuning Job\n",
"\n",
"- Cloud Storage Bucket"
]
},
@@ -1801,70 +1901,15 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "cleanup"
"id": "U98Wzc01ulvd"
},
"outputs": [],
"source": [
"delete_dataset = True\n",
"delete_pipeline = True\n",
"delete_model = True\n",
"delete_endpoint = True\n",
"delete_batchjob = True\n",
"delete_customjob = True\n",
"delete_hptjob = True\n",
"delete_bucket = True\n",
"# 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 fully qualified identifier for the dataset\n",
"try:\n",
" if delete_dataset and \"dataset_id\" in globals():\n",
" clients[\"dataset\"].delete_dataset(name=dataset_id)\n",
"except Exception as e:\n",
" print(e)\n",
"\n",
"# Delete the training pipeline using the Vertex fully qualified identifier for the pipeline\n",
"try:\n",
" if delete_pipeline and \"pipeline_id\" in globals():\n",
" clients[\"pipeline\"].delete_training_pipeline(name=pipeline_id)\n",
"except Exception as e:\n",
" print(e)\n",
"\n",
"# Delete the model using the Vertex fully qualified identifier for the model\n",
"try:\n",
" if delete_model and \"model_to_deploy_id\" in globals():\n",
" clients[\"model\"].delete_model(name=model_to_deploy_id)\n",
"except Exception as e:\n",
" print(e)\n",
"\n",
"# Delete the endpoint using the Vertex fully qualified identifier for the endpoint\n",
"try:\n",
" if delete_endpoint and \"endpoint_id\" in globals():\n",
" clients[\"endpoint\"].delete_endpoint(name=endpoint_id)\n",
"except Exception as e:\n",
" print(e)\n",
"\n",
"# Delete the batch job using the Vertex fully qualified identifier for the batch job\n",
"try:\n",
" if delete_batchjob and \"batch_job_id\" in globals():\n",
" clients[\"job\"].delete_batch_prediction_job(name=batch_job_id)\n",
"except Exception as e:\n",
" print(e)\n",
"\n",
"# Delete the custom job using the Vertex fully qualified identifier for the custom job\n",
"try:\n",
" if delete_customjob and \"job_id\" in globals():\n",
" clients[\"job\"].delete_custom_job(name=job_id)\n",
"except Exception as e:\n",
" print(e)\n",
"\n",
"# Delete the hyperparameter tuning job using the Vertex fully qualified identifier for the hyperparameter tuning job\n",
"try:\n",
" if delete_hptjob and \"hpt_job_id\" in globals():\n",
" clients[\"job\"].delete_hyperparameter_tuning_job(name=hpt_job_id)\n",
"except Exception as e:\n",
" print(e)\n",
"\n",
"if delete_bucket and \"BUCKET_NAME\" in globals():\n",
" ! gsutil rm -r $BUCKET_NAME"
"if delete_bucket or os.getenv(\"IS_TESTING\"):\n",
" ! gsutil rm -r $BUCKET_URI"
]
}
],
@@ -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",
@@ -29,7 +29,7 @@
"id": "title:generic,gcp"
},
"source": [
"# E2E ML on GCP: MLOps stage 2 : experimentation: get started with Logging and Vertex Experiments\n",
"# E2E ML on GCP: MLOps stage 2 : experimentation: get started with Logging and Vertex AI Experiments\n",
"\n",
"<table align=\"left\">\n",
" <td>\n",
@@ -38,9 +38,15 @@
" 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_vertex_experiments.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/ai/platform/notebooks/deploy-notebook?download_url=https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage2/get_started_vertex_experiments.ipynb\">\n",
" Open in Google Cloud Notebooks\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/community/ml_ops/stage2/get_started_vertex_experiments.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",
@@ -56,7 +62,7 @@
"## 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 and Vertex Experiments."
"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 and Vertex AI Experiments."
]
},
{
@@ -93,7 +99,7 @@
"source": [
"### Recommendations\n",
"\n",
"When doing E2E MLOps on Google Cloud, the following best practices for logging data when experimenting or formal training a model.\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",
@@ -105,7 +111,14 @@
"\n",
"#### Experiments\n",
"\n",
"Use Vertex AI Experiments in conjunction with logging when doing experiments to compare results for different experiment configurations."
"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."
]
},
{
@@ -116,7 +129,7 @@
"source": [
"## Installations\n",
"\n",
"Install *one time* the packages for executing the MLOps notebooks."
"Install the following packages for executing this notebook."
]
},
{
@@ -127,20 +140,17 @@
},
"outputs": [],
"source": [
"ONCE_ONLY = False\n",
"if ONCE_ONLY:\n",
" ! pip3 install -U tensorflow==2.5 $USER_FLAG\n",
" ! pip3 install -U tensorflow-data-validation==1.2 $USER_FLAG\n",
" ! pip3 install -U tensorflow-transform==1.2 $USER_FLAG\n",
" ! pip3 install -U tensorflow-io==0.18 $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-aiplatform[tensorboard] $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-pipeline-components $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-bigquery $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-logging $USER_FLAG\n",
" ! pip3 install --upgrade apache-beam[gcp] $USER_FLAG\n",
" ! pip3 install --upgrade pyarrow $USER_FLAG\n",
" ! pip3 install --upgrade cloudml-hypertune $USER_FLAG\n",
" ! pip3 install --upgrade kfp $USER_FLAG"
"import os\n",
"\n",
"# The Google Cloud Notebook product has specific requirements\n",
"IS_GOOGLE_CLOUD_NOTEBOOK = os.path.exists(\"/opt/deeplearning/metadata/env_version\")\n",
"\n",
"# Google Cloud Notebook requires dependencies to be installed with '--user'\n",
"USER_FLAG = \"\"\n",
"if IS_GOOGLE_CLOUD_NOTEBOOK:\n",
" USER_FLAG = \"--user\"\n",
"\n",
"! pip3 install --upgrade google-cloud-logging $USER_FLAG"
]
},
{
@@ -178,6 +188,24 @@
"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`."
@@ -248,7 +276,10 @@
},
"outputs": [],
"source": [
"REGION = \"us-central1\" # @param {type: \"string\"}"
"REGION = \"[your-region]\" # @param {type: \"string\"}\n",
"\n",
"if REGION == \"[your-region]\":\n",
" REGION = \"us-central1\""
]
},
{
@@ -275,6 +306,63 @@
"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 Google Cloud 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 Google Cloud Notebook, then don't execute this code\n",
"if not os.path.exists(\"/opt/deeplearning/metadata/env_version\"):\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": {
@@ -284,7 +372,7 @@
"### Set up variables\n",
"\n",
"Next, set up some variables used throughout the tutorial.\n",
"### Import libraries and define constants"
"### Import libraries"
]
},
{
@@ -295,29 +383,9 @@
},
"outputs": [],
"source": [
"import google.cloud.aiplatform as aip"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "import_logging"
},
"source": [
"#### Import logging\n",
"import logging\n",
"\n",
"Import the logging package into your Python environment."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "import_logging"
},
"outputs": [],
"source": [
"import logging"
"import google.cloud.aiplatform as aiplatform"
]
},
{
@@ -339,7 +407,7 @@
},
"outputs": [],
"source": [
"aip.init(project=PROJECT_ID, location=REGION)"
"aiplatform.init(project=PROJECT_ID, location=REGION)"
]
},
{
@@ -356,9 +424,9 @@
"- Send log output to console.\n",
"- Send log output to a file.\n",
"\n",
"### Logging Levels\n",
"### Logging Levels in Python Logging\n",
"\n",
"The logging levels in order (from least to highest) are, with each level inclusive of the previous level:\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",
@@ -398,7 +466,7 @@
"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 w/o arguments it gets the default handler, named ROOT. With the handler, you set the logging level with the method 'setLevel()`."
"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()`."
]
},
{
@@ -445,7 +513,7 @@
"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()`, with the following paraneters:\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",
@@ -482,7 +550,7 @@
"- Send log output to storage.\n",
"- Retrieve log output from storage.\n",
"\n",
"### Logging Levels\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",
@@ -517,7 +585,7 @@
"from google.cloud.logging.handlers import CloudLoggingHandler\n",
"\n",
"# Connect to the Cloud Logging service\n",
"cl_client = google.cloud.logging.Client()\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",
@@ -539,7 +607,7 @@
"source": [
"### Logging output\n",
"\n",
"To log output at specific levels is identical in method, and method names, as in Python logging, except that you use your instance of the cloud logger in place of logging."
"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."
]
},
{
@@ -567,7 +635,7 @@
"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",
"2. Using the handle, call the method `list_entries()`.\n",
"3. Iterate through the entries."
]
},
@@ -594,10 +662,10 @@
"source": [
"## Logging with Vertex AI Experiments and Vertex AI ML Metadata\n",
"\n",
"You can log results related to training experiments with `Vertex AI Experiments` and `ML Metadata`:\n",
"You can log results related to training experiments with `Vertex AI Experiments` and `ML Metadata` including:\n",
"\n",
"- Preserve results of an experiment.\n",
"- Track multiple runs -- i.e., training runs -- within an experiment.\n",
"- Track multiple runs i.e., training runs within an experiment.\n",
"- Track parameters (configuration) and metrics (results).\n",
"- Retrieve and display the logged output.\n",
"\n",
@@ -612,14 +680,29 @@
"source": [
"### Create experiment for tracking training related metadata\n",
"\n",
"Setup tracking the parameters (configuration) and metrics (results) for each experiment:\n",
"Setup tracking for parameters (configuration) and metrics (results) in each experiment:\n",
"\n",
"- `aip.init()` - Create an experiment instance\n",
"- `aip.start_run()` - Track a specific run within the experiment.\n",
"- `aiplatform.init()` - Create an experiment instance\n",
"- `aiplatform.start_run()` - Track a specific run within the experiment.\n",
"\n",
"Learn more about [Introduction to Vertex AI ML Metadata](https://cloud.google.com/vertex-ai/docs/ml-metadata/introduction)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "1ed46e349cf2"
},
"outputs": [],
"source": [
"# Specify a name for the experiment\n",
"EXPERIMENT_NAME = \"[your-experiment-name]\"\n",
"\n",
"if EXPERIMENT_NAME == \"[your-experiment-name]\":\n",
" EXPERIMENT_NAME = \"example-\" + TIMESTAMP"
]
},
{
"cell_type": "code",
"execution_count": null,
@@ -628,9 +711,9 @@
},
"outputs": [],
"source": [
"EXPERIMENT_NAME = \"example-\" + TIMESTAMP\n",
"aip.init(experiment=EXPERIMENT_NAME)\n",
"aip.start_run(\"run-1\")"
"# Create experiment\n",
"aiplatform.init(experiment=EXPERIMENT_NAME)\n",
"aiplatform.start_run(\"run-1\")"
]
},
{
@@ -641,14 +724,14 @@
"source": [
"### Log parameters for the experiment\n",
"\n",
"Typically, an experiment is associated with a specific dataset and model architecture. Within an experiment, you may have multiple training runs, where each run tries a different configuration. As examples:\n",
"Typically, an experiment is associated with a specific dataset and a model architecture. Within an experiment, you may have multiple training runs, where each run tries a different configuration. For example:\n",
"\n",
"- Dataset split\n",
"- Dataset sampling and boosting\n",
"- Depth and width of layers\n",
"- Hyperparameters\n",
"\n",
"These configuration settings are referred to as parameters, which you store their key/value pair using the method `log_params()`"
"These configuration settings are referred to as parameters, which you store as key-value pairs using the method `log_params()`"
]
},
{
@@ -663,7 +746,7 @@
"hyperparams[\"epochs\"] = 100\n",
"hyperparams[\"batch_size\"] = 32\n",
"hyperparams[\"learning_rate\"] = 0.01\n",
"aip.log_params(hyperparams)"
"aiplatform.log_params(hyperparams)"
]
},
{
@@ -674,14 +757,14 @@
"source": [
"### Log metrics for the experiment\n",
"\n",
"At the completion, or termination, of a run within an experiment, you can log results that you use to compare runs. As examples:\n",
"At the completion or termination of a run within an experiment, you can log results that you use to compare runs. For example:\n",
"\n",
"- Evaluation metrics\n",
"- Hyperparameter search selection\n",
"- Time to train the model\n",
"- Early stop trigger\n",
"\n",
"These results settings are referred to as metrics, which you store their key/value pair using the method `log_metrics()`"
"These results are referred to as metrics, which you store as key-value pairs using the method `log_metrics()`"
]
},
{
@@ -695,7 +778,7 @@
"metrics = {}\n",
"metrics[\"test_acc\"] = 98.7\n",
"metrics[\"train_acc\"] = 99.3\n",
"aip.log_metrics(metrics)"
"aiplatform.log_metrics(metrics)"
]
},
{
@@ -717,36 +800,11 @@
},
"outputs": [],
"source": [
"EXPERIMENT_NAME = \"example\"\n",
"\n",
"experiment_df = aip.get_experiment_df()\n",
"experiment_df = aiplatform.get_experiment_df()\n",
"experiment_df = experiment_df[experiment_df.experiment_name == EXPERIMENT_NAME]\n",
"experiment_df.T"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "delete_experiment"
},
"source": [
"### Delete the experiment\n",
"\n",
"Next, delete the experiment. You will need to get the context via the metadata to delete it."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "delete_experiment"
},
"outputs": [],
"source": [
"c = aiplatform.metadata._Context(EXPERIMENT_NAME)\n",
"c.delete()"
]
},
{
"cell_type": "markdown",
"metadata": {
@@ -760,15 +818,9 @@
"\n",
"Otherwise, you can delete the individual resources you created in this tutorial:\n",
"\n",
"- Dataset\n",
"- Pipeline\n",
"- Model\n",
"- Endpoint\n",
"- AutoML Training Job\n",
"- Batch Job\n",
"- Custom Job\n",
"- Hyperparameter Tuning Job\n",
"- Cloud Storage Bucket"
"### Delete the experiment\n",
"\n",
"Next, delete the experiment. You will need to get the context via the metadata to delete it."
]
},
{
@@ -779,61 +831,8 @@
},
"outputs": [],
"source": [
"delete_all = True\n",
"\n",
"if delete_all:\n",
" # Delete the dataset using the Vertex dataset object\n",
" try:\n",
" if \"dataset\" in globals():\n",
" dataset.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the model using the Vertex model object\n",
" try:\n",
" if \"model\" in globals():\n",
" model.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the endpoint using the Vertex endpoint object\n",
" try:\n",
" if \"endpoint\" in globals():\n",
" endpoint.undeploy_all()\n",
" endpoint.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the AutoML or Pipeline training job\n",
" try:\n",
" if \"dag\" in globals():\n",
" dag.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the custom training job\n",
" try:\n",
" if \"job\" in globals():\n",
" job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the batch prediction job using the Vertex batch prediction object\n",
" try:\n",
" if \"batch_predict_job\" in globals():\n",
" batch_predict_job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the hyperparameter tuning job using the Vertex hyperparameter tuning object\n",
" try:\n",
" if \"hpt_job\" in globals():\n",
" hpt_job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" if \"BUCKET_NAME\" in globals():\n",
" ! gsutil rm -r $BUCKET_NAME"
"c = aiplatform.metadata._Context(EXPERIMENT_NAME)\n",
"c.delete()"
]
}
],
@@ -38,11 +38,20 @@
" View on GitHub\n",
" </a>\n",
" </td>\n",
" \n",
" <td>\n",
" <a href=\"https://console.cloud.google.com/ai/platform/notebooks/deploy-notebook?download_url=https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage2/get_started_vertex_feature_store.ipynb\">\n",
" Open in Google Cloud Notebooks\n",
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage2/get_started_vertex_feature_store.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",
" \n",
" <td>\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/community/ml_ops/stage2/get_started_vertex_feature_store.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",
" \n",
"</table>\n",
"<br/><br/><br/>"
]
@@ -67,9 +76,9 @@
"source": [
"### Dataset\n",
"\n",
"The dataset used for this tutorial is the Movie Recommendations. The version of the dataset you will use in this tutorial is stored in a public Cloud Storage bucket, in Avro format.\n",
"The dataset used for this tutorial is the `Movie Recommendations` dataset. The version of the dataset you will use in this tutorial is stored in a public Cloud Storage bucket, in Avro format.\n",
"\n",
"The dataset predicts whether a persons will watch a movie."
"This dataset is used to predict whether a person will watch a movie or not."
]
},
{
@@ -80,7 +89,7 @@
"source": [
"### Objective\n",
"\n",
"In this tutorial, you learn how to use `Vertex AI Feature Store` for when training and prediction with `Vertex AI`.\n",
"In this tutorial, you learn how to use `Vertex AI Feature Store` when training and predicting with `Vertex AI`.\n",
"\n",
"This tutorial uses the following Google Cloud ML services:\n",
"\n",
@@ -92,10 +101,28 @@
" - Creating `EntityType` resources for the `Featurestore` resource.\n",
" - Creating `Feature` resources for each `EntityType` resource.\n",
"- Import feature values (entity data items) into `Featurestore` resource.\n",
" - From a Cloud Storage location.\n",
" - From a pandas DataFrame.\n",
"- Perform online serving from a `Featurestore` resource.\n",
"- Perform batch serving from a `Featurestore` resource."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "81c777b8ad32"
},
"source": [
"### Costs\n",
"This tutorial uses billable components of Google Cloud:\n",
"\n",
"- Vertex AI\n",
"- Cloud Storage\n",
"- BigQuery\n",
"\n",
"Learn about [Vertex AI pricing](https://cloud.google.com/vertex-ai/pricing), [Cloud Storage pricing](https://cloud.google.com/storage/pricing) and [BigQuery pricing](https://cloud.google.com/bigquery/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": {
@@ -104,7 +131,7 @@
"source": [
"## Installations\n",
"\n",
"Install *one time* the packages for executing the MLOps notebooks."
"Install the following packages for further running this notebook."
]
},
{
@@ -115,24 +142,18 @@
},
"outputs": [],
"source": [
"ONCE_ONLY = False\n",
"if ONCE_ONLY:\n",
" ! pip3 install -U tensorflow==2.5 $USER_FLAG\n",
" ! pip3 install -U tensorflow-data-validation==1.2 $USER_FLAG\n",
" ! pip3 install -U tensorflow-transform==1.2 $USER_FLAG\n",
" ! pip3 install -U tensorflow-io==0.18 $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-aiplatform[tensorboard] $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-pipeline-components $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-bigquery $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-logging $USER_FLAG\n",
" ! pip3 install --upgrade apache-beam[gcp] $USER_FLAG\n",
" ! pip3 install --upgrade pyarrow $USER_FLAG\n",
" ! pip3 install --upgrade cloudml-hypertune $USER_FLAG\n",
" ! pip3 install --upgrade kfp $USER_FLAG\n",
" ! pip3 install --upgrade torchvision $USER_FLAG\n",
" ! pip3 install --upgrade rpy2 $USER_FLAG\n",
" ! pip3 install --upgrade python-tabulate $USER_FLAG\n",
" ! pip3 install -U opencv-python-headless==4.5.2.52 $USER_FLAG"
"import os\n",
"\n",
"# The Google Cloud Notebook product has specific requirements\n",
"IS_GOOGLE_CLOUD_NOTEBOOK = os.path.exists(\"/opt/deeplearning/metadata/env_version\")\n",
"\n",
"# Google Cloud Notebook requires dependencies to be installed with '--user'\n",
"USER_FLAG = \"\"\n",
"if IS_GOOGLE_CLOUD_NOTEBOOK:\n",
" USER_FLAG = \"--user\"\n",
"\n",
"# Install the dependecies\n",
"! pip3 install --upgrade google-cloud-aiplatform google-cloud-bigquery pyarrow avro $USER_FLAG -q"
]
},
{
@@ -240,7 +261,10 @@
},
"outputs": [],
"source": [
"REGION = \"us-central1\" # @param {type: \"string\"}"
"REGION = \"[your-region]\" # @param {type: \"string\"}\n",
"\n",
"if REGION == \"[your-region]\":\n",
" REGION = \"us-central1\""
]
},
{
@@ -267,15 +291,69 @@
"TIMESTAMP = datetime.now().strftime(\"%Y%m%d%H%M%S\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "29b110b44457"
},
"source": [
"### Authenticate your Google Cloud account\n",
"\n",
"**If you are using Google Cloud 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\" into the filter box, and select **Vertex 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": "89788a802687"
},
"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 Google Cloud Notebook, then don't execute this code\n",
"if not os.path.exists(\"/opt/deeplearning/metadata/env_version\"):\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 and define constants"
]
},
@@ -287,28 +365,7 @@
},
"outputs": [],
"source": [
"import google.cloud.aiplatform as aip"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "import_bq"
},
"source": [
"#### Import BigQuery\n",
"\n",
"Import the BigQuery package into your Python environment."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "import_bq"
},
"outputs": [],
"source": [
"import google.cloud.aiplatform as aiplatform\n",
"from google.cloud import bigquery"
]
},
@@ -318,9 +375,7 @@
"id": "init_bq"
},
"source": [
"### Create BigQuery client\n",
"\n",
"Create the BigQuery client."
"Initialize Vertex AI and BigQuery clients."
]
},
{
@@ -331,7 +386,8 @@
},
"outputs": [],
"source": [
"bqclient = bigquery.Client()"
"aiplatform.init(project=PROJECT_ID)\n",
"bqclient = bigquery.Client(project=PROJECT_ID)"
]
},
{
@@ -348,11 +404,11 @@
"\n",
"Now it's time to do a live prediction. You get a transaction from the cash register, but all it has is the credit card number and this transaction. It does not have the enriched data the model needs. During serving, the credit card number is used as an index to Feature Store to get the enriched data needed for the model.\n",
"\n",
"Next problem. Let's say the enriched data the model was trained on was timestamp June 1. This transaction is June 15. Assume that the user has made other transactions between June 1 and 15, and the enriched data has been continuously updated in Feature Store. But the model was trained on June 1st data. FeatureStore knows the version number and serves the June 1 version to the model (not the current June 15); otherwise, if you used June 15 data you have training-serving skew.\n",
"On the other hand, let's say the enriched data the model was trained on was timestamped on June 1st. The current transaction is from June 15th. Assume that the user has made other transactions between June 1st and 15th, and the enriched data has been continuously updated in Feature Store. But the model was trained on June 1st data. FeatureStore knows the version number and serves the June 1st version to the model (not the current June 15th). Otherwise, if you used June 15th data, you would have training-serving skew.\n",
"\n",
"Next problem, data drift. Things change, suddenly one day everybody is buying toilet paper! There is a significant change in the distribution of the current stored enriched data from the distribution that the deployed model was trained on. FeatureStore can detect changes/thresholds in distribution changes and trigger a notification for retraining the model.\n",
"Another problem here is the data drift. Things change and suddenly one day, everybody is buying toilet paper! There is a significant change in the distribution of existing enriched data from the distribution that the deployed model was trained on. FeatureStore can detect changes/thresholds in distribution changes and trigger a notification for retraining the model.\n",
"\n",
"Learn more about [Vertex AI Feature Store API](https://cloud.google.com/vertex-ai/docs/featurestore)"
"Learn more about [Vertex AI Feature Store API](https://cloud.google.com/vertex-ai/docs/featurestore)."
]
},
{
@@ -367,9 +423,9 @@
"\n",
" Featurestore -> EntityType -> Feature\n",
"\n",
"- `Featurestore`: the place to store your features\n",
"- `Featurestore`: the place to store your features.\n",
"- `EntityType`: under a `Featurestore`, an `EntityType` describes an object to be modeled, real one or virtual one.\n",
"- `Feature`: under an `EntityType`, a `Feature` describes an attribute of the `EntityType`\n",
"- `Feature`: under an `EntityType`, a `Feature` describes an attribute of the `EntityType`.\n",
"\n",
"Learn more about [Vertex AI Feature Store data model](https://cloud.google.com/vertex-ai/docs/featurestore/concepts).\n",
"\n",
@@ -405,7 +461,7 @@
"# Represents featurestore resource path.\n",
"FEATURESTORE_NAME = \"movies\"\n",
"\n",
"featurestore = aip.Featurestore.create(\n",
"featurestore = aiplatform.Featurestore.create(\n",
" featurestore_id=FEATURESTORE_NAME,\n",
" online_store_fixed_node_count=1,\n",
" project=PROJECT_ID,\n",
@@ -434,7 +490,7 @@
},
"outputs": [],
"source": [
"for featurestore in aip.Featurestore.list():\n",
"for featurestore in aiplatform.Featurestore.list():\n",
" print(featurestore)"
]
},
@@ -461,7 +517,7 @@
},
"outputs": [],
"source": [
"featurestore = featurestore = aip.Featurestore(\n",
"featurestore = featurestore = aiplatform.Featurestore(\n",
" featurestore_name=FEATURESTORE_NAME, project=PROJECT_ID, location=REGION\n",
")\n",
"print(featurestore)"
@@ -520,7 +576,7 @@
"outputs": [],
"source": [
"def create_features(featurestore_name, entity_name, features):\n",
" entity_type = aip.EntityType(\n",
" entity_type = aiplatform.EntityType(\n",
" entity_type_name=entity_name, featurestore_id=featurestore_name\n",
" )\n",
"\n",
@@ -571,7 +627,7 @@
},
"outputs": [],
"source": [
"for featurestore in aip.Featurestore.list():\n",
"for featurestore in aiplatform.Featurestore.list():\n",
" print(featurestore)"
]
},
@@ -583,7 +639,7 @@
"source": [
"### Search `Feature` resources using a filter\n",
"\n",
"You can narrow your search of `Feature` resources using the method `list_features()` and specifying a `filter` filter."
"You can narrow your search of `Feature` resources using the method `list_features()` and specifying a `filter` string."
]
},
{
@@ -635,17 +691,26 @@
},
"outputs": [],
"source": [
"features = aip.Feature.search(query=\"value_type=DOUBLE\")\n",
"features = aiplatform.Feature.search(query=\"value_type=DOUBLE\")\n",
"print(\"By data type\")\n",
"for feature in features:\n",
" print(features)\n",
"\n",
"aip.Feature.search(query=\"feature_id=title\")\n",
"aiplatform.Feature.search(query=\"feature_id=title\")\n",
"print(\"By Name\")\n",
"for feature in features:\n",
" print(features)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "277e9884cf37"
},
"source": [
"Define paths to the feature data."
]
},
{
"cell_type": "code",
"execution_count": null,
@@ -675,15 +740,15 @@
"\n",
"### Data layout\n",
"\n",
"Each imported `EntityType` resource data must have an ID; also, each `EntityType` resource data item can optionally have a timestamp, sepecifying when the feature values were generated.\n",
"Each imported `EntityType` resource data must have an ID. Also, each `EntityType` resource data item can optionally have a timestamp, sepecifying when the feature values were generated.\n",
"\n",
"When importing, specify the following in your request:\n",
"\n",
"- Data source format: BigQuery Table/Avro/CSV\n",
"- Data source format: BigQuery Table/Avro/CSV/Pandas Dataframe\n",
"- Data source URL\n",
"- Destination: featurestore/entity types/features to be imported\n",
"\n",
"The feature values for the movies dataset are in Avro format. The Avro schemas are as follows:\n",
"The feature values for `Movie Recommendations` dataset are in Avro format. The Avro schemas are as follows:\n",
"\n",
"**Users entity**:\n",
"\n",
@@ -747,7 +812,7 @@
"}\n",
"```\n",
"\n",
"### Importing the feature values\n",
"### Importing the feature values from Cloud Storage\n",
"\n",
"You import the feature values for the `EntityType` resources using the `ingest_from_gcs()` method, with the following parameters:\n",
"\n",
@@ -755,7 +820,7 @@
"- `feature_ids`: A list of identifier names for `Feature` resources' data to add to the `EntityType` resource.\n",
"- `feature_time`: The field corresponding to the timestamp for the features being entered.\n",
"- `gcs_source_type`: The format of the imported data. Must be CSV or Avro.\n",
"- `gcs_source_uris=`: A list of one or more Cloud Storage locations of the imported data files."
"- `gcs_source_uris`: A list of one or more Cloud Storage locations of the imported data files."
]
},
{
@@ -787,6 +852,225 @@
"print(response)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "featurestore_delete_entities:movies"
},
"source": [
"#### Delete the entity types and corresponding features and feature values\n",
"\n",
"Now, in preparation to repeat the process of importing feature values but from a dataframe this time, you delete the existing entity types, and the corresponding content."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "featurestore_delete_entities:movies"
},
"outputs": [],
"source": [
"entity_type = featurestore.get_entity_type(\"users\")\n",
"entity_type.delete(force=True)\n",
"entity_type = featurestore.get_entity_type(\"movies\")\n",
"entity_type.delete(force=True)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "featurestore_create:entity_type"
},
"source": [
"## Create entity types for your `Featurestore` resource\n",
"\n",
"Next, you create the `EntityType` resources again for your `Featurestore` resource using the `create_entity_type()` method, with the following parameters:\n",
"\n",
"- `entity_type_id`: The name of the `EntityType` resource.\n",
"- `description`: A description of the entity type."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "featurestore_create:entity_type"
},
"outputs": [],
"source": [
"for name, description in [(\"users\", \"Users descrip\"), (\"movies\", \"Movies descrip\")]:\n",
" entity_type = featurestore.create_entity_type(\n",
" entity_type_id=name, description=description\n",
" )\n",
" print(entity_type)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "featurestore_create:feature"
},
"source": [
"### Add `Feature` resources for your `EntityType` resources\n",
"\n",
"Further, you create the `Feature` resources again for each of the `EntityType` resources in your `Featurestore` resource using the `create_feature()` method, with the following parameters:\n",
"\n",
"- `feature_id`: The name of the `Feature` resource.\n",
"- `description`: A description of the feature.\n",
"- `value_type`: The data type for the feature."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "featurestore_create:feature,movies"
},
"outputs": [],
"source": [
"def create_features(featurestore_name, entity_name, features):\n",
" entity_type = aiplatform.EntityType(\n",
" entity_type_name=entity_name, featurestore_id=featurestore_name\n",
" )\n",
"\n",
" for feature in features:\n",
" feature = entity_type.create_feature(\n",
" feature_id=feature[0], description=feature[1], value_type=feature[2]\n",
" )\n",
" print(feature)\n",
"\n",
"\n",
"create_features(\n",
" FEATURESTORE_NAME,\n",
" \"users\",\n",
" [\n",
" (\"age\", \"Age descrip\", \"INT64\"),\n",
" (\"gender\", \"Gender descrip\", \"STRING\"),\n",
" (\"liked_genres\", \"Genres descrip\", \"STRING_ARRAY\"),\n",
" ],\n",
")\n",
"\n",
"create_features(\n",
" FEATURESTORE_NAME,\n",
" \"movies\",\n",
" [\n",
" (\"title\", \"Title descrip\", \"STRING\"),\n",
" (\"genres\", \"Genres descrip\", \"STRING\"),\n",
" (\"average_rating\", \"Ave descrip\", \"DOUBLE\"),\n",
" ],\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "8715a3f719c8"
},
"source": [
"Now, copy the `users` and `movies` data into avro files."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "import_file:movies,lbn,df"
},
"outputs": [],
"source": [
"GCS_USERS_AVRO_URI = FS_ENTITIES[\"users\"]\n",
"GCS_MOVIES_AVRO_URI = FS_ENTITIES[\"movies\"]\n",
"\n",
"USERS_AVRO_FN = \"users.avro\"\n",
"MOVIES_AVRO_FN = \"movies.avro\"\n",
"\n",
"! gsutil cp $GCS_USERS_AVRO_URI $USERS_AVRO_FN\n",
"! gsutil cp $GCS_MOVIES_AVRO_URI $MOVIES_AVRO_FN"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "load_df_from_avro"
},
"source": [
"#### Load Avro Files into pandas DataFrames"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "load_df_from_avro"
},
"outputs": [],
"source": [
"from avro.datafile import DataFileReader\n",
"from avro.io import DatumReader\n",
"\n",
"\n",
"class AvroReader:\n",
" def __init__(self, data_file):\n",
" self.avro_reader = DataFileReader(open(data_file, \"rb\"), DatumReader())\n",
"\n",
" def to_dataframe(self):\n",
" records = [record for record in self.avro_reader]\n",
" return pd.DataFrame.from_records(data=records)\n",
"\n",
"\n",
"import pandas as pd\n",
"\n",
"users_avro_reader = AvroReader(data_file=USERS_AVRO_FN)\n",
"users_source_df = users_avro_reader.to_dataframe()\n",
"print(users_source_df)\n",
"\n",
"movies_avro_reader = AvroReader(data_file=MOVIES_AVRO_FN)\n",
"movies_source_df = movies_avro_reader.to_dataframe()\n",
"print(movies_source_df)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "featurestore_import:movies,df"
},
"source": [
"### Importing the feature values from DataFrame\n",
"\n",
"You import the feature values for the `EntityType` resources using the `ingest_from_df()` method, with the following parameters:\n",
"\n",
"- `entity_id_field`: The identifier name for the parent `EntityType` resource.\n",
"- `feature_ids`: A list of identifier names for `Feature` resources' data to add to the `EntityType` resource.\n",
"- `feature_time`: The field corresponding to the timestamp for the features being entered.\n",
"- `df_source`: The DataFrame containing the imported feature values."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "featurestore_import:movies,df"
},
"outputs": [],
"source": [
"entity_type = featurestore.get_entity_type(\"users\")\n",
"entity_type.ingest_from_df(\n",
" feature_ids=[\"age\", \"gender\", \"liked_genres\"],\n",
" feature_time=\"update_time\",\n",
" df_source=users_source_df,\n",
" entity_id_field=\"user_id\",\n",
")\n",
"\n",
"entity_type = featurestore.get_entity_type(\"movies\")\n",
"entity_type.ingest_from_df(\n",
" feature_ids=[\"average_rating\", \"title\", \"genres\"],\n",
" feature_time=\"update_time\",\n",
" df_source=movies_source_df,\n",
" entity_id_field=\"movie_id\",\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
@@ -829,7 +1113,7 @@
"source": [
"## Batch Serving\n",
"\n",
"The Vertex AI Feature Store batch serving service is optimized for serving large batches of features in real-time with high-throughput, typically for training a model or batch prediction.\n",
"The Vertex AI Feature Store's batch serving service is optimized for serving large batches of features in real-time with high throughput, typically for training a model or batch prediction.\n",
"\n",
"One can batch serve to the following destinations:\n",
"\n",
@@ -881,7 +1165,7 @@
"\n",
"You batch serve entity data items to a BigQuery table using the `read_serve_to_bq()` method, with the following parameters:\n",
"\n",
"- `bq_destination_output_uri`: The destination BigQuery table to serve the features to.\n",
"- `bq_destination_output_uri`: The destination BigQuery table to receive the served features.\n",
"- `serving_feature_ids`: A dictionary of entity type and corresponding features to serve.\n",
"- `read_instances_uri`: A Cloud Storage location to read the entity data items from.\n",
"\n",
@@ -914,6 +1198,7 @@
"id": "delete_bq_dataset"
},
"source": [
"## Cleaning up\n",
"### Delete a BigQuery dataset\n",
"\n",
"Use the method `delete_dataset()` to delete a BigQuery dataset along with all its tables, by setting the parameter `delete_contents` to `True`."
@@ -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",
@@ -32,6 +32,11 @@
"# E2E ML on GCP: MLOps stage 2 : experimentation: get started with Vertex Tensorboard\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/stage2/get_started_vertex_tensorboard.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/stage2/get_started_vertex_tensorboard.ipynb\">\n",
" <img src=\"https://cloud.google.com/ml-engine/images/github-logo-32px.png\" alt=\"GitHub logo\">\n",
@@ -39,8 +44,9 @@
" </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/blob/main/notebooks/community/ml_ops/stage2/get_started_vertex_tensorboard.ipynb\">\n",
" Open in Google Cloud Notebooks\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/notebook_template.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",
@@ -81,6 +87,75 @@
"- Using Vertex AI TensorBoard with Vertex AI Training."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "b132d4ef86d6"
},
"source": [
"### Costs \n",
"\n",
"This tutorial uses billable components of Google Cloud:\n",
"\n",
"* Vertex AI\n",
"* Cloud Storage\n",
"\n",
"Learn about [Vertex AI\n",
"pricing](https://cloud.google.com/vertex-ai/pricing) and [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": "94a148f11da5"
},
"source": [
"### Set up your local development environment\n",
"\n",
"**If you are using Colab or Google Cloud Notebooks**, your environment already meets\n",
"all the requirements to run this notebook. You can skip this step."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "56cb7f08a9e8"
},
"source": [
"**Otherwise**, make sure your environment meets this notebook's requirements.\n",
"You need the following:\n",
"\n",
"* The Google Cloud SDK\n",
"* Git\n",
"* Python 3\n",
"* virtualenv\n",
"* Jupyter notebook running in a virtual environment with Python 3\n",
"\n",
"The Google Cloud guide to [Setting up a Python development\n",
"environment](https://cloud.google.com/python/setup) and the [Jupyter\n",
"installation guide](https://jupyter.org/install) provide detailed instructions\n",
"for meeting these requirements. The following steps provide a condensed set of\n",
"instructions:\n",
"\n",
"1. [Install and initialize the Cloud SDK.](https://cloud.google.com/sdk/docs/)\n",
"\n",
"1. [Install Python 3.](https://cloud.google.com/python/setup#installing_python)\n",
"\n",
"1. [Install\n",
" virtualenv](https://cloud.google.com/python/setup#installing_and_using_virtualenv)\n",
" and create a virtual environment that uses Python 3. Activate the virtual environment.\n",
"\n",
"1. To install Jupyter, run `pip3 install jupyter` on the\n",
"command-line in a terminal shell.\n",
"\n",
"1. To launch Jupyter, run `jupyter notebook` on the command-line in a terminal shell.\n",
"\n",
"1. Open this notebook in the Jupyter Notebook Dashboard.\n"
]
},
{
"cell_type": "markdown",
"metadata": {
@@ -89,7 +164,7 @@
"source": [
"### Recommendations\n",
"\n",
"When doing E2E MLOps on Google Cloud, the following best practices for visualizing your training with TensorBoard.\n",
"When doing E2E MLOps on Google Cloud, the following are the best practices for visualizing your training with TensorBoard.\n",
"\n",
"#### Local TensorBoard\n",
"\n",
@@ -115,6 +190,25 @@
"Install *one time* the packages for executing the MLOps notebooks."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "020040f91150"
},
"outputs": [],
"source": [
"import os\n",
"\n",
"# The Google Cloud Notebook product has specific requirements\n",
"IS_GOOGLE_CLOUD_NOTEBOOK = os.path.exists(\"/opt/deeplearning/metadata/env_version\")\n",
"\n",
"# Google Cloud Notebook requires dependencies to be installed with '--user'\n",
"USER_FLAG = \"\"\n",
"if IS_GOOGLE_CLOUD_NOTEBOOK:\n",
" USER_FLAG = \"--user\""
]
},
{
"cell_type": "code",
"execution_count": null,
@@ -123,20 +217,8 @@
},
"outputs": [],
"source": [
"ONCE_ONLY = False\n",
"if ONCE_ONLY:\n",
" ! pip3 install -U tensorflow==2.5 $USER_FLAG\n",
" ! pip3 install -U tensorflow-data-validation==1.2 $USER_FLAG\n",
" ! pip3 install -U tensorflow-transform==1.2 $USER_FLAG\n",
" ! pip3 install -U tensorflow-io==0.18 $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-aiplatform[tensorboard] $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-pipeline-components $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-bigquery $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-logging $USER_FLAG\n",
" ! pip3 install --upgrade apache-beam[gcp] $USER_FLAG\n",
" ! pip3 install --upgrade pyarrow $USER_FLAG\n",
" ! pip3 install --upgrade cloudml-hypertune $USER_FLAG\n",
" ! pip3 install --upgrade kfp $USER_FLAG"
"! pip3 install -U tensorflow==2.8 $USER_FLAG\n",
"! pip3 install --upgrade google-cloud-aiplatform[tensorboard] $USER_FLAG"
]
},
{
@@ -168,6 +250,39 @@
" app.kernel.do_shutdown(True)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "d6a00c14b087"
},
"source": [
"## Before you begin"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "2721ef0202d9"
},
"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 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",
"\n",
"1. If you are running this notebook locally, you will 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."
]
},
{
"cell_type": "markdown",
"metadata": {
@@ -271,6 +386,81 @@
"TIMESTAMP = datetime.now().strftime(\"%Y%m%d%H%M%S\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "2700e693f1b3"
},
"source": [
"### Authenticate your Google Cloud account\n",
"\n",
"**If you are using Google Cloud Notebooks**, your environment is already\n",
"authenticated. Skip this step."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "885395904904"
},
"source": [
"**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",
"1. In the Cloud Console, go to the [**Create service account key**\n",
" page](https://console.cloud.google.com/apis/credentials/serviceaccountkey).\n",
"\n",
"2. Click **Create service account**.\n",
"\n",
"3. In the **Service account name** field, enter a name, and\n",
" click **Create**.\n",
"\n",
"4. In the **Grant this service account access to project** section, click the **Role** drop-down list. Type \"Vertex AI\"\n",
"into the filter box, and select\n",
" **Vertex AI Administrator**. Type \"Storage Object Admin\" into the filter box, and select **Storage Object Admin**.\n",
"\n",
"5. Click *Create*. A JSON file that contains your key downloads to your\n",
"local environment.\n",
"\n",
"6. Enter the path to your service account key as the\n",
"`GOOGLE_APPLICATION_CREDENTIALS` variable in the cell below and run the cell."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "eff327d0552b"
},
"outputs": [],
"source": [
"import os\n",
"import sys\n",
"\n",
"# 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",
"# The Google Cloud Notebook product has specific requirements\n",
"IS_GOOGLE_CLOUD_NOTEBOOK = os.path.exists(\"/opt/deeplearning/metadata/env_version\")\n",
"\n",
"# If on Google Cloud Notebooks, then don't execute this code\n",
"if not IS_GOOGLE_CLOUD_NOTEBOOK:\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": {
@@ -294,7 +484,7 @@
},
"outputs": [],
"source": [
"BUCKET_NAME = \"gs://[your-bucket-name]\" # @param {type:\"string\"}"
"BUCKET_URI = \"gs://[your-bucket-name]\" # @param {type:\"string\"}"
]
},
{
@@ -305,8 +495,8 @@
},
"outputs": [],
"source": [
"if BUCKET_NAME == \"\" or BUCKET_NAME is None or BUCKET_NAME == \"gs://[your-bucket-name]\":\n",
" BUCKET_NAME = \"gs://\" + PROJECT_ID + \"aip-\" + TIMESTAMP"
"if BUCKET_URI == \"\" or BUCKET_URI is None or BUCKET_URI == \"gs://[your-bucket-name]\":\n",
" BUCKET_URI = \"gs://\" + PROJECT_ID + \"aip-\" + TIMESTAMP"
]
},
{
@@ -326,7 +516,7 @@
},
"outputs": [],
"source": [
"! gsutil mb -l $REGION $BUCKET_NAME"
"! gsutil mb -l $REGION $BUCKET_URI"
]
},
{
@@ -346,7 +536,7 @@
},
"outputs": [],
"source": [
"! gsutil ls -al $BUCKET_NAME"
"! gsutil ls -al $BUCKET_URI"
]
},
{
@@ -386,7 +576,7 @@
"):\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",
" SERVICE_ACCOUNT = shell_output[2].replace(\"*\", \"\").strip()\n",
" print(\"Service Account:\", SERVICE_ACCOUNT)"
]
},
@@ -410,7 +600,7 @@
},
"outputs": [],
"source": [
"import google.cloud.aiplatform as aip"
"import google.cloud.aiplatform as aiplatform"
]
},
{
@@ -454,7 +644,7 @@
},
"outputs": [],
"source": [
"aip.init(project=PROJECT_ID, staging_bucket=BUCKET_NAME)"
"aiplatform.init(project=PROJECT_ID, staging_bucket=BUCKET_URI)"
]
},
{
@@ -484,13 +674,15 @@
},
"outputs": [],
"source": [
"import os\n",
"\n",
"if os.getenv(\"IS_TESTING_TRAIN_GPU\"):\n",
" TRAIN_GPU, TRAIN_NGPU = (\n",
" aip.gapic.AcceleratorType.NVIDIA_TESLA_K80,\n",
" aiplatform.gapic.AcceleratorType.NVIDIA_TESLA_K80,\n",
" int(os.getenv(\"IS_TESTING_TRAIN_GPU\")),\n",
" )\n",
"else:\n",
" TRAIN_GPU, TRAIN_NGPU = (aip.gapic.AcceleratorType.NVIDIA_TESLA_K80, 1)"
" TRAIN_GPU, TRAIN_NGPU = (aiplatform.gapic.AcceleratorType.NVIDIA_TESLA_K80, 1)"
]
},
{
@@ -663,9 +855,9 @@
"\n",
"You can upload your TensorBoard logs and share with others using `tensorboard dev` command. Once uploaded, a URL is returned to open up the TensorBoard instance in a brower for visualizing.\n",
"\n",
"*Note:* Your TensorBoard instance is publicly visable.\n",
"*Note:* Your TensorBoard instance is publicly visible.\n",
"\n",
"*Note:* In this example, while running within a notebook, the command will freeze since it is waiting for an interactive yes/no input. You can kill the command with a Ctrl C or kernel interupt.\n",
"*Note:* This cell is for demonstration purposes and must be ran in a terminal shell. In this example, while running within a notebook, the command will freeze since it is waiting for an interactive yes/no input. You can kill the command with a Ctrl C or kernel interupt.\n",
"\n",
"Learn more about [What is TensorBoard.dev](https://tensorboard.dev/)."
]
@@ -678,7 +870,7 @@
},
"outputs": [],
"source": [
"! tensorboard dev upload --logdir {LOG_DIR} \\\n",
"! tensorboard dev upload --logdir logs \\\n",
" --name \"Simple experiment with MNIST\" \\\n",
" --description \"Training results\" \\\n",
" --one_shot"
@@ -706,7 +898,7 @@
"outputs": [],
"source": [
"TENSORBOARD_DISPLAY_NAME = \"example\"\n",
"tensorboard = aip.Tensorboard.create(display_name=TENSORBOARD_DISPLAY_NAME)\n",
"tensorboard = aiplatform.Tensorboard.create(display_name=TENSORBOARD_DISPLAY_NAME)\n",
"tensorboard_resource_name = tensorboard.gca_resource.name\n",
"print(\"TensorBoard resource name:\", tensorboard_resource_name)"
]
@@ -746,9 +938,9 @@
"\n",
"url = output[1].split(' ')[-1]\n",
"\n",
"print(url)\n",
"#print(url)\n",
"\n",
"from IPython.core.display import display, HTML\n",
"from IPython.display import display, HTML\n",
"display(HTML(\"<a href='\" + url + \"'>click here for TensorBoard instance</a>\"))"
]
},
@@ -953,7 +1145,7 @@
"! rm -f custom.tar custom.tar.gz\n",
"! tar cvf custom.tar custom\n",
"! gzip custom.tar\n",
"! gsutil cp custom.tar.gz $BUCKET_NAME/trainer_example.tar.gz"
"! gsutil cp custom.tar.gz $BUCKET_URI/trainer_example.tar.gz"
]
},
{
@@ -985,7 +1177,7 @@
},
"outputs": [],
"source": [
"job = aip.CustomTrainingJob(\n",
"job = aiplatform.CustomTrainingJob(\n",
" display_name=\"example_\" + TIMESTAMP,\n",
" script_path=\"custom/trainer/task.py\",\n",
" container_uri=TRAIN_IMAGE,\n",
@@ -1021,7 +1213,7 @@
},
"outputs": [],
"source": [
"MODEL_DIR = \"{}/{}\".format(BUCKET_NAME, TIMESTAMP)\n",
"MODEL_DIR = \"{}/{}\".format(BUCKET_URI, TIMESTAMP)\n",
"\n",
"EPOCHS = 20\n",
"STEPS = 100\n",
@@ -1143,14 +1335,8 @@
"\n",
"Otherwise, you can delete the individual resources you created in this tutorial:\n",
"\n",
"- Dataset\n",
"- Pipeline\n",
"- Model\n",
"- Endpoint\n",
"- AutoML Training Job\n",
"- Batch Job\n",
"- Custom Job\n",
"- Hyperparameter Tuning Job\n",
"- Cloud Storage Bucket"
]
},
@@ -1162,61 +1348,14 @@
},
"outputs": [],
"source": [
"delete_all = True\n",
"# Delete the custom training job\n",
"job.delete()\n",
"\n",
"if delete_all:\n",
" # Delete the dataset using the Vertex dataset object\n",
" try:\n",
" if \"dataset\" in globals():\n",
" dataset.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"# Set this to true only if you'd like to delete your bucket\n",
"delete_bucket = False\n",
"\n",
" # Delete the model using the Vertex model object\n",
" try:\n",
" if \"model\" in globals():\n",
" model.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the endpoint using the Vertex endpoint object\n",
" try:\n",
" if \"endpoint\" in globals():\n",
" endpoint.undeploy_all()\n",
" endpoint.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the AutoML or Pipeline training job\n",
" try:\n",
" if \"dag\" in globals():\n",
" dag.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the custom training job\n",
" try:\n",
" if \"job\" in globals():\n",
" job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the batch prediction job using the Vertex batch prediction object\n",
" try:\n",
" if \"batch_predict_job\" in globals():\n",
" batch_predict_job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the hyperparameter tuning job using the Vertex hyperparameter tuning object\n",
" try:\n",
" if \"hpt_job\" in globals():\n",
" hpt_job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" if \"BUCKET_NAME\" in globals():\n",
" ! gsutil rm -r $BUCKET_NAME"
"if delete_bucket or os.getenv(\"IS_TESTING\"):\n",
" ! gsutil rm -r $BUCKET_URI"
]
}
],
@@ -39,8 +39,9 @@
" </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/blob/main/notebooks/community/ml_ops/stage2/get_started_vertex_training_pytorch.ipynb\">\n",
" Open in Google Cloud Notebooks\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/notebook_template.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",
@@ -82,8 +83,9 @@
"\n",
"This tutorial uses the following Google Cloud ML services:\n",
"\n",
"- `Vertex AI Training`\n",
"- `Vertex AI Model` resource\n",
"* `Vertex AI Training`\n",
"* `Vertex AI Model` resource\n",
"\n",
"\n",
"The steps performed include:\n",
"\n",
@@ -93,6 +95,75 @@
"- Create a `Vertex AI Model` resource."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "85ee859437ed"
},
"source": [
"## Costs \n",
"\n",
"This tutorial uses billable components of Google Cloud:\n",
"\n",
"* Vertex AI\n",
"* Cloud Storage\n",
"\n",
"Learn about [Vertex AI\n",
"pricing](https://cloud.google.com/vertex-ai/pricing) and [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": "5cd61a5dd9db"
},
"source": [
"### Set up your local development environment\n",
"\n",
"**If you are using Colab or Google Cloud Notebooks**, your environment already meets\n",
"all the requirements to run this notebook. You can skip this step."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "7e689ee0bc3c"
},
"source": [
"**Otherwise**, make sure your environment meets this notebook's requirements.\n",
"You need the following:\n",
"\n",
"* The Google Cloud SDK\n",
"* Git\n",
"* Python 3\n",
"* virtualenv\n",
"* Jupyter notebook running in a virtual environment with Python 3\n",
"\n",
"The Google Cloud guide to [Setting up a Python development\n",
"environment](https://cloud.google.com/python/setup) and the [Jupyter\n",
"installation guide](https://jupyter.org/install) provide detailed instructions\n",
"for meeting these requirements. The following steps provide a condensed set of\n",
"instructions:\n",
"\n",
"1. [Install and initialize the Cloud SDK.](https://cloud.google.com/sdk/docs/)\n",
"\n",
"1. [Install Python 3.](https://cloud.google.com/python/setup#installing_python)\n",
"\n",
"1. [Install\n",
" virtualenv](https://cloud.google.com/python/setup#installing_and_using_virtualenv)\n",
" and create a virtual environment that uses Python 3. Activate the virtual environment.\n",
"\n",
"1. To install Jupyter, run `pip3 install jupyter` on the\n",
"command-line in a terminal shell.\n",
"\n",
"1. To launch Jupyter, run `jupyter notebook` on the command-line in a terminal shell.\n",
"\n",
"1. Open this notebook in the Jupyter Notebook Dashboard."
]
},
{
"cell_type": "markdown",
"metadata": {
@@ -112,22 +183,10 @@
},
"outputs": [],
"source": [
"ONCE_ONLY = False\n",
"if ONCE_ONLY:\n",
" ! pip3 install -U tensorflow==2.5 $USER_FLAG\n",
" ! pip3 install -U tensorflow-data-validation==1.2 $USER_FLAG\n",
" ! pip3 install -U tensorflow-transform==1.2 $USER_FLAG\n",
" ! pip3 install -U tensorflow-io==0.18 $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-aiplatform[tensorboard] $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-pipeline-components $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-bigquery $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-logging $USER_FLAG\n",
" ! pip3 install --upgrade apache-beam[gcp] $USER_FLAG\n",
" ! pip3 install --upgrade pyarrow $USER_FLAG\n",
" ! pip3 install --upgrade cloudml-hypertune $USER_FLAG\n",
" ! pip3 install --upgrade kfp $USER_FLAG\n",
" ! pip3 install --upgrade torchvision $USER_FLAG\n",
" ! pip3 install --upgrade rpy2 $USER_FLAG"
"! pip3 install --upgrade google-cloud-aiplatform[tensorboard] $USER_FLAG\n",
"! pip3 install --upgrade google-cloud-pipeline-components $USER_FLAG\n",
"! pip3 install --upgrade cloudml-hypertune $USER_FLAG\n",
"! pip3 install --upgrade torchvision $USER_FLAG"
]
},
{
@@ -285,7 +344,7 @@
},
"outputs": [],
"source": [
"BUCKET_NAME = \"gs://[your-bucket-name]\" # @param {type:\"string\"}"
"BUCKET_URI = \"gs://[your-bucket-name]\" # @param {type:\"string\"}"
]
},
{
@@ -296,8 +355,8 @@
},
"outputs": [],
"source": [
"if BUCKET_NAME == \"\" or BUCKET_NAME is None or BUCKET_NAME == \"gs://[your-bucket-name]\":\n",
" BUCKET_NAME = \"gs://\" + PROJECT_ID + \"aip-\" + TIMESTAMP"
"if BUCKET_URI == \"\" or BUCKET_URI is None or BUCKET_URI == \"gs://[your-bucket-name]\":\n",
" BUCKET_URI = \"gs://\" + PROJECT_ID + \"aip-\" + TIMESTAMP"
]
},
{
@@ -317,7 +376,7 @@
},
"outputs": [],
"source": [
"! gsutil mb -l $REGION $BUCKET_NAME"
"! gsutil mb -l $REGION $BUCKET_URI"
]
},
{
@@ -337,7 +396,7 @@
},
"outputs": [],
"source": [
"! gsutil ls -al $BUCKET_NAME"
"! gsutil ls -al $BUCKET_URI"
]
},
{
@@ -360,7 +419,7 @@
},
"outputs": [],
"source": [
"import google.cloud.aiplatform as aip"
"import google.cloud.aiplatform as aiplatform"
]
},
{
@@ -382,7 +441,7 @@
},
"outputs": [],
"source": [
"aip.init(project=PROJECT_ID, staging_bucket=BUCKET_NAME)"
"aiplatform.init(project=PROJECT_ID, staging_bucket=BUCKET_URI)"
]
},
{
@@ -412,13 +471,15 @@
},
"outputs": [],
"source": [
"import os\n",
"\n",
"if os.getenv(\"IS_TESTING_TRAIN_GPU\"):\n",
" TRAIN_GPU, TRAIN_NGPU = (\n",
" aip.gapic.AcceleratorType.NVIDIA_TESLA_K80,\n",
" aiplatform.gapic.AcceleratorType.NVIDIA_TESLA_K80,\n",
" int(os.getenv(\"IS_TESTING_TRAIN_GPU\")),\n",
" )\n",
"else:\n",
" TRAIN_GPU, TRAIN_NGPU = (aip.gapic.AcceleratorType.NVIDIA_TESLA_K80, 1)"
" TRAIN_GPU, TRAIN_NGPU = (aiplatform.gapic.AcceleratorType.NVIDIA_TESLA_K80, 1)"
]
},
{
@@ -561,6 +622,7 @@
"# Add package information\n",
"! touch custom/README.md\n",
"\n",
"# Instructions for installing package into environment of the docker image\n",
"setup_cfg = \"[egg_info]\\n\\ntag_build =\\n\\ntag_date = 0\"\n",
"! echo \"$setup_cfg\" > custom/setup.cfg\n",
"\n",
@@ -891,7 +953,7 @@
"! rm -f custom.tar custom.tar.gz\n",
"! tar cvf custom.tar custom\n",
"! gzip custom.tar\n",
"! gsutil cp custom.tar.gz $BUCKET_NAME/trainer_cifar10.tar.gz"
"! gsutil cp custom.tar.gz $BUCKET_URI/trainer_cifar10.tar.gz"
]
},
{
@@ -902,7 +964,7 @@
"source": [
"### Make Pytorch container for prediction\n",
"\n",
"Currently, Vertex AI does not have a prefined container for making predictions with a deployed Pytorch model. No problem, you can assemble your own custom container. Typically, one would base the container on the `Torch Server`. For demonstration purpose, you build a placeholder container (not complete) that includes the latest `Torch Server` image, and push it to the `Container Registry`."
"Currently, Vertex AI does not have a predefined container for making predictions with a deployed Pytorch model. No problem, you can assemble your own custom container. Typically, one would base the container on the `Torch Server`. For demonstration purpose, you build a placeholder container (not complete) that includes the latest `Torch Server` image, and push it to the `Container Registry`."
]
},
{
@@ -974,9 +1036,9 @@
"source": [
"DISPLAY_NAME = \"cifar10_\" + TIMESTAMP\n",
"\n",
"job = aip.CustomPythonPackageTrainingJob(\n",
"job = aiplatform.CustomPythonPackageTrainingJob(\n",
" display_name=DISPLAY_NAME,\n",
" python_package_gcs_uri=f\"{BUCKET_NAME}/trainer_cifar10.tar.gz\",\n",
" python_package_gcs_uri=f\"{BUCKET_URI}/trainer_cifar10.tar.gz\",\n",
" python_module_name=\"trainer.task\",\n",
" container_uri=TRAIN_IMAGE,\n",
" model_serving_container_image_uri=DEPLOY_IMAGE,\n",
@@ -1009,7 +1071,7 @@
},
"outputs": [],
"source": [
"MODEL_DIR = \"{}/{}\".format(BUCKET_NAME, TIMESTAMP)\n",
"MODEL_DIR = \"{}/{}\".format(BUCKET_URI, TIMESTAMP)\n",
"\n",
"DIRECT = False\n",
"if DIRECT:\n",
@@ -1121,7 +1183,7 @@
"source": [
"### Delete a custom training job\n",
"\n",
"After a training job is completed, you can delete the training job with the method `delete()`. Prior to completion, a training job can be canceled with the method `cancel()`."
"After a training job is completed, you can delete the training job with the method `delete()`. Prior to completion, a training job can be cancelled with the method `cancel()`."
]
},
{
@@ -1148,14 +1210,8 @@
"\n",
"Otherwise, you can delete the individual resources you created in this tutorial:\n",
"\n",
"- Dataset\n",
"- Pipeline\n",
"- Model\n",
"- Endpoint\n",
"- AutoML Training Job\n",
"- Batch Job\n",
"- Custom Job\n",
"- Hyperparameter Tuning Job\n",
"- Custom Job (Custom job deleted in previous cell)\n",
"- Cloud Storage Bucket"
]
},
@@ -1167,61 +1223,12 @@
},
"outputs": [],
"source": [
"delete_all = True\n",
"# Delete the model using the Vertex model object\n",
"model.delete()\n",
"\n",
"if delete_all:\n",
" # Delete the dataset using the Vertex dataset object\n",
" try:\n",
" if \"dataset\" in globals():\n",
" dataset.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the model using the Vertex model object\n",
" try:\n",
" if \"model\" in globals():\n",
" model.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the endpoint using the Vertex endpoint object\n",
" try:\n",
" if \"endpoint\" in globals():\n",
" endpoint.undeploy_all()\n",
" endpoint.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the AutoML or Pipeline training job\n",
" try:\n",
" if \"dag\" in globals():\n",
" dag.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the custom training job\n",
" try:\n",
" if \"job\" in globals():\n",
" job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the batch prediction job using the Vertex batch prediction object\n",
" try:\n",
" if \"batch_predict_job\" in globals():\n",
" batch_predict_job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the hyperparameter tuning job using the Vertex hyperparameter tuning object\n",
" try:\n",
" if \"hpt_job\" in globals():\n",
" hpt_job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" if \"BUCKET_NAME\" in globals():\n",
" ! gsutil rm -r $BUCKET_NAME"
"if os.getenv(\"IS_TESTING\"):\n",
" ! gsutil rm -r $BUCKET_URI"
]
}
],
@@ -29,7 +29,7 @@
"id": "title:generic,gcp"
},
"source": [
"# E2E ML on GCP: MLOps stage 2 : experimentation: get started with Vertex Training for R\n",
"# E2E ML on GCP: MLOps stage 2 : experimentation: get started with Vertex AI Training for R\n",
"\n",
"<table align=\"left\">\n",
" <td>\n",
@@ -39,8 +39,9 @@
" </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/blob/main/notebooks/community/ml_ops/stage2/get_started_vertex_training_r.ipynb\">\n",
" Open in Google Cloud Notebooks\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/community/ml_ops/stage2/get_started_vertex_training_r.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",
@@ -56,7 +57,7 @@
"## 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 Vertex Training for R."
"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 Vertex AI Training for R. Please note that this notebook should be ran only in R notebook image (e.g., R4.1)."
]
},
{
@@ -98,6 +99,28 @@
"- Train a R model using `Vertex AI Trainingh` service with the R-to-Python training package."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "0c997d8d92ce"
},
"source": [
"### Costs \n",
"\n",
"\n",
"This tutorial uses billable components of Google Cloud:\n",
"\n",
"* Vertex AI\n",
"* Cloud Storage\n",
"\n",
"\n",
"Learn about [Vertex AI\n",
"pricing](https://cloud.google.com/vertex-ai/pricing) and [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": {
@@ -109,6 +132,25 @@
"Install *one time* the packages for executing the MLOps notebooks."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "1fd00fa70a2a"
},
"outputs": [],
"source": [
"import os\n",
"\n",
"# The Google Cloud Notebook product has specific requirements\n",
"IS_GOOGLE_CLOUD_NOTEBOOK = os.path.exists(\"/opt/deeplearning/metadata/env_version\")\n",
"\n",
"# Google Cloud Notebook requires dependencies to be installed with '--user'\n",
"USER_FLAG = \"\"\n",
"if IS_GOOGLE_CLOUD_NOTEBOOK:\n",
" USER_FLAG = \"--user\""
]
},
{
"cell_type": "code",
"execution_count": null,
@@ -117,22 +159,8 @@
},
"outputs": [],
"source": [
"ONCE_ONLY = False\n",
"if ONCE_ONLY:\n",
" ! pip3 install -U tensorflow==2.5 $USER_FLAG\n",
" ! pip3 install -U tensorflow-data-validation==1.2 $USER_FLAG\n",
" ! pip3 install -U tensorflow-transform==1.2 $USER_FLAG\n",
" ! pip3 install -U tensorflow-io==0.18 $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-aiplatform[tensorboard] $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-pipeline-components $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-bigquery $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-logging $USER_FLAG\n",
" ! pip3 install --upgrade apache-beam[gcp] $USER_FLAG\n",
" ! pip3 install --upgrade pyarrow $USER_FLAG\n",
" ! pip3 install --upgrade cloudml-hypertune $USER_FLAG\n",
" ! pip3 install --upgrade kfp $USER_FLAG\n",
" ! pip3 install --upgrade torchvision $USER_FLAG\n",
" ! pip3 install --upgrade rpy2 $USER_FLAG"
"! pip3 install --upgrade google-cloud-aiplatform[tensorboard] $USER_FLAG\n",
"! pip3 install --upgrade rpy2 $USER_FLAG"
]
},
{
@@ -164,6 +192,39 @@
" app.kernel.do_shutdown(True)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "0e3cab0cc491"
},
"source": [
"## Before you begin"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "be929e7b4d76"
},
"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 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",
"\n",
"1. If you are running this notebook locally, you will 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."
]
},
{
"cell_type": "markdown",
"metadata": {
@@ -183,6 +244,8 @@
},
"outputs": [],
"source": [
"import os\n",
"\n",
"PROJECT_ID = \"[your-project-id]\" # @param {type:\"string\"}"
]
},
@@ -240,7 +303,9 @@
},
"outputs": [],
"source": [
"REGION = \"us-central1\" # @param {type: \"string\"}"
"REGION = \"[your-region]\" # @param {type:\"string\"}\n",
"if REGION == \"[your-region]\":\n",
" REGION = \"us-central1\""
]
},
{
@@ -277,7 +342,7 @@
"\n",
"**The following steps are required, regardless of your notebook environment.**\n",
"\n",
"When you initialize the Vertex 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.\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.\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."
]
@@ -290,7 +355,7 @@
},
"outputs": [],
"source": [
"BUCKET_NAME = \"gs://[your-bucket-name]\" # @param {type:\"string\"}"
"BUCKET_URI = \"gs://[your-bucket-name]\" # @param {type:\"string\"}"
]
},
{
@@ -301,8 +366,8 @@
},
"outputs": [],
"source": [
"if BUCKET_NAME == \"\" or BUCKET_NAME is None or BUCKET_NAME == \"gs://[your-bucket-name]\":\n",
" BUCKET_NAME = \"gs://\" + PROJECT_ID + \"aip-\" + TIMESTAMP"
"if BUCKET_URI == \"\" or BUCKET_URI is None or BUCKET_URI == \"gs://[your-bucket-name]\":\n",
" BUCKET_URI = \"gs://\" + PROJECT_ID + \"aip-\" + TIMESTAMP"
]
},
{
@@ -322,7 +387,7 @@
},
"outputs": [],
"source": [
"! gsutil mb -l $REGION $BUCKET_NAME"
"! gsutil mb -l $REGION $BUCKET_URI"
]
},
{
@@ -342,7 +407,7 @@
},
"outputs": [],
"source": [
"! gsutil ls -al $BUCKET_NAME"
"! gsutil ls -al $BUCKET_URI"
]
},
{
@@ -365,6 +430,8 @@
},
"outputs": [],
"source": [
"import traceback\n",
"\n",
"import google.cloud.aiplatform as aip"
]
},
@@ -387,7 +454,7 @@
},
"outputs": [],
"source": [
"aip.init(project=PROJECT_ID, staging_bucket=BUCKET_NAME)"
"aip.init(project=PROJECT_ID, staging_bucket=BUCKET_URI)"
]
},
{
@@ -964,14 +1031,17 @@
},
"outputs": [],
"source": [
"INSTANCES = [\n",
" {\"sepal_width\": 1, \"sepal_length\": 2, \"petal_width\": 3, \"petal_length\": 1},\n",
" {\"sepal_width\": 4, \"sepal_length\": 2, \"petal_width\": 1, \"petal_length\": 1},\n",
"]\n",
"try:\n",
" INSTANCES = [\n",
" {\"sepal_width\": 1, \"sepal_length\": 2, \"petal_width\": 3, \"petal_length\": 1},\n",
" {\"sepal_width\": 4, \"sepal_length\": 2, \"petal_width\": 1, \"petal_length\": 1},\n",
" ]\n",
"\n",
"prediction = endpoint.predict(instances=INSTANCES)\n",
" prediction = endpoint.predict(instances=INSTANCES)\n",
"\n",
"print(prediction)"
" print(prediction)\n",
"except:\n",
" traceback.print_exc()"
]
},
{
@@ -1242,7 +1312,7 @@
},
"outputs": [],
"source": [
"CMDARGS = [\"--model-dir=\" + BUCKET_NAME]\n",
"CMDARGS = [\"--model-dir=\" + BUCKET_URI]\n",
"\n",
"job.run(args=CMDARGS, replica_count=1, machine_type=TRAIN_COMPUTE, sync=True)"
]
@@ -1282,14 +1352,9 @@
"\n",
"Otherwise, you can delete the individual resources you created in this tutorial:\n",
"\n",
"- Dataset\n",
"- Pipeline\n",
"- Model\n",
"- Endpoint\n",
"- AutoML Training Job\n",
"- Batch Job\n",
"- Custom Job\n",
"- Hyperparameter Tuning Job\n",
"- Model (Already deleted in previous cells)\n",
"- Endpoint (Already deleted in previous cells)\n",
"- Custom Job (Already deleted in previous cells)\n",
"- Cloud Storage Bucket"
]
},
@@ -1301,61 +1366,8 @@
},
"outputs": [],
"source": [
"delete_all = True\n",
"\n",
"if delete_all:\n",
" # Delete the dataset using the Vertex dataset object\n",
" try:\n",
" if \"dataset\" in globals():\n",
" dataset.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the model using the Vertex model object\n",
" try:\n",
" if \"model\" in globals():\n",
" model.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the endpoint using the Vertex endpoint object\n",
" try:\n",
" if \"endpoint\" in globals():\n",
" endpoint.undeploy_all()\n",
" endpoint.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the AutoML or Pipeline training job\n",
" try:\n",
" if \"dag\" in globals():\n",
" dag.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the custom training job\n",
" try:\n",
" if \"job\" in globals():\n",
" job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the batch prediction job using the Vertex batch prediction object\n",
" try:\n",
" if \"batch_predict_job\" in globals():\n",
" batch_predict_job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the hyperparameter tuning job using the Vertex hyperparameter tuning object\n",
" try:\n",
" if \"hpt_job\" in globals():\n",
" hpt_job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" if \"BUCKET_NAME\" in globals():\n",
" ! gsutil rm -r $BUCKET_NAME"
"if os.getenv(\"IS_TESTING\"):\n",
" ! gsutil rm -r $BUCKET_URI"
]
}
],
@@ -40,7 +40,11 @@
" </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/blob/main/notebooks/community/ml_ops/stage2/get_started_vertex_training_sklearn.ipynb\">\n",
" Open in Google Cloud Notebooks\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",
" </a>\n",
" </td>\n",
"</table>\n",
@@ -101,62 +105,7 @@
"source": [
"## Installations\n",
"\n",
"Install *one time* the packages for executing the MLOps notebooks."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "install_mlops"
},
"outputs": [],
"source": [
"ONCE_ONLY = False\n",
"if ONCE_ONLY:\n",
" ! pip3 install -U tensorflow==2.5 $USER_FLAG\n",
" ! pip3 install -U tensorflow-data-validation==1.2 $USER_FLAG\n",
" ! pip3 install -U tensorflow-transform==1.2 $USER_FLAG\n",
" ! pip3 install -U tensorflow-io==0.18 $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-aiplatform[tensorboard] $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-pipeline-components $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-bigquery $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-logging $USER_FLAG\n",
" ! pip3 install --upgrade apache-beam[gcp] $USER_FLAG\n",
" ! pip3 install --upgrade pyarrow $USER_FLAG\n",
" ! pip3 install --upgrade cloudml-hypertune $USER_FLAG\n",
" ! pip3 install --upgrade kfp $USER_FLAG\n",
" ! pip3 install --upgrade torchvision $USER_FLAG\n",
" ! pip3 install --upgrade rpy2 $USER_FLAG"
]
},
{
"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)"
"You will not need special packages for this notebook."
]
},
{
@@ -285,7 +234,7 @@
},
"outputs": [],
"source": [
"BUCKET_NAME = \"gs://[your-bucket-name]\" # @param {type:\"string\"}"
"BUCKET_URI = \"gs://[your-bucket-name]\" # @param {type:\"string\"}"
]
},
{
@@ -296,8 +245,8 @@
},
"outputs": [],
"source": [
"if BUCKET_NAME == \"\" or BUCKET_NAME is None or BUCKET_NAME == \"gs://[your-bucket-name]\":\n",
" BUCKET_NAME = \"gs://\" + PROJECT_ID + \"aip-\" + TIMESTAMP"
"if BUCKET_URI == \"\" or BUCKET_URI is None or BUCKET_URI == \"gs://[your-bucket-name]\":\n",
" BUCKET_URI = \"gs://\" + PROJECT_ID + \"aip-\" + TIMESTAMP"
]
},
{
@@ -317,7 +266,7 @@
},
"outputs": [],
"source": [
"! gsutil mb -l $REGION $BUCKET_NAME"
"! gsutil mb -l $REGION $BUCKET_URI"
]
},
{
@@ -337,7 +286,7 @@
},
"outputs": [],
"source": [
"! gsutil ls -al $BUCKET_NAME"
"! gsutil ls -al $BUCKET_URI"
]
},
{
@@ -382,7 +331,7 @@
},
"outputs": [],
"source": [
"aip.init(project=PROJECT_ID, staging_bucket=BUCKET_NAME)"
"aip.init(project=PROJECT_ID, staging_bucket=BUCKET_URI)"
]
},
{
@@ -415,6 +364,8 @@
},
"outputs": [],
"source": [
"import os\n",
"\n",
"if os.getenv(\"IS_TESTING_TRAIN_GPU\"):\n",
" TRAIN_GPU, TRAIN_NGPU = (\n",
" aip.gapic.AcceleratorType.NVIDIA_TESLA_K80,\n",
@@ -783,7 +734,7 @@
"! rm -f custom.tar custom.tar.gz\n",
"! tar cvf custom.tar custom\n",
"! gzip custom.tar\n",
"! gsutil cp custom.tar.gz $BUCKET_NAME/trainer_newsaggr.tar.gz"
"! gsutil cp custom.tar.gz $BUCKET_URI/trainer_newsaggr.tar.gz"
]
},
{
@@ -823,7 +774,7 @@
"\n",
"job = aip.CustomPythonPackageTrainingJob(\n",
" display_name=DISPLAY_NAME,\n",
" python_package_gcs_uri=f\"{BUCKET_NAME}/trainer_newsaggr.tar.gz\",\n",
" python_package_gcs_uri=f\"{BUCKET_URI}/trainer_newsaggr.tar.gz\",\n",
" python_module_name=\"trainer.task\",\n",
" container_uri=TRAIN_IMAGE,\n",
" model_serving_container_image_uri=DEPLOY_IMAGE,\n",
@@ -857,7 +808,7 @@
},
"outputs": [],
"source": [
"MODEL_DIR = \"{}/{}\".format(BUCKET_NAME, TIMESTAMP)\n",
"MODEL_DIR = \"{}/{}\".format(BUCKET_URI, TIMESTAMP)\n",
"DATASET_URL = \"https://archive.ics.uci.edu/ml/machine-learning-databases/00359/NewsAggregatorDataset.zip\"\n",
"\n",
"DIRECT = False\n",
@@ -1002,14 +953,9 @@
"\n",
"Otherwise, you can delete the individual resources you created in this tutorial:\n",
"\n",
"- Dataset\n",
"- Pipeline\n",
"\n",
"- Model\n",
"- Endpoint\n",
"- AutoML Training Job\n",
"- Batch Job\n",
"- Custom Job\n",
"- Hyperparameter Tuning Job\n",
"- Custom Job (already deleted in previous cell)\n",
"- Cloud Storage Bucket"
]
},
@@ -1017,65 +963,15 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "cleanup:mbsdk"
"id": "b413063dfdcf"
},
"outputs": [],
"source": [
"delete_all = True\n",
"# Delete the model using the Vertex model object\n",
"model.delete()\n",
"\n",
"if delete_all:\n",
" # Delete the dataset using the Vertex dataset object\n",
" try:\n",
" if \"dataset\" in globals():\n",
" dataset.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the model using the Vertex model object\n",
" try:\n",
" if \"model\" in globals():\n",
" model.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the endpoint using the Vertex endpoint object\n",
" try:\n",
" if \"endpoint\" in globals():\n",
" endpoint.undeploy_all()\n",
" endpoint.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the AutoML or Pipeline training job\n",
" try:\n",
" if \"dag\" in globals():\n",
" dag.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the custom training job\n",
" try:\n",
" if \"job\" in globals():\n",
" job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the batch prediction job using the Vertex batch prediction object\n",
" try:\n",
" if \"batch_predict_job\" in globals():\n",
" batch_predict_job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the hyperparameter tuning job using the Vertex hyperparameter tuning object\n",
" try:\n",
" if \"hpt_job\" in globals():\n",
" hpt_job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" if \"BUCKET_NAME\" in globals():\n",
" ! gsutil rm -r $BUCKET_NAME"
"if os.getenv(\"IS_TESTING\"):\n",
" ! gsutil rm -r $BUCKET_URI"
]
}
],
@@ -29,9 +29,15 @@
"id": "title:generic,gcp"
},
"source": [
"# E2E ML on GCP: MLOps stage 2 : experimentation: get started with Vertex Training for XGBoost\n",
"# E2E ML on GCP: MLOps stage 2 : experimentation: get started with Vertex AI Training for XGBoost\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/stage2/get_started_vertex_training_xgboost.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",
" \n",
" <td>\n",
" <a href=\"https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage2/get_started_vertex_training_xgboost.ipynb\">\n",
" <img src=\"https://cloud.google.com/ml-engine/images/github-logo-32px.png\" alt=\"GitHub logo\">\n",
@@ -39,8 +45,9 @@
" </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/blob/main/notebooks/community/ml_ops/stage2/get_started_vertex_training_xgboost.ipynb\">\n",
" Open in Google Cloud Notebooks\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/community/ml_ops/stage2/get_started_vertex_training_xgboost.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",
@@ -56,7 +63,7 @@
"## 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 Vertex Training for XGBoost."
"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 Vertex AI Training for XGBoost."
]
},
{
@@ -90,7 +97,21 @@
"- Training using a Python package.\n",
"- Report accuracy when hyperparameter tuning.\n",
"- Save the model artifacts to Cloud Storage using GCSFuse.\n",
"- Create a `Vertex AI Model` resource."
"- Create a `Vertex AI Model` resource.\n",
"\n",
"### Costs \n",
"\n",
"This tutorial uses billable components of Google Cloud:\n",
"\n",
"* Vertex AI\n",
"* Cloud Storage\n",
"\n",
"\n",
"Learn about [Vertex AI\n",
"pricing](https://cloud.google.com/vertex-ai/pricing) and [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."
]
},
{
@@ -108,55 +129,24 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "install_mlops"
"id": "ncRJ_Dfdox9L"
},
"outputs": [],
"source": [
"ONCE_ONLY = False\n",
"if ONCE_ONLY:\n",
" ! pip3 install -U tensorflow==2.5 $USER_FLAG\n",
" ! pip3 install -U tensorflow-data-validation==1.2 $USER_FLAG\n",
" ! pip3 install -U tensorflow-transform==1.2 $USER_FLAG\n",
" ! pip3 install -U tensorflow-io==0.18 $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-aiplatform[tensorboard] $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-pipeline-components $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-bigquery $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-logging $USER_FLAG\n",
" ! pip3 install --upgrade apache-beam[gcp] $USER_FLAG\n",
" ! pip3 install --upgrade pyarrow $USER_FLAG\n",
" ! pip3 install --upgrade cloudml-hypertune $USER_FLAG\n",
" ! pip3 install --upgrade kfp $USER_FLAG\n",
" ! pip3 install --upgrade torchvision $USER_FLAG\n",
" ! pip3 install --upgrade rpy2 $USER_FLAG"
]
},
{
"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)"
"# ! pip3 install -U tensorflow==2.5 $USER_FLAG\n",
"# ! pip3 install -U tensorflow-data-validation==1.2 $USER_FLAG\n",
"# ! pip3 install -U tensorflow-transform==1.2 $USER_FLAG\n",
"# ! pip3 install -U tensorflow-io==0.18 $USER_FLAG\n",
"! pip3 install --upgrade google-cloud-aiplatform[tensorboard] $USER_FLAG\n",
"# ! pip3 install --upgrade google-cloud-pipeline-components $USER_FLAG\n",
"# ! pip3 install --upgrade google-cloud-bigquery $USER_FLAG\n",
"# ! pip3 install --upgrade google-cloud-logging $USER_FLAG\n",
"# ! pip3 install --upgrade apache-beam[gcp] $USER_FLAG\n",
"# ! pip3 install --upgrade pyarrow $USER_FLAG\n",
"# ! pip3 install --upgrade cloudml-hypertune $USER_FLAG\n",
"# ! pip3 install --upgrade kfp $USER_FLAG\n",
"# ! pip3 install --upgrade torchvision $USER_FLAG\n",
"# ! pip3 install --upgrade rpy2 $USER_FLAG"
]
},
{
@@ -231,11 +221,14 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "region"
"id": "sKBTnvJpox9P"
},
"outputs": [],
"source": [
"REGION = \"us-central1\" # @param {type: \"string\"}"
"REGION = \"[your-region]\" # @param {type:\"string\"}\n",
"\n",
"if REGION == \"[your-region]\":\n",
" REGION = \"us-central1\" # @param {type: \"string\"}"
]
},
{
@@ -253,7 +246,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "timestamp"
"id": "JYtXOocrox9Q"
},
"outputs": [],
"source": [
@@ -262,6 +255,39 @@
"TIMESTAMP = datetime.now().strftime(\"%Y%m%d%H%M%S\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "NNc5Bf_NpPTq"
},
"outputs": [],
"source": [
"import os\n",
"import sys\n",
"\n",
"# 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",
"# The Google Cloud Notebook product has specific requirements\n",
"IS_GOOGLE_CLOUD_NOTEBOOK = os.path.exists(\"/opt/deeplearning/metadata/env_version\")\n",
"\n",
"# If on Google Cloud Notebooks, then don't execute this code\n",
"if not IS_GOOGLE_CLOUD_NOTEBOOK:\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": {
@@ -272,7 +298,7 @@
"\n",
"**The following steps are required, regardless of your notebook environment.**\n",
"\n",
"When you initialize the Vertex 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.\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.\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."
]
@@ -285,7 +311,7 @@
},
"outputs": [],
"source": [
"BUCKET_NAME = \"gs://[your-bucket-name]\" # @param {type:\"string\"}"
"BUCKET_URI = \"gs://[your-bucket-name]\" # @param {type:\"string\"}"
]
},
{
@@ -296,8 +322,8 @@
},
"outputs": [],
"source": [
"if BUCKET_NAME == \"\" or BUCKET_NAME is None or BUCKET_NAME == \"gs://[your-bucket-name]\":\n",
" BUCKET_NAME = \"gs://\" + PROJECT_ID + \"aip-\" + TIMESTAMP"
"if BUCKET_URI == \"\" or BUCKET_URI is None or BUCKET_URI == \"gs://[your-bucket-name]\":\n",
" BUCKET_URI = \"gs://\" + PROJECT_ID + \"aip-\" + TIMESTAMP"
]
},
{
@@ -313,11 +339,11 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "create_bucket"
"id": "aO4sKJfFox9R"
},
"outputs": [],
"source": [
"! gsutil mb -l $REGION $BUCKET_NAME"
"! gsutil mb -l $REGION $BUCKET_URI"
]
},
{
@@ -333,11 +359,11 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "validate_bucket"
"id": "yWnghzKFox9S"
},
"outputs": [],
"source": [
"! gsutil ls -al $BUCKET_NAME"
"! gsutil ls -al $BUCKET_URI"
]
},
{
@@ -378,11 +404,11 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "init_aip:mbsdk"
"id": "JZg2sszQox9T"
},
"outputs": [],
"source": [
"aip.init(project=PROJECT_ID, staging_bucket=BUCKET_NAME)"
"aip.init(project=PROJECT_ID, staging_bucket=BUCKET_URI)"
]
},
{
@@ -411,10 +437,12 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "accelerators:training,cpu,prediction,cpu,mbsdk"
"id": "cQUrG4Mbox9T"
},
"outputs": [],
"source": [
"import os\n",
"\n",
"if os.getenv(\"IS_TESTING_TRAIN_GPU\"):\n",
" TRAIN_GPU, TRAIN_NGPU = (\n",
" aip.gapic.AcceleratorType.NVIDIA_TESLA_K80,\n",
@@ -453,7 +481,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "container:training,prediction,xgboost"
"id": "XujRA5ueox9U"
},
"outputs": [],
"source": [
@@ -497,7 +525,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "machine:training"
"id": "UMPFgENkox9U"
},
"outputs": [],
"source": [
@@ -561,7 +589,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "examine_training_package:xgboost"
"id": "f4wS4eISox9V"
},
"outputs": [],
"source": [
@@ -616,7 +644,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "taskpy_contents:iris,xgboost"
"id": "WiSnFuDoox9W"
},
"outputs": [],
"source": [
@@ -731,14 +759,14 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "tarball_training_script"
"id": "dnmdycf6ox9X"
},
"outputs": [],
"source": [
"! rm -f custom.tar custom.tar.gz\n",
"! tar cvf custom.tar custom\n",
"! gzip custom.tar\n",
"! gsutil cp custom.tar.gz $BUCKET_NAME/trainer_iris.tar.gz"
"! gsutil cp custom.tar.gz $BUCKET_URI/trainer_iris.tar.gz"
]
},
{
@@ -770,7 +798,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "create_custom_pp_training_job:mbsdk"
"id": "rVEMz1xqox9X"
},
"outputs": [],
"source": [
@@ -778,7 +806,7 @@
"\n",
"job = aip.CustomPythonPackageTrainingJob(\n",
" display_name=DISPLAY_NAME,\n",
" python_package_gcs_uri=f\"{BUCKET_NAME}/trainer_iris.tar.gz\",\n",
" python_package_gcs_uri=f\"{BUCKET_URI}/trainer_iris.tar.gz\",\n",
" python_module_name=\"trainer.task\",\n",
" container_uri=TRAIN_IMAGE,\n",
" model_serving_container_image_uri=DEPLOY_IMAGE,\n",
@@ -809,11 +837,11 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "prepare_custom_cmdargs:iris,xgboost"
"id": "AoUfpBqVox9Y"
},
"outputs": [],
"source": [
"MODEL_DIR = \"{}/{}\".format(BUCKET_NAME, TIMESTAMP)\n",
"MODEL_DIR = \"{}/{}\".format(BUCKET_URI, TIMESTAMP)\n",
"DATASET_DIR = \"gs://cloud-samples-data/ai-platform/iris\"\n",
"\n",
"ROUNDS = 20\n",
@@ -858,7 +886,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "run_custom_job:mbsdk"
"id": "JCruQq1aox9Y"
},
"outputs": [],
"source": [
@@ -899,7 +927,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "list_job"
"id": "KBM_KLMSox9Y"
},
"outputs": [],
"source": [
@@ -922,7 +950,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "custom_job_wait:mbsdk"
"id": "lHPMHbSyox9Z"
},
"outputs": [],
"source": [
@@ -944,7 +972,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "delete_job"
"id": "tlYg7Sp-ox9Z"
},
"outputs": [],
"source": [
@@ -964,14 +992,7 @@
"\n",
"Otherwise, you can delete the individual resources you created in this tutorial:\n",
"\n",
"- Dataset\n",
"- Pipeline\n",
"- Model\n",
"- Endpoint\n",
"- AutoML Training Job\n",
"- Batch Job\n",
"- Custom Job\n",
"- Hyperparameter Tuning Job\n",
"- Custom Job (Custome Training job is remove in previous step)\n",
"- Cloud Storage Bucket"
]
},
@@ -979,65 +1000,12 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "cleanup:mbsdk"
"id": "JyWy23gDox9a"
},
"outputs": [],
"source": [
"delete_all = True\n",
"\n",
"if delete_all:\n",
" # Delete the dataset using the Vertex dataset object\n",
" try:\n",
" if \"dataset\" in globals():\n",
" dataset.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the model using the Vertex model object\n",
" try:\n",
" if \"model\" in globals():\n",
" model.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the endpoint using the Vertex endpoint object\n",
" try:\n",
" if \"endpoint\" in globals():\n",
" endpoint.undeploy_all()\n",
" endpoint.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the AutoML or Pipeline training job\n",
" try:\n",
" if \"dag\" in globals():\n",
" dag.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the custom training job\n",
" try:\n",
" if \"job\" in globals():\n",
" job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the batch prediction job using the Vertex batch prediction object\n",
" try:\n",
" if \"batch_predict_job\" in globals():\n",
" batch_predict_job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the hyperparameter tuning job using the Vertex hyperparameter tuning object\n",
" try:\n",
" if \"hpt_job\" in globals():\n",
" hpt_job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" if \"BUCKET_NAME\" in globals():\n",
" ! gsutil rm -r $BUCKET_NAME"
"if os.getenv(\"IS_TESTING\"):\n",
" ! gsutil rm -r $BUCKET_URI"
]
}
],
@@ -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",
@@ -39,10 +39,11 @@
" </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/blob/main/notebooks/community/ml_ops/stage2/get_started_vertex_vizier.ipynb\">\n",
" Open in Google Cloud Notebooks\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/community/ml_ops/stage2/get_started_vertex_vizier.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",
" </td> \n",
"</table>\n",
"<br/><br/><br/>"
]
@@ -139,6 +140,25 @@
"Install *one time* the packages for executing the MLOps notebooks."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "1fd00fa70a2a"
},
"outputs": [],
"source": [
"import os\n",
"\n",
"# The Google Cloud Notebook product has specific requirements\n",
"IS_GOOGLE_CLOUD_NOTEBOOK = os.path.exists(\"/opt/deeplearning/metadata/env_version\")\n",
"\n",
"# Google Cloud Notebook requires dependencies to be installed with '--user'\n",
"USER_FLAG = \"\"\n",
"if IS_GOOGLE_CLOUD_NOTEBOOK:\n",
" USER_FLAG = \"--user\""
]
},
{
"cell_type": "code",
"execution_count": null,
@@ -147,20 +167,8 @@
},
"outputs": [],
"source": [
"ONCE_ONLY = False\n",
"if ONCE_ONLY:\n",
" ! pip3 install -U tensorflow==2.5 $USER_FLAG\n",
" ! pip3 install -U tensorflow-data-validation==1.2 $USER_FLAG\n",
" ! pip3 install -U tensorflow-transform==1.2 $USER_FLAG\n",
" ! pip3 install -U tensorflow-io==0.18 $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-aiplatform[tensorboard] $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-pipeline-components $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-bigquery $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-logging $USER_FLAG\n",
" ! pip3 install --upgrade apache-beam[gcp] $USER_FLAG\n",
" ! pip3 install --upgrade pyarrow $USER_FLAG\n",
" ! pip3 install --upgrade cloudml-hypertune $USER_FLAG\n",
" ! pip3 install --upgrade kfp $USER_FLAG"
"! pip3 install --upgrade google-cloud-aiplatform[tensorboard] $USER_FLAG\n",
" "
]
},
{
@@ -268,7 +276,9 @@
},
"outputs": [],
"source": [
"REGION = \"us-central1\" # @param {type: \"string\"}"
"REGION = \"[your-region]\" # @param {type:\"string\"}\n",
"if REGION == \"[your-region]\":\n",
" REGION = \"us-central1\""
]
},
{
@@ -318,7 +328,7 @@
},
"outputs": [],
"source": [
"BUCKET_NAME = \"gs://[your-bucket-name]\" # @param {type:\"string\"}"
"BUCKET_URI = \"gs://[your-bucket-name]\" # @param {type:\"string\"}"
]
},
{
@@ -329,8 +339,8 @@
},
"outputs": [],
"source": [
"if BUCKET_NAME == \"\" or BUCKET_NAME is None or BUCKET_NAME == \"gs://[your-bucket-name]\":\n",
" BUCKET_NAME = \"gs://\" + PROJECT_ID + \"aip-\" + TIMESTAMP"
"if BUCKET_URI == \"\" or BUCKET_URI is None or BUCKET_URI == \"gs://[your-bucket-name]\":\n",
" BUCKET_URI = \"gs://\" + PROJECT_ID + \"aip-\" + TIMESTAMP"
]
},
{
@@ -350,7 +360,7 @@
},
"outputs": [],
"source": [
"! gsutil mb -l $REGION $BUCKET_NAME"
"! gsutil mb -l $REGION $BUCKET_URI"
]
},
{
@@ -370,7 +380,7 @@
},
"outputs": [],
"source": [
"! gsutil ls -al $BUCKET_NAME"
"! gsutil ls -al $BUCKET_URI"
]
},
{
@@ -415,7 +425,7 @@
},
"outputs": [],
"source": [
"aip.init(project=PROJECT_ID, staging_bucket=BUCKET_NAME)"
"aip.init(project=PROJECT_ID, staging_bucket=BUCKET_URI)"
]
},
{
@@ -808,7 +818,7 @@
"! rm -f custom.tar custom.tar.gz\n",
"! tar cvf custom.tar custom\n",
"! gzip custom.tar\n",
"! gsutil cp custom.tar.gz $BUCKET_NAME/trainer_boston.tar.gz"
"! gsutil cp custom.tar.gz $BUCKET_URI/trainer_boston.tar.gz"
]
},
{
@@ -916,7 +926,7 @@
"outputs": [],
"source": [
"JOB_NAME = \"custom_job_\" + TIMESTAMP\n",
"MODEL_DIR = \"{}/{}\".format(BUCKET_NAME, JOB_NAME)\n",
"MODEL_DIR = \"{}/{}\".format(BUCKET_URI, JOB_NAME)\n",
"\n",
"if not TRAIN_NGPU or TRAIN_NGPU < 2:\n",
" TRAIN_STRATEGY = \"single\"\n",
@@ -948,7 +958,7 @@
" \"disk_spec\": disk_spec,\n",
" \"python_package_spec\": {\n",
" \"executor_image_uri\": TRAIN_IMAGE,\n",
" \"package_uris\": [BUCKET_NAME + \"/trainer_boston.tar.gz\"],\n",
" \"package_uris\": [BUCKET_URI + \"/trainer_boston.tar.gz\"],\n",
" \"python_module\": \"trainer.task\",\n",
" \"args\": CMDARGS,\n",
" },\n",
@@ -1577,14 +1587,6 @@
"\n",
"Otherwise, you can delete the individual resources you created in this tutorial:\n",
"\n",
"- Dataset\n",
"- Pipeline\n",
"- Model\n",
"- Endpoint\n",
"- AutoML Training Job\n",
"- Batch Job\n",
"- Custom Job\n",
"- Hyperparameter Tuning Job\n",
"- Cloud Storage Bucket"
]
},
@@ -1596,61 +1598,8 @@
},
"outputs": [],
"source": [
"delete_all = True\n",
"\n",
"if delete_all:\n",
" # Delete the dataset using the Vertex dataset object\n",
" try:\n",
" if \"dataset\" in globals():\n",
" dataset.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the model using the Vertex model object\n",
" try:\n",
" if \"model\" in globals():\n",
" model.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the endpoint using the Vertex endpoint object\n",
" try:\n",
" if \"endpoint\" in globals():\n",
" endpoint.undeploy_all()\n",
" endpoint.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the AutoML or Pipeline training job\n",
" try:\n",
" if \"dag\" in globals():\n",
" dag.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the custom training job\n",
" try:\n",
" if \"job\" in globals():\n",
" job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the batch prediction job using the Vertex batch prediction object\n",
" try:\n",
" if \"batch_predict_job\" in globals():\n",
" batch_predict_job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the hyperparameter tuning job using the Vertex hyperparameter tuning object\n",
" try:\n",
" if \"hpt_job\" in globals():\n",
" hpt_job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" if \"BUCKET_NAME\" in globals():\n",
" ! gsutil rm -r $BUCKET_NAME"
"if os.getenv(\"IS_TESTING\"):\n",
" ! gsutil rm -r $BUCKET_URI"
]
}
],
@@ -0,0 +1,874 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "VBOfRw7ifk8w"
},
"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 : AutoML Image Classfication Training with Customer Managed Encryption Keys (CMEK)\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_cmek_training.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/ai/platform/notebooks/deploy-notebook?download_url=https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage2/get_started_with_cmek_training.ipynb\">\n",
" Open in Google Cloud Notebooks\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 AutoML training with a customer managed encyrption key CMEK."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "dataset:flowers,icn"
},
"source": [
"### Dataset\n",
"\n",
"The dataset used for this tutorial is the [Flowers dataset](https://www.tensorflow.org/datasets/catalog/tf_flowers) from [TensorFlow](https://www.tensorflow.org/datasets/catalog/overview). The version of the dataset you will use in this tutorial is stored in a public #(GCS) bucket. The trained model predicts the type of flower an image is from a class of five flowers: daisy, dandelion, rose, sunflower, or tulip.\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "objective:mlops,stage3,get_started_automl_pipeline_components"
},
"source": [
"### Objective\n",
"\n",
"In this tutorial, you learn how to use a customer managed encryption key (CMEK) for `Vertex AI AutoML` training.\n",
"\n",
"This tutorial uses the following Google Cloud ML services:\n",
"\n",
"- `Vertex AI AutoML`\n",
"- Customer managed encryption key.\n",
"\n",
"The steps performed include:\n",
"\n",
"- Creating a customer managed encryption key.\n",
"- Creating an image dataset with CMEK encryption.\n",
"- Train an AutoML model with CMEK encryption."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "install_mlops"
},
"source": [
"## Installations\n",
"\n",
"Install the Vertex AI SDK and the KMS package for CMEK encryption."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "sBfZtR4X1Dr_"
},
"outputs": [],
"source": [
"USER_FLAG = \"--user\"\n",
"\n",
"! pip3 install --upgrade google-cloud-aiplatform $USER_FLAG\n",
"! pip3 install --upgrade google-cloud-kms $USER_FLAG"
]
},
{
"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 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 = \"us-central1\" # @param {type: \"string\"}"
]
},
{
"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": "bucket:mbsdk"
},
"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 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.\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": "bucket"
},
"outputs": [],
"source": [
"BUCKET_NAME = \"gs://[your-bucket-name]\" # @param {type:\"string\"}"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "autoset_bucket"
},
"outputs": [],
"source": [
"if BUCKET_NAME == \"\" or BUCKET_NAME is None or BUCKET_NAME == \"gs://[your-bucket-name]\":\n",
" BUCKET_NAME = \"gs://\" + PROJECT_ID + \"aip-\" + TIMESTAMP"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "create_bucket"
},
"source": [
"**Only if your bucket doesn't already exist**: Run the following cell to create your Cloud Storage bucket."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "create_bucket"
},
"outputs": [],
"source": [
"! gsutil mb -l $REGION $BUCKET_NAME"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "validate_bucket"
},
"source": [
"Finally, validate access to your Cloud Storage bucket by examining its contents:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "validate_bucket"
},
"outputs": [],
"source": [
"! gsutil ls -al $BUCKET_NAME"
]
},
{
"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 and define constants"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "import_aip:mbsdk"
},
"outputs": [],
"source": [
"import google.cloud.aiplatform as aip\n",
"from google.cloud import kms"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "init_aip:mbsdk,all"
},
"source": [
"### Initialize Vertex AI SDK for Python\n",
"\n",
"Initialize the Vertex AI SDK for Python for your project and corresponding bucket."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "init_aip:mbsdk,all"
},
"outputs": [],
"source": [
"aip.init(project=PROJECT_ID, location=REGION, staging_bucket=BUCKET_NAME)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "mRk9eoTm6Pyi"
},
"source": [
"## Setting up Customer Managed Encryption Keys\n",
"\n",
"By default, Google Cloud automatically encrypts data when it is stored in Cloud Storage using encryption keys managed by Google. If you have specific compliance or regulatory requirements related to the keys that protect your data, you can use customer-managed encryption keys (CMEK) for your training jobs.\n",
"\n",
"### Enable KMS API\n",
"\n",
"First, you enble the [Cloud Key Management Service (KMS)](https://console.cloud.google.com/flows/enableapi?apiid=cloudkms.googleapis.com)\n",
"\n",
"Learn more about [Customer managed encryption keys (CMEK)](https://cloud.google.com/vertex-ai/docs/general/cmek)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "RD_Pvrg584X3"
},
"source": [
"### Create a key ring\n",
"\n",
"After you have enabled the KMS API, you create a key ring and a key. Use the helper function `create_key_ring()` to create a key ring, with the following parameters:\n",
"\n",
"- `project_id`: Your project ID.\n",
"- `location`: Your region.\n",
"- `key_ring_id`: The unique identifier for your key ring.\n",
"\n",
"The helper function calls the KMS client method `create_key_ring()` to create your key ring.\n",
"\n",
"Learn more about [KMS: Create a key ring](https://cloud.google.com/kms/docs/samples/kms-create-key-ring)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "dxRZzbvQnZC7"
},
"outputs": [],
"source": [
"KEY_RING_ID = \"your_cmek_key_ring_id\"\n",
"\n",
"\n",
"def create_key_ring(project_id, location, key_ring_id):\n",
" \"\"\"\n",
" Creates a new key ring in Cloud KMS\n",
"\n",
" Args:\n",
" project_id (string): Google Cloud project ID (e.g. 'my-project').\n",
" location (string): Cloud KMS location (e.g. 'us-east1').\n",
" id (string): ID of the key ring to create (e.g. 'my-key-ring').\n",
"\n",
" Returns:\n",
" KeyRing: Cloud KMS key ring.\n",
"\n",
" \"\"\"\n",
"\n",
" # Create the client.\n",
" client = kms.KeyManagementServiceClient()\n",
"\n",
" # Build the parent location name.\n",
" location_name = f\"projects/{project_id}/locations/{location}\"\n",
"\n",
" # Build the key ring.\n",
" key_ring = {}\n",
"\n",
" # Call the API.\n",
" created_key_ring = client.create_key_ring(\n",
" request={\n",
" \"parent\": location_name,\n",
" \"key_ring_id\": key_ring_id,\n",
" \"key_ring\": key_ring,\n",
" }\n",
" )\n",
" print(\"Created key ring: {}\".format(created_key_ring.name))\n",
" return created_key_ring\n",
"\n",
"\n",
"key_ring = create_key_ring(\n",
" project_id=PROJECT_ID, location=REGION, key_ring_id=KEY_RING_ID\n",
")\n",
"print(key_ring)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "gCL1-IfFtWXl"
},
"source": [
"### Create a key\n",
"\n",
"Next, you create your key. Use the helper function `create_key()` with the following parameters:\n",
"\n",
"- `project_id`: Your project ID.\n",
"- `location`: Your region.\n",
"- `key_ring_id`: The unique identifier for your key ring.\n",
"- `key_id`: The unique identifier for your key.\n",
"\n",
"The helper function calls the KMS client method `create_cryto_key()` to create your key.\n",
"\n",
"Learn more about [](https://cloud.google.com/kms/docs/samples/kms-create-key-symmetric-encrypt-decrypt)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "LXcagdmSnYYW"
},
"outputs": [],
"source": [
"KEY_ID = \"your_cmek_key_id\"\n",
"\n",
"\n",
"def create_key(project_id, location, key_ring_id, key_id):\n",
" \"\"\"\n",
" Creates a new symmetric encryption/decryption key in Cloud KMS.\n",
"\n",
" Args:\n",
" project_id (string): Google Cloud project ID (e.g. 'my-project').\n",
" location (string): Cloud KMS location (e.g. 'us-east1').\n",
" key_ring_id (string): ID of the Cloud KMS key ring (e.g. 'my-key-ring').\n",
" key_id (string): ID of the key to create (e.g. 'my-symmetric-key').\n",
"\n",
" Returns:\n",
" CryptoKey: Cloud KMS key.\n",
"\n",
" \"\"\"\n",
"\n",
" # Create the client.\n",
" client = kms.KeyManagementServiceClient()\n",
"\n",
" # Build the parent key ring name.\n",
" key_ring_name = client.key_ring_path(project_id, location, key_ring_id)\n",
"\n",
" # Build the key.\n",
" purpose = kms.CryptoKey.CryptoKeyPurpose.ENCRYPT_DECRYPT\n",
" algorithm = (\n",
" kms.CryptoKeyVersion.CryptoKeyVersionAlgorithm.GOOGLE_SYMMETRIC_ENCRYPTION\n",
" )\n",
" key = {\n",
" \"purpose\": purpose,\n",
" \"version_template\": {\n",
" \"algorithm\": algorithm,\n",
" },\n",
" }\n",
"\n",
" # Call the API.\n",
" created_key = client.create_crypto_key(\n",
" request={\"parent\": key_ring_name, \"crypto_key_id\": key_id, \"crypto_key\": key}\n",
" )\n",
" print(\"Created symmetric key: {}\".format(created_key.name))\n",
" return created_key\n",
"\n",
"\n",
"key_id = create_key(\n",
" project_id=PROJECT_ID, location=REGION, key_ring_id=KEY_RING_ID, key_id=KEY_ID\n",
")\n",
"\n",
"print(key_id)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "3gKDBOqC8Gl5"
},
"source": [
"### Set service account permissions\n",
"\n",
"Next, you set permissions for your Vertex AI service account to encrypt and decrypt resources using your key.\n",
"\n",
"Learn more about [Grant Vertex AI permissions](https://cloud.google.com/vertex-ai/docs/general/cmek#grant_permissions)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "6QrRg08Vqfru"
},
"outputs": [],
"source": [
"# Reference: https://cloud.google.com/vertex-ai/docs/general/cmek#granting_permissions\n",
"# Get the service account\n",
"SERVICE_ACCOUNT = ! gcloud projects get-iam-policy {PROJECT_ID} \\\n",
" --flatten=\"bindings[].members\" \\\n",
" --format=\"table(bindings.members)\" \\\n",
" --filter=\"bindings.role:roles/aiplatform.serviceAgent\" \\\n",
" | grep -oP \"service-.+?@gcp-sa-aiplatform.iam.gserviceaccount.com\"\n",
"SERVICE_ACCOUNT = SERVICE_ACCOUNT[0]\n",
"\n",
"print(f\"Service account is: {SERVICE_ACCOUNT}\")\n",
"\n",
"# Give permissions\n",
"! gcloud kms keys add-iam-policy-binding {KEY_ID} \\\n",
" --keyring={KEY_RING_ID} \\\n",
" --location={REGION} \\\n",
" --project={PROJECT_ID} \\\n",
" --member=serviceAccount:{SERVICE_ACCOUNT} \\\n",
" --role=roles/cloudkms.cryptoKeyEncrypterDecrypter"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "1e8cd37e5f99"
},
"source": [
"Create the full resource identifier for the created key"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "ebAHZg2vlhXL"
},
"outputs": [],
"source": [
"ENCRYPTION_SPEC_KEY_NAME = key_id.name"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Aa_8wrqSkamz"
},
"source": [
"## Initialize Vertex SDK for Python\n",
"\n",
"Initialize the *client* for Vertex AI\n",
"\n",
"All resources created during this Notebook run will encrypted with the encryption key created above.\n",
"\n",
"You can override the encryption key at each function call."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "init_aip:mbsdk,all"
},
"source": [
"### Initialize Vertex AI SDK for Python\n",
"\n",
"Initialize the Vertex AI SDK for Python for your project, bucket, and corresponding encryption key.\n",
"\n",
"All resources created during this session are encrypted with the encryption key you created.\n",
"\n",
"*Note:* You can override the encryption key at each function call."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "ohdgOs69kGNU"
},
"outputs": [],
"source": [
"aip.init(\n",
" project=PROJECT_ID,\n",
" staging_bucket=BUCKET_NAME,\n",
" location=REGION,\n",
" encryption_spec_key_name=ENCRYPTION_SPEC_KEY_NAME,\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "import_file:u_dataset,csv"
},
"source": [
"#### Location of Cloud Storage training data.\n",
"\n",
"Now set the variable `IMPORT_FILE` to the location of the CSV index file in Cloud Storage."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "import_file:flowers,csv,icn"
},
"outputs": [],
"source": [
"IMPORT_FILE = (\n",
" \"gs://cloud-samples-data/vision/automl_classification/flowers/all_data_v2.csv\"\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "35QVNhACqcTJ"
},
"source": [
"# Create `Vertex AI ImageDataset` resource\n",
"\n",
"Next, you create an `ImageDataset` resource, which will be encrypted using your encryption key."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "4OfCqaYRqcTJ"
},
"outputs": [],
"source": [
"dataset = aip.ImageDataset.create(\n",
" display_name=\"flowers_\" + TIMESTAMP,\n",
" gcs_source=[IMPORT_FILE],\n",
" import_schema_uri=aip.schema.dataset.ioformat.image.single_label_classification,\n",
")\n",
"\n",
"print(dataset.resource_name)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "6-bBqipfqcTS"
},
"source": [
"# Launch a Training Job to Create a Model\n",
"\n",
"Train an AutoML Image Classification model."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "aA41rT_mb-rV"
},
"outputs": [],
"source": [
"job = aiplatform.AutoMLImageTrainingJob(\n",
" display_name=\"flowers_\" + TIMESTAMP,\n",
" prediction_type=\"classification\",\n",
" multi_label=False,\n",
" model_type=\"CLOUD\",\n",
" base_model=None,\n",
")\n",
"\n",
"# This will take around half an hour to run\n",
"model = job.run(\n",
" dataset=ds,\n",
" model_display_name=\"flowers_\" + TIMESTAMP,\n",
" training_fraction_split=0.6,\n",
" validation_fraction_split=0.2,\n",
" test_fraction_split=0.2,\n",
" budget_milli_node_hours=8000,\n",
" disable_early_stopping=False,\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "5vhDsMJNqcTW"
},
"source": [
"# Deploy Your Model\n",
"\n",
"Deploy your model, then wait until the model FINISHES deployment before proceeding to prediction."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "Y9GH72wWqcTX"
},
"outputs": [],
"source": [
"endpoint = model.deploy()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "nIw1ifPuqcTb"
},
"source": [
"# Predict on Endpoint\n",
"- Take one sample from the data imported to the dataset\n",
"- This sample will be encoded to base64 and passed to the endpoint for prediction"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "H23ISHdHVIZM"
},
"outputs": [],
"source": [
"test_item = !gsutil cat $IMPORT_FILE | head -n1\n",
"test_item, test_label = str(test_item[0]).split(\",\")\n",
"\n",
"print(test_item, test_label)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "TF_N0kqZU768"
},
"outputs": [],
"source": [
"import base64\n",
"\n",
"import tensorflow as tf\n",
"\n",
"with tf.io.gfile.GFile(test_item, \"rb\") as f:\n",
" content = f.read()\n",
"\n",
"# The format of each instance should conform to the deployed model's prediction input schema.\n",
"instances_list = [{\"content\": base64.b64encode(content).decode(\"utf-8\")}]\n",
"\n",
"prediction = endpoint.predict(instances=instances_list)\n",
"\n",
"print(prediction)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "nWA3qocXfk82"
},
"source": [
"# Undeploy Model from Endpoint"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "V1brMaO_fk82"
},
"outputs": [],
"source": [
"endpoint.undeploy_all()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "e00750837ca8"
},
"outputs": [],
"source": [
"# missing\n",
"endpoint.delete()\n",
"model.delete()\n",
"dataset.delete()\n",
"\n",
"! gcloud kms keys versions destroy key-version \\\n",
" --key key {KEY_ID} \\\n",
" --keyring={KEY_RING_ID} \\\n",
" --location={REGION} "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "aa95b7fff9b5"
},
"outputs": [],
"source": [
"! gcloud kms keys list --location {REGION} --keyring {KEY_RING_ID}"
]
}
],
"metadata": {
"colab": {
"collapsed_sections": [],
"name": "get_started_with_cmek_training.ipynb",
"toc_visible": true
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+40 -13
View File
@@ -41,6 +41,7 @@ The steps performed include:
- Building KFP lightweight Python function components.
- Assembling and compiling KFP components into a pipeline.
- Executing a KFP pipeline using Vertex AI Pipelines.
- Loading component and pipeline definitions from a source code repository.
- Building sequential, parallel, multiple output components.
- Building control flow into pipelines.
```
@@ -65,6 +66,17 @@ The steps performed include:
- Execute a Vertex AI pipeline.
```
[Get Started with Dataproc components](get_started_with_dataproc_pipeline_components.ipynb)
```
The steps performed include:
- DataprocPySparkBatchOp for PySpark batch workloads.
- DataprocSparkBatchOp for Spark batch workloads.
- DataprocSparkSqlBatchOp for running Spark SQL batch workloads.
- DataprocSparkRBatchOp for running SparkR batch workloads.
```
[Get Started with Vertex AI AutoML components](get_started_with_automl_pipeline_components.ipynb)
```
@@ -91,19 +103,6 @@ The steps performed include:
[Get Started with Vertex AI Hyperparameter Tuning components](get_started_with_hpt_pipeline_components.ipynb)
```
- Construct a pipeline for:
- Training BigQuery ML model.
- Evaluating the BigQuery ML model.
- Exporting the BigQuery ML model.
- Importing the BigQuery ML model to a Vertex AI model.
- Deploy the Vertex AI model.
- Execute a Vertex AI pipeline.
- Make a prediction with the deployed Vertex AI model.
```
[Get Started with BQML components](get_started_with_bqml_pipeline_components.ipynb)
```
The steps performed include:
@@ -116,6 +115,34 @@ The steps performed include:
- Execute a Vertex AI pipeline.
```
[Get Started with BQML components](get_started_with_bqml_pipeline_components.ipynb)
```
The steps performed include:
- Construct a pipeline for:
- Training BigQuery ML model.
- Evaluating the BigQuery ML model.
- Exporting the BigQuery ML model.
- Importing the BigQuery ML model to a Vertex AI model.
- Deploy the Vertex AI model.
- Execute a Vertex AI pipeline.
- Make a prediction with the deployed Vertex AI model.
```
[Get Started with rapid prototyping with BQML and AutoML components](get_started_with_rapid_prototyping_bqml_automl.ipynb)
```
The steps performed include:
- Creating a BigQuery and Vertex AI training dataset.
- Training a BigQuery ML and AutoML model.
- Extracting evaluation metrics from the BigQueryML and AutoML models.
- Selecting the best trained model.
- Deploying the best trained model.
- Testing the deployed model infrastructure.
```
### E2E Stage Example
@@ -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",
@@ -38,9 +38,15 @@
" 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/stage3/get_started_with_automl_pipeline_components.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/ai/platform/notebooks/deploy-notebook?download_url=https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage3/get_started_with_automl_pipeline_components.ipynb\">\n",
" Open in Google Cloud Notebooks\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/community/ml_ops/stage3/get_started_with_automl_pipeline_components.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",
@@ -67,7 +73,7 @@
"source": [
"### Dataset\n",
"\n",
"The dataset used for this tutorial is the [Flowers dataset](https://www.tensorflow.org/datasets/catalog/tf_flowers) from [TensorFlow Datasets](https://www.tensorflow.org/datasets/catalog/overview). The version of the dataset you will use in this tutorial is stored in a public Cloud Storage bucket. The trained model predicts the type of flower an image is from a class of five flowers: daisy, dandelion, rose, sunflower, or tulip."
"The dataset used for this tutorial is the [Flowers dataset](https://www.tensorflow.org/datasets/catalog/tf_flowers) from [TensorFlow Datasets](https://www.tensorflow.org/datasets/catalog/overview). The version of the dataset you will use in this tutorial is stored in a public Cloud Storage bucket. The trained model predicts the type of flower in the given image from the five classes of flowers: daisy, dandelion, rose, sunflower, or tulip."
]
},
{
@@ -94,7 +100,15 @@
" - Training a Vertex AI AutoML trained model.\n",
" - Test the serving binary with a batch prediction job.\n",
" - Deploying a Vertex AI AutoML trained model.\n",
"- Execute a Vertex AI pipeline."
"- Execute a Vertex AI pipeline.\n",
"\n",
"### Costs\n",
"This tutorial uses billable components of Google Cloud:\n",
"\n",
"- Vertex AI\n",
"- Cloud Storage\n",
"\n",
"Learn about [Vertex AI pricing](https://cloud.google.com/vertex-ai/pricing) and [Cloud Storage pricing](https://cloud.google.com/storage/pricing) and use the [Pricing Calculator](https://cloud.google.com/products/calculator/) to generate a cost estimate based on your projected usage."
]
},
{
@@ -105,7 +119,7 @@
"source": [
"## Installations\n",
"\n",
"Install *one time* the packages for executing the MLOps notebooks."
"Install the following packages for executing this MLOps notebook."
]
},
{
@@ -116,22 +130,22 @@
},
"outputs": [],
"source": [
"ONCE_ONLY = False\n",
"if ONCE_ONLY:\n",
" ! pip3 install -U tensorflow==2.5 $USER_FLAG\n",
" ! pip3 install -U tensorflow-data-validation==1.2 $USER_FLAG\n",
" ! pip3 install -U tensorflow-transform==1.2 $USER_FLAG\n",
" ! pip3 install -U tensorflow-io==0.18 $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-aiplatform[tensorboard] $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-pipeline-components $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-bigquery $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-logging $USER_FLAG\n",
" ! pip3 install --upgrade apache-beam[gcp] $USER_FLAG\n",
" ! pip3 install --upgrade pyarrow $USER_FLAG\n",
" ! pip3 install --upgrade cloudml-hypertune $USER_FLAG\n",
" ! pip3 install --upgrade kfp $USER_FLAG\n",
" ! pip3 install --upgrade torchvision $USER_FLAG\n",
" ! pip3 install --upgrade rpy2 $USER_FLAG"
"import os\n",
"\n",
"# The Google Cloud Notebook product has specific requirements\n",
"IS_GOOGLE_CLOUD_NOTEBOOK = os.path.exists(\"/opt/deeplearning/metadata/env_version\")\n",
"\n",
"# Google Cloud Notebook requires dependencies to be installed with '--user'\n",
"USER_FLAG = \"\"\n",
"if IS_GOOGLE_CLOUD_NOTEBOOK:\n",
" USER_FLAG = \"--user\"\n",
" \n",
"! pip3 install tensorflow-io==0.18 $USER_FLAG -q\n",
"! pip3 install --upgrade google-cloud-aiplatform \\\n",
" google-cloud-pipeline-components \\\n",
" google-cloud-logging \\\n",
" pyarrow \\\n",
" kfp $USER_FLAG -q"
]
},
{
@@ -142,7 +156,7 @@
"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."
"Once you've installed the additional packages, you need to restart the notebook kernel so that it can find the packages."
]
},
{
@@ -239,7 +253,10 @@
},
"outputs": [],
"source": [
"REGION = \"us-central1\" # @param {type: \"string\"}"
"REGION = \"[your-region]\" # @param {type: \"string\"}\n",
"\n",
"if REGION == \"[your-region]\":\n",
" REGION = \"us-central1\""
]
},
{
@@ -266,6 +283,63 @@
"TIMESTAMP = datetime.now().strftime(\"%Y%m%d%H%M%S\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "c38be665ca50"
},
"source": [
"### Authenticate your Google Cloud account\n",
"\n",
"**If you are using Google Cloud 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\" into the filter box, and select **Vertex 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 Google Cloud Notebook, then don't execute this code\n",
"if not os.path.exists(\"/opt/deeplearning/metadata/env_version\"):\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": {
@@ -289,7 +363,8 @@
},
"outputs": [],
"source": [
"BUCKET_NAME = \"gs://[your-bucket-name]\" # @param {type:\"string\"}"
"BUCKET_NAME = \"[your-bucket-name]\" # @param {type:\"string\"}\n",
"BUCKET_URI = f\"gs://{BUCKET_NAME}\""
]
},
{
@@ -300,8 +375,8 @@
},
"outputs": [],
"source": [
"if BUCKET_NAME == \"\" or BUCKET_NAME is None or BUCKET_NAME == \"gs://[your-bucket-name]\":\n",
" BUCKET_NAME = \"gs://\" + PROJECT_ID + \"aip-\" + TIMESTAMP"
"if BUCKET_URI == \"\" or BUCKET_URI is None or BUCKET_URI == \"gs://[your-bucket-name]\":\n",
" BUCKET_URI = \"gs://\" + PROJECT_ID + \"aip-\" + TIMESTAMP"
]
},
{
@@ -321,7 +396,7 @@
},
"outputs": [],
"source": [
"! gsutil mb -l $REGION $BUCKET_NAME"
"! gsutil mb -l $REGION $BUCKET_URI"
]
},
{
@@ -341,7 +416,7 @@
},
"outputs": [],
"source": [
"! gsutil ls -al $BUCKET_NAME"
"! gsutil ls -al $BUCKET_URI"
]
},
{
@@ -352,7 +427,7 @@
"source": [
"#### Service Account\n",
"\n",
"**If you don't know your service account**, try to get your service account using `gcloud` command by executing the second cell below."
"You use a service account to create Vertex AI Pipeline jobs. If you do not want to use your project's Compute Engine service account, set `SERVICE_ACCOUNT` to another service account ID."
]
},
{
@@ -376,13 +451,15 @@
"source": [
"if (\n",
" SERVICE_ACCOUNT == \"\"\n",
" or SERVICE_ACCOUNT is None\n",
" or SERVICE_ACCOUNT == \"[your-service-account]\"\n",
" or SERVICE_ACCOUNT is None\n",
"):\n",
" # Get your GCP project id from gcloud\n",
" shell_output = !gcloud auth list 2>/dev/null\n",
" SERVICE_ACCOUNT = shell_output[2].replace(\"*\", \"\").strip()\n",
" print(\"Service Account:\", SERVICE_ACCOUNT)"
" shell_output = ! gcloud projects describe $PROJECT_ID | sed -nre 's:.*projectNumber\\: (.*):\\1:p'\n",
" SERVICE_ACCOUNT = (\n",
" shell_output[0].replace(\"'\", \"\") + \"-compute@developer.gserviceaccount.com\"\n",
" )\n",
"\n",
"print(\"Service Account:\", SERVICE_ACCOUNT)"
]
},
{
@@ -393,7 +470,7 @@
"source": [
"#### Set service account access for Vertex AI Pipelines\n",
"\n",
"Run the following commands to grant your service account access to read and write pipeline artifacts in the bucket that you created in the previous step -- you only need to run these once per service account."
"Run the following commands to grant your service account access to read and write pipeline artifacts in the bucket that you created in the previous step. You only need to run this step once per service account."
]
},
{
@@ -404,9 +481,9 @@
},
"outputs": [],
"source": [
"! gsutil iam ch serviceAccount:{SERVICE_ACCOUNT}:roles/storage.objectCreator $BUCKET_NAME\n",
"! gsutil iam ch serviceAccount:{SERVICE_ACCOUNT}:roles/storage.objectCreator $BUCKET_URI\n",
"\n",
"! gsutil iam ch serviceAccount:{SERVICE_ACCOUNT}:roles/storage.objectViewer $BUCKET_NAME"
"! gsutil iam ch serviceAccount:{SERVICE_ACCOUNT}:roles/storage.objectViewer $BUCKET_URI"
]
},
{
@@ -415,32 +492,7 @@
"id": "setup_vars"
},
"source": [
"### Set up variables\n",
"\n",
"Next, set up some variables used throughout the tutorial.\n",
"### Import libraries and define constants"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "import_aip:mbsdk"
},
"outputs": [],
"source": [
"import google.cloud.aiplatform as aip"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "import_tf"
},
"source": [
"#### Import TensorFlow\n",
"\n",
"Import the TensorFlow package into your Python environment."
"### Import libraries"
]
},
{
@@ -451,22 +503,14 @@
},
"outputs": [],
"source": [
"import tensorflow as tf"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "import_kfp"
},
"outputs": [],
"source": [
"import base64\n",
"import json\n",
"\n",
"import google.cloud.aiplatform as aiplatform\n",
"import tensorflow as tf\n",
"from kfp import dsl\n",
"from kfp.v2 import compiler\n",
"from kfp.v2.dsl import component"
"from kfp.v2.dsl import Artifact, Input, Output, component"
]
},
{
@@ -488,7 +532,7 @@
},
"outputs": [],
"source": [
"aip.init(project=PROJECT_ID, location=REGION, staging_bucket=BUCKET_NAME)"
"aiplatform.init(project=PROJECT_ID, location=REGION, staging_bucket=BUCKET_URI)"
]
},
{
@@ -528,7 +572,7 @@
"- Takes as input the region and Model artifacts returned from an AutoML training component.\n",
"- Create a client interface to the Vertex AI Model service (`metadata[\"resource_name\"]).\n",
"- Construct the resource ID for the model from the model artifact parameter.\n",
"- Retrieve the model evaluation\n",
"- Retrieve the model evaluation.\n",
"- Return the model evaluation as a string."
]
},
@@ -540,11 +584,10 @@
},
"outputs": [],
"source": [
"from kfp.v2.dsl import Artifact, Input, Model\n",
"\n",
"\n",
"@component(packages_to_install=[\"google-cloud-aiplatform\"])\n",
"def evaluateAutoMLModelOp(model: Input[Artifact], region: str) -> str:\n",
"def evaluateAutoMLModelOp(\n",
" model: Input[Artifact], region: str, model_evaluation: Output[Artifact]\n",
"):\n",
" import logging\n",
"\n",
" import google.cloud.aiplatform.gapic as gapic\n",
@@ -557,8 +600,7 @@
"\n",
" model_evaluations = model_service_client.list_model_evaluations(parent=model_id)\n",
" model_evaluation = list(model_evaluations)[0]\n",
" logging.info(model_evaluation)\n",
" return str(model_evaluation)"
" logging.info(model_evaluation)"
]
},
{
@@ -574,7 +616,7 @@
"1. Use the prebuilt component `ImageDatasetCreateOp` to create a Vertex AI Dataset resource, where:\n",
" - The display name for the dataset is passed into the pipeline.\n",
" - The import file for the dataset is passed into the pipeline.\n",
" - The component returns the dataset resource as `outputs[\"dataset\"]`\n",
" - The component returns the dataset resource as `outputs[\"dataset\"]`.\n",
"\n",
"\n",
"2. Use the prebuilt component `AutoMLImageTrainingJobRunOp` to train a Vertex AI AutoML Model resource, where:\n",
@@ -593,12 +635,12 @@
" - The component returns the endpoint resource as `outputs[\"endpoint\"]`.\n",
"\n",
"\n",
"5. Use the prebuilt component `ModelDeployOp` to deploy the trained AutoML model to, where:\n",
"5. Use the prebuilt component `ModelDeployOp` to deploy the trained AutoML model where:\n",
" - The display name for the dataset is passed into the pipeline.\n",
" - The model is the output from the `AutoMLTrainingJobRunOp`.\n",
" - The endpoint is the output from the `EndpointCreateOp`\n",
" - The endpoint is the output from the `EndpointCreateOp`.\n",
"\n",
"*Note:* Since each component is executed as a graph node in its own execution context, you pass the parameter `project` for each component op, in constrast to doing a `aip.init(project=project)` if this was a Python script calling the SDK methods directly within the same execution context."
"*Note:* Since each component is executed as a graph node in its own execution context, you pass the parameter `project` for each component op, in constrast to doing a `aiplatform.init(project=project)` if this was a Python script calling the SDK methods directly within the same execution context."
]
},
{
@@ -609,9 +651,7 @@
},
"outputs": [],
"source": [
"from google_cloud_pipeline_components import aiplatform as gcc_aip\n",
"\n",
"PIPELINE_ROOT = \"{}/pipeline_root/automl_icn_training\".format(BUCKET_NAME)\n",
"PIPELINE_ROOT = \"{}/pipeline_root/automl_icn_training\".format(BUCKET_URI)\n",
"DEPLOY_COMPUTE = \"n1-standard-4\"\n",
"\n",
"\n",
@@ -626,12 +666,13 @@
" project: str = PROJECT_ID,\n",
" region: str = REGION,\n",
"):\n",
" from google_cloud_pipeline_components import aiplatform as gcc_aip\n",
"\n",
" dataset_op = gcc_aip.ImageDatasetCreateOp(\n",
" project=project,\n",
" display_name=display_name,\n",
" gcs_source=import_file,\n",
" import_schema_uri=aip.schema.dataset.ioformat.image.single_label_classification,\n",
" import_schema_uri=aiplatform.schema.dataset.ioformat.image.single_label_classification,\n",
" )\n",
"\n",
" training_op = gcc_aip.AutoMLImageTrainingJobRunOp(\n",
@@ -669,11 +710,12 @@
" display_name=display_name,\n",
" ).after(batch_op)\n",
"\n",
" deploy_op = gcc_aip.ModelDeployOp(\n",
" _ = gcc_aip.ModelDeployOp(\n",
" model=training_op.outputs[\"model\"],\n",
" endpoint=endpoint_op.outputs[\"endpoint\"],\n",
" automatic_resources_min_replica_count=1,\n",
" automatic_resources_max_replica_count=1,\n",
" traffic_split={\"0\": 100},\n",
" )"
]
},
@@ -685,7 +727,7 @@
"source": [
"### Get test item(s)\n",
"\n",
"Now do a batch prediction to your Vertex model. You will use arbitrary examples out of the dataset as a test items. Don't be concerned that the examples were likely used in training the model -- we just want to demonstrate how to make a prediction."
"In the pipeline, you do a batch prediction on your Vertex model. You will use arbitrary examples from the dataset as test items. Don't be concerned that the examples were likely used while training the model. This step is just to demonstrate how to make a prediction."
]
},
{
@@ -730,11 +772,11 @@
"file_1 = test_item_1.split(\"/\")[-1]\n",
"file_2 = test_item_2.split(\"/\")[-1]\n",
"\n",
"! gsutil cp $test_item_1 $BUCKET_NAME/$file_1\n",
"! gsutil cp $test_item_2 $BUCKET_NAME/$file_2\n",
"! gsutil cp $test_item_1 $BUCKET_URI/$file_1\n",
"! gsutil cp $test_item_2 $BUCKET_URI/$file_2\n",
"\n",
"test_item_1 = BUCKET_NAME + \"/\" + file_1\n",
"test_item_2 = BUCKET_NAME + \"/\" + file_2"
"test_item_1 = BUCKET_URI + \"/\" + file_1\n",
"test_item_2 = BUCKET_URI + \"/\" + file_2"
]
},
{
@@ -745,14 +787,14 @@
"source": [
"### Make the batch input file\n",
"\n",
"Now make a batch input file, which you will store in your local Cloud Storage bucket. The batch input file can be either CSV or JSONL. You will use JSONL in this tutorial. For JSONL file, you make one dictionary entry per line for each data item (instance). The dictionary contains the key/value pairs:\n",
"Now make a batch input file, which you will store in your local Cloud Storage bucket. The batch input file can only be in JSONL format. For JSONL file, you make one dictionary entry per line for each data item (instance). The dictionary contains key/value pairs:\n",
"\n",
"- `content`: The Cloud Storage path to the image.\n",
"- `mime_type`: The content type. In our example, it is a `jpeg` file.\n",
"\n",
"For example:\n",
"\n",
" {'content': '[your-bucket]/file1.jpg', 'mime_type': 'jpeg'}"
" {'content': '[your-bucket]/file1.jpg', 'mime_type': 'jpeg'}"
]
},
{
@@ -763,11 +805,7 @@
},
"outputs": [],
"source": [
"import json\n",
"\n",
"import tensorflow as tf\n",
"\n",
"gcs_input_uri = BUCKET_NAME + \"/test.jsonl\"\n",
"gcs_input_uri = BUCKET_URI + \"/test.jsonl\"\n",
"with tf.io.gfile.GFile(gcs_input_uri, \"w\") as f:\n",
" data = {\"content\": test_item_1, \"mime_type\": \"image/jpeg\"}\n",
" f.write(json.dumps(data) + \"\\n\")\n",
@@ -807,7 +845,7 @@
" pipeline_func=pipeline, package_path=\"automl_icn_training.json\"\n",
")\n",
"\n",
"pipeline = aip.PipelineJob(\n",
"pipeline = aiplatform.PipelineJob(\n",
" display_name=\"automl_icn_training\",\n",
" template_path=\"automl_icn_training.json\",\n",
" pipeline_root=PIPELINE_ROOT,\n",
@@ -877,14 +915,29 @@
" + str(TASK_ID)\n",
" + \"/gcp_resources\"\n",
" )\n",
" EVAL_METRICS = (\n",
" PIPELINE_ROOT\n",
" + \"/\"\n",
" + PROJECT_NUMBER\n",
" + \"/\"\n",
" + JOB_ID\n",
" + \"/\"\n",
" + output_task_name\n",
" + \"_\"\n",
" + str(TASK_ID)\n",
" + \"/evaluation_metrics\"\n",
" )\n",
" if tf.io.gfile.exists(EXECUTE_OUTPUT):\n",
" ! gsutil cat $EXECUTE_OUTPUT\n",
" break\n",
" return EXECUTE_OUTPUT\n",
" elif tf.io.gfile.exists(GCP_RESOURCES):\n",
" ! gsutil cat $GCP_RESOURCES\n",
" break\n",
" return GCP_RESOURCES\n",
" elif tf.io.gfile.exists(EVAL_METRICS):\n",
" ! gsutil cat $EVAL_METRICS\n",
" return EVAL_METRICS\n",
"\n",
" return EXECUTE_OUTPUT\n",
" return None\n",
"\n",
"\n",
"print(\"image-dataset-create\")\n",
@@ -893,9 +946,21 @@
"print(\"automl-image-training-job\")\n",
"artifacts = print_pipeline_output(pipeline, \"automl-image-training-job\")\n",
"print(\"\\n\\n\")\n",
"output = !gsutil cat $artifacts\n",
"output = json.loads(output[0])\n",
"model_id = output[\"artifacts\"][\"model\"][\"artifacts\"][0][\"metadata\"][\"resourceName\"]\n",
"print(\"\\n\")\n",
"print(model_id)\n",
"print(\"endpoint-create\")\n",
"artifacts = print_pipeline_output(pipeline, \"endpoint-create\")\n",
"print(\"\\n\\n\")\n",
"output = !gsutil cat $artifacts\n",
"output = json.loads(output[0])\n",
"endpoint_id = output[\"artifacts\"][\"endpoint\"][\"artifacts\"][0][\"metadata\"][\n",
" \"resourceName\"\n",
"]\n",
"print(\"\\n\")\n",
"print(endpoint_id)\n",
"print(\"model-deploy\")\n",
"artifacts = print_pipeline_output(pipeline, \"model-deploy\")\n",
"print(\"\\n\\n\")\n",
@@ -911,7 +976,12 @@
" output[\"artifacts\"][\"batchpredictionjob\"][\"artifacts\"][0][\"metadata\"][\n",
" \"gcsOutputDirectory\"\n",
" ]\n",
")"
")\n",
"output = !gsutil cat $artifacts\n",
"output = json.loads(output[0])\n",
"batch_job_id = output[\"artifacts\"][\"batchpredictionjob\"][\"artifacts\"][0][\"metadata\"][\n",
" \"resourceName\"\n",
"]"
]
},
{
@@ -939,7 +1009,117 @@
{
"cell_type": "markdown",
"metadata": {
"id": "cleanup:mbsdk"
"id": "endpoint_load:mbsdk"
},
"source": [
"#### Load an endpoint\n",
"\n",
"The 'Endpoint' initializer will load an endpoint from an endpoint identifier."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "endpoint_load:mbsdk"
},
"outputs": [],
"source": [
"endpoint = aiplatform.Endpoint(endpoint_id)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "make_prediction"
},
"source": [
"## Send a online prediction request\n",
"\n",
"Send a online prediction request to your deployed model."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "get_test_item"
},
"source": [
"### Get test item\n",
"\n",
"You will use an arbitrary example out of the dataset as a test item. Don't be concerned that the example was likely used while training the model. This step is just to demonstrate how to make a prediction."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "get_test_item:automl,icn,csv"
},
"outputs": [],
"source": [
"test_item = !gsutil cat $IMPORT_FILE | head -n1\n",
"if len(str(test_item[0]).split(\",\")) == 3:\n",
" _, test_item, test_label = str(test_item[0]).split(\",\")\n",
"else:\n",
" test_item, test_label = str(test_item[0]).split(\",\")\n",
"\n",
"print(test_item, test_label)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "predict_request:mbsdk,icn"
},
"source": [
"### Make the prediction\n",
"\n",
"Now that your `Model` resource is deployed to an `Endpoint` resource, you can do online predictions by sending prediction requests to the Endpoint resource.\n",
"\n",
"#### Request\n",
"\n",
"Since in this example your test item is in a Cloud Storage bucket, you open and read the contents of the image using `tf.io.gfile.Gfile()`. To pass the test data to the prediction service, you encode the bytes into base64 which makes the content safe from modification while transmitting binary data over the network.\n",
"\n",
"The format of each instance is:\n",
"\n",
" { 'content': { 'b64': base64_encoded_bytes } }\n",
"\n",
"Since the `predict()` method can take multiple items (instances), send your single test item as a list of one test item.\n",
"\n",
"#### Response\n",
"\n",
"The response from the `predict()` call is a Python dictionary with the following entries:\n",
"\n",
"- `ids`: The internal assigned unique identifiers for each prediction request.\n",
"- `displayNames`: The class names for each class label.\n",
"- `confidences`: The predicted confidence, between 0 and 1, per class label.\n",
"- `deployed_model_id`: The Vertex AI identifier for the deployed Model resource which did the predictions."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "predict_request:mbsdk,icn"
},
"outputs": [],
"source": [
"with tf.io.gfile.GFile(test_item, \"rb\") as f:\n",
" content = f.read()\n",
"\n",
"# The format of each instance should conform to the deployed model's prediction input schema.\n",
"instances = [{\"content\": base64.b64encode(content).decode(\"utf-8\")}]\n",
"\n",
"prediction = endpoint.predict(instances=instances)\n",
"\n",
"print(prediction)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "9d347472d5ba"
},
"source": [
"# Cleaning up\n",
@@ -947,17 +1127,40 @@
"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:\n",
"Otherwise, you can delete the individual resources you created in this tutorial.\n",
"\n",
"- Dataset\n",
"- Pipeline\n",
"- Model\n",
"- Endpoint\n",
"- AutoML Training Job\n",
"- Batch Job\n",
"- Custom Job\n",
"- Hyperparameter Tuning Job\n",
"- Cloud Storage Bucket"
"#### Delete the Vertex AI Model, Endpoint and BatchPredictionJob resources\n",
"\n",
"Undelpoy and delete the Vertex AI Model, Endpoint and BatchPredictionJob resources."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "baa3e1071f7b"
},
"outputs": [],
"source": [
"endpoint.undeploy_all()\n",
"endpoint.delete()\n",
"\n",
"model = aiplatform.Model(model_id)\n",
"model.delete()\n",
"\n",
"batch_job = aiplatform.BatchPredictionJob(batch_job_id)\n",
"batch_job.delete()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "a802da1f6fa7"
},
"source": [
"#### Delete the Cloud Storage bucket\n",
"\n",
"Set `delete_bucket` to *True* to delete the Cloud storage bucket used in this notebook."
]
},
{
@@ -968,61 +1171,10 @@
},
"outputs": [],
"source": [
"delete_all = True\n",
"delete_bucket = False\n",
"\n",
"if delete_all:\n",
" # Delete the dataset using the Vertex dataset object\n",
" try:\n",
" if \"dataset\" in globals():\n",
" dataset.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the model using the Vertex model object\n",
" try:\n",
" if \"model\" in globals():\n",
" model.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the endpoint using the Vertex endpoint object\n",
" try:\n",
" if \"endpoint\" in globals():\n",
" endpoint.undeploy_all()\n",
" endpoint.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the AutoML or Pipeline training job\n",
" try:\n",
" if \"dag\" in globals():\n",
" dag.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the custom training job\n",
" try:\n",
" if \"job\" in globals():\n",
" job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the batch prediction job using the Vertex batch prediction object\n",
" try:\n",
" if \"batch_predict_job\" in globals():\n",
" batch_predict_job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the hyperparameter tuning job using the Vertex hyperparameter tuning object\n",
" try:\n",
" if \"hpt_job\" in globals():\n",
" hpt_job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" if \"BUCKET_NAME\" in globals():\n",
" ! gsutil rm -r $BUCKET_NAME"
"if delete_bucket or os.getenv(\"IS_TESTING\"):\n",
" ! gsutil rm -r $BUCKET_URI"
]
}
],
@@ -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",
@@ -33,14 +33,20 @@
"\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/stage3/get_started_with_bq_tfdv_pipeline_components.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/stage3/get_started_with_bq_tfdv_pipeline_components.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/ai/platform/notebooks/deploy-notebook?download_url=https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage3/get_started_with_bq_tfdv_pipeline_components.ipynb\">\n",
" Open in Google Cloud Notebooks\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/community/ml_ops/stage3/get_started_with_bq_tfdv_pipeline_components.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",
@@ -93,6 +99,28 @@
"- Execute a Vertex AI pipeline."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "0c997d8d92ce"
},
"source": [
"### Costs \n",
"\n",
"\n",
"This tutorial uses billable components of Google Cloud:\n",
"\n",
"* Vertex AI\n",
"* Cloud Storage\n",
"\n",
"\n",
"Learn about [Vertex AI\n",
"pricing](https://cloud.google.com/vertex-ai/pricing) and [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": {
@@ -104,6 +132,25 @@
"Install *one time* the packages for executing the MLOps notebooks."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "1fd00fa70a2a"
},
"outputs": [],
"source": [
"import os\n",
"\n",
"# The Google Cloud Notebook product has specific requirements\n",
"IS_GOOGLE_CLOUD_NOTEBOOK = os.path.exists(\"/opt/deeplearning/metadata/env_version\")\n",
"\n",
"# Google Cloud Notebook requires dependencies to be installed with '--user'\n",
"USER_FLAG = \"\"\n",
"if IS_GOOGLE_CLOUD_NOTEBOOK:\n",
" USER_FLAG = \"--user\""
]
},
{
"cell_type": "code",
"execution_count": null,
@@ -112,20 +159,9 @@
},
"outputs": [],
"source": [
"ONCE_ONLY = False\n",
"if ONCE_ONLY:\n",
" ! pip3 install -U tensorflow==2.5 $USER_FLAG\n",
" ! pip3 install -U tensorflow-data-validation==1.2 $USER_FLAG\n",
" ! pip3 install -U tensorflow-transform==1.2 $USER_FLAG\n",
" ! pip3 install -U tensorflow-io==0.18 $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-aiplatform[tensorboard] $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-pipeline-components $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-bigquery $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-logging $USER_FLAG\n",
" ! pip3 install --upgrade apache-beam[gcp] $USER_FLAG\n",
" ! pip3 install --upgrade pyarrow $USER_FLAG\n",
" ! pip3 install --upgrade cloudml-hypertune $USER_FLAG\n",
" ! pip3 install --upgrade kfp $USER_FLAG"
"! pip3 install -U tensorflow $USER_FLAG\n",
"! pip3 install --upgrade google-cloud-aiplatform[tensorboard] $USER_FLAG\n",
"! pip3 install --upgrade kfp $USER_FLAG"
]
},
{
@@ -176,6 +212,8 @@
},
"outputs": [],
"source": [
"import os\n",
"\n",
"PROJECT_ID = \"[your-project-id]\" # @param {type:\"string\"}"
]
},
@@ -233,7 +271,9 @@
},
"outputs": [],
"source": [
"REGION = \"us-central1\" # @param {type: \"string\"}"
"REGION = \"[your-region]\" # @param {type:\"string\"}\n",
"if REGION == \"[your-region]\":\n",
" REGION = \"us-central1\""
]
},
{
@@ -260,6 +300,81 @@
"TIMESTAMP = datetime.now().strftime(\"%Y%m%d%H%M%S\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "648aa9824ac6"
},
"source": [
"### Authenticate your Google Cloud account\n",
"\n",
"**If you are using Google Cloud Notebooks**, your environment is already\n",
"authenticated. Skip this step."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "fc52bba17ee3"
},
"source": [
"**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",
"1. In the Cloud Console, go to the [**Create service account key**\n",
" page](https://console.cloud.google.com/apis/credentials/serviceaccountkey).\n",
"\n",
"2. Click **Create service account**.\n",
"\n",
"3. In the **Service account name** field, enter a name, and\n",
" click **Create**.\n",
"\n",
"4. In the **Grant this service account access to project** section, click the **Role** drop-down list. Type \"Vertex AI\"\n",
"into the filter box, and select\n",
" **Vertex AI Administrator**. Type \"Storage Object Admin\" into the filter box, and select **Storage Object Admin**.\n",
"\n",
"5. Click *Create*. A JSON file that contains your key downloads to your\n",
"local environment.\n",
"\n",
"6. Enter the path to your service account key as the\n",
"`GOOGLE_APPLICATION_CREDENTIALS` variable in the cell below and run the cell."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "535223fa4b84"
},
"outputs": [],
"source": [
"import os\n",
"import sys\n",
"\n",
"# 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",
"# The Google Cloud Notebook product has specific requirements\n",
"IS_GOOGLE_CLOUD_NOTEBOOK = os.path.exists(\"/opt/deeplearning/metadata/env_version\")\n",
"\n",
"# If on Google Cloud Notebooks, then don't execute this code\n",
"if not IS_GOOGLE_CLOUD_NOTEBOOK:\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": {
@@ -283,7 +398,7 @@
},
"outputs": [],
"source": [
"BUCKET_NAME = \"gs://[your-bucket-name]\" # @param {type:\"string\"}"
"BUCKET_URI = \"gs://[your-bucket-name]\" # @param {type:\"string\"}"
]
},
{
@@ -294,8 +409,8 @@
},
"outputs": [],
"source": [
"if BUCKET_NAME == \"\" or BUCKET_NAME is None or BUCKET_NAME == \"gs://[your-bucket-name]\":\n",
" BUCKET_NAME = \"gs://\" + PROJECT_ID + \"aip-\" + TIMESTAMP"
"if BUCKET_URI == \"\" or BUCKET_URI is None or BUCKET_URI == \"gs://[your-bucket-name]\":\n",
" BUCKET_URI = \"gs://\" + PROJECT_ID + \"aip-\" + TIMESTAMP"
]
},
{
@@ -315,7 +430,7 @@
},
"outputs": [],
"source": [
"! gsutil mb -l $REGION $BUCKET_NAME"
"! gsutil mb -l $REGION $BUCKET_URI"
]
},
{
@@ -335,7 +450,7 @@
},
"outputs": [],
"source": [
"! gsutil ls -al $BUCKET_NAME"
"! gsutil ls -al $BUCKET_URI"
]
},
{
@@ -346,7 +461,9 @@
"source": [
"#### Service Account\n",
"\n",
"**If you don't know your service account**, try to get your service account using `gcloud` command by executing the second cell below."
"**If you don't know your service account**, try to get your service account using `gcloud` command by executing the second cell below.\n",
"\n",
"*Note:* The code for automatically finding your service account works on a user-managed Workbench AI noteboook. If you are using a fully-managed notebook or colab, you will need to manually enter your service account."
]
},
{
@@ -375,7 +492,7 @@
"):\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",
" SERVICE_ACCOUNT = shell_output[2].replace(\"*\", \"\").strip()\n",
" print(\"Service Account:\", SERVICE_ACCOUNT)"
]
},
@@ -398,9 +515,9 @@
},
"outputs": [],
"source": [
"! gsutil iam ch serviceAccount:{SERVICE_ACCOUNT}:roles/storage.objectCreator $BUCKET_NAME\n",
"! gsutil iam ch serviceAccount:{SERVICE_ACCOUNT}:roles/storage.objectCreator $BUCKET_URI\n",
"\n",
"! gsutil iam ch serviceAccount:{SERVICE_ACCOUNT}:roles/storage.objectViewer $BUCKET_NAME"
"! gsutil iam ch serviceAccount:{SERVICE_ACCOUNT}:roles/storage.objectViewer $BUCKET_URI"
]
},
{
@@ -482,7 +599,7 @@
},
"outputs": [],
"source": [
"aip.init(project=PROJECT_ID, staging_bucket=BUCKET_NAME)"
"aip.init(project=PROJECT_ID, staging_bucket=BUCKET_URI)"
]
},
{
@@ -597,7 +714,7 @@
" return dataset.column_names\n",
"\n",
"\n",
"PIPELINE_ROOT = \"{}/pipeline_root/dataset_bq\".format(BUCKET_NAME)\n",
"PIPELINE_ROOT = \"{}/pipeline_root/dataset_bq\".format(BUCKET_URI)\n",
"\n",
"\n",
"@dsl.pipeline(\n",
@@ -610,9 +727,9 @@
"):\n",
" create_op = create_dataset_bq(bq_table, display_name, project)\n",
"\n",
" source_op = get_dataset_source(create_op.output)\n",
" _ = get_dataset_source(create_op.output)\n",
"\n",
" column_names_op = get_column_names(create_op.output)\n",
" _ = get_column_names(create_op.output)\n",
"\n",
"\n",
"compiler.Compiler().compile(pipeline_func=pipeline, package_path=\"dataset_bq.json\")\n",
@@ -811,7 +928,7 @@
" return (stats_file, schema_file)\n",
"\n",
"\n",
"PIPELINE_ROOT = \"{}/pipeline_root/dataset_stats\".format(BUCKET_NAME)\n",
"PIPELINE_ROOT = \"{}/pipeline_root/dataset_stats\".format(BUCKET_URI)\n",
"\n",
"\n",
"@dsl.pipeline(\n",
@@ -819,7 +936,7 @@
")\n",
"def pipeline(dataset_id: str, label: str, bucket: str):\n",
"\n",
" stats_op = statistics(dataset_id, label, bucket)\n",
" _ = statistics(dataset_id, label, bucket)\n",
"\n",
"\n",
"compiler.Compiler().compile(pipeline_func=pipeline, package_path=\"dataset_stats.json\")\n",
@@ -831,7 +948,7 @@
" parameter_values={\n",
" \"dataset_id\": dataset_id,\n",
" \"label\": \"mean_temp\",\n",
" \"bucket\": BUCKET_NAME,\n",
" \"bucket\": BUCKET_URI,\n",
" },\n",
")\n",
"\n",
@@ -901,14 +1018,7 @@
"\n",
"Otherwise, you can delete the individual resources you created in this tutorial:\n",
"\n",
"- Dataset\n",
"- Pipeline\n",
"- Model\n",
"- Endpoint\n",
"- AutoML Training Job\n",
"- Batch Job\n",
"- Custom Job\n",
"- Hyperparameter Tuning Job\n",
"- Vertex AI dataset\n",
"- Cloud Storage Bucket"
]
},
@@ -920,61 +1030,17 @@
},
"outputs": [],
"source": [
"delete_all = True\n",
"# Set this to true only if you'd like to delete your bucket\n",
"delete_bucket = False\n",
"\n",
"if delete_all:\n",
" # Delete the dataset using the Vertex dataset object\n",
" try:\n",
" if \"dataset\" in globals():\n",
" dataset.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"# Create reference to Vertex AI dataset created in pipeline\n",
"dataset = aip.TabularDataset(dataset_id)\n",
"\n",
" # Delete the model using the Vertex model object\n",
" try:\n",
" if \"model\" in globals():\n",
" model.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"# delete Vertex AI dataset\n",
"dataset.delete()\n",
"\n",
" # Delete the endpoint using the Vertex endpoint object\n",
" try:\n",
" if \"endpoint\" in globals():\n",
" endpoint.undeploy_all()\n",
" endpoint.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the AutoML or Pipeline training job\n",
" try:\n",
" if \"dag\" in globals():\n",
" dag.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the custom training job\n",
" try:\n",
" if \"job\" in globals():\n",
" job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the batch prediction job using the Vertex batch prediction object\n",
" try:\n",
" if \"batch_predict_job\" in globals():\n",
" batch_predict_job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the hyperparameter tuning job using the Vertex hyperparameter tuning object\n",
" try:\n",
" if \"hpt_job\" in globals():\n",
" hpt_job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" if \"BUCKET_NAME\" in globals():\n",
" ! gsutil rm -r $BUCKET_NAME"
"if delete_bucket or os.getenv(\"IS_TESTING\"):\n",
" ! gsutil rm -r $BUCKET_URI"
]
}
],
File diff suppressed because it is too large Load Diff
@@ -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",
@@ -33,14 +33,20 @@
"\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/stage3/get_started_with_custom_training_pipeline_components.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/stage3/get_started_with_custom_training_pipeline_components.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/ai/platform/notebooks/deploy-notebook?download_url=https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage3/get_started_with_custom_training_pipeline_components.ipynb\">\n",
" Open in Google Cloud Notebooks\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/community/ml_ops/stage3/get_started_with_custom_training_pipeline_components.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",
@@ -94,9 +100,37 @@
" - Training a Vertex AI custom trained model.\n",
" - Test the serving binary with a batch prediction job.\n",
" - Deploying a Vertex AI custom trained model.\n",
"- Execute a Vertex AI pipeline.\n",
"- Construct a pipeline for:\n",
" - Construct a custom training component.\n",
" - Convert custom training component to CustomTrainingJobOp.\n",
" - Training a Vertex AI custom trained model using the converted component.\n",
" - Deploying a Vertex AI custom trained model.\n",
"- Execute a Vertex AI pipeline."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "0c997d8d92ce"
},
"source": [
"### Costs \n",
"\n",
"\n",
"This tutorial uses billable components of Google Cloud:\n",
"\n",
"* Vertex AI\n",
"* Cloud Storage\n",
"\n",
"\n",
"Learn about [Vertex AI\n",
"pricing](https://cloud.google.com/vertex-ai/pricing) and [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": {
@@ -108,6 +142,25 @@
"Install *one time* the packages for executing the MLOps notebooks."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "1fd00fa70a2a"
},
"outputs": [],
"source": [
"import os\n",
"\n",
"# The Google Cloud Notebook product has specific requirements\n",
"IS_GOOGLE_CLOUD_NOTEBOOK = os.path.exists(\"/opt/deeplearning/metadata/env_version\")\n",
"\n",
"# Google Cloud Notebook requires dependencies to be installed with '--user'\n",
"USER_FLAG = \"\"\n",
"if IS_GOOGLE_CLOUD_NOTEBOOK:\n",
" USER_FLAG = \"--user\""
]
},
{
"cell_type": "code",
"execution_count": null,
@@ -116,24 +169,10 @@
},
"outputs": [],
"source": [
"ONCE_ONLY = False\n",
"if ONCE_ONLY:\n",
" ! pip3 install -U tensorflow==2.5 $USER_FLAG\n",
" ! pip3 install -U tensorflow-data-validation==1.2 $USER_FLAG\n",
" ! pip3 install -U tensorflow-transform==1.2 $USER_FLAG\n",
" ! pip3 install -U tensorflow-io==0.18 $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-aiplatform[tensorboard] $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-pipeline-components $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-bigquery $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-logging $USER_FLAG\n",
" ! pip3 install --upgrade apache-beam[gcp] $USER_FLAG\n",
" ! pip3 install --upgrade pyarrow $USER_FLAG\n",
" ! pip3 install --upgrade cloudml-hypertune $USER_FLAG\n",
" ! pip3 install --upgrade kfp $USER_FLAG\n",
" ! pip3 install --upgrade torchvision $USER_FLAG\n",
" ! pip3 install --upgrade rpy2 $USER_FLAG\n",
" ! pip3 install --upgrade python-tabulate $USER_FLAG\n",
" ! pip3 install -U opencv-python-headless==4.5.2.52 $USER_FLAG"
"! pip3 install -U tensorflow $USER_FLAG\n",
"! pip3 install --upgrade google-cloud-aiplatform[tensorboard] $USER_FLAG\n",
"! pip3 install --upgrade google-cloud-pipeline-components $USER_FLAG\n",
"! pip3 install --upgrade kfp $USER_FLAG\n"
]
},
{
@@ -184,6 +223,8 @@
},
"outputs": [],
"source": [
"import os\n",
"\n",
"PROJECT_ID = \"[your-project-id]\" # @param {type:\"string\"}"
]
},
@@ -241,7 +282,9 @@
},
"outputs": [],
"source": [
"REGION = \"us-central1\" # @param {type: \"string\"}"
"REGION = \"[your-region]\" # @param {type:\"string\"}\n",
"if REGION == \"[your-region]\":\n",
" REGION = \"us-central1\""
]
},
{
@@ -268,6 +311,81 @@
"TIMESTAMP = datetime.now().strftime(\"%Y%m%d%H%M%S\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "648aa9824ac6"
},
"source": [
"### Authenticate your Google Cloud account\n",
"\n",
"**If you are using Google Cloud Notebooks**, your environment is already\n",
"authenticated. Skip this step."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "fc52bba17ee3"
},
"source": [
"**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",
"1. In the Cloud Console, go to the [**Create service account key**\n",
" page](https://console.cloud.google.com/apis/credentials/serviceaccountkey).\n",
"\n",
"2. Click **Create service account**.\n",
"\n",
"3. In the **Service account name** field, enter a name, and\n",
" click **Create**.\n",
"\n",
"4. In the **Grant this service account access to project** section, click the **Role** drop-down list. Type \"Vertex AI\"\n",
"into the filter box, and select\n",
" **Vertex AI Administrator**. Type \"Storage Object Admin\" into the filter box, and select **Storage Object Admin**.\n",
"\n",
"5. Click *Create*. A JSON file that contains your key downloads to your\n",
"local environment.\n",
"\n",
"6. Enter the path to your service account key as the\n",
"`GOOGLE_APPLICATION_CREDENTIALS` variable in the cell below and run the cell."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "535223fa4b84"
},
"outputs": [],
"source": [
"import os\n",
"import sys\n",
"\n",
"# 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",
"# The Google Cloud Notebook product has specific requirements\n",
"IS_GOOGLE_CLOUD_NOTEBOOK = os.path.exists(\"/opt/deeplearning/metadata/env_version\")\n",
"\n",
"# If on Google Cloud Notebooks, then don't execute this code\n",
"if not IS_GOOGLE_CLOUD_NOTEBOOK:\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": {
@@ -291,7 +409,8 @@
},
"outputs": [],
"source": [
"BUCKET_NAME = \"gs://[your-bucket-name]\" # @param {type:\"string\"}"
"BUCKET_NAME = \"[your-bucket-name]\" # @param {type:\"string\"}\n",
"BUCKET_URI = f\"gs://{BUCKET_NAME}\""
]
},
{
@@ -302,8 +421,8 @@
},
"outputs": [],
"source": [
"if BUCKET_NAME == \"\" or BUCKET_NAME is None or BUCKET_NAME == \"gs://[your-bucket-name]\":\n",
" BUCKET_NAME = \"gs://\" + PROJECT_ID + \"aip-\" + TIMESTAMP"
"if BUCKET_URI == \"\" or BUCKET_URI is None or BUCKET_URI == \"gs://[your-bucket-name]\":\n",
" BUCKET_URI = \"gs://\" + PROJECT_ID + \"aip-\" + TIMESTAMP"
]
},
{
@@ -323,7 +442,7 @@
},
"outputs": [],
"source": [
"! gsutil mb -l $REGION $BUCKET_NAME"
"! gsutil mb -l $REGION $BUCKET_URI"
]
},
{
@@ -343,7 +462,7 @@
},
"outputs": [],
"source": [
"! gsutil ls -al $BUCKET_NAME"
"! gsutil ls -al $BUCKET_URI"
]
},
{
@@ -406,9 +525,9 @@
},
"outputs": [],
"source": [
"! gsutil iam ch serviceAccount:{SERVICE_ACCOUNT}:roles/storage.objectCreator $BUCKET_NAME\n",
"! gsutil iam ch serviceAccount:{SERVICE_ACCOUNT}:roles/storage.objectCreator $BUCKET_URI\n",
"\n",
"! gsutil iam ch serviceAccount:{SERVICE_ACCOUNT}:roles/storage.objectViewer $BUCKET_NAME"
"! gsutil iam ch serviceAccount:{SERVICE_ACCOUNT}:roles/storage.objectViewer $BUCKET_URI"
]
},
{
@@ -490,7 +609,7 @@
},
"outputs": [],
"source": [
"aip.init(project=PROJECT_ID, location=REGION, staging_bucket=BUCKET_NAME)"
"aip.init(project=PROJECT_ID, location=REGION, staging_bucket=BUCKET_URI)"
]
},
{
@@ -529,7 +648,7 @@
" int(os.getenv(\"IS_TESTING_TRAIN_GPU\")),\n",
" )\n",
"else:\n",
" TRAIN_GPU, TRAIN_NGPU = (aip.gapic.AcceleratorType.NVIDIA_TESLA_K80, 1)\n",
" TRAIN_GPU, TRAIN_NGPU = (None, None)\n",
"\n",
"if os.getenv(\"IS_TESTING_DEPLOY_GPU\"):\n",
" DEPLOY_GPU, DEPLOY_NGPU = (\n",
@@ -1017,7 +1136,7 @@
"! rm -f custom.tar custom.tar.gz\n",
"! tar cvf custom.tar custom\n",
"! gzip custom.tar\n",
"! gsutil cp custom.tar.gz $BUCKET_NAME/trainer_flowers.tar.gz"
"! gsutil cp custom.tar.gz $BUCKET_URI/trainer_flowers.tar.gz"
]
},
{
@@ -1077,9 +1196,20 @@
},
"outputs": [],
"source": [
"PIPELINE_ROOT = \"{}/pipeline_root/custom_icn_training\".format(BUCKET_NAME)\n",
"PIPELINE_ROOT = \"{}/pipeline_root/custom_icn_training\".format(BUCKET_URI)\n",
"DEPLOY_COMPUTE = \"n1-standard-4\"\n",
"\n",
"# If TRAIN_GPU is None, keeping gpu as no accelerator and accelerator_count as 0\n",
"gpu = \"ACCELERATOR_TYPE_UNSPECIFIED\"\n",
"accelerator_count = 0\n",
"\n",
"if TRAIN_GPU:\n",
" gpu = TRAIN_GPU.name\n",
" accelerator_count = 1\n",
"else:\n",
" gpu = \"ACCELERATOR_TYPE_UNSPECIFIED\" # Unspecified accelerator type, which means no accelerator.\n",
" accelerator_count = 0\n",
"\n",
"\n",
"@dsl.pipeline(\n",
" name=\"flowers-custom-training\",\n",
@@ -1121,8 +1251,8 @@
" args=[\"--epochs\", \"50\", \"--image-width\", \"32\", \"--image-height\", \"32\"],\n",
" replica_count=1,\n",
" machine_type=TRAIN_COMPUTE,\n",
" accelerator_type=TRAIN_GPU.name,\n",
" accelerator_count=TRAIN_NGPU,\n",
" accelerator_type=gpu,\n",
" accelerator_count=accelerator_count,\n",
" # Serving - As part of this operation, the model is registered to Vertex AI\n",
" model_serving_container_image_uri=DEPLOY_IMAGE,\n",
" model_display_name=display_name,\n",
@@ -1148,7 +1278,7 @@
" display_name=display_name,\n",
" ).after(batch_op)\n",
"\n",
" deploy_op = ModelDeployOp(\n",
" _ = ModelDeployOp(\n",
" model=training_op.outputs[\"model\"],\n",
" endpoint=endpoint_op.outputs[\"endpoint\"],\n",
" dedicated_resources_min_replica_count=1,\n",
@@ -1210,11 +1340,11 @@
"file_1 = test_item_1.split(\"/\")[-1]\n",
"file_2 = test_item_2.split(\"/\")[-1]\n",
"\n",
"! gsutil cp $test_item_1 $BUCKET_NAME/$file_1\n",
"! gsutil cp $test_item_2 $BUCKET_NAME/$file_2\n",
"! gsutil cp $test_item_1 $BUCKET_URI/$file_1\n",
"! gsutil cp $test_item_2 $BUCKET_URI/$file_2\n",
"\n",
"test_item_1 = BUCKET_NAME + \"/\" + file_1\n",
"test_item_2 = BUCKET_NAME + \"/\" + file_2"
"test_item_1 = BUCKET_URI + \"/\" + file_1\n",
"test_item_2 = BUCKET_URI + \"/\" + file_2"
]
},
{
@@ -1243,11 +1373,7 @@
},
"outputs": [],
"source": [
"import json\n",
"\n",
"import tensorflow as tf\n",
"\n",
"gcs_input_uri = BUCKET_NAME + \"/test.jsonl\"\n",
"gcs_input_uri = BUCKET_URI + \"/test.jsonl\"\n",
"with tf.io.gfile.GFile(gcs_input_uri, \"w\") as f:\n",
" data = {\"content\": test_item_1, \"mime_type\": \"image/jpeg\"}\n",
" f.write(json.dumps(data) + \"\\n\")\n",
@@ -1297,7 +1423,7 @@
" \"import_file\": IMPORT_FILE,\n",
" \"batch_files\": [gcs_input_uri],\n",
" \"display_name\": \"flowers\" + TIMESTAMP,\n",
" \"python_package\": f\"{BUCKET_NAME}/trainer_flowers.tar.gz\",\n",
" \"python_package\": f\"{BUCKET_URI}/trainer_flowers.tar.gz\",\n",
" \"python_module\": \"trainer.task\",\n",
" \"project\": PROJECT_ID,\n",
" \"region\": REGION,\n",
@@ -1361,25 +1487,53 @@
" + str(TASK_ID)\n",
" + \"/gcp_resources\"\n",
" )\n",
" EVAL_METRICS = (\n",
" PIPELINE_ROOT\n",
" + \"/\"\n",
" + PROJECT_NUMBER\n",
" + \"/\"\n",
" + JOB_ID\n",
" + \"/\"\n",
" + output_task_name\n",
" + \"_\"\n",
" + str(TASK_ID)\n",
" + \"/evaluation_metrics\"\n",
" )\n",
" if tf.io.gfile.exists(EXECUTE_OUTPUT):\n",
" ! gsutil cat $EXECUTE_OUTPUT\n",
" break\n",
" return EXECUTE_OUTPUT\n",
" elif tf.io.gfile.exists(GCP_RESOURCES):\n",
" ! gsutil cat $GCP_RESOURCES\n",
" break\n",
" return GCP_RESOURCES\n",
" elif tf.io.gfile.exists(EVAL_METRICS):\n",
" ! gsutil cat $EVAL_METRICS\n",
" return EVAL_METRICS\n",
"\n",
" return EXECUTE_OUTPUT\n",
" return None\n",
"\n",
"\n",
"print(\"image-dataset-create\")\n",
"artifacts = print_pipeline_output(pipeline, \"image-dataset-create\")\n",
"print(\"\\n\\n\")\n",
"output = !gsutil cat $artifacts\n",
"output = json.loads(output[0])\n",
"dataset_id = output[\"artifacts\"][\"dataset\"][\"artifacts\"][0][\"metadata\"][\"resourceName\"]\n",
"print(\"\\n\\n\")\n",
"print(\"custompythonpackagetrainingjob-run\")\n",
"artifacts = print_pipeline_output(pipeline, \"custompythonpackagetrainingjob-run\")\n",
"print(\"\\n\\n\")\n",
"output = !gsutil cat $artifacts\n",
"output = json.loads(output[0])\n",
"model_id = output[\"artifacts\"][\"model\"][\"artifacts\"][0][\"metadata\"][\"resourceName\"]\n",
"print(\"\\n\\n\")\n",
"print(\"endpoint-create\")\n",
"artifacts = print_pipeline_output(pipeline, \"endpoint-create\")\n",
"print(\"\\n\\n\")\n",
"output = !gsutil cat $artifacts\n",
"output = json.loads(output[0])\n",
"endpoint_id = output[\"artifacts\"][\"endpoint\"][\"artifacts\"][0][\"metadata\"][\n",
" \"resourceName\"\n",
"]\n",
"print(\"model-deploy\")\n",
"artifacts = print_pipeline_output(pipeline, \"model-deploy\")\n",
"print(\"\\n\\n\")\n",
@@ -1392,7 +1546,13 @@
" output[\"artifacts\"][\"batchpredictionjob\"][\"artifacts\"][0][\"metadata\"][\n",
" \"gcsOutputDirectory\"\n",
" ]\n",
")"
")\n",
"output = !gsutil cat $artifacts\n",
"output = json.loads(output[0])\n",
"batch_job_id = output[\"artifacts\"][\"batchpredictionjob\"][\"artifacts\"][0][\"metadata\"][\n",
" \"resourceName\"\n",
"]\n",
"print(\"\\n\\n\")"
]
},
{
@@ -1417,6 +1577,49 @@
"pipeline.delete()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "d614c239d74c"
},
"source": [
"#### Delete the Vertex AI Model, Endpoint and BatchPredictionJob resources\n",
"\n",
"Next, delete the daatset, undelpoy and delete the Vertex AI Model, Endpoint and BathPredictionJob resources."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "417791a1a7e2"
},
"outputs": [],
"source": [
"dataset = aip.ImageDataset(dataset_id)\n",
"try:\n",
" dataset.delete()\n",
"except:\n",
" pass\n",
"\n",
"\n",
"endpoint = aip.Endpoint(endpoint_id)\n",
"endpoint.undeploy_all()\n",
"try:\n",
" endpoint.delete()\n",
"except:\n",
" pass\n",
"\n",
"model = aip.Model(model_id)\n",
"try:\n",
" model.delete()\n",
"except:\n",
" pass\n",
"\n",
"batch_job = aip.BatchPredictionJob(batch_job_id)\n",
"batch_job.delete()"
]
},
{
"cell_type": "markdown",
"metadata": {
@@ -1459,7 +1662,6 @@
"outputs": [],
"source": [
"from google_cloud_pipeline_components.v1.custom_job import utils\n",
"from kfp.v2.dsl import Artifact\n",
"\n",
"\n",
"@component(\n",
@@ -1616,9 +1818,7 @@
},
"outputs": [],
"source": [
"from google_cloud_pipeline_components import aiplatform as gcc_aip\n",
"\n",
"PIPELINE_ROOT = \"{}/pipeline_root/custom_cifar10_training\".format(BUCKET_NAME)\n",
"PIPELINE_ROOT = \"{}/pipeline_root/custom_cifar10_training\".format(BUCKET_URI)\n",
"\n",
"\n",
"@dsl.pipeline(name=\"custom-model-training-sample-pipeline\")\n",
@@ -1632,6 +1832,8 @@
" location: str = REGION,\n",
" deploy_image: str = \"us-docker.pkg.dev/cloud-aiplatform/prediction/tf2-cpu.2-3:latest\",\n",
"):\n",
" from google_cloud_pipeline_components import aiplatform as gcc_aip\n",
"\n",
" custom_job_op = custom_job_training_op(\n",
" model_dir=model_dir,\n",
" lr=lr,\n",
@@ -1657,7 +1859,7 @@
" display_name=display_name,\n",
" ).after(model_upload_op)\n",
"\n",
" deploy_op = gcc_aip.ModelDeployOp(\n",
" _ = gcc_aip.ModelDeployOp(\n",
" model=model_upload_op.outputs[\"model\"],\n",
" endpoint=endpoint_op.outputs[\"endpoint\"],\n",
" dedicated_resources_min_replica_count=1,\n",
@@ -1735,46 +1937,6 @@
"PROJECT_NUMBER = pipeline.gca_resource.name.split(\"/\")[1]\n",
"print(PROJECT_NUMBER)\n",
"\n",
"\n",
"def print_pipeline_output(job, output_task_name):\n",
" JOB_ID = job.name\n",
" print(JOB_ID)\n",
" for _ in range(len(job.gca_resource.job_detail.task_details)):\n",
" TASK_ID = job.gca_resource.job_detail.task_details[_].task_id\n",
" EXECUTE_OUTPUT = (\n",
" PIPELINE_ROOT\n",
" + \"/\"\n",
" + PROJECT_NUMBER\n",
" + \"/\"\n",
" + JOB_ID\n",
" + \"/\"\n",
" + output_task_name\n",
" + \"_\"\n",
" + str(TASK_ID)\n",
" + \"/executor_output.json\"\n",
" )\n",
" GCP_RESOURCES = (\n",
" PIPELINE_ROOT\n",
" + \"/\"\n",
" + PROJECT_NUMBER\n",
" + \"/\"\n",
" + JOB_ID\n",
" + \"/\"\n",
" + output_task_name\n",
" + \"_\"\n",
" + str(TASK_ID)\n",
" + \"/gcp_resources\"\n",
" )\n",
" if tf.io.gfile.exists(EXECUTE_OUTPUT):\n",
" ! gsutil cat $EXECUTE_OUTPUT\n",
" break\n",
" elif tf.io.gfile.exists(GCP_RESOURCES):\n",
" ! gsutil cat $GCP_RESOURCES\n",
" break\n",
"\n",
" return EXECUTE_OUTPUT\n",
"\n",
"\n",
"print(\"custom-train-model\")\n",
"artifacts = print_pipeline_output(pipeline, \"custom-train-model\")\n",
"print(\"\\n\\n\")\n",
@@ -1784,9 +1946,17 @@
"print(\"model-upload\")\n",
"artifacts = print_pipeline_output(pipeline, \"model-upload\")\n",
"print(\"\\n\\n\")\n",
"output = !gsutil cat $artifacts\n",
"output = json.loads(output[0])\n",
"model_id = output[\"artifacts\"][\"model\"][\"artifacts\"][0][\"metadata\"][\"resourceName\"]\n",
"print(\"endpoint-create\")\n",
"artifacts = print_pipeline_output(pipeline, \"endpoint-create\")\n",
"print(\"\\n\\n\")\n",
"output = !gsutil cat $artifacts\n",
"output = json.loads(output[0])\n",
"endpoint_id = output[\"artifacts\"][\"endpoint\"][\"artifacts\"][0][\"metadata\"][\n",
" \"resourceName\"\n",
"]\n",
"print(\"model-deploy\")\n",
"artifacts = print_pipeline_output(pipeline, \"model-deploy\")\n",
"print(\"\\n\\n\")"
@@ -1814,6 +1984,49 @@
"pipeline.delete()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "93e69fc8b9e3"
},
"source": [
"#### Delete the Vertex AI Model and Endpoint resource\n",
"\n",
"Next, undelpoy and delete the Vertex AI Model and Endpoint resources."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "c9d18ae084b1"
},
"source": [
"#### Delete the Vertex model and endpoint\n",
"\n",
"Next, undelpoy and delete the Vertex Model and Endpoint resource."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "dccf71121d0b"
},
"outputs": [],
"source": [
"endpoint.undeploy_all()\n",
"try:\n",
" endpoint.delete()\n",
"except:\n",
" pass\n",
"\n",
"model = aip.Model(model_id)\n",
"try:\n",
" model.delete()\n",
"except:\n",
" pass"
]
},
{
"cell_type": "markdown",
"metadata": {
@@ -1825,17 +2038,7 @@
"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:\n",
"\n",
"- Dataset\n",
"- Pipeline\n",
"- Model\n",
"- Endpoint\n",
"- AutoML Training Job\n",
"- Batch Job\n",
"- Custom Job\n",
"- Hyperparameter Tuning Job\n",
"- Cloud Storage Bucket"
"Otherwise, you can delete the individual resources you created in this tutorial."
]
},
{
@@ -1846,61 +2049,10 @@
},
"outputs": [],
"source": [
"delete_all = True\n",
"delete_bucket = False\n",
"\n",
"if delete_all:\n",
" # Delete the dataset using the Vertex dataset object\n",
" try:\n",
" if \"dataset\" in globals():\n",
" dataset.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the model using the Vertex model object\n",
" try:\n",
" if \"model\" in globals():\n",
" model.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the endpoint using the Vertex endpoint object\n",
" try:\n",
" if \"endpoint\" in globals():\n",
" endpoint.undeploy_all()\n",
" endpoint.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the AutoML or Pipeline training job\n",
" try:\n",
" if \"dag\" in globals():\n",
" dag.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the custom training job\n",
" try:\n",
" if \"job\" in globals():\n",
" job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the batch prediction job using the Vertex batch prediction object\n",
" try:\n",
" if \"batch_predict_job\" in globals():\n",
" batch_predict_job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the hyperparameter tuning job using the Vertex hyperparameter tuning object\n",
" try:\n",
" if \"hpt_job\" in globals():\n",
" hpt_job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" if \"BUCKET_NAME\" in globals():\n",
" ! gsutil rm -r $BUCKET_NAME"
"if delete_bucket or os.getenv(\"IS_TESTING\"):\n",
" ! gsutil rm -r $BUCKET_URI"
]
}
],
@@ -32,6 +32,11 @@
"# E2E ML on GCP: MLOps stage 3 : formalization: get started with Hyperparameter Tuning pipeline components\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/stage3/get_started_with_hpt_pipeline_components.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/stage3/get_started_with_hpt_pipeline_components.ipynb\">\n",
" <img src=\"https://cloud.google.com/ml-engine/images/github-logo-32px.png\" alt=\"GitHub logo\">\n",
@@ -39,7 +44,8 @@
" </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/blob/main/notebooks/community/ml_ops/stage3/get_started_with_hpt_pipeline_components.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/community/ml_ops/stage3/get_started_with_hpt_pipeline_components.ipynb\">\n",
" <img src=\"https://lh3.googleusercontent.com/UiNooY4LUgW_oTvpsNhPpQzsstV5W8F7rYgxgGBD85cWJoLmrOzhVs_ksK_vgx40SHs7jCqkTkCk=e14-rj-sc0xffffff-h130-w32\" alt=\"Vertex AI logo\">\n",
" Open in Google Cloud Notebooks\n",
" </a>\n",
" </td>\n",
@@ -94,7 +100,20 @@
" - If the metrics exceed a specified threshold.\n",
" - Get the location of the model artifacts for the best tuned model.\n",
" - Upload the model artifacts to a `Vertex AI Model` resource.\n",
"- Execute a Vertex AI pipeline."
"- Execute a Vertex AI pipeline.\n",
"\n",
"### Costs \n",
"\n",
"This tutorial uses billable components of Google Cloud:\n",
"\n",
"* Vertex AI\n",
"* Cloud Storage\n",
"\n",
"Learn about [Vertex AI\n",
"pricing](https://cloud.google.com/vertex-ai/pricing) and [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."
]
},
{
@@ -112,28 +131,26 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "install_mlops"
"id": "LR9HQnyiMoT5"
},
"outputs": [],
"source": [
"ONCE_ONLY = False\n",
"if ONCE_ONLY:\n",
" ! pip3 install -U tensorflow==2.5 $USER_FLAG\n",
" ! pip3 install -U tensorflow-data-validation==1.2 $USER_FLAG\n",
" ! pip3 install -U tensorflow-transform==1.2 $USER_FLAG\n",
" ! pip3 install -U tensorflow-io==0.18 $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-aiplatform[tensorboard] $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-pipeline-components $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-bigquery $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-logging $USER_FLAG\n",
" ! pip3 install --upgrade apache-beam[gcp] $USER_FLAG\n",
" ! pip3 install --upgrade pyarrow $USER_FLAG\n",
" ! pip3 install --upgrade cloudml-hypertune $USER_FLAG\n",
" ! pip3 install --upgrade kfp $USER_FLAG\n",
" ! pip3 install --upgrade torchvision $USER_FLAG\n",
" ! pip3 install --upgrade rpy2 $USER_FLAG\n",
" ! pip3 install --upgrade python-tabulate $USER_FLAG\n",
" ! pip3 install -U opencv-python-headless==4.5.2.52 $USER_FLAG"
"! pip3 install -U tensorflow==2.5 $USER_FLAG\n",
"! pip3 install -U tensorflow-data-validation==1.2 $USER_FLAG\n",
"! pip3 install -U tensorflow-transform==1.2 $USER_FLAG\n",
"! pip3 install -U tensorflow-io==0.18 $USER_FLAG\n",
"! pip3 install --upgrade google-cloud-aiplatform[tensorboard] $USER_FLAG\n",
"! pip3 install --upgrade google-cloud-pipeline-components $USER_FLAG\n",
"# ! pip3 install --upgrade google-cloud-bigquery $USER_FLAG\n",
"# ! pip3 install --upgrade google-cloud-logging $USER_FLAG\n",
"# ! pip3 install --upgrade apache-beam[gcp] $USER_FLAG\n",
"# ! pip3 install --upgrade pyarrow $USER_FLAG\n",
"# ! pip3 install --upgrade cloudml-hypertune $USER_FLAG\n",
"! pip3 install --upgrade kfp $USER_FLAG\n",
"# ! pip3 install --upgrade torchvision $USER_FLAG\n",
"# ! pip3 install --upgrade rpy2 $USER_FLAG\n",
"# ! pip3 install --upgrade python-tabulate $USER_FLAG\n",
"# ! pip3 install -U opencv-python-headless==4.5.2.52 $USER_FLAG"
]
},
{
@@ -151,7 +168,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "restart"
"id": "VeBfL2pmMoT7"
},
"outputs": [],
"source": [
@@ -237,11 +254,14 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "region"
"id": "7iewOt9NMoT8"
},
"outputs": [],
"source": [
"REGION = \"us-central1\" # @param {type: \"string\"}"
"REGION = \"[your-region]\" # @param {type:\"string\"}\n",
"\n",
"if REGION == \"[your-region]\":\n",
" REGION = \"us-central1\" # @param {type: \"string\"}"
]
},
{
@@ -259,7 +279,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "timestamp"
"id": "Y-vhpfibMoT9"
},
"outputs": [],
"source": [
@@ -268,6 +288,39 @@
"TIMESTAMP = datetime.now().strftime(\"%Y%m%d%H%M%S\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "-V_6SvMUNUa1"
},
"outputs": [],
"source": [
"import os\n",
"import sys\n",
"\n",
"# 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",
"# The Google Cloud Notebook product has specific requirements\n",
"IS_GOOGLE_CLOUD_NOTEBOOK = os.path.exists(\"/opt/deeplearning/metadata/env_version\")\n",
"\n",
"# If on Google Cloud Notebooks, then don't execute this code\n",
"if not IS_GOOGLE_CLOUD_NOTEBOOK:\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": {
@@ -291,7 +344,7 @@
},
"outputs": [],
"source": [
"BUCKET_NAME = \"gs://[your-bucket-name]\" # @param {type:\"string\"}"
"BUCKET_URI = \"gs://[your-bucket-name]\" # @param {type:\"string\"}"
]
},
{
@@ -302,8 +355,8 @@
},
"outputs": [],
"source": [
"if BUCKET_NAME == \"\" or BUCKET_NAME is None or BUCKET_NAME == \"gs://[your-bucket-name]\":\n",
" BUCKET_NAME = \"gs://\" + PROJECT_ID + \"aip-\" + TIMESTAMP"
"if BUCKET_URI == \"\" or BUCKET_URI is None or BUCKET_URI == \"gs://[your-bucket-name]\":\n",
" BUCKET_URI = \"gs://\" + PROJECT_ID + \"aip-\" + TIMESTAMP"
]
},
{
@@ -319,11 +372,11 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "create_bucket"
"id": "2smRgc53MoT-"
},
"outputs": [],
"source": [
"! gsutil mb -l $REGION $BUCKET_NAME"
"! gsutil mb -l $REGION $BUCKET_URI"
]
},
{
@@ -339,11 +392,11 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "validate_bucket"
"id": "ME1Tr9j_MoT-"
},
"outputs": [],
"source": [
"! gsutil ls -al $BUCKET_NAME"
"! gsutil ls -al $BUCKET_URI"
]
},
{
@@ -361,7 +414,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "set_service_account"
"id": "EIivrR-3MoT-"
},
"outputs": [],
"source": [
@@ -378,13 +431,15 @@
"source": [
"if (\n",
" SERVICE_ACCOUNT == \"\"\n",
" or SERVICE_ACCOUNT is None\n",
" or SERVICE_ACCOUNT == \"[your-service-account]\"\n",
" or SERVICE_ACCOUNT is None\n",
"):\n",
" # Get your GCP project id from gcloud\n",
" shell_output = !gcloud auth list 2>/dev/null\n",
" SERVICE_ACCOUNT = shell_output[2].replace(\"*\", \"\").strip()\n",
" print(\"Service Account:\", SERVICE_ACCOUNT)"
" shell_output = ! gcloud projects describe $PROJECT_ID | sed -nre 's:.*projectNumber\\: (.*):\\1:p'\n",
" SERVICE_ACCOUNT = (\n",
" shell_output[0].replace(\"'\", \"\") + \"-compute@developer.gserviceaccount.com\"\n",
" )\n",
"\n",
"print(\"Service Account:\", SERVICE_ACCOUNT)"
]
},
{
@@ -402,13 +457,13 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "set_service_account:pipelines"
"id": "mtwsjYnIMoT_"
},
"outputs": [],
"source": [
"! gsutil iam ch serviceAccount:{SERVICE_ACCOUNT}:roles/storage.objectCreator $BUCKET_NAME\n",
"! gsutil iam ch serviceAccount:{SERVICE_ACCOUNT}:roles/storage.objectCreator $BUCKET_URI\n",
"\n",
"! gsutil iam ch serviceAccount:{SERVICE_ACCOUNT}:roles/storage.objectViewer $BUCKET_NAME"
"! gsutil iam ch serviceAccount:{SERVICE_ACCOUNT}:roles/storage.objectViewer $BUCKET_URI"
]
},
{
@@ -464,7 +519,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "import_tf"
"id": "DtTIHh_KMoUA"
},
"outputs": [],
"source": [
@@ -486,11 +541,11 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "init_aip:mbsdk"
"id": "sUFJPDW0MoUA"
},
"outputs": [],
"source": [
"aip.init(project=PROJECT_ID, staging_bucket=BUCKET_NAME)"
"aip.init(project=PROJECT_ID, staging_bucket=BUCKET_URI)"
]
},
{
@@ -519,17 +574,19 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "accelerators:training,prediction,ngpu,mbsdk"
"id": "A6dzi4cXMoUA"
},
"outputs": [],
"source": [
"import os\n",
"\n",
"if os.getenv(\"IS_TESTING_TRAIN_GPU\"):\n",
" TRAIN_GPU, TRAIN_NGPU = (\n",
" aip.gapic.AcceleratorType.NVIDIA_TESLA_K80,\n",
" int(os.getenv(\"IS_TESTING_TRAIN_GPU\")),\n",
" )\n",
"else:\n",
" TRAIN_GPU, TRAIN_NGPU = (aip.gapic.AcceleratorType.NVIDIA_TESLA_K80, 1)\n",
" TRAIN_GPU, TRAIN_NGPU = (None, None)\n",
"\n",
"if os.getenv(\"IS_TESTING_DEPLOY_GPU\"):\n",
" DEPLOY_GPU, DEPLOY_NGPU = (\n",
@@ -560,7 +617,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "container:prediction"
"id": "gxai072KMoUB"
},
"outputs": [],
"source": [
@@ -616,7 +673,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "machine:training,prediction"
"id": "LEYjL1ojMoUB"
},
"outputs": [],
"source": [
@@ -672,7 +729,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "examine_training_package"
"id": "UIoZdxPqMoUC"
},
"outputs": [],
"source": [
@@ -735,7 +792,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "taskpy_contents:dataset,horses_or_humans"
"id": "uk4MAGErMoUC"
},
"outputs": [],
"source": [
@@ -872,14 +929,14 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "tarball_training_script"
"id": "bHcLQLGkMoUD"
},
"outputs": [],
"source": [
"! rm -f custom.tar custom.tar.gz\n",
"! tar cvf custom.tar custom\n",
"! gzip custom.tar\n",
"! gsutil cp custom.tar.gz $BUCKET_NAME/trainer_horses_or_humans.tar.gz"
"! gsutil cp custom.tar.gz $BUCKET_URI/trainer_horses_or_humans.tar.gz"
]
},
{
@@ -912,7 +969,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "write_docker_file:training,tf-dlvm"
"id": "MaMK4AoBMoUE"
},
"outputs": [],
"source": [
@@ -945,7 +1002,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "name_container:training"
"id": "9qVJGXT2MoUE"
},
"outputs": [],
"source": [
@@ -965,7 +1022,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "build_container:training"
"id": "7-dkQP8hMoUE"
},
"outputs": [],
"source": [
@@ -987,7 +1044,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "register_container:training"
"id": "7-kh6QBLMoUF"
},
"outputs": [],
"source": [
@@ -1010,19 +1067,18 @@
"- Determine if the best trial results exceed a threshold\n",
" - Retrieve the hyperparameter values\n",
" - Determine Cloud Storage location of the best model\n",
" - Import the best model as an UnmanagedContainerModel artifact\n",
" - Upload the UnmanagedContainerModel artifact as a Vertex AI Model resource."
" - Upload the best model as a Vertex AI Model resource."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "create_hpt_pipeline:icn"
"id": "Epzlh8M-MoUF"
},
"outputs": [],
"source": [
"PIPELINE_ROOT = \"{}/pipeline_root/custom_icn_tuning\".format(BUCKET_NAME)\n",
"PIPELINE_ROOT = \"{}/pipeline_root/custom_icn_tuning\".format(BUCKET_URI)\n",
"\n",
"\n",
"@component(packages_to_install=[\"google-cloud-aiplatform\"])\n",
@@ -1043,6 +1099,7 @@
" study_spec_metrics: list,\n",
" study_spec_parameters: list,\n",
" threshold: float,\n",
" deploy_image: str,\n",
" max_trial_count: int = 5,\n",
" parallel_trial_count: int = 1,\n",
" base_output_directory: str = PIPELINE_ROOT,\n",
@@ -1053,10 +1110,10 @@
"\n",
" from google_cloud_pipeline_components.experimental import \\\n",
" hyperparameter_tuning_job\n",
" from google_cloud_pipeline_components.types import artifact_types\n",
" from google_cloud_pipeline_components.v1.hyperparameter_tuning_job import \\\n",
" HyperparameterTuningJobRunOp\n",
" from google_cloud_pipeline_components.v1.model import ModelUploadOp\n",
" from google_cloud_pipeline_components.types import artifact_types\n",
" from kfp.v2.components import importer_node\n",
"\n",
" tuning_op = HyperparameterTuningJobRunOp(\n",
@@ -1089,28 +1146,25 @@
" threshold_op.output == \"true\",\n",
" name=\"deploy_decision\",\n",
" ):\n",
" best_hyperparameters_op = hyperparameter_tuning_job.GetHyperparametersOp(\n",
" trial=best_trial_op.output\n",
" )\n",
" _ = hyperparameter_tuning_job.GetHyperparametersOp(trial=best_trial_op.output)\n",
"\n",
" model_dir_op = model_dir(base_output_directory, best_trial_op.output)\n",
"\n",
" unmanaged_model_importer = importer_node.importer(\n",
" artifact_uri=model_dir_op.output,\n",
" artifact_class=artifact_types.UnmanagedContainerModel,\n",
" metadata={\n",
" 'containerSpec': {\n",
" 'imageUri': DEPLOY_IMAGE\n",
" }\n",
" }\n",
" )\n",
" import_unmanaged_model_op = importer_node.importer(\n",
" artifact_uri=model_dir_op.output,\n",
" artifact_class=artifact_types.UnmanagedContainerModel,\n",
" metadata={\n",
" \"containerSpec\": {\n",
" \"imageUri\": DEPLOY_IMAGE,\n",
" },\n",
" },\n",
" ).after(model_dir_op)\n",
"\n",
" model_upload_op = ModelUploadOp(\n",
" display_name=display_name,\n",
" unmanaged_container_model=unmanaged_model_importer.outputs['artifact'],\n",
" _ = ModelUploadOp(\n",
" project=project,\n",
" location=region,\n",
" )"
" display_name=display_name,\n",
" unmanaged_container_model=import_unmanaged_model_op.outputs[\"artifact\"],\n",
" ).after(import_unmanaged_model_op)"
]
},
{
@@ -1140,13 +1194,26 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "create_hpt_specs"
"id": "aEm7RuwMMoUG"
},
"outputs": [],
"source": [
"from google_cloud_pipeline_components.experimental import \\\n",
" hyperparameter_tuning_job\n",
"\n",
"gpu = \"ACCELERATOR_TYPE_UNSPECIFIED\"\n",
"accelerator_count = 0\n",
"\n",
"if TRAIN_GPU:\n",
" gpu = TRAIN_GPU.name\n",
" accelerator_count = 1\n",
"\n",
"else:\n",
" gpu = \"ACCELERATOR_TYPE_UNSPECIFIED\"\n",
" accelerator_count = (\n",
" 0 # same problem with accelerator_count, if we keep is as \"None\" its not\n",
" )\n",
"\n",
"CMDARGS = [\n",
" \"--epochs=10\",\n",
"]\n",
@@ -1156,8 +1223,8 @@
" {\n",
" \"machine_spec\": {\n",
" \"machine_type\": TRAIN_COMPUTE,\n",
" \"accelerator_type\": TRAIN_GPU.name,\n",
" \"accelerator_count\": TRAIN_NGPU,\n",
" \"accelerator_type\": gpu,\n",
" \"accelerator_count\": accelerator_count,\n",
" },\n",
" \"replica_count\": 1,\n",
" \"container_spec\": {\"image_uri\": TRAIN_IMAGE, \"args\": CMDARGS},\n",
@@ -1206,7 +1273,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "run_pipeline:hpt"
"id": "42YNp9Y9MoUG"
},
"outputs": [],
"source": [
@@ -1224,6 +1291,7 @@
" \"study_spec_metrics\": metric_spec,\n",
" \"study_spec_parameters\": parameter_spec,\n",
" \"threshold\": 0.7,\n",
" \"deploy_image\": DEPLOY_IMAGE,\n",
" },\n",
" enable_caching=False,\n",
")\n",
@@ -1246,7 +1314,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "view_pipleline_results:hpt,horses_or_humans"
"id": "4X3jrdX1MoUH"
},
"outputs": [],
"source": [
@@ -1283,14 +1351,29 @@
" + str(TASK_ID)\n",
" + \"/gcp_resources\"\n",
" )\n",
" EVAL_METRICS = (\n",
" PIPELINE_ROOT\n",
" + \"/\"\n",
" + PROJECT_NUMBER\n",
" + \"/\"\n",
" + JOB_ID\n",
" + \"/\"\n",
" + output_task_name\n",
" + \"_\"\n",
" + str(TASK_ID)\n",
" + \"/evaluation_metrics\"\n",
" )\n",
" if tf.io.gfile.exists(EXECUTE_OUTPUT):\n",
" ! gsutil cat $EXECUTE_OUTPUT\n",
" break\n",
" return EXECUTE_OUTPUT\n",
" elif tf.io.gfile.exists(GCP_RESOURCES):\n",
" ! gsutil cat $GCP_RESOURCES\n",
" break\n",
" return GCP_RESOURCES\n",
" elif tf.io.gfile.exists(EVAL_METRICS):\n",
" ! gsutil cat $EVAL_METRICS\n",
" return EVAL_METRICS\n",
"\n",
" return EXECUTE_OUTPUT\n",
" return None\n",
"\n",
"\n",
"print(\"hyperparameter-tuning-job\")\n",
@@ -1343,7 +1426,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "delete_pipeline"
"id": "hS53o3FcMoUH"
},
"outputs": [],
"source": [
@@ -1363,14 +1446,6 @@
"\n",
"Otherwise, you can delete the individual resources you created in this tutorial:\n",
"\n",
"- Dataset\n",
"- Pipeline\n",
"- Model\n",
"- Endpoint\n",
"- AutoML Training Job\n",
"- Batch Job\n",
"- Custom Job\n",
"- Hyperparameter Tuning Job\n",
"- Cloud Storage Bucket"
]
},
@@ -1378,70 +1453,18 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "cleanup:mbsdk"
"id": "laAQFM4aoBm3"
},
"outputs": [],
"source": [
"delete_all = True\n",
"\n",
"if delete_all:\n",
" # Delete the dataset using the Vertex dataset object\n",
" try:\n",
" if \"dataset\" in globals():\n",
" dataset.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the model using the Vertex model object\n",
" try:\n",
" if \"model\" in globals():\n",
" model.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the endpoint using the Vertex endpoint object\n",
" try:\n",
" if \"endpoint\" in globals():\n",
" endpoint.undeploy_all()\n",
" endpoint.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the AutoML or Pipeline training job\n",
" try:\n",
" if \"dag\" in globals():\n",
" dag.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the custom training job\n",
" try:\n",
" if \"job\" in globals():\n",
" job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the batch prediction job using the Vertex batch prediction object\n",
" try:\n",
" if \"batch_predict_job\" in globals():\n",
" batch_predict_job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the hyperparameter tuning job using the Vertex hyperparameter tuning object\n",
" try:\n",
" if \"hpt_job\" in globals():\n",
" hpt_job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" if \"BUCKET_NAME\" in globals():\n",
" ! gsutil rm -r $BUCKET_NAME"
"if os.getenv(\"IS_TESTING\"):\n",
" ! gsutil rm -r $BUCKET_URI"
]
}
],
"metadata": {
"colab": {
"collapsed_sections": [],
"name": "get_started_with_hpt_pipeline_components.ipynb",
"toc_visible": true
},
@@ -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",
@@ -38,9 +38,16 @@
" 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/stage3/get_started_with_kubeflow_pipelines.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",
" \n",
" <td>\n",
" <a href=\"https://console.cloud.google.com/ai/platform/notebooks/deploy-notebook?download_url=https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage3/get_started_with_kubeflow_pipelines.ipynb\">\n",
" Open in Google Cloud Notebooks\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/community/ml_ops/stage3/get_started_with_kubeflow_pipelines.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",
@@ -67,7 +74,7 @@
"source": [
"### Objective\n",
"\n",
"In this tutorial, you learn how to use `Kubeflow Pipelines`.\n",
"In this tutorial, you learn how to use `Kubeflow Pipelines`(KFP).\n",
"\n",
"This tutorial uses the following Google Cloud ML services:\n",
"\n",
@@ -78,8 +85,17 @@
"- Building KFP lightweight Python function components.\n",
"- Assembling and compiling KFP components into a pipeline.\n",
"- Executing a KFP pipeline using Vertex AI Pipelines.\n",
"- Loading component and pipeline definitions from a source code repository.\n",
"- Building sequential, parallel, multiple output components.\n",
"- Building control flow into pipelines."
"- Building control flow into pipelines.\n",
"\n",
"### Costs\n",
"This tutorial uses billable components of Google Cloud:\n",
"\n",
"- Vertex AI\n",
"- Cloud Storage\n",
"\n",
"Learn about [Vertex AI pricing](https://cloud.google.com/vertex-ai/pricing) and [Cloud Storage pricing](https://cloud.google.com/storage/pricing) and use the [Pricing Calculator](https://cloud.google.com/products/calculator/) to generate a cost estimate based on your projected usage."
]
},
{
@@ -90,7 +106,7 @@
"source": [
"## Installations\n",
"\n",
"Install *one time* the packages for executing the MLOps notebooks."
"Install the following packages for executing this MLOps notebooks."
]
},
{
@@ -101,20 +117,20 @@
},
"outputs": [],
"source": [
"ONCE_ONLY = False\n",
"if ONCE_ONLY:\n",
" ! pip3 install -U tensorflow==2.5 $USER_FLAG\n",
" ! pip3 install -U tensorflow-data-validation==1.2 $USER_FLAG\n",
" ! pip3 install -U tensorflow-transform==1.2 $USER_FLAG\n",
" ! pip3 install -U tensorflow-io==0.18 $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-aiplatform[tensorboard] $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-pipeline-components $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-bigquery $USER_FLAG\n",
" ! pip3 install --upgrade google-cloud-logging $USER_FLAG\n",
" ! pip3 install --upgrade apache-beam[gcp] $USER_FLAG\n",
" ! pip3 install --upgrade pyarrow $USER_FLAG\n",
" ! pip3 install --upgrade cloudml-hypertune $USER_FLAG\n",
" ! pip3 install --upgrade kfp $USER_FLAG"
"import os\n",
"\n",
"# The Google Cloud Notebook product has specific requirements\n",
"IS_GOOGLE_CLOUD_NOTEBOOK = os.path.exists(\"/opt/deeplearning/metadata/env_version\")\n",
"\n",
"# Google Cloud Notebook requires dependencies to be installed with '--user'\n",
"USER_FLAG = \"\"\n",
"if IS_GOOGLE_CLOUD_NOTEBOOK:\n",
" USER_FLAG = \"--user\"\n",
" \n",
"! pip3 install tensorflow-io==0.18 $USER_FLAG -q\n",
"! pip3 install --upgrade google-cloud-aiplatform \\\n",
" pyarrow \\\n",
" kfp $USER_FLAG -q"
]
},
{
@@ -222,7 +238,10 @@
},
"outputs": [],
"source": [
"REGION = \"us-central1\" # @param {type: \"string\"}"
"REGION = \"[your-region]\" # @param {type: \"string\"}\n",
"\n",
"if REGION == \"[your-region]\":\n",
" REGION = \"us-central1\""
]
},
{
@@ -249,6 +268,63 @@
"TIMESTAMP = datetime.now().strftime(\"%Y%m%d%H%M%S\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "b5627478895e"
},
"source": [
"### Authenticate your Google Cloud account\n",
"\n",
"**If you are using Google Cloud 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\" into the filter box, and select **Vertex 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": "49ee8894d674"
},
"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 Google Cloud Notebook, then don't execute this code\n",
"if not os.path.exists(\"/opt/deeplearning/metadata/env_version\"):\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": {
@@ -272,7 +348,8 @@
},
"outputs": [],
"source": [
"BUCKET_NAME = \"gs://[your-bucket-name]\" # @param {type:\"string\"}"
"BUCKET_NAME = \"[your-bucket-name]\" # @param {type:\"string\"}\n",
"BUCKET_URI = \"gs://{}\".format(BUCKET_NAME)"
]
},
{
@@ -283,8 +360,8 @@
},
"outputs": [],
"source": [
"if BUCKET_NAME == \"\" or BUCKET_NAME is None or BUCKET_NAME == \"gs://[your-bucket-name]\":\n",
" BUCKET_NAME = \"gs://\" + PROJECT_ID + \"aip-\" + TIMESTAMP"
"if BUCKET_URI == \"\" or BUCKET_URI is None or BUCKET_URI == \"gs://[your-bucket-name]\":\n",
" BUCKET_URI = \"gs://\" + PROJECT_ID + \"aip-\" + TIMESTAMP"
]
},
{
@@ -304,7 +381,7 @@
},
"outputs": [],
"source": [
"! gsutil mb -l $REGION $BUCKET_NAME"
"! gsutil mb -l $REGION $BUCKET_URI"
]
},
{
@@ -324,7 +401,7 @@
},
"outputs": [],
"source": [
"! gsutil ls -al $BUCKET_NAME"
"! gsutil ls -al $BUCKET_URI"
]
},
{
@@ -335,7 +412,7 @@
"source": [
"#### Service Account\n",
"\n",
"**If you don't know your service account**, try to get your service account using `gcloud` command by executing the second cell below."
"You use a service account to create Vertex AI Pipeline jobs. If you do not want to use your project's Compute Engine service account, set `SERVICE_ACCOUNT` to another service account ID."
]
},
{
@@ -359,13 +436,15 @@
"source": [
"if (\n",
" SERVICE_ACCOUNT == \"\"\n",
" or SERVICE_ACCOUNT is None\n",
" or SERVICE_ACCOUNT == \"[your-service-account]\"\n",
" or SERVICE_ACCOUNT is None\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",
" print(\"Service Account:\", SERVICE_ACCOUNT)"
" shell_output = ! gcloud projects describe $PROJECT_ID | sed -nre 's:.*projectNumber\\: (.*):\\1:p'\n",
" SERVICE_ACCOUNT = (\n",
" shell_output[0].replace(\"'\", \"\") + \"-compute@developer.gserviceaccount.com\"\n",
" )\n",
"\n",
"print(\"Service Account:\", SERVICE_ACCOUNT)"
]
},
{
@@ -376,7 +455,7 @@
"source": [
"#### Set service account access for Vertex AI Pipelines\n",
"\n",
"Run the following commands to grant your service account access to read and write pipeline artifacts in the bucket that you created in the previous step -- you only need to run these once per service account."
"Run the following commands to grant your service account access to read and write pipeline artifacts in the bucket that you created in the previous step. You only need to run this step once per service account."
]
},
{
@@ -387,9 +466,9 @@
},
"outputs": [],
"source": [
"! gsutil iam ch serviceAccount:{SERVICE_ACCOUNT}:roles/storage.objectCreator $BUCKET_NAME\n",
"! gsutil iam ch serviceAccount:{SERVICE_ACCOUNT}:roles/storage.objectCreator $BUCKET_URI\n",
"\n",
"! gsutil iam ch serviceAccount:{SERVICE_ACCOUNT}:roles/storage.objectViewer $BUCKET_NAME"
"! gsutil iam ch serviceAccount:{SERVICE_ACCOUNT}:roles/storage.objectViewer $BUCKET_URI"
]
},
{
@@ -398,10 +477,7 @@
"id": "setup_vars"
},
"source": [
"### Set up variables\n",
"\n",
"Next, set up some variables used throughout the tutorial.\n",
"### Import libraries and define constants"
"### Import libraries"
]
},
{
@@ -411,42 +487,11 @@
"id": "import_aip:mbsdk"
},
"outputs": [],
"source": [
"import google.cloud.aiplatform as aip"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "import_tf"
},
"source": [
"#### Import TensorFlow\n",
"\n",
"Import the TensorFlow package into your Python environment."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "import_tf"
},
"outputs": [],
"source": [
"import tensorflow as tf"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "import_kfp:namedtuple"
},
"outputs": [],
"source": [
"from typing import NamedTuple\n",
"\n",
"import google.cloud.aiplatform as aiplatform\n",
"import tensorflow as tf\n",
"from kfp import dsl\n",
"from kfp.v2 import compiler\n",
"from kfp.v2.dsl import component"
@@ -471,7 +516,7 @@
},
"outputs": [],
"source": [
"aip.init(project=PROJECT_ID, staging_bucket=BUCKET_NAME)"
"aiplatform.init(project=PROJECT_ID, staging_bucket=BUCKET_URI)"
]
},
{
@@ -486,14 +531,14 @@
"\n",
" 1. Design the pipeline workflow.\n",
" 2. Compile the pipeline.\n",
" 3. Schedule execution (or run now) the pipeline.\n",
" 3. Schedule pipeline execution (or run now).\n",
" 4. Get the pipeline results.\n",
"\n",
"Pipelines are designed using language specific domain specific language (DSL). Vertex AI Pipelines support both KFP DSL and TFX DSL for designing pipelines.\n",
"Pipelines are designed using domain specific language (DSL). Vertex AI Pipelines support both KFP DSL and TFX DSL for designing pipelines.\n",
"\n",
"In addition to designing components, you can use a wide variety of pre-built Google Cloud Pipeline Components for Vertex AI services.\n",
"\n",
"Learn more about [Building a pipeline](https://cloud.google.com/vertex-ai/docs/pipelines/build-pipeline)"
"Learn more about [Building a pipeline](https://cloud.google.com/vertex-ai/docs/pipelines/build-pipeline)."
]
},
{
@@ -502,9 +547,9 @@
"id": "pipelines_intro:helloworld"
},
"source": [
"## Basic pipeline introduction\n",
"## Basic pipeline\n",
"\n",
"This demonstrates the basics of constructing and executing a pipeline. You do the following:\n",
"This step demonstrates the basics of constructing and executing a pipeline. You do the following:\n",
"\n",
"1. Design a simple Python function based component to output the input string.\n",
"2. Construct a pipeline that uses the component.\n",
@@ -522,8 +567,8 @@
"\n",
"To create a KFP component from a Python function, you add the KFP DSL decorator `@component` to the function. In this example, the decorator takes the following parameters:\n",
"\n",
"- `output_component_file`: (optional) write the component description to a YAML file such that the component is portable.\n",
"- `base_image`: (optional): The interpreter for executing the Python function. By default it is Python 3.7"
"- `output_component_file`(optional): write the component description to a YAML file such that the component is portable.\n",
"- `base_image`(optional): The interpreter for executing the Python function. By default it is Python 3.7"
]
},
{
@@ -566,7 +611,7 @@
},
"outputs": [],
"source": [
"PIPELINE_ROOT = \"{}/pipeline_root/hello_world\".format(BUCKET_NAME)\n",
"PIPELINE_ROOT = \"{}/pipeline_root/hello_world\".format(BUCKET_URI)\n",
"\n",
"\n",
"@dsl.pipeline(\n",
@@ -575,7 +620,8 @@
" pipeline_root=PIPELINE_ROOT,\n",
")\n",
"def pipeline(text: str = \"hi there\"):\n",
" hello_world_task = hello_world(text)"
" hello_world_task = hello_world(text)\n",
" return hello_world_task"
]
},
{
@@ -588,7 +634,7 @@
"\n",
"Once the design of the pipeline is completed, the next step is to compile it. The pipeline definition is compiled into a JSON formatted file, which is transportable and can be interpreted by both KFP and Vertex AI Pipelines.\n",
"\n",
"You compile the pipeline with the method Compiler().compile(), with the following parameters:\n",
"Compile the pipeline with the Compiler().compile() method using the following parameters:\n",
"\n",
"- `pipeline_func`: The corresponding DSL function that defines the pipeline.\n",
"- `package_path`: The JSON file to write the transportable compiled pipeline to."
@@ -615,14 +661,14 @@
"source": [
"### Execute the hello world pipeline\n",
"\n",
"Now that the pipeline is compiled, you can execute by:\n",
"Now that the pipeline is compiled, you can execute it by:\n",
"\n",
"- Create a Vertex AI PipelineJob, with the following parameters:\n",
"- Creating a Vertex AI PipelineJob with the following parameters:\n",
" - `display_name`: The human readable name for the job.\n",
" - `template_path`: Thee compiled JSON pipeline definition.\n",
" - `template_path`: The compiled JSON pipeline definition.\n",
" - `pipeline_root`: Where to write output artifacts to.\n",
"\n",
"Click on the generated link below `INFO:google.cloud.aiplatform.pipeline_jobs:View Pipeline Job:` to see your run in the Cloud Console."
"Click on the generated link below `INFO:google.cloud.aiplatform.pipeline_jobs:View Pipeline Job:` to see your job run in the Cloud Console."
]
},
{
@@ -633,7 +679,7 @@
},
"outputs": [],
"source": [
"pipeline = aip.PipelineJob(\n",
"pipeline = aiplatform.PipelineJob(\n",
" display_name=\"hello_world\",\n",
" template_path=\"hello_world.json\",\n",
" pipeline_root=PIPELINE_ROOT,\n",
@@ -694,14 +740,29 @@
" + str(TASK_ID)\n",
" + \"/gcp_resources\"\n",
" )\n",
" EVAL_METRICS = (\n",
" PIPELINE_ROOT\n",
" + \"/\"\n",
" + PROJECT_NUMBER\n",
" + \"/\"\n",
" + JOB_ID\n",
" + \"/\"\n",
" + output_task_name\n",
" + \"_\"\n",
" + str(TASK_ID)\n",
" + \"/evaluation_metrics\"\n",
" )\n",
" if tf.io.gfile.exists(EXECUTE_OUTPUT):\n",
" ! gsutil cat $EXECUTE_OUTPUT\n",
" break\n",
" return EXECUTE_OUTPUT\n",
" elif tf.io.gfile.exists(GCP_RESOURCES):\n",
" ! gsutil cat $GCP_RESOURCES\n",
" break\n",
" return GCP_RESOURCES\n",
" elif tf.io.gfile.exists(EVAL_METRICS):\n",
" ! gsutil cat $EVAL_METRICS\n",
" return EVAL_METRICS\n",
"\n",
" return EXECUTE_OUTPUT\n",
" return None\n",
"\n",
"\n",
"print_pipeline_output(pipeline, \"hello-world\")"
@@ -715,7 +776,7 @@
"source": [
"### Delete a pipeline job\n",
"\n",
"After a pipeline job is completed, you can delete the pipeline job with the method `delete()`. Prior to completion, a pipeline job can be canceled with the method `cancel()`."
"After a pipeline job is completed, you can delete the pipeline job with the `delete()` method. Prior to completion, a pipeline job can be canceled with the method `cancel()`."
]
},
{
@@ -741,7 +802,7 @@
"\n",
" hello_world_op = components.load_component_from_file('./hello_world.yaml').\n",
"\n",
"You can also use the load_component_from_url method, if your component YAML file is stored online, such as if in a git repo."
"You can also use the `load_component_from_url` method, if your component YAML file is stored online, such as in a git repository."
]
},
{
@@ -754,7 +815,7 @@
"source": [
"from kfp import components\n",
"\n",
"PIPELINE_ROOT = \"{}/pipeline_root/hello_world-v2\".format(BUCKET_NAME)\n",
"PIPELINE_ROOT = \"{}/pipeline_root/hello_world-v2\".format(BUCKET_URI)\n",
"\n",
"hello_world_op = components.load_component_from_file(\"./hello_world.yaml\")\n",
"\n",
@@ -765,12 +826,13 @@
" pipeline_root=PIPELINE_ROOT,\n",
")\n",
"def pipeline(text: str = \"hi there\"):\n",
" hellow_world_task = hello_world_op(text)\n",
" hello_world_task = hello_world_op(text)\n",
" return hello_world_task\n",
"\n",
"\n",
"compiler.Compiler().compile(pipeline_func=pipeline, package_path=\"hello_world-v2.json\")\n",
"\n",
"pipeline = aip.PipelineJob(\n",
"pipeline = aiplatform.PipelineJob(\n",
" display_name=\"hello_world-v2\",\n",
" template_path=\"hello_world-v2.json\",\n",
" pipeline_root=PIPELINE_ROOT,\n",
@@ -789,7 +851,74 @@
"source": [
"### Delete a pipeline job\n",
"\n",
"After a pipeline job is completed, you can delete the pipeline job with the method `delete()`. Prior to completion, a pipeline job can be canceled with the method `cancel()`."
"After a pipeline job is completed, you can delete the pipeline job with the `delete()` method. Prior to completion, a pipeline job can be canceled with the method `cancel()`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "delete_pipeline"
},
"outputs": [],
"source": [
"pipeline.delete()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "load_component_pipeline_git:helloworld"
},
"source": [
"### Loading components and pipeline YAML definitions from source control\n",
"\n",
"By storing the component and pipeline definitions in a source repository, like Github, you can version control your components and pipelines, as follows:\n",
"\n",
"- Use the method `load_component_from_url()`.\n",
"\n",
"- Pull the raw file format version from the repo. For github, that will be in the form of:\n",
"\n",
" https://raw.githubusercontent.com/....\n",
"\n",
"- Specify the version of the component/pipeline. For github, that will be the branch."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "load_component_pipeline_git:helloworld"
},
"outputs": [],
"source": [
"VERSION = \"main\"\n",
"hello_world_op = components.load_component_from_url(\n",
" f\"https://raw.githubusercontent.com/GoogleCloudPlatform/vertex-ai-samples/{VERSION}/notebooks/community/ml_ops/stage3/src/hello_world.yaml\"\n",
")\n",
"\n",
"! wget https://raw.githubusercontent.com/GoogleCloudPlatform/vertex-ai-samples/{VERSION}/notebooks/community/ml_ops/stage3/src/hello_world.json -O hello_git_example.json\n",
"\n",
"pipeline = aiplatform.PipelineJob(\n",
" display_name=\"hello_world-git\",\n",
" template_path=\"hello_git_example.json\",\n",
" pipeline_root=PIPELINE_ROOT,\n",
")\n",
"\n",
"pipeline.run()\n",
"\n",
"! rm -f hello_git_example.json"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "delete_pipeline"
},
"source": [
"### Delete a pipeline job\n",
"\n",
"After a pipeline job is completed, you can delete the pipeline job with the `delete()` method. Prior to completion, a pipeline job can be canceled with the method `cancel()`."
]
},
{
@@ -829,7 +958,7 @@
" return np.mean(values)\n",
"\n",
"\n",
"PIPELINE_ROOT = \"{}/pipeline_root/numpy_mean\".format(BUCKET_NAME)\n",
"PIPELINE_ROOT = \"{}/pipeline_root/numpy_mean\".format(BUCKET_URI)\n",
"\n",
"\n",
"@dsl.pipeline(\n",
@@ -837,11 +966,12 @@
")\n",
"def pipeline(values: list = [2, 3]):\n",
" numpy_task = numpy_mean(values)\n",
" return numpy_task\n",
"\n",
"\n",
"compiler.Compiler().compile(pipeline_func=pipeline, package_path=\"numpy_mean.json\")\n",
"\n",
"pipeline = aip.PipelineJob(\n",
"pipeline = aiplatform.PipelineJob(\n",
" display_name=\"numpy_mean\",\n",
" template_path=\"numpy_mean.json\",\n",
" pipeline_root=PIPELINE_ROOT,\n",
@@ -862,7 +992,7 @@
"source": [
"### Delete a pipeline job\n",
"\n",
"After a pipeline job is completed, you can delete the pipeline job with the method `delete()`. Prior to completion, a pipeline job can be canceled with the method `cancel()`."
"After a pipeline job is completed, you can delete the pipeline job with the `delete()` method. Prior to completion, a pipeline job can be canceled with the method `cancel()`."
]
},
{
@@ -897,7 +1027,7 @@
},
"outputs": [],
"source": [
"PIPELINE_ROOT = \"{}/pipeline_root/add_div2\".format(BUCKET_NAME)\n",
"PIPELINE_ROOT = \"{}/pipeline_root/add_div2\".format(BUCKET_URI)\n",
"\n",
"\n",
"@component(output_component_file=\"add.yaml\", base_image=\"python:3.9\")\n",
@@ -916,11 +1046,12 @@
"def pipeline(v1: int = 4, v2: int = 5):\n",
" add_task = add(v1, v2)\n",
" div2_task = div_by_2(add_task.output)\n",
" return div2_task\n",
"\n",
"\n",
"compiler.Compiler().compile(pipeline_func=pipeline, package_path=\"add_div2.json\")\n",
"\n",
"pipeline = aip.PipelineJob(\n",
"pipeline = aiplatform.PipelineJob(\n",
" display_name=\"add_div2\",\n",
" template_path=\"add_div2.json\",\n",
" pipeline_root=PIPELINE_ROOT,\n",
@@ -941,7 +1072,7 @@
"source": [
"### Delete a pipeline job\n",
"\n",
"After a pipeline job is completed, you can delete the pipeline job with the method `delete()`. Prior to completion, a pipeline job can be canceled with the method `cancel()`."
"After a pipeline job is completed, you can delete the pipeline job with the `delete()` method. Prior to completion, a pipeline job can be canceled with the method `cancel()`."
]
},
{
@@ -963,7 +1094,7 @@
"source": [
"### Multiple output pipeline\n",
"\n",
"Next, you design and execute a pipeline where a first component has multiple outputs, which are then used as inputs to the next component. To distinquish between the outputs, when used as inputs to the next component, you do:\n",
"Next, you design and execute a pipeline where a first component has multiple outputs, which are then used as inputs to the next component. To distinguish between the outputs, when used as inputs to the next component, you follow:\n",
"\n",
"1. Set the function return type to `NamedTuple`.\n",
"2. In NamedTuple, specify a name and type for each output, in the specified order.\n",
@@ -978,7 +1109,7 @@
},
"outputs": [],
"source": [
"PIPELINE_ROOT = \"{}/pipeline_root/multi_output\".format(BUCKET_NAME)\n",
"PIPELINE_ROOT = \"{}/pipeline_root/multi_output\".format(BUCKET_URI)\n",
"\n",
"\n",
"@component()\n",
@@ -1012,11 +1143,12 @@
" multi_output_task.outputs[\"output_1\"],\n",
" multi_output_task.outputs[\"output_2\"],\n",
" )\n",
" return concat_task\n",
"\n",
"\n",
"compiler.Compiler().compile(pipeline_func=pipeline, package_path=\"multi_output.json\")\n",
"\n",
"pipeline = aip.PipelineJob(\n",
"pipeline = aiplatform.PipelineJob(\n",
" display_name=\"multi-output\",\n",
" template_path=\"multi_output.json\",\n",
" pipeline_root=PIPELINE_ROOT,\n",
@@ -1037,7 +1169,7 @@
"source": [
"### Delete a pipeline job\n",
"\n",
"After a pipeline job is completed, you can delete the pipeline job with the method `delete()`. Prior to completion, a pipeline job can be canceled with the method `cancel()`."
"After a pipeline job is completed, you can delete the pipeline job with the `delete()` method. Prior to completion, a pipeline job can be canceled with the method `cancel()`."
]
},
{
@@ -1059,9 +1191,9 @@
"source": [
"## Parallel tasks in component\n",
"\n",
"Next, you design and execute a pipeline with parallel tasks. In this example, one parallel task adds up a list of integers and another substracts them. Note that the compiler knows these two tasks can be ran in parallel, because their input is not dependent on the output of the other task.\n",
"Next, you design and execute a pipeline with parallel tasks. In this example, one parallel task adds up a list of integers and another substracts them. Note that the compiler knows these two tasks can be run in parallel, because their input is not dependent on the output of the other task.\n",
"\n",
"Finally, the add task waits on the two parallel tasks to complete, and then adds together the two outputs."
"Finally, the `add_int` task waits on the two parallel tasks to complete, and then adds together the two outputs."
]
},
{
@@ -1072,14 +1204,14 @@
},
"outputs": [],
"source": [
"PIPELINE_ROOT = \"{}/pipeline_root/parallel\".format(BUCKET_NAME)\n",
"PIPELINE_ROOT = \"{}/pipeline_root/parallel\".format(BUCKET_URI)\n",
"\n",
"\n",
"@component()\n",
"def add_list(values: list) -> int:\n",
" ret = 0\n",
" for value in values:\n",
" ret += 1\n",
" ret = value + ret\n",
" return ret\n",
"\n",
"\n",
@@ -1087,12 +1219,12 @@
"def sub_list(values: list) -> int:\n",
" ret = 0\n",
" for value in values:\n",
" ret -= 1\n",
" ret = value - ret\n",
" return ret\n",
"\n",
"\n",
"@component()\n",
"def add(value1: int, value2: int) -> int:\n",
"def add_int(value1: int, value2: int) -> int:\n",
" return value1 + value2\n",
"\n",
"\n",
@@ -1102,12 +1234,13 @@
"def pipeline(values: list = [1, 2, 3]):\n",
" add_list_task = add_list(values)\n",
" sub_list_task = sub_list(values)\n",
" add_task = add(add_list_task.output, sub_list_task.output)\n",
" add_task = add_int(add_list_task.output, sub_list_task.output)\n",
" return add_task\n",
"\n",
"\n",
"compiler.Compiler().compile(pipeline_func=pipeline, package_path=\"parallel.json\")\n",
"\n",
"pipeline = aip.PipelineJob(\n",
"pipeline = aiplatform.PipelineJob(\n",
" display_name=\"parallel\",\n",
" template_path=\"parallel.json\",\n",
" pipeline_root=PIPELINE_ROOT,\n",
@@ -1128,7 +1261,7 @@
"source": [
"### Delete a pipeline job\n",
"\n",
"After a pipeline job is completed, you can delete the pipeline job with the method `delete()`. Prior to completion, a pipeline job can be canceled with the method `cancel()`."
"After a pipeline job is completed, you can delete the pipeline job with the `delete()` method. Prior to completion, a pipeline job can be canceled with the method `cancel()`."
]
},
{
@@ -1150,7 +1283,7 @@
"source": [
"## Control flow in pipeline\n",
"\n",
"While Python control statements, e.g., if/else, for, can be used in a component, they cannot be used in the pipeline function. Each task in the pipeline function runs as a node in a graph. Thus a control flow statement also has to run as a graph node. To support this, KFP provides a set of DSL statements that implement control flow as a graph node."
"While Python control statements(e.g., if/else, for) can be used in a component, they cannot be used in a pipeline function. Each task in a pipeline function runs as a node in a graph. Thus a control flow statement also has to run as a graph node. To support this, KFP provides a set of DSL statements that implement control flow as a graph node."
]
},
{
@@ -1161,7 +1294,7 @@
"source": [
"### dsl.ParallelFor\n",
"\n",
"The statement `dsl.ParallelFor()` implements a for loop, where each iteration in the for loop runs in parallel."
"The statement `dsl.ParallelFor()` implements a `for` loop, where each iteration in the `for` loop runs in parallel."
]
},
{
@@ -1172,7 +1305,7 @@
},
"outputs": [],
"source": [
"PIPELINE_ROOT = \"{}/pipeline_root/parallel_for\".format(BUCKET_NAME)\n",
"PIPELINE_ROOT = \"{}/pipeline_root/parallel_for\".format(BUCKET_URI)\n",
"\n",
"\n",
"@component()\n",
@@ -1194,11 +1327,12 @@
" with dsl.ParallelFor(values) as item:\n",
" output = double(item).output\n",
" echo_task = echo(output)\n",
" return echo_task\n",
"\n",
"\n",
"compiler.Compiler().compile(pipeline_func=pipeline, package_path=\"parallel_for.json\")\n",
"\n",
"pipeline = aip.PipelineJob(\n",
"pipeline = aiplatform.PipelineJob(\n",
" display_name=\"parallel-for\",\n",
" template_path=\"parallel_for.json\",\n",
" pipeline_root=PIPELINE_ROOT,\n",
@@ -1219,7 +1353,7 @@
"source": [
"### Delete a pipeline job\n",
"\n",
"After a pipeline job is completed, you can delete the pipeline job with the method `delete()`. Prior to completion, a pipeline job can be canceled with the method `cancel()`."
"After a pipeline job is completed, you can delete the pipeline job with the `delete()` method. Prior to completion, a pipeline job can be canceled with the method `cancel()`."
]
},
{
@@ -1241,7 +1375,15 @@
"source": [
"### dsl.Condition\n",
"\n",
"The statement `dsl.Condition()` implements an `if` statement. There is no support for an `else` or `elif` statement. You use a separate `dsl.Condition()` for each value you want to test for. For example, if the output from a task is `True` or `False`, you will have two `dsl.Condition()` statements, one for True and one for False."
"The statement `dsl.Condition()` implements an `if` statement. There is no support for an `else` or `elif` statement. You use a separate `dsl.Condition()` for each value you want to test for. For example, if the output from a task is `1` or `0`, you will have two `dsl.Condition()` statements, one for 1 and one for 0.\n",
"\n",
"The condition in `dsl.Condition()` is evaluated at run-time, not compile time. As such it is not Python code anymore. The condition is of type `ConditionOperator`. This operator has three parts:\n",
"\n",
"1. PipelineParam or task output\n",
"2. == or !=\n",
"3. string or integer value\n",
"\n",
"A `dsl.Condition()` can be named using the `name` parameter while defining the condition."
]
},
{
@@ -1280,11 +1422,12 @@
" task = heads()\n",
" with dsl.Condition(flip_task.output == 0, name=\"false_clause\"):\n",
" task = tails()\n",
" return task\n",
"\n",
"\n",
"compiler.Compiler().compile(pipeline_func=pipeline, package_path=\"condition.json\")\n",
"\n",
"pipeline = aip.PipelineJob(\n",
"pipeline = aiplatform.PipelineJob(\n",
" display_name=\"condition\",\n",
" template_path=\"condition.json\",\n",
" pipeline_root=PIPELINE_ROOT,\n",
@@ -1305,7 +1448,7 @@
"source": [
"### Delete a pipeline job\n",
"\n",
"After a pipeline job is completed, you can delete the pipeline job with the method `delete()`. Prior to completion, a pipeline job can be canceled with the method `cancel()`."
"After a pipeline job is completed, you can delete the pipeline job with the `delete()` method. Prior to completion, a pipeline job can be canceled with the method `cancel()`."
]
},
{
@@ -1325,16 +1468,14 @@
"id": "pipeline_errata"
},
"source": [
"## Errata\n",
"\n",
"### Caching in pipeline components\n",
"\n",
"When running a pipeline with Vertex AI Pipelines, the outcome state of each task is cached. With caching, if the pipeline is ran again, and the compiled definition of the task and state has not changed, the cached output will be used instead of running the task again.\n",
"When running a pipeline with Vertex AI Pipelines, the outcome state of each task is cached. With caching, if the pipeline is run again, and the compiled definition of the task and state has not changed, the cached output will be used instead of running the task again.\n",
"\n",
"To override caching, i.e., forceable run the task, you set the parameter `enable_caching` to `False` when creating the Vertex AI Pipeline job.\n",
"To override caching, i.e., force run the task, you set the parameter `enable_caching` to `False` when creating the Vertex AI Pipeline job.\n",
"\n",
"```\n",
"pipeline = aip.PipelineJob(\n",
"pipeline = aiplatform.PipelineJob(\n",
" display_name=\"example\",\n",
" template_path=\"example.json\",\n",
" pipeline_root=PIPELINE_ROOT,\n",
@@ -1344,11 +1485,11 @@
"\n",
"### Asynchronous execution of pipeline\n",
"\n",
"When running a pipeline with the method `run()`, the pipeline is ran synchronously. To run asynchronously, you use the method `submit()`. Once the job has started, your Python script can continue to execute. Then when you need to block execution using the method `wait()`.\n",
"When running a pipeline with the method `run()`, the pipeline is run synchronously. To run asynchronously, you use the method `submit()`. Once the job has started, your Python script can continue to execute. To block execution, you can use the method `wait()`.\n",
"\n",
"### Setting machine resources for pipeline steps\n",
"\n",
"By default, Vertex AI Pipelines will automatically find the best matching machine type to run the component. You can override and specify the machine resources on a per component basis, when you invoke the component in a pipeline, as follows:\n",
"By default, Vertex AI Pipelines automatically finds the best matching machine type to run the component. You can override and specify the machine resources on a per component basis, when you invoke the component in a pipeline, as follows:\n",
"\n",
"```\n",
"@dsl.pipeline(name='my-pipeline')\n",
@@ -1376,15 +1517,9 @@
"\n",
"Otherwise, you can delete the individual resources you created in this tutorial:\n",
"\n",
"- Dataset\n",
"- Pipeline\n",
"- Model\n",
"- Endpoint\n",
"- AutoML Training Job\n",
"- Batch Job\n",
"- Custom Job\n",
"- Hyperparameter Tuning Job\n",
"- Cloud Storage Bucket"
"### Cloud Storage Bucket\n",
"\n",
"Set `delete_bucket` to True to delete the Cloud storage bucket used in this notebook."
]
},
{
@@ -1395,61 +1530,10 @@
},
"outputs": [],
"source": [
"delete_all = True\n",
"delete_bucket = False\n",
"\n",
"if delete_all:\n",
" # Delete the dataset using the Vertex dataset object\n",
" try:\n",
" if \"dataset\" in globals():\n",
" dataset.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the model using the Vertex model object\n",
" try:\n",
" if \"model\" in globals():\n",
" model.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the endpoint using the Vertex endpoint object\n",
" try:\n",
" if \"endpoint\" in globals():\n",
" endpoint.undeploy_all()\n",
" endpoint.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the AutoML or Pipeline training job\n",
" try:\n",
" if \"dag\" in globals():\n",
" dag.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the custom training job\n",
" try:\n",
" if \"job\" in globals():\n",
" job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the batch prediction job using the Vertex batch prediction object\n",
" try:\n",
" if \"batch_predict_job\" in globals():\n",
" batch_predict_job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the hyperparameter tuning job using the Vertex hyperparameter tuning object\n",
" try:\n",
" if \"hpt_job\" in globals():\n",
" hpt_job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" if \"BUCKET_NAME\" in globals():\n",
" ! gsutil rm -r $BUCKET_NAME"
"if delete_bucket or os.getenv(\"IS_TESTING\"):\n",
" ! gsutil rm -r $BUCKET_URI"
]
}
],
@@ -8,7 +8,7 @@
},
"outputs": [],
"source": [
"# Copyright 2022 Google LLC\n",
"# Copyright 2021 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",
@@ -1872,14 +1872,29 @@
" + str(TASK_ID)\n",
" + \"/gcp_resources\"\n",
" )\n",
" EVAL_METRICS = (\n",
" PIPELINE_ROOT\n",
" + \"/\"\n",
" + PROJECT_NUMBER\n",
" + \"/\"\n",
" + JOB_ID\n",
" + \"/\"\n",
" + output_task_name\n",
" + \"_\"\n",
" + str(TASK_ID)\n",
" + \"/evaluation_metrics\"\n",
" )\n",
" if tf.io.gfile.exists(EXECUTE_OUTPUT):\n",
" ! gsutil cat $EXECUTE_OUTPUT\n",
" break\n",
" return EXECUTE_OUTPUT\n",
" elif tf.io.gfile.exists(GCP_RESOURCES):\n",
" ! gsutil cat $GCP_RESOURCES\n",
" break\n",
" return GCP_RESOURCES\n",
" elif tf.io.gfile.exists(EVAL_METRICS):\n",
" ! gsutil cat $EVAL_METRICS\n",
" return EVAL_METRICS\n",
"\n",
" return EXECUTE_OUTPUT\n",
" return None\n",
"\n",
"\n",
"print(\"make-chicago-bq-dataset\")\n",
@@ -2120,7 +2135,9 @@
" region: str = REGION,\n",
" labels: dict = {\"base_model\": \"1\"},\n",
"):\n",
" from google_cloud_pipeline_components import aiplatform as gcc_aip\n",
" from google_cloud_pipeline_components.types import artifact_types\n",
" from google_cloud_pipeline_components.v1.model import ModelUploadOp\n",
" from kfp.v2.components import importer_node\n",
"\n",
" model_build_op = build_model(\n",
" dataset_id=dataset_id,\n",
@@ -2130,14 +2147,21 @@
" project=project,\n",
" )\n",
"\n",
" model_upload_op = gcc_aip.ModelUploadOp(\n",
" display_name=display_name,\n",
" import_unmanaged_model_task = importer_node.importer(\n",
" artifact_uri=model_build_op.output,\n",
" serving_container_image_uri=deploy_image,\n",
" labels=labels,\n",
" artifact_class=artifact_types.UnmanagedContainerModel,\n",
" metadata={\n",
" \"containerSpec\": {\n",
" \"imageUri\": DEPLOY_IMAGE,\n",
" },\n",
" },\n",
" ).after(model_build_op)\n",
"\n",
" model_upload = ModelUploadOp(\n",
" project=project,\n",
" location=region,\n",
" )"
" display_name=display_name,\n",
" unmanaged_container_model=import_unmanaged_model_task.outputs[\"artifact\"],\n",
" ).after(import_unmanaged_model_task)"
]
},
{
@@ -3048,6 +3072,8 @@
" region: str = REGION,\n",
"):\n",
" from google_cloud_pipeline_components import aiplatform as gcc_aip\n",
" from google_cloud_pipeline_components.v1.endpoint import (EndpointCreateOp,\n",
" ModelDeployOp)\n",
"\n",
" with dsl.Condition(warmup == \"True\", name=\"warmup-model\"):\n",
"\n",
@@ -3089,13 +3115,13 @@
" labels=label,\n",
" )\n",
"\n",
" endpoint_op = gcc_aip.EndpointCreateOp(\n",
" endpoint_op = EndpointCreateOp(\n",
" project=project,\n",
" location=region,\n",
" display_name=display_name,\n",
" ).after(training_op)\n",
"\n",
" deploy_op = gcc_aip.ModelDeployOp(\n",
" deploy_op = ModelDeployOp(\n",
" model=training_op.outputs[\"model\"],\n",
" endpoint=endpoint_op.outputs[\"endpoint\"],\n",
" dedicated_resources_min_replica_count=1,\n",
@@ -0,0 +1,91 @@
{
"pipelineSpec": {
"components": {
"comp-hello-world": {
"executorLabel": "exec-hello-world",
"inputDefinitions": {
"parameters": {
"text": {
"type": "STRING"
}
}
},
"outputDefinitions": {
"parameters": {
"Output": {
"type": "STRING"
}
}
}
}
},
"deploymentSpec": {
"executors": {
"exec-hello-world": {
"container": {
"args": [
"--executor_input",
"{{$}}",
"--function_to_execute",
"hello_world"
],
"command": [
"sh",
"-c",
"\nif ! [ -x \"$(command -v pip)\" ]; then\n python3 -m ensurepip || python3 -m ensurepip --user || apt-get install python3-pip\nfi\n\nPIP_DISABLE_PIP_VERSION_CHECK=1 python3 -m pip install --quiet --no-warn-script-location 'kfp==1.8.11' && \"$0\" \"$@\"\n",
"sh",
"-ec",
"program_path=$(mktemp -d)\nprintf \"%s\" \"$0\" > \"$program_path/ephemeral_component.py\"\npython3 -m kfp.v2.components.executor_main --component_module_path \"$program_path/ephemeral_component.py\" \"$@\"\n",
"\nimport kfp\nfrom kfp.v2 import dsl\nfrom kfp.v2.dsl import *\nfrom typing import *\n\ndef hello_world(text: str) -> str:\n print(text)\n return text\n\n"
],
"image": "python:3.9"
}
}
}
},
"pipelineInfo": {
"name": "hello-world"
},
"root": {
"dag": {
"tasks": {
"hello-world": {
"cachingOptions": {
"enableCache": true
},
"componentRef": {
"name": "comp-hello-world"
},
"inputs": {
"parameters": {
"text": {
"componentInputParameter": "text"
}
}
},
"taskInfo": {
"name": "hello-world"
}
}
}
},
"inputDefinitions": {
"parameters": {
"text": {
"type": "STRING"
}
}
}
},
"schemaVersion": "2.0.0",
"sdkVersion": "kfp-1.8.11"
},
"runtimeConfig": {
"gcsOutputDirectory": "gs://andy-1234-221921aip-20220302183146/pipeline_root/hello_world",
"parameters": {
"text": {
"stringValue": "hi there"
}
}
}
}
@@ -0,0 +1,40 @@
name: Hello world
inputs:
- {name: text, type: String}
outputs:
- {name: Output, type: String}
implementation:
container:
image: python:3.9
command:
- sh
- -c
- |2
if ! [ -x "$(command -v pip)" ]; then
python3 -m ensurepip || python3 -m ensurepip --user || apt-get install python3-pip
fi
PIP_DISABLE_PIP_VERSION_CHECK=1 python3 -m pip install --quiet --no-warn-script-location 'kfp==1.8.11' && "$0" "$@"
- sh
- -ec
- |
program_path=$(mktemp -d)
printf "%s" "$0" > "$program_path/ephemeral_component.py"
python3 -m kfp.v2.components.executor_main --component_module_path "$program_path/ephemeral_component.py" "$@"
- |2+
import kfp
from kfp.v2 import dsl
from kfp.v2.dsl import *
from typing import *
def hello_world(text: str) -> str:
print(text)
return text
args:
- --executor_input
- {executorInput: null}
- --function_to_execute
- hello_world
@@ -44,16 +44,66 @@ This stage may be done entirely by MLOps. We recommend:
[Get started with Google Artifact Registry](get_started_with_google_artifact_registry.ipynb)
```
The steps performed include:
- Creating a private Docker repository.
- Tagging a container image, specific to the private Docker repository.
- Pushing a container image to the private Docker repository.
- Pulling a container image from the private Docker repository.
- Deleting a private Docker repository.
```
Get started with Vertex Model Registry
[Get started with Vertex ML Metadata](get_started_with_vertex_ml_metadata.ipynb)
```
The steps performed include:
- Create a `Metadatastore` resource.
- Create (record)/List an `Artifact`, with artifacts and metadata.
- Create (record)/List an `Execution`.
- Create (record)/List a `Context`.
- Add `Artifact` to `Execution` as events.
- Add `Execution` and `Artifact` into the `Context`
- Delete `Artifact`, `Execution` and `Context`.
- Create and run a `Vertex AI Pipeline` ML workflow to train and deploy a scikit-learn model.
- Create custom pipeline components that generate artifacts and metadata.
- Compare Vertex AI Pipelines runs.
- Trace the lineage for pipeline-generated artifacts.
- Query your pipeline run metadata.
```
Get started with custom model evaluation
Get started with A/B Testing
[Get started with Vertex Explainable AI](get_started_with_vertex_xai.ipynb)
```
The steps performed include:
- Train an AutoML tabular model.
- Do a batch prediction with explanations.
- Do an online prediction with explanations.
- Train an custom TensorFlow tabular model.
- Manually set configuration metadata.
- Do a batch prediction with explanations.
- Do an online prediction with explanations.
- Automatically set configuration metadata.
- Train an custom TensorFlow image model.
- Manually set configuration metadata.
- Do a batch prediction with explanations.
- Do an online prediction with explanations.
- Train an custom XGBoost tabular model.
- Manually set configuration metadata.
- Do an online prediction with explanations.
- Train an custom scikit-learn tabular model.
- Manually set configuration metadata.
- Do an online prediction with explanations.
```
### E2E Stage Example
Stage 4: Evaluation
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,47 @@
# Stage 5: Deployment
## Purpose
## Recommendations
<img src='stage5.png'>
## Notebooks
### Get Started
[Get started with Vertex AI Endpoints](get_started_with_vertex_endpoints.ipynb)
```
The steps include:
- Creating an `Endpoint` resource.
- List all `Endpoint` resources.
- List `Endpoint` resources by query filter.
- Configuring the serving binary of a `Model` resource for deployment to an `Endpoint` resource.
- Deploying a single `Model` resource to an `Endpoint` resource.
- Get deployment settings for a deployed `Model` resource.
- Configuring auto-scaling.
- Deploying multiple `Model` resources to an `Endpoint` resource and configuring a traffic split.
- Dynamically change the traffic split for an `Endpoint` resource.
- Undeploy a single `Model` resource to an `Endpoint` resource.
- Undeploy all `Model` resources from an `Endpoint` resource.
- Delete an `Endpoint` resource.
- In pipeline: Create an `Endpoint` resource and deploy an existing `Model` resource to the `Endpoint` resource.
- In pipeline: Deploy an existing `Model` resource to an existing `Endpoint` resource.
```
[Get started with Vertex AI Private Endpoints](get_started_with_vertex_private_endpoints.ipynb)
```
The steps performed include:
- Creating a `Private Endpoint` resource.
- Configure a VPC peering connection.
- Configuring the serving binary of a `Model` resource for deployment to a `Private Endpoint` resource.
- Deploying a `Model` resource to a `Private Endpoint` resource.
- Send a prediction request to a `Private Endpoint`
```
File diff suppressed because it is too large Load Diff
+131
View File
@@ -0,0 +1,131 @@
# Stage 6: Serving
## Purpose
Process prediction requests and return corresponding predictions in a timely manner consistent with the business requirement, whether online, on-demand or batch predictions
## Recommendations
The sixth stage in MLOps is serving predictions from the blessed model deployed to production. The serving methods, depending on business requirements may be one or more of the following:
- Batch predictions – prediction requests that are queued and handled offline. This is done entirely with Google Cloud core infrastructure.
- Online predictions - prediction requests that are received externally over the Internet and processed in (near) real-time. The serving of the requests/responses is done entirely with Google Cloud core infrastructure, the requesting web application/clients may originate anywhere on the Internet. If the request originates outside of the Google Cloud core infrastructure, a proxy is needed to traverse through the firewall.
- On-demand predictions - prediction requests that are received internally with Google Cloud core infrastructure, or direct via an edge device. The prediction response to the requestor must be near instantaneous. The serving of the requests/responses may be either within Google Cloud core infrastructure, or externally on an edge device. An example of the former is an emergency sensor and on the later a medical sensor.
This stage may be done entirely by MLOps. We recommend:
- Use Google Cloud core infrastructure for online serving and batch serving, and on-demand serving where it meets the speed requirements for how the responses are utilized.
- Use IAM role settings for access control in cross-project when the application and the serving binaries are entirely within Google Cloud core infrastructure, but in different projects.
- Deploy serving binaries within regions that are the closest to where the requests originate. Deploy in multiple regions, when requests span regional boundaries.
- Use Cloud Functions as a proxy when prediction requests originate externally to Google Cloud core infrastructure, or must otherwise cross firewall boundaries that cannot not otherwise be handled by IAM role settings.
- Features that dynamically change per example (e.g., bank balance) are stored in Vertex Feature Store.
<img src='stage6a.png'>
<img src='stage6b.png'>
<img src='stage6c.png'>
## Notebooks
### Get Started
[Get started with Custom Prediction Routine](get_started_with_cpr.ipynb)
```
The steps performed include:
- Write a custom data preprocessor.
- Train the model.
- Build a custom scikit-learn serving container with custom data preprocessing using the Custom Prediction Routine model server.
- Test the model serving container locally.
- Upload and deploy the model serving container to Vertex AI Endpoint.
- Make a prediction request.
- Build a custom scikit-learn serving container with custom predictor (post-processing) using the Custom Prediction Routine model server.
- Implement custom predictor.
- Test the model serving container locally.
- Upload and deploy the model serving container to Vertex AI Endpoint.
- Make a prediction request.
- Build a custom scikit-learn serving container with custom predictor and HTTP request handler using the Custom Prediction Routine model server.
- Implement a custom handler.
- Test the model serving container locally.
- Upload and deploy the model serving container to Vertex AI Endpoint.
- Make a prediction request.
- Customize the Dockerfile for a custom scikit-learn serving container with custom predictor and HTTP request handler using the Custom Prediction Routine model server.
- Implement a custom Dockerfile.
- Test the model serving container locally.
- Upload and deploy the model serving container to Vertex AI Endpoint.
- Make a prediction request.
```
[Get started with Vertex AI Raw Prediction](get_started_with_raw_predict.ipynb)
```
The steps performed include:
- Download a pretrained tabular classification model artifacts for a TensorFlow 1.x estimator.
- Upload the TensorFlow estimator model as a `Vertex AI Model` resource.
- Creating an `Endpoint` resource.
- Deploying the `Model` resource to an `Endpoint` resource.
- Make an online raw prediction to the `Model` resource instance deployed to the `Endpoint` resource.
```
[Get started with serving functions for TensorFlow model](get_started_with_tf_serving_function.ipynb)
```
The steps performed include:
- Download a pretrained image classification model from TensorFlow Hub.
- Create a serving function to receive compressed image data, and output decomopressed preprocessed data for the model input.
- Upload the TensorFlow Hub model and serving function as a `Vertex AI Model` resource.
- Creating an `Endpoint` resource.
- Deploying the `Model` resource to an `Endpoint` resource.
- Make an online prediction to the `Model` resource instance deployed to the `Endpoint` resource.
```
[Get started with TensorFlow Serving](get_started_with_tf_serving.ipynb)
```
The steps performed include:
- Download a pretrained image classification model from TensorFlow Hub.
- Create a serving function to receive compressed image data, and output decomopressed preprocessed data for the model input.
- Upload the TensorFlow Hub model and serving function as a `Vertex AI Model` resource.
- Creating an `Endpoint` resource.
- Deploying the `Model` resource to an `Endpoint` resource with `TensorFlow Serving` serving binary.
- Make an online prediction to the `Model` resource instance deployed to the `Endpoint` resource.
```
[Get started with FastAPI serving binary](get_started_with_fastapi.ipynb)
```
The steps performed include:
- Download a pretrained image classification model from TensorFlow Hub.
- Create a serving function to receive compressed image data, and output decomopressed preprocessed data for the model input.
- Upload the TensorFlow Hub model and serving function as a `Vertex AI Model` resource.
- Creating an `Endpoint` resource.
- Deploying the `Model` resource to an `Endpoint` resource with `FastAPI` custom serving binary.
- Make an online prediction to the `Model` resource instance deployed to the `Endpoint` resource.
```
[Get started with Vertex AI Prediction optimized TensorFlow run-time container](get_started_with_optimized_tfe_bert.ipynb)
```
The steps performed include:
- Download a pretrained BERT model from TensorFlow Hub.
- Fine-tune (transfer learning) the BERT model as a binary classifier.
- Upload the TensorFlow Hub model as a `Vertex AI Model` resource, with standard TensorFlow serving container.
- Upload the TensorFlow Hub model as a `Vertex AI Model` resource, with `Vertex AI Prediction optimized TensorFlow runtime` container
- Create two `Endpoint` resources.
- Deploying both `Model` resources to separate `Endpoint` resources.
- Make the same online prediction requests to both `Model` resource instances deployed to the `Endpoint` resources.
- Compare the prediction accuracy between the two deployed `Model` resources.
- Configuring container settings for fine-tune control of optimizations.
- Create a `Private Endpoint` resource.
- Deploy the `Model` resoure with then `Vertex AI Prediction optimized TensorFlow runtime` to the `Private Endpoint` resource.
- Make an online prediction request to the `Private Endpoint` resource.
```
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
@@ -0,0 +1,909 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "ur8xi4C7S06n"
},
"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 6 : Get started with TensorFlow serving functions with Vertex AI Raw Prediction\n",
"\n",
"<table align=\"left\">\n",
" <td>\n",
" <a href=\"https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage6/get_started_with_vertex_raw_predict.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/ai/platform/notebooks/deploy-notebook?download_url=https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage6/get_started_with_vertex_raw_predict.ipynb\">\n",
" Open in Vertex AI Workbench\n",
" </a>\n",
" </td>\n",
"</table>\n",
"<br/><br/><br/>"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "tvgnzT1CKxrO"
},
"source": [
"## Overview\n",
"\n",
"This tutorial demonstrates how use `Vertex AI Raw Prediction` to send raw HTTP content directly to a model deployed to a `Vertex AI Endpoint`. \n",
"\n",
"For example, the HTTP server for pre-built `Vertex AI` deployment containers does not support the HTTP request body for TensorFlow 1.x estimators. Using raw predict, one can send raw content through the HTTP server that is presented to the model input as-is -- no canonical processing."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "c9402cfbdc2d"
},
"source": [
"### Objective\n",
"\n",
"In this tutorial, you learn how to use `Vertex AI Raw Prediction` on a `Vertex AI Endpoint` resource.\n",
"\n",
"This tutorial uses the following Google Cloud ML services and resources:\n",
"\n",
"- `Vertex AI Raw Prediction`\n",
"- `Vertex AI Models`\n",
"- `Vertex AI Endpoints`\n",
"\n",
"The steps performed include:\n",
"\n",
"- Download a pretrained tabular classification model artifacts for a TensorFlow 1.x estimator.\n",
"- Upload the TensorFlow estimator model as a `Vertex AI Model` resource.\n",
"- Creating an `Endpoint` resource.\n",
"- Deploying the `Model` resource to an `Endpoint` resource.\n",
"- Make an online raw prediction to the `Model` resource instance deployed to the `Endpoint` resource."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "dataset:iris,lcn"
},
"source": [
"### Dataset\n",
"\n",
"This tutorial uses a pre-trained tabular classification model from a public Cloud Storage bucket, which is trained on the Penguins dataset (https://cloud.google.com/bigquery/public-data). The version of the dataset predicts the species."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "costs"
},
"source": [
"### Costs\n",
"\n",
"This tutorial uses billable components of Google Cloud:\n",
"\n",
"* Vertex AI\n",
"* Cloud Storage\n",
"\n",
"Learn about [Vertex AI\n",
"pricing](https://cloud.google.com/vertex-ai/pricing) and [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": "install_aip"
},
"source": [
"## Installation\n",
"\n",
"Install the following packages to execute this notebook."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "install_aip"
},
"outputs": [],
"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",
"\n",
"! pip3 install --upgrade google-cloud-aiplatform $USER_FLAG\n",
"! pip3 install --upgrade google-cloud-pipeline-components $USER_FLAG\n",
"! pip3 install tensorflow-hub $USER_FLAG"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "hhq5zEbGg0XX"
},
"source": [
"### Restart the kernel\n",
"\n",
"After you install the additional packages, you need to restart the notebook kernel so it can find the packages."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "EzrelQZ22IZj"
},
"outputs": [],
"source": [
"# Automatically restart kernel after installs\n",
"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": "before_you_begin"
},
"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: Vertex AI APIs, Compute Engine APIs, and Cloud Storage.](https://console.cloud.google.com/flows/enableapi?apiid=ml.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": "markdown",
"metadata": {
"id": "project_id"
},
"source": [
"#### 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": "gcp_authenticate"
},
"source": [
"### Authenticate your Google Cloud account\n",
"\n",
"**If you are using Google Cloud 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",
"**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 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": "gcp_authenticate"
},
"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 Google Cloud Notebook, then don't execute this code\n",
"if not os.path.exists(\"/opt/deeplearning/metadata/env_version\"):\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": "bucket:mbsdk"
},
"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.\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": "bucket"
},
"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": "autoset_bucket"
},
"outputs": [],
"source": [
"if BUCKET_URI == \"\" or BUCKET_URI is None or BUCKET_URI == \"gs://[your-bucket-name]\":\n",
" BUCKET_NAME = PROJECT_ID + \"aip-\" + TIMESTAMP\n",
" BUCKET_URI = \"gs://\" + BUCKET_NAME"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "create_bucket"
},
"source": [
"**Only if your bucket doesn't already exist**: Run the following cell to create your Cloud Storage bucket."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "create_bucket"
},
"outputs": [],
"source": [
"! gsutil mb -l $REGION $BUCKET_URI"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "validate_bucket"
},
"source": [
"Finally, validate access to your Cloud Storage bucket by examining its contents:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "validate_bucket"
},
"outputs": [],
"source": [
"! gsutil ls -al $BUCKET_URI"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "setup_vars"
},
"source": [
"### Set up variables\n",
"\n",
"Next, set up some variables used throughout the tutorial.\n",
"### Import libraries and define constants"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "import_aip:mbsdk"
},
"outputs": [],
"source": [
"import google.cloud.aiplatform as aip\n",
"import tensorflow as tf\n",
"import tensorflow_hub as hub"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "init_aip:mbsdk"
},
"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"
},
"outputs": [],
"source": [
"aip.init(project=PROJECT_ID, staging_bucket=BUCKET_URI)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "accelerators:training,cpu,prediction,cpu,mbsdk"
},
"source": [
"#### Set hardware accelerators\n",
"\n",
"You can set hardware accelerators for training and prediction.\n",
"\n",
"Set the variables `DEPLOY_GPU/DEPLOY_NGPU` to use a container image supporting a GPU and the number of GPUs allocated to the virtual machine (VM) instance. For example, to use a GPU container image with 4 Nvidia Telsa K80 GPUs allocated to each VM, you would specify:\n",
"\n",
" (aip.AcceleratorType.NVIDIA_TESLA_K80, 4)\n",
"\n",
"\n",
"Otherwise specify `(None, None)` to use a container image to run on a CPU.\n",
"\n",
"Learn more about [hardware accelerator support for your region](https://cloud.google.com/vertex-ai/docs/general/locations#accelerators).\n",
"\n",
"*Note*: TF releases before 2.3 for GPU support will fail to load the custom model in this tutorial. It is a known issue and fixed in TF 2.3. This is caused by static graph ops that are generated in the serving function. If you encounter this issue on your own custom models, use a container image for TF 2.3 with GPU support."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "accelerators:training,cpu,prediction,cpu,mbsdk"
},
"outputs": [],
"source": [
"if os.getenv(\"IS_TESTING_DEPLOY_GPU\"):\n",
" DEPLOY_GPU, DEPLOY_NGPU = (\n",
" aip.gapic.AcceleratorType.NVIDIA_TESLA_K80,\n",
" int(os.getenv(\"IS_TESTING_DEPLOY_GPU\")),\n",
" )\n",
"else:\n",
" DEPLOY_GPU, DEPLOY_NGPU = (None, None)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "container:training,prediction"
},
"source": [
"#### Set pre-built containers\n",
"\n",
"Set the pre-built Docker container image for prediction.\n",
"\n",
"\n",
"For the latest list, see [Pre-built containers for prediction](https://cloud.google.com/ai-platform-unified/docs/predictions/pre-built-containers)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "container:training,prediction"
},
"outputs": [],
"source": [
"if os.getenv(\"IS_TESTING_TF\"):\n",
" TF = os.getenv(\"IS_TESTING_TF\")\n",
"else:\n",
" TF = \"2.5\".replace(\".\", \"-\")\n",
"\n",
"if TF[0] == \"2\":\n",
" if DEPLOY_GPU:\n",
" DEPLOY_VERSION = \"tf2-gpu.{}\".format(TF)\n",
" else:\n",
" DEPLOY_VERSION = \"tf2-cpu.{}\".format(TF)\n",
"else:\n",
" if DEPLOY_GPU:\n",
" DEPLOY_VERSION = \"tf-gpu.{}\".format(TF)\n",
" else:\n",
" DEPLOY_VERSION = \"tf-cpu.{}\".format(TF)\n",
"\n",
"DEPLOY_IMAGE = \"{}-docker.pkg.dev/vertex-ai/prediction/{}:latest\".format(\n",
" REGION.split(\"-\")[0], DEPLOY_VERSION\n",
")\n",
"\n",
"print(\"Deployment:\", DEPLOY_IMAGE, DEPLOY_GPU, DEPLOY_NGPU)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "machine:training"
},
"source": [
"#### Set machine type\n",
"\n",
"Next, set the machine type to use for prediction.\n",
"\n",
"- Set the variable `DEPLOY_COMPUTE` to configure the compute resources for the VMs you will use for for prediction.\n",
" - `machine type`\n",
" - `n1-standard`: 3.75GB of memory per vCPU.\n",
" - `n1-highmem`: 6.5GB of memory per vCPU\n",
" - `n1-highcpu`: 0.9 GB of memory per vCPU\n",
" - `vCPUs`: number of \\[2, 4, 8, 16, 32, 64, 96 \\]\n",
"\n",
"*Note: You may also use n2 and e2 machine types for training and deployment, but they do not support GPUs*."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "machine:training"
},
"outputs": [],
"source": [
"if os.getenv(\"IS_TESTING_DEPLOY_MACHINE\"):\n",
" MACHINE_TYPE = os.getenv(\"IS_TESTING_DEPLOY_MACHINE\")\n",
"else:\n",
" MACHINE_TYPE = \"n1-standard\"\n",
"\n",
"VCPU = \"4\"\n",
"DEPLOY_COMPUTE = MACHINE_TYPE + \"-\" + VCPU\n",
"print(\"Train machine type\", DEPLOY_COMPUTE)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "d8128b8ff025"
},
"source": [
"## Get pretrained model from the public Cloud Storage location\n",
"\n",
"For demonstration purposes, this tutorial uses a pretrained model TensorFlow 1.x estimator tabular classification Model, which is then uploaded to a `Vertex AI Model` resource. Once you have a `Vertex AI Model` resource, the model can be deployed to a `Vertex AI Endpoint` resource.\n",
"\n",
"### Download the pretrained model\n",
"\n",
"Download the pretrained TensorFlow estimator model artifacts from the public Cloud Storage, and then upload the model artifacts to your own Cloud Storage bucket."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "c55fa4c826f7"
},
"outputs": [],
"source": [
"MODEL_DIR = BUCKET_URI + \"/model\"\n",
"\n",
"! gsutil cp -r gs://cloud-samples-data/vertex-ai/google-cloud-aiplatform-ci-artifacts/models/penguins/estimator/ {MODEL_DIR}"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "e8ce91147c93"
},
"source": [
"## Upload the TensorFlow estimator model to a `Vertex AI Model` resource\n",
"\n",
"Finally, you upload the model artifacts from the TFHub model and serving function into a `Vertex AI Model` resource.\n",
"\n",
"*Note:* When you upload the model artifacts to a `Vertex AI Model` resource, you specify the corresponding deployment container image."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "ad61e1429512"
},
"outputs": [],
"source": [
"model = aip.Model.upload(\n",
" display_name=\"example_\" + TIMESTAMP,\n",
" artifact_uri=MODEL_DIR,\n",
" serving_container_image_uri=DEPLOY_IMAGE,\n",
")\n",
"\n",
"print(model)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "628de0914ba1"
},
"source": [
"## Creating an `Endpoint` resource\n",
"\n",
"You create an `Endpoint` resource using the `Endpoint.create()` method. At a minimum, you specify the display name for the endpoint. Optionally, you can specify the project and location (region); otherwise the settings are inherited by the values you set when you initialized the Vertex AI SDK with the `init()` method.\n",
"\n",
"In this example, the following parameters are specified:\n",
"\n",
"- `display_name`: A human readable name for the `Endpoint` resource.\n",
"- `project`: Your project ID.\n",
"- `location`: Your region.\n",
"- `labels`: (optional) User defined metadata for the `Endpoint` in the form of key/value pairs.\n",
"\n",
"This method returns an `Endpoint` object.\n",
"\n",
"Learn more about [Vertex AI Endpoints](https://cloud.google.com/vertex-ai/docs/predictions/deploy-model-api)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "0ea443f9593b"
},
"outputs": [],
"source": [
"endpoint = aip.Endpoint.create(\n",
" display_name=\"example_\" + TIMESTAMP,\n",
" project=PROJECT_ID,\n",
" location=REGION,\n",
" labels={\"your_key\": \"your_value\"},\n",
")\n",
"\n",
"print(endpoint)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "ca3fa3f6a894"
},
"source": [
"## Deploying `Model` resources to an `Endpoint` resource.\n",
"\n",
"You can deploy one of more `Vertex AI Model` resource instances to the same endpoint. Each `Vertex AI Model` resource that is deployed will have its own deployment container for the serving binary. \n",
"\n",
"BLAH\n",
"\n",
"In the next example, you deploy the `Vertex AI Model` resource to a `Vertex AI Endpoint` resource. The `Vertex AI Model` resource already has defined for it the deployment container image. To deploy, you specify the following additional configuration settings:\n",
"\n",
"- The machine type.\n",
"- The (if any) type and number of GPUs.\n",
"- Static, manual or auto-scaling of VM instances.\n",
"\n",
"In this example, you deploy the model with the minimal amount of specified parameters, as follows:\n",
"\n",
"- `model`: The `Model` resource.\n",
"- `deployed_model_displayed_name`: The human readable name for the deployed model instance.\n",
"- `machine_type`: The machine type for each VM instance.\n",
"\n",
"Do to the requirements to provision the resource, this may take upto a few minutes."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "4e93b034a72f"
},
"outputs": [],
"source": [
"response = endpoint.deploy(\n",
" model=model,\n",
" deployed_model_display_name=\"example_\" + TIMESTAMP,\n",
" machine_type=DEPLOY_COMPUTE,\n",
")\n",
"\n",
"print(endpoint)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "make_test_items:bqml,penguins"
},
"source": [
"#### Make prediction instances\n",
"\n",
"Next, you prepare a prediction request using a synthetic example. In this example, the model format is a TensorFlow 1.x estimator format. This model format takes a request signature not supported by the HTTP server in the `Vertex AI` prebuilt TensorFlow serving containers.\n",
"\n",
"For this model format, you use the `raw_predict()` to pass as-is a request that matches directly the serving interfac of the model, with the following request format:\n",
"\n",
" http_body -> {\n",
" 'signature_name' : serving_signature,\n",
" 'instances': [ {instance_1}, {instance_2}, ... ]\n",
" }\n",
"\n",
" instance -> { 'feature_1': value_1, 'feature_2': value_2, ... }\n",
"\n",
" serving_signature -> \"predict\"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "make_test_items:bqml,penguins"
},
"outputs": [],
"source": [
"import json\n",
"\n",
"from google.api import httpbody_pb2\n",
"from google.cloud import aiplatform_v1\n",
"\n",
"DATA = {\n",
" \"signature_name\": \"predict\",\n",
" \"instances\": [\n",
" {\n",
" \"island\": \"DREAM\",\n",
" \"culmen_length_mm\": 36.6,\n",
" \"culmen_depth_mm\": 18.4,\n",
" \"flipper_length_mm\": 184.0,\n",
" \"body_mass_g\": 3475.0,\n",
" \"sex\": \"FEMALE\",\n",
" }\n",
" ],\n",
"}\n",
"\n",
"http_body = httpbody_pb2.HttpBody(\n",
" data=json.dumps(DATA).encode(\"utf-8\"),\n",
" content_type=\"application/json\",\n",
")\n",
"\n",
"req = aiplatform_v1.RawPredictRequest(\n",
" http_body=http_body, endpoint=endpoint.resource_name\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "endpoint_predict:mbsdk"
},
"source": [
"### Make a prediction\n",
"\n",
"Finally, you make the prediction request using Vertex AI Prediction service."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "endpoint_predict:mbsdk"
},
"outputs": [],
"source": [
"API_ENDPOINT = \"{}-aiplatform.googleapis.com\".format(REGION)\n",
"client_options = {\"api_endpoint\": API_ENDPOINT}\n",
"\n",
"pred_client = aip.gapic.PredictionServiceClient(client_options=client_options)\n",
"\n",
"response = pred_client.raw_predict(req)\n",
"print(response)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "TpV-iwP9qw9c"
},
"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:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "sx_vKniMq9ZX"
},
"outputs": [],
"source": [
"delete_bucket = True\n",
"delete_model = True\n",
"delete_endpoint = True\n",
"\n",
"if delete_endpoint:\n",
" try:\n",
" endpoint.undeploy_all()\n",
" endpoint.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
"if delete_model:\n",
" try:\n",
" model.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
"if delete_bucket or os.getenv(\"IS_TESTING\"):\n",
" ! gsutil rm -rf {BUCKET_URI}"
]
}
],
"metadata": {
"colab": {
"collapsed_sections": [],
"name": "get_started_with_raw_predict.ipynb",
"toc_visible": true
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
@@ -0,0 +1,137 @@
import itertools
import json
import threading
import time
from collections import defaultdict
import numpy as np
import tensorflow as tf
logging = tf.get_logger()
logging.propagate = False
logging.setLevel("INFO")
def benchmark_qps(send_request, requests, qps):
logging.info("Running benchmark at {} qps".format(qps))
# List appends are thread safe
num_requests = len(requests)
success = []
error = []
latency = []
def _make_call(i):
"""Send a request to using specified method and measure observed latency."""
start_time = time.time()
try:
_ = send_request(requests[i])
success.append(1)
except Exception as e:
print(e)
error.append(1)
latency.append(time.time() - start_time)
if len(latency) % (qps * 10) == 0:
logging.info("received {} responses.".format(len(latency)))
thread_lst = []
miss_rate_percent = []
start_time = time.time()
previous_worker_start = start_time
for i in range(num_requests):
thread = threading.Thread(target=_make_call, args=(i,))
thread_lst.append(thread)
thread.start()
if i % (qps * 10) == 0 and i != 0:
logging.info("sent {} requests.".format(i))
# send requests at a constant rate and adjust for the time it took to send previous request
pause = 1.0 / qps - (time.time() - previous_worker_start)
if pause > 0:
time.sleep(pause)
else:
missed_delay = (
100 * ((time.time() - previous_worker_start) - 1.0 / qps) / (1.0 / qps)
)
miss_rate_percent.append(missed_delay)
previous_worker_start = time.time()
for thread in thread_lst:
thread.join()
acc_time = time.time() - start_time
avg_miss_rate_percent = 0
if len(miss_rate_percent) > 0:
avg_miss_rate_percent = np.average(miss_rate_percent)
logging.warning(
"couldn't keep up at current QPS rate, average miss rate:{:.2f}%".format(
avg_miss_rate_percent
)
)
logging.info(
"num_qps:{} requests/second: {:.2f} #success:{} #error:{} "
"latencies: [avg:{:.2f}ms p50:{:.2f}ms p90:{:.2f}ms p99:{:.2f}ms]".format(
qps,
num_requests / acc_time,
sum(success),
sum(error),
np.average(latency) * 1000,
np.percentile(latency, 50) * 1000,
np.percentile(latency, 90) * 1000,
np.percentile(latency, 99) * 1000,
)
)
return {
"reqested_qps": qps,
"actual_qps": num_requests / acc_time,
"success": sum(success),
"error": sum(error),
"time": acc_time,
"avg_latency": np.average(latency) * 1000,
"p50": np.percentile(latency, 50) * 1000,
"p90": np.percentile(latency, 90) * 1000,
"p99": np.percentile(latency, 99) * 1000,
"avg_miss_rate_percent": avg_miss_rate_percent,
}
def benchmark(
send_request,
build_request,
request_file_path,
qps_list,
duration_sec,
model_name="default",
):
requests = []
with tf.io.gfile.GFile(request_file_path, "r") as f:
for line in f:
row_dict = json.loads(line)
requests.append(build_request(row_dict, model_name))
results = []
for qps in qps_list:
num_requests = max(qps * duration_sec, 10)
requests_for_qps = list(
itertools.islice(itertools.cycle(requests), num_requests)
)
logging.info(f"benchmarking at {qps} QPS, sending {num_requests} requests")
results.append(benchmark_qps(send_request, requests_for_qps, qps))
columns = [
"reqested_qps",
"actual_qps",
"avg_latency",
"p50",
"p90",
"p99",
"success",
"error",
]
merged_results = defaultdict(list)
for result in results:
for column in columns:
merged_results[column].append(result[column])
return merged_results
+8 -2
View File
@@ -32,16 +32,22 @@
"<table align=\"left\">\n",
"\n",
" <td>\n",
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/vertex-ai-samples/blob/master/notebooks/notebook_template.ipynb\"\">\n",
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/notebook_template.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/notebook_template.ipynb\">\n",
" <a href=\"https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/notebook_template.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://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/notebook_template.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>"
]
},
+4
View File
@@ -7,6 +7,8 @@
# matching_engine folder
/matching_engine @shenzhimo2
/tabnet/tabnet_vertex_tutorial.ipynb @longtle
/migration @aferlitsch
/explainabl_ai @aferlitsch
/pipelines @aferlitsch
@@ -18,3 +20,5 @@
/vizier/gapic-vizier-multi-objective-optimization.ipynb @halio-g
/feature_store/gapic-feature-store.ipynb @protorganizer @diemtvu
/managed_notebooks @GoogleCloudPlatform/notebooks-team
/pipelines/google_cloud_pipeline_components_bqml_text.ipynb @inardini
/pipelines/google_cloud_pipelines_dataproc_tabular @inardini
File diff suppressed because it is too large Load Diff
@@ -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",
@@ -45,6 +45,7 @@
" </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/tree/master/notebooks/official/automl/sdk_automl_tabular_forecasting_batch.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",
@@ -173,19 +174,8 @@
"else:\n",
" USER_FLAG = \"\"\n",
"\n",
"! pip3 install --upgrade google-cloud-aiplatform $USER_FLAG"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "install_tensorflow"
},
"outputs": [],
"source": [
"if os.environ[\"IS_TESTING\"]:\n",
" ! pip3 install --upgrade tensorflow $USER_FLAG"
"! pip3 install --upgrade google-cloud-aiplatform $USER_FLAG\n",
"! pip3 install --upgrade tensorflow $USER_FLAG"
]
},
{
@@ -419,7 +409,7 @@
},
"outputs": [],
"source": [
"BUCKET_NAME = \"gs://[your-bucket-name]\" # @param {type:\"string\"}"
"BUCKET_URI = \"gs://[your-bucket-name]\" # @param {type:\"string\"}"
]
},
{
@@ -430,8 +420,8 @@
},
"outputs": [],
"source": [
"if BUCKET_NAME == \"\" or BUCKET_NAME is None or BUCKET_NAME == \"gs://[your-bucket-name]\":\n",
" BUCKET_NAME = \"gs://\" + PROJECT_ID + \"aip-\" + TIMESTAMP"
"if BUCKET_URI == \"\" or BUCKET_URI is None or BUCKET_URI == \"gs://[your-bucket-name]\":\n",
" BUCKET_URI = \"gs://\" + PROJECT_ID + \"aip-\" + TIMESTAMP"
]
},
{
@@ -451,7 +441,7 @@
},
"outputs": [],
"source": [
"! gsutil mb -l $REGION $BUCKET_NAME"
"! gsutil mb -l $REGION $BUCKET_URI"
]
},
{
@@ -471,7 +461,7 @@
},
"outputs": [],
"source": [
"! gsutil ls -al $BUCKET_NAME"
"! gsutil ls -al $BUCKET_URI"
]
},
{
@@ -516,7 +506,7 @@
},
"outputs": [],
"source": [
"aiplatform.init(project=PROJECT_ID, staging_bucket=BUCKET_NAME)"
"aiplatform.init(project=PROJECT_ID, staging_bucket=BUCKET_URI)"
]
},
{
@@ -798,6 +788,15 @@
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "99b7a9287ba6"
},
"source": [
"`batch_predict` can export predictions either to BigQuery or GCS. The BQ option is commented out below and the predictions will be exported to the BUCKET_URI."
]
},
{
"cell_type": "code",
"execution_count": null,
@@ -807,14 +806,15 @@
"outputs": [],
"source": [
"PREDICTION_DATASET_BQ_PATH = (\n",
" \"bq://bigquery-public-data:iowa_liquor_sales_forecasting.2020_sales_train\"\n",
" \"bq://bigquery-public-data:iowa_liquor_sales_forecasting.2021_sales_predict\"\n",
")\n",
"\n",
"batch_prediction_job = model.batch_predict(\n",
" job_display_name=f\"iowa_liquor_sales_forecasting_predictions_{TIMESTAMP}\",\n",
" bigquery_source=PREDICTION_DATASET_BQ_PATH,\n",
" instances_format=\"bigquery\",\n",
" bigquery_destination_prefix=batch_predict_bq_output_uri_prefix,\n",
" # bigquery_destination_prefix=batch_predict_bq_output_uri_prefix,\n",
" gcs_destination_prefix=BUCKET_URI,\n",
" predictions_format=\"bigquery\",\n",
" sync=False,\n",
")\n",
@@ -1018,6 +1018,9 @@
},
"outputs": [],
"source": [
"# Set this to true only if you'd like to delete your bucket\n",
"delete_bucket = False\n",
"\n",
"# Delete dataset\n",
"dataset.delete()\n",
"\n",
@@ -1030,8 +1033,8 @@
"# Delete batch prediction job\n",
"batch_prediction_job.delete()\n",
"\n",
"if os.getenv(\"IS_TESTING\"):\n",
" ! gsutil rm -r $BUCKET_NAME"
"if delete_bucket or os.getenv(\"IS_TESTING\"):\n",
" ! gsutil rm -r $BUCKET_URI"
]
}
],
@@ -0,0 +1,916 @@
{
"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"
},
"source": [
"# Vertex AI SDK: AutoML training tabular regression model for online prediction using BigQuery\n",
"\n",
"<table align=\"left\">\n",
" <td>\n",
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/vertex-ai-samples/tree/master/notebooks/official/automl/sdk_automl_tabular_regression_online_bq.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/tree/master/notebooks/official/automl/sdk_automl_tabular_regression_online_bq.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/ai/platform/notebooks/deploy-notebook?download_url=https://github.com/GoogleCloudPlatform/vertex-ai-samples/tree/master/notebooks/official/automl/sdk_automl_tabular_regression_online_bq.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:automl"
},
"source": [
"## Overview\n",
"\n",
"\n",
"This tutorial demonstrates how to use the Vertex AI SDK for Python to create tabular regression models and do online prediction using a Google Cloud [AutoML](https://cloud.google.com/vertex-ai/docs/start/automl-users) model."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "dataset:gsod,lrg"
},
"source": [
"### Dataset\n",
"\n",
"The dataset used for this tutorial is the GSOD dataset from [BigQuery public datasets](https://cloud.google.com/bigquery/public-data). The version of the dataset you use only the fields year, month and day to predict the value of mean daily temperature (mean_temp)."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "objective:automl,training,online_prediction"
},
"source": [
"### Objective\n",
"\n",
"In this tutorial, you create an AutoML tabular regression model and deploy for online prediction from a Python script using the Vertex AI SDK. You can alternatively create and deploy models using the `gcloud` command-line tool or online using the Cloud Console.\n",
"\n",
"The steps performed include:\n",
"\n",
"- Create a Vertex `Dataset` resource.\n",
"- Train the model.\n",
"- View the model evaluation.\n",
"- Deploy the `Model` resource to a serving `Endpoint` resource.\n",
"- Make a prediction.\n",
"- Undeploy the `Model`."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "costs"
},
"source": [
"### Costs\n",
"\n",
"This tutorial uses billable components of Google Cloud:\n",
"\n",
"* Vertex AI\n",
"* Cloud Storage\n",
"\n",
"Learn about [Vertex AI\n",
"pricing](https://cloud.google.com/vertex-ai/pricing) and [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": "setup_local"
},
"source": [
"### Set up your local development environment\n",
"\n",
"If you are using Colab or Google Cloud 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 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 SDK](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": "install_aip:mbsdk"
},
"source": [
"## Installation\n",
"\n",
"Install the latest version of Vertex AI SDK for Python."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "install_aip:mbsdk"
},
"outputs": [],
"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",
"\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": "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": "before_you_begin:nogpu"
},
"source": [
"## Before you begin\n",
"\n",
"### GPU runtime\n",
"\n",
"This tutorial does not require a GPU runtime.\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: Vertex AI APIs, Compute Engine APIs, and Cloud Storage.](https://console.cloud.google.com/flows/enableapi?apiid=ml.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": "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 = \"us-central1\" # @param {type: \"string\"}"
]
},
{
"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": "gcp_authenticate"
},
"source": [
"### Authenticate your Google Cloud account\n",
"\n",
"**If you are using Google Cloud 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",
"**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 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": "gcp_authenticate"
},
"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 Google Cloud Notebook, then don't execute this code\n",
"if not os.path.exists(\"/opt/deeplearning/metadata/env_version\"):\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": "code",
"execution_count": null,
"metadata": {
"id": "bucket"
},
"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": "autoset_bucket"
},
"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"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "create_bucket"
},
"source": [
"**Only if your bucket doesn't already exist**: Run the following cell to create your Cloud Storage bucket."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "create_bucket"
},
"outputs": [],
"source": [
"! gsutil mb -l $REGION $BUCKET_URI"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "validate_bucket"
},
"source": [
"Finally, validate access to your Cloud Storage bucket by examining its contents:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "validate_bucket"
},
"outputs": [],
"source": [
"! gsutil ls -al $BUCKET_URI"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "setup_vars"
},
"source": [
"### Set up variables\n",
"\n",
"Next, set up some variables used throughout the tutorial.\n",
"### Import libraries and define constants"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "import_aip:mbsdk"
},
"outputs": [],
"source": [
"import google.cloud.aiplatform as aiplatform"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "init_aip:mbsdk"
},
"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"
},
"outputs": [],
"source": [
"aiplatform.init(project=PROJECT_ID, location=REGION)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "tutorial_start:automl"
},
"source": [
"# Tutorial\n",
"\n",
"Now you are ready to start creating your own AutoML tabular regression model."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "import_file:u_dataset,bq"
},
"source": [
"#### Location of BigQuery training data.\n",
"\n",
"Now set the variable `IMPORT_FILE` to the location of the data table in BigQuery."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "import_file:gsod,bq,lrg"
},
"outputs": [],
"source": [
"IMPORT_FILE = \"bq://bigquery-public-data.samples.gsod\""
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "create_dataset:tabular,bq,lrg"
},
"source": [
"### Create the Dataset\n",
"\n",
"Next, create the `Dataset` resource using the `create` method for the `TabularDataset` class, which takes the following parameters:\n",
"\n",
"- `display_name`: The human readable name for the `Dataset` resource.\n",
"- `bq_source`: Alternatively, import data items from a BigQuery table into the `Dataset` resource.\n",
"\n",
"This operation may take several minutes."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "create_dataset:tabular,bq,lrg"
},
"outputs": [],
"source": [
"dataset = aiplatform.TabularDataset.create(\n",
" display_name=\"NOAA historical weather data\" + \"_\" + TIMESTAMP,\n",
" bq_source=[IMPORT_FILE],\n",
")\n",
"\n",
"label_column = \"mean_temp\"\n",
"\n",
"print(dataset.resource_name)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "set_transformations:gsod"
},
"outputs": [],
"source": [
"TRANSFORMATIONS = [\n",
" {\"auto\": {\"column_name\": \"year\"}},\n",
" {\"auto\": {\"column_name\": \"month\"}},\n",
" {\"auto\": {\"column_name\": \"day\"}},\n",
"]\n",
"\n",
"label_column = \"mean_temp\""
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "create_automl_pipeline:tabular,lrg,transformations"
},
"source": [
"### Create and run training pipeline\n",
"\n",
"To train an AutoML model, you perform two steps: 1) create a training pipeline, and 2) run the pipeline.\n",
"\n",
"#### Create training pipeline\n",
"\n",
"An AutoML training pipeline is created with the `AutoMLTabularTrainingJob` class, with the following parameters:\n",
"\n",
"- `display_name`: The human readable name for the `TrainingJob` resource.\n",
"- `optimization_prediction_type`: The type task to train the model for.\n",
" - `classification`: A tabuar classification model.\n",
" - `regression`: A tabular regression model.\n",
"- `column_transformations`: (Optional): Transformations to apply to the input columns\n",
"- `optimization_objective`: The optimization objective to minimize or maximize.\n",
" - binary classification:\n",
" - `minimize-log-loss`\n",
" - `maximize-au-roc`\n",
" - `maximize-au-prc`\n",
" - `maximize-precision-at-recall`\n",
" - `maximize-recall-at-precision`\n",
" - multi-class classification:\n",
" - `minimize-log-loss`\n",
" - regression:\n",
" - `minimize-rmse`\n",
" - `minimize-mae`\n",
" - `minimize-rmsle`\n",
"\n",
"The instantiated object is the DAG (directed acyclic graph) for the training pipeline."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "create_automl_pipeline:tabular,lrg,transformations"
},
"outputs": [],
"source": [
"job = aiplatform.AutoMLTabularTrainingJob(\n",
" display_name=\"gsod_\" + TIMESTAMP,\n",
" optimization_prediction_type=\"regression\",\n",
" optimization_objective=\"minimize-rmse\",\n",
" column_transformations=TRANSFORMATIONS,\n",
")\n",
"\n",
"print(job)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "run_automl_pipeline:tabular"
},
"source": [
"#### Run the training pipeline\n",
"\n",
"Next, you run the DAG (object 'job') to start the training job by invoking the method `run`, with the following parameters:\n",
"\n",
"- `dataset`: The `Dataset` resource to train the model.\n",
"- `model_display_name`: The human readable name for the trained model.\n",
"- `training_fraction_split`: The percentage of the dataset to use for training.\n",
"- `test_fraction_split`: The percentage of the dataset to use for test (holdout data).\n",
"- `validation_fraction_split`: The percentage of the dataset to use for validation.\n",
"- `target_column`: The name of the column to train as the label.\n",
"- `budget_milli_node_hours`: (optional) Maximum training time specified in unit of millihours (1000 = hour).\n",
"- `disable_early_stopping`: If `True`, training maybe completed before using the entire budget if the service believes it cannot further improve on the model objective measurements.\n",
"\n",
"The `run` method when completed returns the `Model` resource.\n",
"\n",
"The execution of the training pipeline will take upto 8 hours."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "run_automl_pipeline:tabular"
},
"outputs": [],
"source": [
"model = job.run(\n",
" dataset=dataset,\n",
" model_display_name=\"gsod_\" + TIMESTAMP,\n",
" training_fraction_split=0.6,\n",
" validation_fraction_split=0.2,\n",
" test_fraction_split=0.2,\n",
" budget_milli_node_hours=8000,\n",
" disable_early_stopping=False,\n",
" target_column=label_column,\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "evaluate_the_model:mbsdk"
},
"source": [
"## Review model evaluation scores\n",
"After your model has finished training, you can review the evaluation scores for it.\n",
"\n",
"First, you need to get a reference to the new model. As with datasets, you can either use the reference to the model variable you created when you deployed the model or you can list all of the models in your project."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "evaluate_the_model:mbsdk"
},
"outputs": [],
"source": [
"# Get model resource ID\n",
"models = aiplatform.Model.list(filter=\"display_name=gsod_\" + TIMESTAMP)\n",
"\n",
"# Get a reference to the Model Service client\n",
"client_options = {\"api_endpoint\": f\"{REGION}-aiplatform.googleapis.com\"}\n",
"model_service_client = aiplatform.gapic.ModelServiceClient(\n",
" client_options=client_options\n",
")\n",
"\n",
"model_evaluations = model_service_client.list_model_evaluations(\n",
" parent=models[0].resource_name\n",
")\n",
"model_evaluation = list(model_evaluations)[0]\n",
"print(model_evaluation)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "deploy_model:mbsdk,dedicated"
},
"source": [
"## Deploy the model\n",
"\n",
"Next, deploy your model for online prediction. To deploy the model, you invoke the `deploy` method, with the following parameters:\n",
"\n",
"- `machine_type`: The type of compute machine."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "deploy_model:mbsdk,dedicated"
},
"outputs": [],
"source": [
"endpoint = model.deploy(machine_type=\"n1-standard-4\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "make_prediction"
},
"source": [
"## Send a online prediction request\n",
"\n",
"Send a online prediction to your deployed model."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "make_test_item:automl,online_prediction"
},
"source": [
"### Make test item\n",
"\n",
"You will use synthetic data as a test data item. Don't be concerned that we are using synthetic data -- we just want to demonstrate how to make a prediction."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "make_test_item:automl,tabular,gsod"
},
"outputs": [],
"source": [
"INSTANCE = {\"year\": \"1932\", \"month\": \"11\", \"day\": \"6\"}"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "predict_request:mbsdk,lrg"
},
"source": [
"### Make the prediction\n",
"\n",
"Now that your `Model` resource is deployed to an `Endpoint` resource, you can do online predictions by sending prediction requests to the `Endpoint` resource.\n",
"\n",
"#### Request\n",
"\n",
"The format of each instance is:\n",
"\n",
" [feature_list]\n",
"\n",
"Since the predict() method can take multiple items (instances), send your single test item as a list of one test item.\n",
"\n",
"#### Response\n",
"\n",
"The response from the predict() call is a Python dictionary with the following entries:\n",
"\n",
"- `ids`: The internal assigned unique identifiers for each prediction request.\n",
"- `value`: The predicted value for each prediction.\n",
"- `deployed_model_id`: The Vertex AI identifier for the deployed `Model` resource which did the predictions."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "predict_request:mbsdk,lrg"
},
"outputs": [],
"source": [
"instances_list = [INSTANCE]\n",
"\n",
"prediction = endpoint.predict(instances_list)\n",
"print(prediction)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "undeploy_model:mbsdk"
},
"source": [
"## Undeploy the model\n",
"\n",
"When you are done doing predictions, you undeploy the model from the `Endpoint` resouce. This deprovisions all compute resources and ends billing for the deployed model."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "undeploy_model:mbsdk"
},
"outputs": [],
"source": [
"endpoint.undeploy_all()"
]
},
{
"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:\n",
"\n",
"- Dataset\n",
"- Model\n",
"- Endpoint\n",
"- AutoML Training Job"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "cleanup:mbsdk"
},
"outputs": [],
"source": [
"delete_all = True\n",
"\n",
"if delete_all:\n",
" # Delete the dataset using the Vertex dataset object\n",
" dataset.delete()\n",
"\n",
" # Delete the model using the Vertex model object\n",
" model.delete()\n",
"\n",
" # Delete the endpoint using the Vertex endpoint object\n",
" endpoint.delete()\n",
"\n",
" # Delete the AutoML trainig job\n",
" job.delete()\n",
"\n",
" if os.getenv(\"IS_TESTING\"):\n",
" ! gsutil rm -r $BUCKET_URI"
]
}
],
"metadata": {
"colab": {
"name": "sdk_automl_tabular_regression_online_bq.ipynb",
"toc_visible": true
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
@@ -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",
@@ -29,23 +29,24 @@
"id": "title"
},
"source": [
"# Vertex SDK: AutoML training text entity extraction model for online prediction\n",
"# Vertex AI SDK for Python: AutoML training text entity extraction model for online prediction\n",
"\n",
"<table align=\"left\">\n",
" <td>\n",
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/vertex-ai-samples/tree/master/notebooks/official/automl/sdk_automl_text_entity_extraction_online.ipynb\">\n",
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/official/automl/sdk_automl_text_entity_extraction_online.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/tree/master/notebooks/official/automl/sdk_automl_text_entity_extraction_online.ipynb\">\n",
" <a href=\"https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/official/automl/sdk_automl_text_entity_extraction_online.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/ai/platform/notebooks/deploy-notebook?download_url=https://github.com/GoogleCloudPlatform/vertex-ai-samples/tree/master/notebooks/official/automl/sdk_automl_text_entity_extraction_online.ipynb\">\n",
" Open in Google Cloud Notebooks\n",
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://github.com/GoogleCloudPlatform/vertex-ai-samples/tree/master/notebooks/official/automl/sdk_automl_text_entity_extraction_online.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",
@@ -61,7 +62,7 @@
"## Overview\n",
"\n",
"\n",
"This tutorial demonstrates how to use the Vertex SDK to create text entity extraction models and do online prediction using a Google Cloud [AutoML](https://cloud.google.com/vertex-ai/docs/start/automl-users) model."
"This tutorial demonstrates how to use the Vertex AI SDK for Python to create text entity extraction models and do online prediction using a Google Cloud [AutoML](https://cloud.google.com/vertex-ai/docs/start/automl-users) model."
]
},
{
@@ -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",
@@ -33,18 +33,18 @@
"\n",
"<table align=\"left\">\n",
" <td>\n",
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/vertex-ai-samples/tree/master/notebooks/official/automl/sdk_automl_text_sentiment_analysis_online.ipynb\">\n",
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/official/automl/sdk_automl_text_sentiment_analysis_online.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/tree/master/notebooks/official/automl/sdk_automl_text_sentiment_analysis_online.ipynb\">\n",
" <a href=\"https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/official/automl/sdk_automl_text_sentiment_analysis_online.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/ai/platform/notebooks/deploy-notebook?download_url=https://github.com/GoogleCloudPlatform/vertex-ai-samples/tree/master/notebooks/official/automl/sdk_automl_text_sentiment_analysis_online.ipynb\">\n",
" <a href=\"https://console.cloud.google.com/ai/platform/notebooks/deploy-notebook?download_url=https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/official/automl/sdk_automl_text_sentiment_analysis_online.ipynb\">\n",
" Open in Google Cloud Notebooks\n",
" </a>\n",
" </td>\n",
@@ -72,7 +72,7 @@
"source": [
"### Dataset\n",
"\n",
"The dataset used for this tutorial is the [Crowdflower Claritin-Twitter dataset](https://data.world/crowdflower/claritin-twitter) from [data.world Datasets](https://data.world). The version of the dataset you will use in this tutorial is stored in a public Cloud Storage bucket."
"The dataset used for this tutorial is the [Crowdflower Claritin-Twitter dataset](https://data.world/crowdflower/claritin-twitter) that consists of tweets tagged with sentiment, the author's gender, and whether or not they mention any of the top 10 adverse events reported to the FDA. The version of the dataset you will use in this tutorial is stored in a public Cloud Storage bucket. In this tutorial, you will use the tweets' data to build an AutoML-text-sentiment-analysis model on Google Cloud platform."
]
},
{
@@ -88,7 +88,7 @@
"The steps performed include:\n",
"\n",
"- Create a Vertex `Dataset` resource.\n",
"- Train the model.\n",
"- Create a training job for the model.\n",
"- View the model evaluation.\n",
"- Deploy the `Model` resource to a serving `Endpoint` resource.\n",
"- Make a prediction.\n",
@@ -184,7 +184,9 @@
"id": "install_storage"
},
"source": [
"Install the latest GA version of *google-cloud-storage* library as well."
"Install the latest GA version of *google-cloud-storage* library as well.\n",
"\n",
"**Note**: You may encounter a PIP dependency error during the installation of the Google Cloud Storage package. This can be ignored as it will not affect the proper running of this script."
]
},
{
@@ -198,18 +200,6 @@
"! pip3 install -U google-cloud-storage $USER_FLAG"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "install_tensorflow"
},
"outputs": [],
"source": [
"if os.environ[\"IS_TESTING\"]:\n",
" ! pip3 install --upgrade tensorflow $USER_FLAG"
]
},
{
"cell_type": "markdown",
"metadata": {
@@ -218,7 +208,7 @@
"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."
"Once you've installed the additional packages, you need to restart the notebook kernel so it can find the packages. The following cell will restart the kernel."
]
},
{
@@ -334,7 +324,10 @@
},
"outputs": [],
"source": [
"REGION = \"us-central1\" # @param {type: \"string\"}"
"REGION = \"[your-region]\" # @param {type: \"string\"}\n",
"\n",
"if REGION == \"[your-region]\":\n",
" REGION = \"us-central1\""
]
},
{
@@ -516,7 +509,7 @@
},
"outputs": [],
"source": [
"import google.cloud.aiplatform as aip"
"import google.cloud.aiplatform as aiplatform"
]
},
{
@@ -538,7 +531,7 @@
},
"outputs": [],
"source": [
"aip.init(project=PROJECT_ID, staging_bucket=BUCKET_NAME)"
"aiplatform.init(project=PROJECT_ID, staging_bucket=BUCKET_NAME)"
]
},
{
@@ -596,10 +589,7 @@
},
"outputs": [],
"source": [
"if \"IMPORT_FILES\" in globals():\n",
" FILE = IMPORT_FILES[0]\n",
"else:\n",
" FILE = IMPORT_FILE\n",
"FILE = IMPORT_FILE\n",
"\n",
"count = ! gsutil cat $FILE | wc -l\n",
"print(\"Number of Examples\", int(count[0]))\n",
@@ -633,10 +623,10 @@
},
"outputs": [],
"source": [
"dataset = aip.TextDataset.create(\n",
"dataset = aiplatform.TextDataset.create(\n",
" display_name=\"Crowdflower Claritin-Twitter\" + \"_\" + TIMESTAMP,\n",
" gcs_source=[IMPORT_FILE],\n",
" import_schema_uri=aip.schema.dataset.ioformat.text.sentiment,\n",
" import_schema_uri=aiplatform.schema.dataset.ioformat.text.sentiment,\n",
")\n",
"\n",
"print(dataset.resource_name)"
@@ -662,9 +652,7 @@
" - `sentiment`: A text sentiment analysis model.\n",
" - `extraction`: A text entity extraction model.\n",
"- `multi_label`: If a classification task, whether single (False) or multi-labeled (True).\n",
"- `sentiment_max`: If a sentiment analysis task, the maximum sentiment value.\n",
"\n",
"The instantiated object is the DAG (directed acyclic graph) for the training pipeline."
"- `sentiment_max`: If a sentiment analysis task, the maximum sentiment value."
]
},
{
@@ -675,13 +663,13 @@
},
"outputs": [],
"source": [
"dag = aip.AutoMLTextTrainingJob(\n",
"job = aiplatform.AutoMLTextTrainingJob(\n",
" display_name=\"claritin_\" + TIMESTAMP,\n",
" prediction_type=\"sentiment\",\n",
" sentiment_max=SENTIMENT_MAX,\n",
")\n",
"\n",
"print(dag)"
"print(job)"
]
},
{
@@ -692,7 +680,7 @@
"source": [
"#### Run the training pipeline\n",
"\n",
"Next, you run the DAG to start the training job by invoking the method `run`, with the following parameters:\n",
"Next, you run the training job by invoking the method `run`, with the following parameters:\n",
"\n",
"- `dataset`: The `Dataset` resource to train the model.\n",
"- `model_display_name`: The human readable name for the trained model.\n",
@@ -702,7 +690,7 @@
"\n",
"The `run` method when completed returns the `Model` resource.\n",
"\n",
"The execution of the training pipeline will take upto 20 minutes."
"The execution of the training pipeline will take upto 180 minutes."
]
},
{
@@ -713,7 +701,7 @@
},
"outputs": [],
"source": [
"model = dag.run(\n",
"model = job.run(\n",
" dataset=dataset,\n",
" model_display_name=\"claritin_\" + TIMESTAMP,\n",
" training_fraction_split=0.8,\n",
@@ -743,11 +731,13 @@
"outputs": [],
"source": [
"# Get model resource ID\n",
"models = aip.Model.list(filter=\"display_name=claritin_\" + TIMESTAMP)\n",
"models = aiplatform.Model.list(filter=\"display_name=claritin_\" + TIMESTAMP)\n",
"\n",
"# Get a reference to the Model Service client\n",
"client_options = {\"api_endpoint\": f\"{REGION}-aiplatform.googleapis.com\"}\n",
"model_service_client = aip.gapic.ModelServiceClient(client_options=client_options)\n",
"model_service_client = aiplatform.gapic.ModelServiceClient(\n",
" client_options=client_options\n",
")\n",
"\n",
"model_evaluations = model_service_client.list_model_evaluations(\n",
" parent=models[0].resource_name\n",
@@ -894,13 +884,9 @@
"Otherwise, you can delete the individual resources you created in this tutorial:\n",
"\n",
"- Dataset\n",
"- Pipeline\n",
"- Model\n",
"- Endpoint\n",
"- AutoML Training Job\n",
"- Batch Job\n",
"- Custom Job\n",
"- Hyperparameter Tuning Job\n",
"- Cloud Storage Bucket"
]
},
@@ -912,60 +898,21 @@
},
"outputs": [],
"source": [
"delete_all = True\n",
"# Delete the dataset using the Vertex dataset object\n",
"dataset.delete()\n",
"\n",
"if delete_all:\n",
" # Delete the dataset using the Vertex dataset object\n",
" try:\n",
" if \"dataset\" in globals():\n",
" dataset.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"# Delete the model using the Vertex model object\n",
"model.delete()\n",
"\n",
" # Delete the model using the Vertex model object\n",
" try:\n",
" if \"model\" in globals():\n",
" model.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"# Delete the endpoint using the Vertex endpoint object\n",
"endpoint.delete()\n",
"\n",
" # Delete the endpoint using the Vertex endpoint object\n",
" try:\n",
" if \"endpoint\" in globals():\n",
" endpoint.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"# Delete the AutoML or Pipeline training job\n",
"job.delete()\n",
"\n",
" # Delete the AutoML or Pipeline trainig job\n",
" try:\n",
" if \"dag\" in globals():\n",
" dag.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the custom trainig job\n",
" try:\n",
" if \"job\" in globals():\n",
" job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the batch prediction job using the Vertex batch prediction object\n",
" try:\n",
" if \"batch_predict_job\" in globals():\n",
" batch_predict_job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the hyperparameter tuning job using the Vertex hyperparameter tuning object\n",
" try:\n",
" if \"hpt_job\" in globals():\n",
" hpt_job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" if \"BUCKET_NAME\" in globals():\n",
" ! gsutil rm -r $BUCKET_NAME"
"# Delete the Cloud storage bucket\n",
"if os.getenv(\"IS_TESTING\"):\n",
" ! gsutil rm -r $BUCKET_NAME"
]
}
],
@@ -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",
@@ -33,18 +33,18 @@
"\n",
"<table align=\"left\">\n",
" <td>\n",
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/vertex-ai-samples/tree/master/notebooks/official/automl/sdk_automl_video_action_recognition_batch.ipynb\">\n",
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/official/automl/sdk_automl_video_action_recognition_batch.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/tree/master/notebooks/official/automl/sdk_automl_video_action_recognition_batch.ipynb\">\n",
" <a href=\"https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/official/automl/sdk_automl_video_action_recognition_batch.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/ai/platform/notebooks/deploy-notebook?download_url=https://github.com/GoogleCloudPlatform/vertex-ai-samples/tree/master/notebooks/official/automl/sdk_automl_video_action_recognition_batch.ipynb\">\n",
" <a href=\"https://console.cloud.google.com/ai/platform/notebooks/deploy-notebook?download_url=https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/official/automl/sdk_automl_video_action_recognition_batch.ipynb\">\n",
" Open in Google Cloud Notebooks\n",
" </a>\n",
" </td>\n",
@@ -72,7 +72,7 @@
"source": [
"### Dataset\n",
"\n",
"The dataset used for this tutorial is the golf swing recognition portion of the [Human Motion dataset](https://todo) from [MIT](http://cbcl.mit.edu/publications/ps/Kuehne_etal_iccv11.pdf). The version of the dataset you will use in this tutorial is stored in a public Cloud Storage bucket. The trained model will predict the start frame where a golf swing begins."
"The dataset used for this tutorial is the golf swing recognition portion of the [Human Motion dataset from MIT](http://cbcl.mit.edu/publications/ps/Kuehne_etal_iccv11.pdf). The version of the dataset you will use in this tutorial is stored in a public Cloud Storage bucket. The trained model will predict the start frame where an action of golf swing begins."
]
},
{
@@ -188,7 +188,9 @@
"id": "install_storage"
},
"source": [
"Install the latest GA version of *google-cloud-storage* library as well."
"Install the latest GA version of *google-cloud-storage* library as well.\n",
"\n",
"**Note**: You may encounter a PIP dependency error during the installation of the Google Cloud Storage package. This can be ignored as it will not affect the proper running of this script."
]
},
{
@@ -202,18 +204,6 @@
"! pip3 install -U google-cloud-storage $USER_FLAG"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "install_tensorflow"
},
"outputs": [],
"source": [
"if os.environ[\"IS_TESTING\"]:\n",
" ! pip3 install --upgrade tensorflow $USER_FLAG"
]
},
{
"cell_type": "markdown",
"metadata": {
@@ -222,7 +212,7 @@
"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."
"Once you've installed the additional packages, you need to restart the notebook kernel so it can find the packages. The following cell will restart the kernel."
]
},
{
@@ -338,7 +328,10 @@
},
"outputs": [],
"source": [
"REGION = \"us-central1\" # @param {type: \"string\"}"
"REGION = \"[your-region]\" # @param {type: \"string\"}\n",
"\n",
"if REGION == \"[your-region]\":\n",
" REGION = \"us-central1\""
]
},
{
@@ -520,7 +513,7 @@
},
"outputs": [],
"source": [
"import google.cloud.aiplatform as aip"
"import google.cloud.aiplatform as aiplatform"
]
},
{
@@ -542,7 +535,7 @@
},
"outputs": [],
"source": [
"aip.init(project=PROJECT_ID, staging_bucket=BUCKET_NAME)"
"aiplatform.init(project=PROJECT_ID, staging_bucket=BUCKET_NAME)"
]
},
{
@@ -564,7 +557,7 @@
"source": [
"#### Location of Cloud Storage training data.\n",
"\n",
"Now set the variable `IMPORT_FILE` to the location of the CSV index file in Cloud Storage."
"Now set the variable `IMPORT_FILES` to the location of the CSV index files in Cloud Storage."
]
},
{
@@ -602,10 +595,7 @@
},
"outputs": [],
"source": [
"if \"IMPORT_FILES\" in globals():\n",
" FILE = IMPORT_FILES[0]\n",
"else:\n",
" FILE = IMPORT_FILE\n",
"FILE = IMPORT_FILES[0]\n",
"\n",
"count = ! gsutil cat $FILE | wc -l\n",
"print(\"Number of Examples\", int(count[0]))\n",
@@ -638,10 +628,10 @@
},
"outputs": [],
"source": [
"dataset = aip.VideoDataset.create(\n",
"dataset = aiplatform.VideoDataset.create(\n",
" display_name=\"Golf Swings\" + \"_\" + TIMESTAMP,\n",
" gcs_source=IMPORT_FILES,\n",
" import_schema_uri=aip.schema.dataset.ioformat.video.action_recognition,\n",
" import_schema_uri=aiplatform.schema.dataset.ioformat.video.action_recognition,\n",
")\n",
"\n",
"print(dataset.resource_name)"
@@ -665,9 +655,7 @@
"- `prediction_type`: The type task to train the model for.\n",
" - `classification`: A video classification model.\n",
" - `object_tracking`: A video object tracking model.\n",
" - `action_recognition`: A video action recognition model.\n",
"\n",
"The instantiated object is the DAG (directed acyclic graph) for the training pipeline."
" - `action_recognition`: A video action recognition model."
]
},
{
@@ -678,12 +666,12 @@
},
"outputs": [],
"source": [
"dag = aip.AutoMLVideoTrainingJob(\n",
"job = aiplatform.AutoMLVideoTrainingJob(\n",
" display_name=\"golf_\" + TIMESTAMP,\n",
" prediction_type=\"action_recognition\",\n",
")\n",
"\n",
"print(dag)"
"print(job)"
]
},
{
@@ -694,7 +682,7 @@
"source": [
"#### Run the training pipeline\n",
"\n",
"Next, you run the DAG to start the training job by invoking the method `run`, with the following parameters:\n",
"Next, you run the training job by invoking the method `run`, with the following parameters:\n",
"\n",
"- `dataset`: The `Dataset` resource to train the model.\n",
"- `model_display_name`: The human readable name for the trained model.\n",
@@ -703,7 +691,7 @@
"\n",
"The `run` method when completed returns the `Model` resource.\n",
"\n",
"The execution of the training pipeline will take upto 20 minutes."
"The execution of the training pipeline can take upto 40 minutes."
]
},
{
@@ -714,7 +702,7 @@
},
"outputs": [],
"source": [
"model = dag.run(\n",
"model = job.run(\n",
" dataset=dataset,\n",
" model_display_name=\"golf_\" + TIMESTAMP,\n",
" training_fraction_split=0.8,\n",
@@ -743,11 +731,13 @@
"outputs": [],
"source": [
"# Get model resource ID\n",
"models = aip.Model.list(filter=\"display_name=golf_\" + TIMESTAMP)\n",
"models = aiplatform.Model.list(filter=\"display_name=golf_\" + TIMESTAMP)\n",
"\n",
"# Get a reference to the Model Service client\n",
"client_options = {\"api_endpoint\": f\"{REGION}-aiplatform.googleapis.com\"}\n",
"model_service_client = aip.gapic.ModelServiceClient(client_options=client_options)\n",
"model_service_client = aiplatform.gapic.ModelServiceClient(\n",
" client_options=client_options\n",
")\n",
"\n",
"model_evaluations = model_service_client.list_model_evaluations(\n",
" parent=models[0].resource_name\n",
@@ -775,7 +765,7 @@
"source": [
"### Get test item(s)\n",
"\n",
"Now do a batch prediction to your Vertex model. You will use arbitrary examples out of the dataset as a test items. Don't be concerned that the examples were likely used in training the model -- we just want to demonstrate how to make a prediction."
"Now do a batch prediction to your Vertex model. You will use arbitrary examples out of the dataset as a test items. Don't be concerned that the examples were likely used in training the model as we just want to demonstrate how to make a prediction."
]
},
{
@@ -821,31 +811,38 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "make_batch_file:automl,video"
"id": "13a02e5067ab"
},
"outputs": [],
"source": [
"import json\n",
"\n",
"import tensorflow as tf\n",
"from google.cloud import storage\n",
"\n",
"gcs_input_uri = BUCKET_NAME + \"/test.jsonl\"\n",
"with tf.io.gfile.GFile(gcs_input_uri, \"w\") as f:\n",
" data = {\n",
" \"content\": test_item_1,\n",
" \"mimeType\": \"video/avi\",\n",
" \"timeSegmentStart\": \"0.0s\",\n",
" \"timeSegmentEnd\": \"5.0s\",\n",
" }\n",
" f.write(json.dumps(data) + \"\\n\")\n",
" data = {\n",
" \"content\": test_item_2,\n",
" \"mimeType\": \"video/avi\",\n",
" \"timeSegmentStart\": \"0.0s\",\n",
" \"timeSegmentEnd\": \"5.0s\",\n",
" }\n",
" f.write(json.dumps(data) + \"\\n\")\n",
"test_filename = \"test.jsonl\"\n",
"gcs_input_uri = BUCKET_NAME + \"/\" + test_filename\n",
"\n",
"# Configure the test-data\n",
"data_1 = {\n",
" \"content\": test_item_1,\n",
" \"mimeType\": \"video/avi\",\n",
" \"timeSegmentStart\": \"0.0s\",\n",
" \"timeSegmentEnd\": \"5.0s\",\n",
"}\n",
"data_2 = {\n",
" \"content\": test_item_2,\n",
" \"mimeType\": \"video/avi\",\n",
" \"timeSegmentStart\": \"0.0s\",\n",
" \"timeSegmentEnd\": \"5.0s\",\n",
"}\n",
"\n",
"# Upload the test-data to Cloud storage bucket\n",
"bucket = storage.Client(project=PROJECT_ID).bucket(BUCKET_NAME.replace(\"gs://\", \"\"))\n",
"blob = bucket.blob(blob_name=test_filename)\n",
"data = json.dumps(data_1) + \"\\n\" + json.dumps(data_2) + \"\\n\"\n",
"blob.upload_from_string(data)\n",
"\n",
"# Check the Cloud storage uri\n",
"print(gcs_input_uri)\n",
"! gsutil cat $gcs_input_uri"
]
@@ -931,14 +928,10 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "get_batch_prediction:mbsdk,var"
"id": "76f7d62916bc"
},
"outputs": [],
"source": [
"import json\n",
"\n",
"import tensorflow as tf\n",
"\n",
"bp_iter_outputs = batch_predict_job.iter_outputs()\n",
"\n",
"prediction_results = list()\n",
@@ -946,14 +939,13 @@
" if blob.name.split(\"/\")[-1].startswith(\"prediction\"):\n",
" prediction_results.append(blob.name)\n",
"\n",
"tags = list()\n",
"for prediction_result in prediction_results:\n",
" gfile_name = f\"gs://{bp_iter_outputs.bucket.name}/{prediction_result}\"\n",
" with tf.io.gfile.GFile(name=gfile_name, mode=\"r\") as gfile:\n",
" for line in gfile.readlines():\n",
" line = json.loads(line)\n",
" print(line)\n",
" break"
" gfile_name = f\"gs://{bp_iter_outputs.bucket.name}/{prediction_result}\".replace(\n",
" BUCKET_NAME + \"/\", \"\"\n",
" )\n",
" data = bucket.get_blob(gfile_name).download_as_string()\n",
" data = json.loads(data)\n",
" print(data)"
]
},
{
@@ -970,13 +962,9 @@
"Otherwise, you can delete the individual resources you created in this tutorial:\n",
"\n",
"- Dataset\n",
"- Pipeline\n",
"- Model\n",
"- Endpoint\n",
"- AutoML Training Job\n",
"- Batch Job\n",
"- Custom Job\n",
"- Hyperparameter Tuning Job\n",
"- Cloud Storage Bucket"
]
},
@@ -988,60 +976,21 @@
},
"outputs": [],
"source": [
"delete_all = True\n",
"# Delete the dataset using the Vertex dataset object\n",
"dataset.delete()\n",
"\n",
"if delete_all:\n",
" # Delete the dataset using the Vertex dataset object\n",
" try:\n",
" if \"dataset\" in globals():\n",
" dataset.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"# Delete the model using the Vertex model object\n",
"model.delete()\n",
"\n",
" # Delete the model using the Vertex model object\n",
" try:\n",
" if \"model\" in globals():\n",
" model.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"# Delete the AutoML or Pipeline training job\n",
"job.delete()\n",
"\n",
" # Delete the endpoint using the Vertex endpoint object\n",
" try:\n",
" if \"endpoint\" in globals():\n",
" endpoint.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"# Delete the batch prediction job using the Vertex batch prediction object\n",
"batch_predict_job.delete()\n",
"\n",
" # Delete the AutoML or Pipeline trainig job\n",
" try:\n",
" if \"dag\" in globals():\n",
" dag.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the custom trainig job\n",
" try:\n",
" if \"job\" in globals():\n",
" job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the batch prediction job using the Vertex batch prediction object\n",
" try:\n",
" if \"batch_predict_job\" in globals():\n",
" batch_predict_job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" # Delete the hyperparameter tuning job using the Vertex hyperparameter tuning object\n",
" try:\n",
" if \"hpt_job\" in globals():\n",
" hpt_job.delete()\n",
" except Exception as e:\n",
" print(e)\n",
"\n",
" if \"BUCKET_NAME\" in globals():\n",
" ! gsutil rm -r $BUCKET_NAME"
"# Delete the Cloud Storage bucket\n",
"if os.getenv(\"IS_TESTING\"):\n",
" ! gsutil rm -r $BUCKET_NAME"
]
}
],
@@ -33,19 +33,20 @@
"\n",
"<table align=\"left\">\n",
" <td>\n",
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/vertex-ai-samples/tree/master/notebooks/official/automl/sdk_automl_video_classification_batch.ipynb\">\n",
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/official/automl/sdk_automl_video_classification_batch.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/tree/master/notebooks/official/automl/sdk_automl_video_classification_batch.ipynb\">\n",
" <a href=\"https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/official/automl/sdk_automl_video_classification_batch.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/ai/platform/notebooks/deploy-notebook?download_url=https://github.com/GoogleCloudPlatform/vertex-ai-samples/tree/master/notebooks/official/automl/sdk_automl_video_classification_batch.ipynb\">\n",
" Open in Google Cloud Notebooks\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/automl/sdk_automl_video_classification_batch.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",
@@ -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",
@@ -29,23 +29,24 @@
"id": "title"
},
"source": [
"# Vertex SDK: AutoML training video object tracking model for batch prediction\n",
"# Vertex AI SDK for Python: AutoML training video object tracking model for batch prediction\n",
"\n",
"<table align=\"left\">\n",
" <td>\n",
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/vertex-ai-samples/tree/master/notebooks/official/automl/sdk_automl_video_object_tracking_batch.ipynb\">\n",
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/official/automl/sdk_automl_video_object_tracking_batch.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/tree/master/notebooks/official/automl/sdk_automl_video_object_tracking_batch.ipynb\">\n",
" <a href=\"https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/official/automl/sdk_automl_video_object_tracking_batch.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/ai/platform/notebooks/deploy-notebook?download_url=https://github.com/GoogleCloudPlatform/vertex-ai-samples/tree/master/notebooks/official/automl/sdk_automl_video_object_tracking_batch.ipynb\">\n",
" Open in Google Cloud Notebooks\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/automl/sdk_automl_video_object_tracking_batch.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",
@@ -61,7 +62,7 @@
"## Overview\n",
"\n",
"\n",
"This tutorial demonstrates how to use the Vertex SDK to create video object tracking models and do batch prediction using a Google Cloud [AutoML](https://cloud.google.com/vertex-ai/docs/start/automl-users) model."
"This tutorial demonstrates how to use the Vertex AI SDK for Python to create video object tracking models and do batch prediction using a Google Cloud [AutoML](https://cloud.google.com/vertex-ai/docs/start/automl-users) model."
]
},
{
@@ -8,7 +8,7 @@
},
"outputs": [],
"source": [
"# Copyright 2020 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",
@@ -43,6 +43,12 @@
" 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://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/official/custom/custom-tabular-bq-managed-dataset.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>"
]
},
@@ -55,7 +61,7 @@
"## Overview\n",
"\n",
"\n",
"This tutorial demonstrates how to use the Vertex SDK for Python to train and deploy a custom tabular classification model for online prediction."
"This tutorial demonstrates how to use the Vertex AI SDK for Python to train and deploy a custom tabular classification model for online prediction."
]
},
{
@@ -116,7 +122,7 @@
"source": [
"## Installation\n",
"\n",
"Install the latest version of Vertex SDK for Python."
"Install the latest version of Vertex AI SDK for Python."
]
},
{
@@ -425,8 +431,8 @@
},
"outputs": [],
"source": [
"BUCKET_NAME = \"\" # @param {type:\"string\"}\n",
"REGION = \"us-central1\" # @param {type:\"string\"}"
"BUCKET_URI = \"gs://[your-bucket-name]\"\n",
"REGION = \"[your-region]\" # @param {type:\"string\"}"
]
},
{
@@ -437,8 +443,11 @@
},
"outputs": [],
"source": [
"if BUCKET_NAME == \"\" or BUCKET_NAME is None or BUCKET_NAME == \"gs://[your-bucket-name]\":\n",
" BUCKET_NAME = \"gs://\" + PROJECT_ID + \"aip-\" + TIMESTAMP"
"if BUCKET_URI == \"\" or BUCKET_URI is None or BUCKET_URI == \"gs://[your-bucket-name]\":\n",
" BUCKET_URI = \"gs://\" + PROJECT_ID + \"aip-\" + TIMESTAMP\n",
"\n",
"if REGION == \"[your-region]\":\n",
" REGION = \"us-central1\""
]
},
{
@@ -458,7 +467,7 @@
},
"outputs": [],
"source": [
"! gsutil mb -l $REGION $BUCKET_NAME"
"! gsutil mb -l $REGION $BUCKET_URI\n"
]
},
{
@@ -478,7 +487,7 @@
},
"outputs": [],
"source": [
"! gsutil ls -al $BUCKET_NAME"
"! gsutil ls -al $BUCKET_URI"
]
},
{
@@ -498,9 +507,9 @@
"id": "import_aip"
},
"source": [
"### Import Vertex SDK for Python\n",
"### Import Vertex AI SDK for Python\n",
"\n",
"Import the Vertex SDK for Python into your Python environment and initialize it."
"Import the Vertex AI SDK for Python into your Python environment and initialize it."
]
},
{
@@ -511,13 +520,15 @@
},
"outputs": [],
"source": [
"import json\n",
"import os\n",
"import sys\n",
"\n",
"from google.cloud import aiplatform\n",
"import numpy as np\n",
"from google.cloud import aiplatform, bigquery\n",
"from google.cloud.aiplatform import gapic as aip\n",
"\n",
"aiplatform.init(project=PROJECT_ID, location=REGION, staging_bucket=BUCKET_NAME)"
"aiplatform.init(project=PROJECT_ID, location=REGION, staging_bucket=BUCKET_URI)"
]
},
{
@@ -575,8 +586,8 @@
},
"outputs": [],
"source": [
"TRAIN_VERSION = \"tf-gpu.2-4\"\n",
"DEPLOY_VERSION = \"tf2-gpu.2-4\"\n",
"TRAIN_VERSION = \"tf-gpu.2-8\"\n",
"DEPLOY_VERSION = \"tf2-gpu.2-8\"\n",
"\n",
"TRAIN_IMAGE = \"us-docker.pkg.dev/vertex-ai/training/{}:latest\".format(TRAIN_VERSION)\n",
"DEPLOY_IMAGE = \"us-docker.pkg.dev/vertex-ai/prediction/{}:latest\".format(DEPLOY_VERSION)\n",
@@ -665,11 +676,7 @@
},
"outputs": [],
"source": [
"import json\n",
"\n",
"import numpy as np\n",
"# Calculate mean and std across all rows\n",
"from google.cloud import bigquery\n",
"\n",
"NA_VALUES = [\"NA\", \".\"]\n",
"\n",
@@ -724,7 +731,7 @@
" json.dump(mean_and_std, outfile)\n",
"\n",
"# Save to the staging bucket\n",
"! gsutil cp {MEAN_AND_STD_JSON_FILE} {BUCKET_NAME}"
"! gsutil cp {MEAN_AND_STD_JSON_FILE} {BUCKET_URI}"
]
},
{
@@ -807,7 +814,7 @@
" \"--epochs=\" + str(EPOCHS),\n",
" \"--batch_size=\" + str(BATCH_SIZE),\n",
" \"--distribute=\" + TRAIN_STRATEGY,\n",
" \"--mean_and_std_json_file=\" + f\"{BUCKET_NAME}/{MEAN_AND_STD_JSON_FILE}\",\n",
" \"--mean_and_std_json_file=\" + f\"{BUCKET_URI}/{MEAN_AND_STD_JSON_FILE}\",\n",
"]"
]
},
@@ -853,9 +860,9 @@
"from google.cloud import storage\n",
"\n",
"# Read environmental variables\n",
"training_data_uri = os.environ[\"AIP_TRAINING_DATA_URI\"]\n",
"validation_data_uri = os.environ[\"AIP_VALIDATION_DATA_URI\"]\n",
"test_data_uri = os.environ[\"AIP_TEST_DATA_URI\"]\n",
"training_data_uri = os.getenv(\"AIP_TRAINING_DATA_URI\")\n",
"validation_data_uri = os.getenv(\"AIP_VALIDATION_DATA_URI\")\n",
"test_data_uri = os.getenv(\"AIP_TEST_DATA_URI\")\n",
"\n",
"# Read args\n",
"parser = argparse.ArgumentParser()\n",
@@ -1128,7 +1135,7 @@
"# Train the model\n",
"model.fit(dataset_train, epochs=args.epochs, validation_data=dataset_validation)\n",
"\n",
"tf.saved_model.save(model, os.environ[\"AIP_MODEL_DIR\"])\n",
"tf.saved_model.save(model, os.getenv(\"AIP_MODEL_DIR\"))\n",
"\n",
"df_test.head()"
]
@@ -1175,7 +1182,7 @@
" display_name=JOB_NAME,\n",
" script_path=\"task.py\",\n",
" container_uri=TRAIN_IMAGE,\n",
" requirements=[\"google-cloud-bigquery>=2.20.0\"],\n",
" requirements=[\"google-cloud-bigquery>=2.20.0\", \"db-dtypes\"],\n",
" model_serving_container_image_uri=DEPLOY_IMAGE,\n",
")\n",
"\n",
@@ -1501,10 +1508,6 @@
},
"outputs": [],
"source": [
"delete_training_job = True\n",
"delete_model = True\n",
"delete_endpoint = True\n",
"\n",
"# Warning: Setting this to true will delete everything in your bucket\n",
"delete_bucket = False\n",
"\n",
@@ -1517,8 +1520,8 @@
"# Delete the endpoint\n",
"endpoint.delete()\n",
"\n",
"if delete_bucket and \"BUCKET_NAME\" in globals():\n",
" ! gsutil -m rm -r $BUCKET_NAME"
"if delete_bucket or os.getenv(\"IS_TESTING\"):\n",
" ! gsutil rm -r $BUCKET_URI"
]
}
],
@@ -1544,7 +1544,7 @@
},
"outputs": [],
"source": [
"if not os.environ[\"IS_TESTING\"]:\n",
"if not os.getenv(\"IS_TESTING\"):\n",
" batch_predict_job.wait()"
]
},
@@ -1572,7 +1572,7 @@
},
"outputs": [],
"source": [
"if not os.environ[\"IS_TESTING\"]:\n",
"if not os.getenv(\"IS_TESTING\"):\n",
" import tensorflow as tf\n",
"\n",
" bp_iter_outputs = batch_predict_job.iter_outputs()\n",
@@ -171,7 +171,7 @@
},
"outputs": [],
"source": [
"! pip install {USER_FLAG} --upgrade git+https://github.com/googleapis/python-aiplatform.git@v1.6.0"
"! pip install {USER_FLAG} --upgrade google-cloud-aiplatform"
]
},
{
@@ -266,7 +266,7 @@
"\n",
"# Get your Google Cloud project ID from gcloud\n",
"if not os.getenv(\"IS_TESTING\"):\n",
" shell_output=!gcloud config list --format 'value(core.project)' 2>/dev/null\n",
" shell_output = !gcloud config list --format 'value(core.project)' 2>/dev/null\n",
" PROJECT_ID = shell_output[0]\n",
" print(\"Project ID: \", PROJECT_ID)"
]
@@ -543,29 +543,22 @@
"outputs": [],
"source": [
"FEATURESTORE_ID = \"movie_prediction\"\n",
"create_lro = admin_client.create_featurestore(\n",
" featurestore_service_pb2.CreateFeaturestoreRequest(\n",
" parent=BASE_RESOURCE_PATH,\n",
" featurestore_id=FEATURESTORE_ID,\n",
" featurestore=featurestore_pb2.Featurestore(\n",
" online_serving_config=featurestore_pb2.Featurestore.OnlineServingConfig(\n",
" fixed_node_count=1\n",
"try:\n",
" create_lro = admin_client.create_featurestore(\n",
" featurestore_service_pb2.CreateFeaturestoreRequest(\n",
" parent=BASE_RESOURCE_PATH,\n",
" featurestore_id=FEATURESTORE_ID,\n",
" featurestore=featurestore_pb2.Featurestore(\n",
" online_serving_config=featurestore_pb2.Featurestore.OnlineServingConfig(\n",
" fixed_node_count=1\n",
" ),\n",
" ),\n",
" ),\n",
" )\n",
" )\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "57V8eVcB5VFZ"
},
"outputs": [],
"source": [
"# Wait for LRO to finish and get the LRO result.\n",
"print(create_lro.result())"
" # Wait for LRO to finish and get the LRO result.\n",
" print(create_lro.result())\n",
"except Exception as e:\n",
" print(e)"
]
},
{
@@ -590,6 +583,41 @@
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "018ab19d934f"
},
"source": [
"Auto scaling is available in v1beta1 since v1.11. Below is the example for the `CreateFeaturestoreRequest` with auto-scaling, use it with `aiplatform_v1beta1.FeaturestoreServiceClient` to create Featurestore:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "aea39718b5d3"
},
"outputs": [],
"source": [
"from google.cloud.aiplatform_v1beta1.types import \\\n",
" featurestore as v1beta1_featurestore_pb2\n",
"from google.cloud.aiplatform_v1beta1.types import \\\n",
" featurestore_service as v1beta1_featurestore_service_pb2\n",
"\n",
"create_featurestore_request = v1beta1_featurestore_service_pb2.CreateFeaturestoreRequest(\n",
" parent=BASE_RESOURCE_PATH,\n",
" featurestore_id=FEATURESTORE_ID,\n",
" featurestore=v1beta1_featurestore_pb2.Featurestore(\n",
" online_serving_config=v1beta1_featurestore_pb2.Featurestore.OnlineServingConfig(\n",
" scaling=v1beta1_featurestore_pb2.Featurestore.OnlineServingConfig.Scaling(\n",
" min_node_count=1, max_node_count=5\n",
" )\n",
" ),\n",
" ),\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
@@ -607,18 +635,20 @@
},
"outputs": [],
"source": [
"users_entity_type_lro = admin_client.create_entity_type(\n",
" featurestore_service_pb2.CreateEntityTypeRequest(\n",
" parent=admin_client.featurestore_path(PROJECT_ID, REGION, FEATURESTORE_ID),\n",
" entity_type_id=\"users\",\n",
" entity_type=entity_type_pb2.EntityType(\n",
" description=\"Users entity\",\n",
" ),\n",
"try:\n",
" users_entity_type_lro = admin_client.create_entity_type(\n",
" featurestore_service_pb2.CreateEntityTypeRequest(\n",
" parent=admin_client.featurestore_path(PROJECT_ID, REGION, FEATURESTORE_ID),\n",
" entity_type_id=\"users\",\n",
" entity_type=entity_type_pb2.EntityType(\n",
" description=\"Users entity\",\n",
" ),\n",
" )\n",
" )\n",
")\n",
"\n",
"# Similarly, wait for EntityType creation operation.\n",
"print(users_entity_type_lro.result())"
" # Similarly, wait for EntityType creation operation.\n",
" print(users_entity_type_lro.result())\n",
"except Exception as e:\n",
" print(e)"
]
},
{
@@ -630,16 +660,19 @@
"outputs": [],
"source": [
"# Create movies entity type without a monitoring configuration.\n",
"movies_entity_type_lro = admin_client.create_entity_type(\n",
" featurestore_service_pb2.CreateEntityTypeRequest(\n",
" parent=admin_client.featurestore_path(PROJECT_ID, REGION, FEATURESTORE_ID),\n",
" entity_type_id=\"movies\",\n",
" entity_type=entity_type_pb2.EntityType(description=\"Movies entity\"),\n",
"try:\n",
" movies_entity_type_lro = admin_client.create_entity_type(\n",
" featurestore_service_pb2.CreateEntityTypeRequest(\n",
" parent=admin_client.featurestore_path(PROJECT_ID, REGION, FEATURESTORE_ID),\n",
" entity_type_id=\"movies\",\n",
" entity_type=entity_type_pb2.EntityType(description=\"Movies entity\"),\n",
" )\n",
" )\n",
")\n",
"\n",
"# Similarly, wait for EntityType creation operation.\n",
"print(movies_entity_type_lro.result())"
" # Similarly, wait for EntityType creation operation.\n",
" print(movies_entity_type_lro.result())\n",
"except Exception as e:\n",
" print(e)"
]
},
{
@@ -648,7 +681,10 @@
"id": "85b1f59fbf6d"
},
"source": [
"Feature [monitoring](https://cloud.google.com/vertex-ai/docs/featurestore/monitoring) is in preview, so you need to use v1beta1 Python. The easiest way to set this for now is using [console UI](https://console.cloud.google.com/vertex-ai/features). For completeness, below is example to do this using v1beta1 SDK\n"
"Feature [monitoring](https://cloud.google.com/vertex-ai/docs/featurestore/monitoring) is in preview, so you need to use v1beta1 Python. The easiest way to set this for now is using [console UI](https://console.cloud.google.com/vertex-ai/features). For completeness, below is example to do this using v1beta1 SDK.\n",
"\n",
"\n",
"You can view monitoring statistics on [console UI](https://console.cloud.google.com/vertex-ai/features)."
]
},
{
@@ -708,32 +744,37 @@
"outputs": [],
"source": [
"# Create features for the 'users' entity.\n",
"admin_client.batch_create_features(\n",
" parent=admin_client.entity_type_path(PROJECT_ID, REGION, FEATURESTORE_ID, \"users\"),\n",
" requests=[\n",
" featurestore_service_pb2.CreateFeatureRequest(\n",
" feature=feature_pb2.Feature(\n",
" value_type=feature_pb2.Feature.ValueType.INT64,\n",
" description=\"User age\",\n",
" ),\n",
" feature_id=\"age\",\n",
"try:\n",
" admin_client.batch_create_features(\n",
" parent=admin_client.entity_type_path(\n",
" PROJECT_ID, REGION, FEATURESTORE_ID, \"users\"\n",
" ),\n",
" featurestore_service_pb2.CreateFeatureRequest(\n",
" feature=feature_pb2.Feature(\n",
" value_type=feature_pb2.Feature.ValueType.STRING,\n",
" description=\"User gender\",\n",
" requests=[\n",
" featurestore_service_pb2.CreateFeatureRequest(\n",
" feature=feature_pb2.Feature(\n",
" value_type=feature_pb2.Feature.ValueType.INT64,\n",
" description=\"User age\",\n",
" ),\n",
" feature_id=\"age\",\n",
" ),\n",
" feature_id=\"gender\",\n",
" ),\n",
" featurestore_service_pb2.CreateFeatureRequest(\n",
" feature=feature_pb2.Feature(\n",
" value_type=feature_pb2.Feature.ValueType.STRING_ARRAY,\n",
" description=\"An array of genres that this user liked\",\n",
" featurestore_service_pb2.CreateFeatureRequest(\n",
" feature=feature_pb2.Feature(\n",
" value_type=feature_pb2.Feature.ValueType.STRING,\n",
" description=\"User gender\",\n",
" ),\n",
" feature_id=\"gender\",\n",
" ),\n",
" feature_id=\"liked_genres\",\n",
" ),\n",
" ],\n",
").result()"
" featurestore_service_pb2.CreateFeatureRequest(\n",
" feature=feature_pb2.Feature(\n",
" value_type=feature_pb2.Feature.ValueType.STRING_ARRAY,\n",
" description=\"An array of genres that this user liked\",\n",
" ),\n",
" feature_id=\"liked_genres\",\n",
" ),\n",
" ],\n",
" ).result()\n",
"except Exception as e:\n",
" print(e)"
]
},
{
@@ -745,33 +786,37 @@
"outputs": [],
"source": [
"# Create features for movies type.\n",
"# 'title' Feature enables monitoring.\n",
"admin_client.batch_create_features(\n",
" parent=admin_client.entity_type_path(PROJECT_ID, REGION, FEATURESTORE_ID, \"movies\"),\n",
" requests=[\n",
" featurestore_service_pb2.CreateFeatureRequest(\n",
" feature=feature_pb2.Feature(\n",
" value_type=feature_pb2.Feature.ValueType.STRING,\n",
" description=\"The title of the movie\",\n",
" ),\n",
" feature_id=\"title\",\n",
"try:\n",
" admin_client.batch_create_features(\n",
" parent=admin_client.entity_type_path(\n",
" PROJECT_ID, REGION, FEATURESTORE_ID, \"movies\"\n",
" ),\n",
" featurestore_service_pb2.CreateFeatureRequest(\n",
" feature=feature_pb2.Feature(\n",
" value_type=feature_pb2.Feature.ValueType.STRING,\n",
" description=\"The genres of the movie\",\n",
" requests=[\n",
" featurestore_service_pb2.CreateFeatureRequest(\n",
" feature=feature_pb2.Feature(\n",
" value_type=feature_pb2.Feature.ValueType.STRING,\n",
" description=\"The title of the movie\",\n",
" ),\n",
" feature_id=\"title\",\n",
" ),\n",
" feature_id=\"genres\",\n",
" ),\n",
" featurestore_service_pb2.CreateFeatureRequest(\n",
" feature=feature_pb2.Feature(\n",
" value_type=feature_pb2.Feature.ValueType.DOUBLE,\n",
" description=\"The average rating for the movie, range is [1.0-5.0]\",\n",
" featurestore_service_pb2.CreateFeatureRequest(\n",
" feature=feature_pb2.Feature(\n",
" value_type=feature_pb2.Feature.ValueType.STRING,\n",
" description=\"The genres of the movie\",\n",
" ),\n",
" feature_id=\"genres\",\n",
" ),\n",
" feature_id=\"average_rating\",\n",
" ),\n",
" ],\n",
").result()"
" featurestore_service_pb2.CreateFeatureRequest(\n",
" feature=feature_pb2.Feature(\n",
" value_type=feature_pb2.Feature.ValueType.DOUBLE,\n",
" description=\"The average rating for the movie, range is [1.0-5.0]\",\n",
" ),\n",
" feature_id=\"average_rating\",\n",
" ),\n",
" ],\n",
" ).result()\n",
"except Exception as e:\n",
" print(e)"
]
},
{
@@ -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",
@@ -268,7 +268,7 @@
"\n",
"# Get your Google Cloud project ID from gcloud\n",
"if not os.getenv(\"IS_TESTING\"):\n",
" shell_output=! gcloud config list --format 'value(core.project)' 2>/dev/null\n",
" shell_output = ! gcloud config list --format 'value(core.project)' 2>/dev/null\n",
" PROJECT_ID = shell_output[0]\n",
" print(\"Project ID: \", PROJECT_ID)"
]
@@ -497,7 +497,6 @@
},
"outputs": [],
"source": [
"import json\n",
"import os\n",
"import re\n",
"import time\n",
@@ -169,7 +169,7 @@
},
"outputs": [],
"source": [
"if os.environ[\"IS_TESTING\"]:\n",
"if os.getenv(\"IS_TESTING\"):\n",
" ! pip3 install --upgrade tensorflow $USER_FLAG"
]
},
@@ -171,7 +171,7 @@
},
"outputs": [],
"source": [
"if os.environ[\"IS_TESTING\"]:\n",
"if os.getenv(\"IS_TESTING\"):\n",
" ! pip3 install --upgrade tensorflow $USER_FLAG"
]
},
@@ -169,7 +169,7 @@
},
"outputs": [],
"source": [
"if os.environ[\"IS_TESTING\"]:\n",
"if os.getenv(\"IS_TESTING\"):\n",
" ! pip3 install --upgrade tensorflow $USER_FLAG"
]
},
@@ -169,7 +169,7 @@
},
"outputs": [],
"source": [
"if os.environ[\"IS_TESTING\"]:\n",
"if os.getenv(\"IS_TESTING\"):\n",
" ! pip3 install --upgrade tensorflow $USER_FLAG"
]
},
@@ -169,7 +169,7 @@
},
"outputs": [],
"source": [
"if os.environ[\"IS_TESTING\"]:\n",
"if os.getenv(\"IS_TESTING\"):\n",
" ! apt-get update && apt-get install -y python3-opencv-headless\n",
" ! apt-get install -y libgl1-mesa-dev\n",
" ! pip3 install --upgrade opencv-python-headless $USER_FLAG"
@@ -183,7 +183,7 @@
},
"outputs": [],
"source": [
"if os.environ[\"IS_TESTING\"]:\n",
"if os.getenv(\"IS_TESTING\"):\n",
" ! pip3 install --upgrade tensorflow $USER_FLAG"
]
},
@@ -169,7 +169,7 @@
},
"outputs": [],
"source": [
"if os.environ[\"IS_TESTING\"]:\n",
"if os.getenv(\"IS_TESTING\"):\n",
" ! apt-get update && apt-get install -y python3-opencv-headless\n",
" ! apt-get install -y libgl1-mesa-dev\n",
" ! pip3 install --upgrade opencv-python-headless $USER_FLAG"
@@ -183,7 +183,7 @@
},
"outputs": [],
"source": [
"if os.environ[\"IS_TESTING\"]:\n",
"if os.getenv(\"IS_TESTING\"):\n",
" ! pip3 install --upgrade tensorflow $USER_FLAG"
]
},

Some files were not shown because too many files have changed in this diff Show More