notebooks/community/model_garden/model_garden_pytorch_clip.ipynb (313 lines of code) (raw):

{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": { "cellView": "form", "id": "7d9bbf86da5e" }, "outputs": [], "source": [ "# Copyright 2025 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": "2bd716bf3e39" }, "source": [ "# Vertex AI Model Garden - CLIP\n", "\n", "<table><tbody><tr>\n", " <td style=\"text-align: center\">\n", " <a href=\"https://console.cloud.google.com/vertex-ai/workbench/instances\">\n", " <img alt=\"Workbench logo\" src=\"https://lh3.googleusercontent.com/UiNooY4LUgW_oTvpsNhPpQzsstV5W8F7rYgxgGBD85cWJoLmrOzhVs_ksK_vgx40SHs7jCqkTkCk=e14-rj-sc0xffffff-h130-w32\" width=\"32px\"><br> Run in Workbench\n", " </a>\n", " </td>\n", " <td style=\"text-align: center\">\n", " <a href=\"https://console.cloud.google.com/vertex-ai/colab/import/https:%2F%2Fraw.githubusercontent.com%2FGoogleCloudPlatform%2Fvertex-ai-samples%2Fmain%2Fnotebooks%2Fcommunity%2Fmodel_garden%2Fmodel_garden_pytorch_clip.ipynb\">\n", " <img alt=\"Google Cloud Colab Enterprise logo\" src=\"https://lh3.googleusercontent.com/JmcxdQi-qOpctIvWKgPtrzZdJJK-J3sWE1RsfjZNwshCFgE_9fULcNpuXYTilIR2hjwN\" width=\"32px\"><br> Run in Colab Enterprise\n", " </a>\n", " </td>\n", " <td style=\"text-align: center\">\n", " <a href=\"https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/model_garden/model_garden_pytorch_clip.ipynb\">\n", " <img alt=\"GitHub logo\" src=\"https://cloud.google.com/ml-engine/images/github-logo-32px.png\" width=\"32px\"><br> View on GitHub\n", " </a>\n", " </td>\n", "</tr></tbody></table>" ] }, { "cell_type": "markdown", "metadata": { "id": "d8cd12648da4" }, "source": [ "## Overview\n", "\n", "This notebook demonstrates deploying the pre-trained [CLIP](https://huggingface.co/openai/clip-vit-base-patch32) model on Vertex AI for online prediction.\n", "\n", "### Objective\n", "\n", "- Upload the model to [Model Registry](https://cloud.google.com/vertex-ai/docs/model-registry/introduction).\n", "- Deploy the model on [Endpoint](https://cloud.google.com/vertex-ai/docs/predictions/using-private-endpoints).\n", "- Run online predictions for image captioning.\n", "\n", "### File a bug\n", "\n", "File a bug on [GitHub](https://github.com/GoogleCloudPlatform/vertex-ai-samples/issues/new) if you encounter any issue with the notebook.\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 pricing](https://cloud.google.com/vertex-ai/pricing), [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." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "cellView": "form", "id": "_53r3GqThdEP" }, "outputs": [], "source": [ "# @title Setup Google Cloud project\n", "\n", "# Import the necessary packages\n", "\n", "# Upgrade Vertex AI SDK.\n", "! pip3 install --upgrade --quiet 'google-cloud-aiplatform>=1.84.0'\n", "\n", "# @markdown 1. [Make sure that billing is enabled for your project](https://cloud.google.com/billing/docs/how-to/modify-project).\n", "\n", "# @markdown 2. **[Optional]** [Create a Cloud Storage bucket](https://cloud.google.com/storage/docs/creating-buckets) for storing experiment outputs. Set the BUCKET_URI for the experiment environment. The specified Cloud Storage bucket (`BUCKET_URI`) should be located in the same region as where the notebook was launched. Note that a multi-region bucket (eg. \"us\") is not considered a match for a single region covered by the multi-region range (eg. \"us-central1\"). If not set, a unique GCS bucket will be created instead.\n", "\n", "BUCKET_URI = \"gs://\" # @param {type:\"string\"}\n", "\n", "# @markdown 3. **[Optional]** Set region. If not set, the region will be set automatically according to Colab Enterprise environment.\n", "\n", "REGION = \"\" # @param {type:\"string\"}\n", "\n", "import importlib\n", "import os\n", "\n", "from google.cloud import aiplatform\n", "\n", "if os.environ.get(\"VERTEX_PRODUCT\") != \"COLAB_ENTERPRISE\":\n", " ! pip install --upgrade tensorflow\n", "! git clone https://github.com/GoogleCloudPlatform/vertex-ai-samples.git\n", "\n", "common_util = importlib.import_module(\n", " \"vertex-ai-samples.community-content.vertex_model_garden.model_oss.notebook_util.common_util\"\n", ")\n", "\n", "\n", "# Get the default cloud project id.\n", "PROJECT_ID = os.environ[\"GOOGLE_CLOUD_PROJECT\"]\n", "\n", "# Get the default region for launching jobs.\n", "if not REGION:\n", " REGION = os.environ[\"GOOGLE_CLOUD_REGION\"]\n", "\n", "# Initialize Vertex AI API.\n", "print(\"Initializing Vertex AI API.\")\n", "aiplatform.init(project=PROJECT_ID, location=REGION)\n", "\n", "! gcloud config set project $PROJECT_ID\n", "\n", "aiplatform.init(project=PROJECT_ID, location=REGION)\n", "\n", "# The pre-built serving docker image. It contains serving scripts and models.\n", "SERVE_DOCKER_URI = \"us-docker.pkg.dev/vertex-ai/vertex-vision-model-garden-dockers/pytorch-transformers-serve\"\n", "\n", "models, endpoints = {}, {}\n", "LABEL = \"endpoint\"\n", "\n", "import vertexai\n", "\n", "vertexai.init(\n", " project=PROJECT_ID,\n", " location=REGION,\n", ")\n", "\n", "version_id = \"clip-vit-base-patch32\"\n", "PUBLISHER_MODEL_NAME = f\"publishers/openai/models/clip-vit-base-patch32@{version_id}\"\n", "\n", "\n", "def deploy_model(model_id, task):\n", " model_name = \"clip\"\n", " endpoint = aiplatform.Endpoint.create(display_name=f\"{model_name}-endpoint\")\n", " serving_env = {\n", " \"MODEL_ID\": model_id,\n", " \"TASK\": task,\n", " \"DEPLOY_SOURCE\": \"notebook\",\n", " }\n", " # If the model_id is a GCS path, use artifact_uri to pass it to serving docker.\n", " artifact_uri = model_id if model_id.startswith(\"gs://\") else None\n", " model = aiplatform.Model.upload(\n", " display_name=model_name,\n", " serving_container_image_uri=SERVE_DOCKER_URI,\n", " serving_container_ports=[7080],\n", " serving_container_predict_route=\"/predictions/transformers_serving\",\n", " serving_container_health_route=\"/ping\",\n", " serving_container_environment_variables=serving_env,\n", " artifact_uri=artifact_uri,\n", " model_garden_source_model_name=\"publishers/openai/models/clip-vit-base-patch32\",\n", " )\n", " model.deploy(\n", " endpoint=endpoint,\n", " machine_type=\"n1-standard-8\",\n", " accelerator_type=\"NVIDIA_TESLA_T4\",\n", " accelerator_count=1,\n", " deploy_request_timeout=1800,\n", " system_labels={\n", " \"NOTEBOOK_NAME\": \"model_garden_pytorch_clip.ipynb\",\n", " \"NOTEBOOK_ENVIRONMENT\": common_util.get_deploy_source(),\n", " },\n", " )\n", " return model, endpoint" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "cellView": "form", "id": "LQir_tczhdEP" }, "outputs": [], "source": [ "accelerator_type = \"NVIDIA_TESLA_T4\"\n", "machine_type = \"n1-standard-8\"\n", "accelerator_count = 1\n", "\n", "# @title [Option 1] Deploy with Model Garden SDK\n", "\n", "# @markdown Deploy with Gen AI model-centric SDK. This section uploads the prebuilt model to Model Registry and deploys it to a Vertex AI Endpoint. It takes 15 minutes to 1 hour to finish depending on the size of the model. See [use open models with Vertex AI](https://cloud.google.com/vertex-ai/generative-ai/docs/open-models/use-open-models) for documentation on other use cases.\n", "from vertexai.preview import model_garden\n", "\n", "model = model_garden.OpenModel(PUBLISHER_MODEL_NAME)\n", "endpoints[LABEL] = model.deploy(\n", " machine_type=machine_type,\n", " accelerator_type=accelerator_type,\n", " accelerator_count=accelerator_count,\n", " accept_eula=True, # Accept the End User License Agreement (EULA) on the model card before deploy. Otherwise, the deployment will be forbidden.\n", ")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "cellView": "form", "id": "vBvfVTWOhdEP" }, "outputs": [], "source": [ "# @title [Option 2] Deploy with customized configs\n", "\n", "# @markdown This section uploads the pre-trained model to Model Registry and deploys it on the Endpoint with 1 T4 GPU.\n", "# @markdown The model deployment step will take ~15 minutes to complete.\n", "\n", "models[LABEL], endpoints[LABEL] = deploy_model(\n", " model_id=\"openai/clip-vit-base-patch32\", task=\"zero-shot-image-classification\"\n", ")\n", "\n", "image1 = common_util.download_image(\n", " \"http://images.cocodataset.org/val2017/000000039769.jpg\"\n", ")\n", "image2 = common_util.download_image(\n", " \"http://images.cocodataset.org/val2017/000000000285.jpg\"\n", ")\n", "grid = common_util.image_grid([image1, image2], 1, 2)\n", "display(grid)\n", "\n", "instances = [\n", " {\"image\": common_util.image_to_base64(image1), \"text\": \"two cats\"},\n", " {\"image\": common_util.image_to_base64(image2), \"text\": \"a bear\"},\n", "]\n", "preds = endpoints[LABEL].predict(instances=instances).predictions\n", "print(preds)\n", "\n", "models[LABEL], endpoints[LABEL] = deploy_model(\n", " model_id=\"openai/clip-vit-base-patch32\", task=\"feature-embedding\"\n", ")\n", "\n", "import numpy as np\n", "\n", "# Extract feature embedding of images.\n", "image = common_util.download_image(\n", " \"http://images.cocodataset.org/val2017/000000039769.jpg\"\n", ")\n", "display(image)\n", "instances = [\n", " {\"image\": common_util.image_to_base64(image)},\n", "]\n", "preds = endpoints[LABEL].predict(instances=instances).predictions\n", "image_features = np.array(preds[0][\"image_features\"])\n", "print(image_features.shape)\n", "\n", "# Extract feature embedding of texts.\n", "instances = [\n", " {\"text\": \"two cats\"},\n", " {\"text\": \"hello world\"},\n", "]\n", "preds = endpoints[LABEL].predict(instances=instances).predictions\n", "text_features = np.array(preds[0][\"text_features\"])\n", "print(text_features.shape)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "cellView": "form", "id": "712eb9d0b336" }, "outputs": [], "source": [ "# @markdown Delete the experiment models and endpoints to recycle the resources\n", "# @markdown and avoid unnecessary continuous charges that may incur.\n", "\n", "# Undeploy model and delete endpoint.\n", "for endpoint in endpoints.values():\n", " endpoint.delete(force=True)\n", "\n", "# Delete models.\n", "for model in models.values():\n", " model.delete()" ] } ], "metadata": { "colab": { "name": "model_garden_pytorch_clip.ipynb", "toc_visible": true }, "kernelspec": { "display_name": "Python 3", "name": "python3" } }, "nbformat": 4, "nbformat_minor": 0 }