mirror of
https://github.com/GoogleCloudPlatform/vertex-ai-samples.git
synced 2026-09-26 14:42:04 +00:00
36 KiB
36 KiB
In [ ]:
# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.In [ ]:
%%writefile requirements.txt
joblib~=1.0
numpy~=1.20
scikit-learn~=0.24
google-cloud-storage>=1.26.0,<2.0.0devIn [ ]:
# Required in Docker serving container
! pip3 install -U -r requirements.txt -q
# For local FastAPI development and running
! pip3 install -U "uvicorn[standard]>=0.12.0,<0.14.0" fastapi~=0.63 -q
# Vertex SDK for Python
! pip3 install --upgrade --quiet google-cloud-aiplatformIn [ ]:
import sys
if "google.colab" in sys.modules:
import IPython
app = IPython.Application.instance()
app.kernel.do_shutdown(True)In [ ]:
import sys
if "google.colab" in sys.modules:
from google.colab import auth
auth.authenticate_user()In [ ]:
PROJECT_ID = "[your-project-id]" # @param {type:"string"}
LOCATION = "us-central1" # @param {type:"string"}
In [ ]:
BUCKET_URI = f"gs://your-bucket-name-{PROJECT_ID}-unique" # @param {type:"string"}In [ ]:
! gcloud storage buckets create --location={LOCATION} --project={PROJECT_ID} {BUCKET_URI}In [ ]:
from google.cloud import aiplatform
aiplatform.init(project=PROJECT_ID, location=LOCATION, staging_bucket=BUCKET_URI)In [ ]:
import os
import sysIn [ ]:
MODEL_ARTIFACT_DIR = "[your-artifact-directory]" # @param {type:"string"}
REPOSITORY = "[your-repository-name]" # @param {type:"string"}
IMAGE = "[your-image-name]" # @param {type:"string"}
MODEL_DISPLAY_NAME = "[your-model-display-name]" # @param {type:"string"}
# Set the defaults if no names were specified
if MODEL_ARTIFACT_DIR == "[your-artifact-directory]":
MODEL_ARTIFACT_DIR = "custom-container-prediction-model"
if REPOSITORY == "[your-repository-name]":
REPOSITORY = "custom-container-prediction"
if IMAGE == "[your-image-name]":
IMAGE = "sklearn-fastapi-server"
if MODEL_DISPLAY_NAME == "[your-model-display-name]":
MODEL_DISPLAY_NAME = "sklearn-custom-container"In [ ]:
%mkdir appIn [ ]:
%%writefile app/preprocess.py
import numpy as np
class MySimpleScaler(object):
def __init__(self):
self._means = None
self._stds = None
def preprocess(self, data):
if self._means is None: # during training only
self._means = np.mean(data, axis=0)
if self._stds is None: # during training only
self._stds = np.std(data, axis=0)
if not self._stds.all():
raise ValueError("At least one column has standard deviation of 0.")
return (data - self._means) / self._stds
In [ ]:
%cd app/
import pickle
import joblib
from preprocess import MySimpleScaler
from sklearn.datasets import load_iris
from sklearn.ensemble import RandomForestClassifier
iris = load_iris()
scaler = MySimpleScaler()
X = scaler.preprocess(iris.data)
y = iris.target
model = RandomForestClassifier()
model.fit(X, y)
joblib.dump(model, "model.joblib")
with open("preprocessor.pkl", "wb") as f:
pickle.dump(scaler, f)In [ ]:
!gcloud storage cp model.joblib preprocessor.pkl {BUCKET_URI}/{MODEL_ARTIFACT_DIR}/
%cd ..In [ ]:
%%writefile app/main.py
from fastapi import FastAPI, Request
import joblib
import json
import numpy as np
import pickle
import os
from google.cloud import storage
from preprocess import MySimpleScaler
from sklearn.datasets import load_iris
app = FastAPI()
gcs_client = storage.Client()
with open("preprocessor.pkl", 'wb') as preprocessor_f, open("model.joblib", 'wb') as model_f:
gcs_client.download_blob_to_file(
f"{os.environ['AIP_STORAGE_URI']}/preprocessor.pkl", preprocessor_f
)
gcs_client.download_blob_to_file(
f"{os.environ['AIP_STORAGE_URI']}/model.joblib", model_f
)
with open("preprocessor.pkl", "rb") as f:
preprocessor = pickle.load(f)
_class_names = load_iris().target_names
_model = joblib.load("model.joblib")
_preprocessor = preprocessor
@app.get(os.environ['AIP_HEALTH_ROUTE'], status_code=200)
def health():
return {}
@app.post(os.environ['AIP_PREDICT_ROUTE'])
async def predict(request: Request):
body = await request.json()
instances = body["instances"]
inputs = np.asarray(instances)
preprocessed_inputs = _preprocessor.preprocess(inputs)
outputs = _model.predict(preprocessed_inputs)
return {"predictions": [_class_names[class_num] for class_num in outputs]}
In [ ]:
%%writefile app/prestart.sh
#!/bin/bash
export PORT=$AIP_HTTP_PORTIn [ ]:
%%writefile instances.json
{
"instances": [
[6.7, 3.1, 4.7, 1.5],
[4.6, 3.1, 1.5, 0.2]
]
}In [ ]:
%%writefile Dockerfile
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.9
COPY ./app /app
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txtIn [ ]:
IS_COLAB = "google.colab" in sys.modules
if not IS_COLAB and not os.getenv("IS_TESTING"):
! sudo docker build \
--tag="{LOCATION}-docker.pkg.dev/{PROJECT_ID}/{REPOSITORY}/{IMAGE}" \
.In [ ]:
if not IS_COLAB and not os.getenv("IS_TESTING"):
! sudo docker stop local-iris
! sudo docker rm local-iris
! docker run -d -p 80:8080 \
--name=local-iris \
-e AIP_HTTP_PORT=8080 \
-e AIP_HEALTH_ROUTE=/health \
-e AIP_PREDICT_ROUTE=/predict \
-e AIP_STORAGE_URI={BUCKET_URI}/{MODEL_ARTIFACT_DIR} \
"{LOCATION}-docker.pkg.dev/{PROJECT_ID}/{REPOSITORY}/{IMAGE}"In [ ]:
if not IS_COLAB and not os.getenv("IS_TESTING"):
! curl localhost/healthIn [ ]:
if not IS_COLAB and not os.getenv("IS_TESTING"):
! curl -X POST \
-d @instances.json \
-H "Content-Type: application/json; charset=utf-8" \
localhost/predictIn [ ]:
if not IS_COLAB and not os.getenv("IS_TESTING"):
! sudo docker stop local-iris
! sudo docker rm local-irisIn [ ]:
! gcloud services enable artifactregistry.googleapis.com
if os.getenv("IS_TESTING"):
! sudo apt-get update --yes && sudo apt-get --only-upgrade --yes install google-cloud-sdk-cloud-run-proxy google-cloud-sdk-harbourbridge google-cloud-sdk-cbt google-cloud-sdk-gke-gcloud-auth-plugin google-cloud-sdk-kpt google-cloud-sdk-local-extract google-cloud-sdk-minikube google-cloud-sdk-app-engine-java google-cloud-sdk-app-engine-go google-cloud-sdk-app-engine-python google-cloud-sdk-spanner-emulator google-cloud-sdk-bigtable-emulator google-cloud-sdk-nomos google-cloud-sdk-package-go-module google-cloud-sdk-firestore-emulator kubectl google-cloud-sdk-datastore-emulator google-cloud-sdk-app-engine-python-extras google-cloud-sdk-cloud-build-local google-cloud-sdk-kubectl-oidc google-cloud-sdk-anthos-auth google-cloud-sdk-app-engine-grpc google-cloud-sdk-pubsub-emulator google-cloud-sdk-datalab google-cloud-sdk-skaffold google-cloud-sdk google-cloud-sdk-terraform-tools google-cloud-sdk-config-connector
! gcloud components update --quietIn [ ]:
REPOSITORY = "my-docker-repo-unique"
! gcloud artifacts repositories create {REPOSITORY} --repository-format=docker --location={LOCATION} --description="Docker repository"
! gcloud artifacts repositories listIn [ ]:
!gcloud builds submit --region={LOCATION} --tag={LOCATION}-docker.pkg.dev/{PROJECT_ID}/{REPOSITORY}/{IMAGE}In [ ]:
model = aiplatform.Model.upload(
display_name=MODEL_DISPLAY_NAME,
artifact_uri=f"{BUCKET_URI}/{MODEL_ARTIFACT_DIR}",
serving_container_image_uri=f"{LOCATION}-docker.pkg.dev/{PROJECT_ID}/{REPOSITORY}/{IMAGE}",
)In [ ]:
endpoint = model.deploy(machine_type="n1-standard-4")In [ ]:
# Send some sample data to the endpoint
endpoint.predict(instances=[[6.7, 3.1, 4.7, 1.5], [4.6, 3.1, 1.5, 0.2]])In [ ]:
# Fetch the endpoint name
ENDPOINT_ID = endpoint.nameIn [ ]:
# Send a prediction request using sample data
! curl \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
-d @instances.json \
https://{LOCATION}-aiplatform.googleapis.com/v1/projects/{PROJECT_ID}/locations/{LOCATION}/endpoints/{ENDPOINT_ID}:predictIn [ ]:
!gcloud ai endpoints predict $ENDPOINT_ID \
--region=$LOCATION \
--json-request=instances.jsonIn [ ]:
delete_bucket = False
delete_art_repo = False
# Undeploy model and delete endpoint
endpoint.undeploy_all()
endpoint.delete()
#Delete the model resource
model.delete()
# Delete the container image from Artifact Registry
!gcloud artifacts docker images delete \
--quiet \
--delete-tags \
{LOCATION}-docker.pkg.dev/{PROJECT_ID}/{REPOSITORY}/{IMAGE}
# Delete the Artifact Repository
if delete_art_repo:
! gcloud artifacts repositories delete {REPOSITORY} --location=$LOCATION -q
# Delete the Cloud Storage bucket
if delete_bucket:
! gcloud storage rm --recursive $BUCKET_URIIn [ ]:
! rm -rf app/
! rm requirements.txt
! rm instances.json
! rm Dockerfile