mirror of
https://github.com/GoogleCloudPlatform/vertex-ai-samples.git
synced 2026-09-26 14:42:04 +00:00
* feat: SDK2 remote predict * fix: 3.10 * fix: py check * fix: py check * fix: review comments * fix: pytorch lightning not support register model
41 KiB
41 KiB
In [ ]:
# Copyright 2023 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 --quiet google-cloud-aiplatform[preview,autologging]
! pip3 install --upgrade --quiet lightning
! pip3 install --upgrade --quiet tensorflow==2.12In [ ]:
# Automatically restart kernel after installs so that your environment can access the new packages
# import IPython
# app = IPython.Application.instance()
# app.kernel.do_shutdown(True)In [ ]:
PROJECT_ID = "[your-project-id]" # @param {type:"string"}
# Set the project id
! gcloud config set project {PROJECT_ID}In [ ]:
REGION = "us-central1"In [ ]:
# ! gcloud auth loginIn [ ]:
# from google.colab import auth
# auth.authenticate_user()In [ ]:
BUCKET_URI = f"gs://your-bucket-name-{PROJECT_ID}-unique" # @param {type:"string"}In [ ]:
! gsutil mb -l {REGION} -p {PROJECT_ID} {BUCKET_URI}In [ ]:
import vertexai.preview
from sklearn.datasets import load_iris
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScalerIn [ ]:
vertexai.init(
project=PROJECT_ID,
location=REGION,
staging_bucket=BUCKET_URI,
)In [ ]:
dataset = load_iris()
X, X_retrain, y, y_retrain = train_test_split(
dataset.data, dataset.target, test_size=0.60, random_state=42
)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.20, random_state=42
)
print("Data size: ", len(dataset.target))
print("X_train size: ", len(X_train))
print("X_retrain size: ", len(X_retrain))
print("X_test size: ", len(X_test))In [ ]:
# Switch to remote mode for training
vertexai.preview.init(remote=True)In [ ]:
REMOTE_JOB_NAME = "remote-scalar"
REMOTE_JOB_BUCKET = f"{BUCKET_URI}/{REMOTE_JOB_NAME}"
# Wrap classes to enable Vertex remote execution
# Don't need this step after import hook is implemented
StandardScaler = vertexai.preview.remote(StandardScaler)
# Instantiate transformer
transformer = StandardScaler()
# Set training config
transformer.fit_transform.vertex.remote_config.display_name = (
f"{REMOTE_JOB_NAME}-fit-transformer"
)
transformer.fit_transform.vertex.remote_config.staging_bucket = REMOTE_JOB_BUCKET
# Execute transformer on Vertex
X_train = transformer.fit_transform(X_train)In [ ]:
# Transform test dataset before calculate test score
transformer.transform.vertex.remote_config.display_name = (
REMOTE_JOB_NAME + "-transformer"
)
transformer.transform.vertex.remote_config.staging_bucket = REMOTE_JOB_BUCKET
X_test = transformer.transform(X_test)In [ ]:
# Switch to local transformation
vertexai.preview.init(remote=False)
X_retrain = transformer.transform(X_retrain)In [ ]:
# Switch to remote mode for training
vertexai.preview.init(remote=True)
# Wrap classes to enable Vertex remote execution
# Don't need this step after import hook is implemented
LogisticRegression = vertexai.preview.remote(LogisticRegression)
# Instantiate model, warm_start=True for uptraining
model = LogisticRegression(warm_start=True)
# Set training config
model.fit.vertex.remote_config.display_name = REMOTE_JOB_NAME + "-sklearn-model"
model.fit.vertex.remote_config.staging_bucket = REMOTE_JOB_BUCKET
# Train model on Vertex
model = model.fit(X_train, y_train)In [ ]:
registered_model = vertexai.preview.register(model)
pulled_model = vertexai.preview.from_pretrained(
model_name=registered_model.resource_name
)In [ ]:
pulled_model.fit(X_retrain, y_retrain)In [ ]:
# Switch to local mode for testing
vertexai.preview.init(remote=False)
# Evaluate model's accuracy score
print(f"Train accuracy: {model.score(X_train, y_train)}")
print(f"Test accuracy: {model.score(X_test, y_test)}")
# Evaluate uptrained model's accuracy score
print(f"Train accuracy: {pulled_model.score(X_train, y_train)}")
print(f"Test accuracy: {pulled_model.score(X_test, y_test)}")In [ ]:
# Remote mode for prediction
vertexai.preview.init(remote=True)
predictions = model.predict(X_test)
print(predictions)In [ ]:
registered_model.delete()In [ ]:
# Switch to remote mode for training
vertexai.preview.init(remote=True)
import torch
from vertexai.preview import VertexModel
# define the custom model
class TorchLogisticRegression(VertexModel, torch.nn.Module):
def __init__(self, input_size: int, output_size: int):
torch.nn.Module.__init__(self)
VertexModel.__init__(self)
self.linear = torch.nn.Linear(input_size, output_size)
self.softmax = torch.nn.Softmax(dim=1)
def forward(self, x):
return self.softmax(self.linear(x))
@vertexai.preview.developer.mark.train()
def train(self, X, y, num_epochs, lr):
X, y = torch.tensor(X).to(torch.float32), torch.tensor(y)
dataloader = torch.utils.data.DataLoader(
torch.utils.data.TensorDataset(X, y),
batch_size=10,
shuffle=True,
generator=torch.Generator(device=X.device),
)
criterion = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(self.parameters(), lr=lr)
for t in range(num_epochs):
for batch, (X, y) in enumerate(dataloader):
optimizer.zero_grad()
pred = self(X)
loss = criterion(pred, y)
loss.backward()
optimizer.step()
@vertexai.preview.developer.mark.predict()
def predict(self, X):
X = torch.tensor(X).to(torch.float32)
with torch.no_grad():
pred = torch.argmax(self(X), dim=1)
return pred
# Instantiate model
model = TorchLogisticRegression(4, 3)
# Set training config
model.train.vertex.remote_config.display_name = (
REMOTE_JOB_NAME + "-pytorch-custom-model"
)
model.train.vertex.remote_config.staging_bucket = REMOTE_JOB_BUCKET
# Train model on Vertex
# Currently update trained model in place hasn't been implemented, so need to get the return value
model.train(X_train, y_train, num_epochs=100, lr=0.05)In [ ]:
registered_model = vertexai.preview.register(model)
pulled_model = vertexai.preview.from_pretrained(
model_name=registered_model.resource_name
)In [ ]:
# Get Python version
py_v = ! python3 --version
py_v = py_v[0].split(".")[1]
# only supported by Pythn 3.10+
if int(py_v) >= 10:
pulled_model.train.vertex.remote_config.enable_cuda = True
pulled_model.train.vertex.remote_config.display_name = (
REMOTE_JOB_NAME + "-pytorch-custom-model-gpu"
)
pulled_model.train(X_retrain, y_retrain, num_epochs=100, lr=0.05)In [ ]:
from sklearn.metrics import accuracy_score
# Switch to local mode for testing
vertexai.preview.init(remote=False)
# Evaluate model's accuracy score
print(f"Train accuracy: {accuracy_score(y_train, model.predict(X_train))}")
print(f"Test accuracy: {accuracy_score(y_test, model.predict(X_test))}")
# Evaluate uptrained model's accuracy score
# only supported by Pythn 3.10+
if py_v >= "3.10":
print(f"Train accuracy: {accuracy_score(y_train, pulled_model.predict(X_train))}")
print(f"Test accuracy: {accuracy_score(y_test, pulled_model.predict(X_test))}")In [ ]:
# Remote mode for prediction
vertexai.preview.init(remote=True)
predictions = model.predict(X_test)
print(predictions)In [ ]:
registered_model.delete()In [ ]:
# Switch to remote mode for training
vertexai.preview.init(remote=True)
from tensorflow import keras
# Wrap classes to enable Vertex remote execution
# Don't need this step after import hook is implemented
keras.Sequential = vertexai.preview.remote(keras.Sequential)
# Instantiate model
model = keras.Sequential(
[keras.layers.Dense(5, input_shape=(4,)), keras.layers.Softmax()]
)
# Specify optimizer and loss function
model.compile(optimizer="adam", loss="mean_squared_error")
# Set training config
model.fit.vertex.remote_config.enable_cuda = True
model.fit.vertex.remote_config.display_name = REMOTE_JOB_NAME + "-keras-model-gpu"
model.fit.vertex.remote_config.staging_bucket = REMOTE_JOB_BUCKET
# TODO: Remove
# Manually set compute resources this time
# model.fit.vertex.remote_config.machine_type = "n1-highmem-4"
# model.fit.vertex.remote_config.accelerator_type = "NVIDIA_TESLA_K80"
# model.fit.vertex.remote_config.accelerator_count = 4
# Train model on Vertex
# Currently update trained model in place hasn't been implemented, so need to get the return value
model.fit(X_train, y_train, epochs=10, batch_size=32)In [ ]:
registered_model = vertexai.preview.register(model)
pulled_model = vertexai.preview.from_pretrained(
model_name=registered_model.resource_name
)In [ ]:
# Config experiment and turn on autologging
# Config experiment and turn on autologging
vertexai.init(
project=PROJECT_ID,
location=REGION,
staging_bucket=BUCKET_URI,
experiment="test-remote-training-autologging",
)
vertexai.preview.init(remote=True, autolog=True)
# service account is required since autolog is True
pulled_model.fit.vertex.remote_config.service_account = "GCE"
# Set GPU configs to None
pulled_model.fit.vertex.remote_config.enable_cuda = False
pulled_model.fit.vertex.remote_config.machine_type = None
pulled_model.fit.vertex.remote_config.accelerator_type = None
pulled_model.fit.vertex.remote_config.accelerator_count = None
pulled_model.fit.vertex.remote_config.display_name = (
REMOTE_JOB_NAME + "-keras-model-autologging"
)
pulled_model.fit(X_retrain, y_retrain, epochs=10, batch_size=32)
# TODO InvalidArgument: 400 User-specified resource ID must match the regular expression '[a-z0-9][a-z0-9-]{0,127}'In [ ]:
# View logged metrics & params
vertexai.preview.get_experiment_df()
# Turn off the autologging
vertexai.preview.init(autolog=False)In [ ]:
# Switch to local mode for testing
vertexai.preview.init(remote=False)
# Evaluate model's mean square errors
print(f"Train loss: {model.evaluate(X_train, y_train)}")
print(f"Test loss: {model.evaluate(X_test, y_test)}")
# Evaluate uptrained model's mean square errors
print(f"Train loss: {pulled_model.evaluate(X_train, y_train)}")
print(f"Test loss: {pulled_model.evaluate(X_test, y_test)}")In [ ]:
# Remote mode for prediction
vertexai.preview.init(remote=True)
predictions = model.predict(X_test)
print(predictions)In [ ]:
registered_model.delete()In [ ]:
# Switch to local mode for testing
vertexai.preview.init(remote=True, autolog=True)
import lightning.pytorch as pl
import torch
# Wrap classes to enable Vertex remote execution
# Don't need this step after import hook is implemented
pl.Trainer = vertexai.preview.remote(pl.Trainer)
# prepare data loader
train_loader = torch.utils.data.DataLoader(
torch.utils.data.TensorDataset(
torch.tensor(X_train).to(torch.float32),
torch.tensor(y_train),
),
batch_size=10,
shuffle=True,
)
# define the model
class LitLogisticRegression(pl.LightningModule):
def __init__(self, input_size: int, output_size: int):
super().__init__()
self.linear = torch.nn.Linear(input_size, output_size)
self.softmax = torch.nn.Softmax(dim=1)
def forward(self, x):
return self.softmax(self.linear(x))
def training_step(self, batch, batch_idx):
x, y = batch
y_hat = self(x)
loss = torch.nn.functional.cross_entropy(y_hat, y)
return loss
def configure_optimizers(self):
return torch.optim.Adam(self.parameters(), lr=0.05)
def predict(self, X):
X = torch.tensor(X).to(torch.float32)
with torch.no_grad():
pred = torch.argmax(self(X), dim=1)
return pred
model = LitLogisticRegression(4, 3)
# set up the trainer and training config
trainer = pl.Trainer(max_epochs=100, accelerator="cpu")
trainer.fit.vertex.remote_config.display_name = REMOTE_JOB_NAME + "-lightning-model"
trainer.fit.vertex.remote_config.staging_bucket = REMOTE_JOB_BUCKET
trainer.fit.vertex.remote_config.service_account = "GCE"
# Train model on Vertex
trainer.fit(model, train_dataloaders=train_loader)In [ ]:
from sklearn.metrics import accuracy_score
# Switch to local mode for testing
vertexai.preview.init(remote=False)
# Evaluate model's accuracy score
print(f"Train accuracy: {accuracy_score(y_train, model.predict(X_train))}")
print(f"Test accuracy: {accuracy_score(y_test, model.predict(X_test))}")In [ ]:
# Remote mode for prediction
vertexai.preview.init(remote=True)
predictions = model.predict(X_test)
print(predictions)In [ ]:
import os
from google.cloud import aiplatform
delete_bucket = False
if delete_bucket or os.getenv("IS_TESTING"):
! gsutil rm -rf {BUCKET_URI}
try:
experiment_name = vertexai.preview.get_experiment_df()["experiment_name"]
aiplatform.Experiment(experiment_name[0]).delete()
except Exception as e:
print(e)
Run in Colab
View on GitHub