mirror of
https://github.com/GoogleCloudPlatform/vertex-ai-samples.git
synced 2026-09-26 14:42:04 +00:00
34 KiB
34 KiB
In [ ]:
# Copyright 2022 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 [ ]:
! pip3 install --upgrade google-cloud-aiplatform --quietIn [ ]:
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 [ ]:
! gsutil mb -l $LOCATION $BUCKET_URIIn [ ]:
import google.cloud.aiplatform as aiplatform
aiplatform.init(project=PROJECT_ID, location=LOCATION, staging_bucket=BUCKET_URI)In [ ]:
TRAIN_GPU, TRAIN_NGPU = (None, None)
DEPLOY_GPU, DEPLOY_NGPU = (None, None)In [ ]:
TRAIN_VERSION = "xgboost-cpu.1-1"
DEPLOY_VERSION = "xgboost-cpu.1-1"
TRAIN_IMAGE = "{}-docker.pkg.dev/vertex-ai/training/{}:latest".format(
LOCATION.split("-")[0], TRAIN_VERSION
)
DEPLOY_IMAGE = "{}-docker.pkg.dev/vertex-ai/prediction/{}:latest".format(
LOCATION.split("-")[0], DEPLOY_VERSION
)In [ ]:
TRAIN_COMPUTE = "n1-standard-4"
print("Train machine type", TRAIN_COMPUTE)In [ ]:
# Make folder for Python training script
! rm -rf custom
! mkdir custom
# Add package information
! touch custom/README.md
setup_cfg = "[egg_info]\n\ntag_build =\n\ntag_date = 0"
! echo "$setup_cfg" > custom/setup.cfg
setup_py = "import setuptools\n\nsetuptools.setup(\n\n install_requires=[\n\n 'cloudml-hypertune',\n\n ],\n\n packages=setuptools.find_packages())"
! echo "$setup_py" > custom/setup.py
pkg_info = "Metadata-Version: 1.0\n\nName: Iris tabular classification\n\nVersion: 0.0.0\n\nSummary: Demostration training script\n\nHome-page: www.google.com\n\nAuthor: Google\n\nAuthor-email: aferlitsch@google.com\n\nLicense: Public\n\nDescription: Demo\n\nPlatform: Vertex"
! echo "$pkg_info" > custom/PKG-INFO
# Make the training subfolder
! mkdir custom/trainer
! touch custom/trainer/__init__.pyIn [ ]:
%%writefile custom/trainer/task.py
import datetime
import os
import subprocess
import sys
import pandas as pd
import xgboost as xgb
import hypertune
import argparse
import logging
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
parser = argparse.ArgumentParser()
parser.add_argument('--model-dir', dest='model_dir',
default=os.getenv('AIP_MODEL_DIR'), type=str, help='Model dir.')
parser.add_argument("--dataset-data-url", dest="dataset_data_url",
type=str, help="Download url for the training data.")
parser.add_argument("--dataset-labels-url", dest="dataset_labels_url",
type=str, help="Download url for the training data labels.")
parser.add_argument("--boost-rounds", dest="boost_rounds",
default=20, type=int, help="Number of boosted rounds")
args = parser.parse_args()
logging.getLogger().setLevel(logging.INFO)
def get_data():
logging.info("Downloading training data and labelsfrom: {}, {}".format(args.dataset_data_url, args.dataset_labels_url))
# gsutil outputs everything to stderr so we need to divert it to stdout.
subprocess.check_call(['gsutil', 'cp', args.dataset_data_url, 'data.csv'], stderr=sys.stdout)
# gsutil outputs everything to stderr so we need to divert it to stdout.
subprocess.check_call(['gsutil', 'cp', args.dataset_labels_url, 'labels.csv'], stderr=sys.stdout)
# Load data into pandas, then use `.values` to get NumPy arrays
data = pd.read_csv('data.csv').values
labels = pd.read_csv('labels.csv').values
# Convert one-column 2D array into 1D array for use with XGBoost
labels = labels.reshape((labels.size,))
train_data, test_data, train_labels, test_labels = train_test_split(data, labels, test_size=0.2, random_state=7)
# Load data into DMatrix object
dtrain = xgb.DMatrix(train_data, label=train_labels)
return dtrain, test_data, test_labels
def train_model(dtrain):
logging.info("Start training ...")
# Train XGBoost model
params = {
'objective': 'multi:softprob',
'num_class': 3
}
model = xgb.train(params, dtrain, num_boost_round=args.boost_rounds)
logging.info("Training completed")
return model
def evaluate_model(model, test_data, test_labels):
dtest = xgb.DMatrix(test_data)
pred = model.predict(dtest)
predictions = [np.around(value) for value in pred]
# evaluate predictions
try:
accuracy = accuracy_score(test_labels, predictions)
except:
accuracy = 0.0
logging.info(f"Evaluation completed with model accuracy: {accuracy}")
# report metric for hyperparameter tuning
hpt = hypertune.HyperTune()
hpt.report_hyperparameter_tuning_metric(
hyperparameter_metric_tag='accuracy',
metric_value=accuracy
)
return accuracy
dtrain, test_data, test_labels = get_data()
model = train_model(dtrain)
accuracy = evaluate_model(model, test_data, test_labels)
# GCSFuse conversion
gs_prefix = 'gs://'
gcsfuse_prefix = '/gcs/'
if args.model_dir.startswith(gs_prefix):
args.model_dir = args.model_dir.replace(gs_prefix, gcsfuse_prefix)
dirpath = os.path.split(args.model_dir)[0]
if not os.path.isdir(dirpath):
os.makedirs(dirpath)
# Export the classifier to a file
gcs_model_path = os.path.join(args.model_dir, 'model.bst')
logging.info("Saving model artifacts to {}". format(gcs_model_path))
model.save_model(gcs_model_path)
logging.info("Saving metrics to {}/metrics.json". format(args.model_dir))
gcs_metrics_path = os.path.join(args.model_dir, 'metrics.json')
with open(gcs_metrics_path, "w") as f:
f.write(f"{'accuracy: {accuracy}'}")In [ ]:
! rm -f custom.tar custom.tar.gz
! tar cvf custom.tar custom
! gzip custom.tar
! gsutil cp custom.tar.gz $BUCKET_URI/trainer_iris.tar.gzIn [ ]:
DISPLAY_NAME = "iris"
job = aiplatform.CustomPythonPackageTrainingJob(
display_name=DISPLAY_NAME,
python_package_gcs_uri=f"{BUCKET_URI}/trainer_iris.tar.gz",
python_module_name="trainer.task",
container_uri=TRAIN_IMAGE,
model_serving_container_image_uri=DEPLOY_IMAGE,
project=PROJECT_ID,
)In [ ]:
MODEL_DIR = "{}/{}".format(BUCKET_URI, "model")
DATASET_DIR = "gs://cloud-samples-data/ai-platform/iris"
ROUNDS = 20
DIRECT = False
if DIRECT:
CMDARGS = [
"--dataset-data-url=" + DATASET_DIR + "/iris_data.csv",
"--dataset-labels-url=" + DATASET_DIR + "/iris_target.csv",
"--boost-rounds=" + str(ROUNDS),
"--model_dir=" + MODEL_DIR,
]
else:
CMDARGS = [
"--dataset-data-url=" + DATASET_DIR + "/iris_data.csv",
"--dataset-labels-url=" + DATASET_DIR + "/iris_target.csv",
"--boost-rounds=" + str(ROUNDS),
]In [ ]:
if TRAIN_GPU:
model = job.run(
model_display_name="iris",
args=CMDARGS,
replica_count=1,
machine_type=TRAIN_COMPUTE,
accelerator_type=TRAIN_GPU.name,
accelerator_count=TRAIN_NGPU,
base_output_dir=MODEL_DIR,
sync=False,
)
else:
model = job.run(
model_display_name="iris",
args=CMDARGS,
replica_count=1,
machine_type=TRAIN_COMPUTE,
base_output_dir=MODEL_DIR,
sync=False,
)
model_path_to_deploy = MODEL_DIRIn [ ]:
_job = job.list(filter=f"display_name={DISPLAY_NAME}")
print(_job)In [ ]:
model.wait()In [ ]:
job.delete()In [ ]:
delete_bucket = False
model.delete()
if delete_bucket:
! gsutil rm -r $BUCKET_URI