1. 概要
このラボでは、Google Cloud が新たに発表したマネージド ML プラットフォームである Vertex AI を使用して、エンドツーエンドの ML ワークフローを構築する方法を学びます。元データからデプロイ済みモデルに移行する方法を学びます。このワークショップでは、Vertex AI を使用して独自の ML プロジェクトを開発、本番環境に導入できるよう準備を整えます。このラボでは、Cloud Shell を使用してカスタム Docker イメージを作成し、Vertex AI でのトレーニング用のカスタム コンテナのデモを行います。
ここではモデルのコードに TensorFlow を使用していますが、別のフレームワークに簡単に置き換えることができます。
学習内容
次の方法を学習します。
- Cloud Shell を使用してモデルのトレーニング コードを構築し、コンテナ化する
- カスタムモデルのトレーニング ジョブを Vertex AI に送信する
- トレーニング済みモデルをエンドポイントにデプロイし、そのエンドポイントを使用して予測を取得する
このラボを Google Cloud で実行するための総費用は約 $2 です。
2. Vertex AI の概要
このラボでは、Google Cloud で利用できる最新の AI プロダクトを使用します。Vertex AI は Google Cloud 全体の ML サービスを統合してシームレスな開発エクスペリエンスを提供します。以前は、AutoML でトレーニングしたモデルやカスタムモデルには、個別のサービスを介してアクセスする必要がありました。Vertex AI は、これらの個別のサービスを他の新しいプロダクトとともに 1 つの API へと結合します。既存のプロジェクトを Vertex AI に移行することもできます。ご意見やご質問がありましたら、サポートページからお寄せください。
以下の図に示すように、Vertex には ML ワークフローの各ステージに役立つさまざまなツールが含まれています。以下でハイライト表示されている Vertex のトレーニングと予測の使用に重点を置きます。
3. 環境を設定する
セルフペース型の環境設定
Cloud コンソールにログインして、新しいプロジェクトを作成するか、既存のプロジェクトを再利用します(Gmail アカウントも Google Workspace アカウントもまだお持ちでない場合は、アカウントを作成してください)。
プロジェクト ID を忘れないようにしてください。プロジェクト ID はすべての Google Cloud プロジェクトで一意の名前にする必要があります(上記の名前はすでに使用されているため、使用できません)。
次に、Google Cloud リソースを使用するために、Cloud Console で課金を有効にする必要があります。
このコードラボを実行しても、費用はほとんどかからないはずです。このチュートリアル以外で請求が発生しないように、リソースのシャットダウン方法を説明する「クリーンアップ」セクションの手順に従うようにしてください。Google Cloud の新規ユーザーは、$300 USD 分の無料トライアル プログラムをご利用いただけます。
ステップ 1: Cloud Shell を起動する
このラボでは、Cloud Shell セッションで作業します。Cloud Shell は、Google のクラウドで実行されている仮想マシンによってホストされるコマンド インタープリタです。このセクションは、パソコンでもローカルで簡単に実行できますが、Cloud Shell を使用することで、誰もが一貫した環境での再現可能な操作性を利用できるようになります。本ラボの後、このセクションをパソコン上で再度実行してみてください。
Cloud Shell をアクティブにする
Cloud コンソールの右上で、下のボタンをクリックして [Cloud Shell をアクティブにする] をクリックします。
Cloud Shell を初めて起動する場合は、その内容を説明する中間画面(スクロールしなければ見えない範囲)が表示されます。その場合は、[続行] をクリックします(今後表示されなくなります)。この中間画面は次のようになります。
Cloud Shell のプロビジョニングと接続に少し時間がかかる程度です。
この仮想マシンには、必要な開発ツールがすべて含まれています。仮想マシンは Google Cloud で稼働し、永続的なホーム ディレクトリが 5 GB 用意されているため、ネットワークのパフォーマンスと認証が大幅に向上しています。このコードラボでの作業のほとんどは、ブラウザまたは Chromebook から実行できます。
Cloud Shell に接続すると、すでに認証は完了しており、プロジェクトに各自のプロジェクト ID が設定されていることがわかります。
Cloud Shell で次のコマンドを実行して、認証されたことを確認します。
gcloud auth list
コマンド出力
Credentialed Accounts ACTIVE ACCOUNT * <my_account>@<my_domain.com> To set the active account, run: $ gcloud config set account `ACCOUNT`
Cloud Shell で次のコマンドを実行して、gcloud コマンドがプロジェクトを認識していることを確認します。
gcloud config list project
コマンド出力
[core] project = <PROJECT_ID>
上記のようになっていない場合は、次のコマンドで設定できます。
gcloud config set project <PROJECT_ID>
コマンド出力
Updated property [core/project].
Cloud Shell には、現在の Cloud プロジェクトの名前が格納されている GOOGLE_CLOUD_PROJECT
など、いくつかの環境変数があります。ラボでは、さまざまな場所でこれを使用します。次を実行すると確認できます。
echo $GOOGLE_CLOUD_PROJECT
ステップ 2: API を有効にする
これらのサービスがどこで(なぜ)必要になるかは、後の手順でわかります。とりあえず、次のコマンドを実行して Compute Engine、Container Registry、Vertex AI の各サービスへのアクセス権をプロジェクトに付与します。
gcloud services enable compute.googleapis.com \
containerregistry.googleapis.com \
aiplatform.googleapis.com
成功すると次のようなメッセージが表示されます。
Operation "operations/acf.cc11852d-40af-47ad-9d59-477a12847c9e" finished successfully.
ステップ 3: Cloud Storage バケットを作成する
Vertex AI でトレーニング ジョブを実行するには、保存したモデルアセットを保存するストレージ バケットが必要です。Cloud Shell で次のコマンドを実行して、バケットを作成します。
BUCKET_NAME=gs://$GOOGLE_CLOUD_PROJECT-bucket
gsutil mb -l us-central1 $BUCKET_NAME
ステップ 4: エイリアス Python 3
このラボのコードでは Python 3 を使用します。このラボで作成するスクリプトの実行時に Python 3 を使用するように、Cloud Shell で次のコマンドを実行してエイリアスを作成します。
alias python=python3
このラボでトレーニングして提供するモデルは、TensorFlow ドキュメントのこのチュートリアルに基づいて構築されています。このチュートリアルでは、Kaggle の Auto MPG データセットを使用して車両の燃費を予測します。
4. トレーニング コードをコンテナ化する
このトレーニング ジョブを Vertex に送信しましょう。トレーニング コードを Docker コンテナに格納し、このコンテナを Google Container Registry に push します。この方法を使用すると、任意のフレームワークで構築されたモデルをトレーニングできます。
ステップ 1: ファイルを設定する
まず、Cloud Shell のターミナルから次のコマンドを実行して、Docker コンテナに必要なファイルを作成します。
mkdir mpg
cd mpg
touch Dockerfile
mkdir trainer
touch trainer/train.py
これで、次のような mpg/
ディレクトリが作成されます。
+ Dockerfile
+ trainer/
+ train.py
これらのファイルを表示して編集するには、Cloud Shell に組み込まれたコードエディタを使用します。Cloud Shell の右上のメニューバーにあるボタンをクリックすると、エディタとターミナルを切り替えることができます。
ステップ 2: Dockerfile を作成する
コードをコンテナ化するために、まず Dockerfile を作成します。Dockerfile には、イメージの実行に必要なすべてのコマンドを含めます。使用しているすべてのライブラリがインストールされ、トレーニング コードのエントリ ポイントが設定されます。
Cloud Shell ファイル エディタで mpg/
ディレクトリを開き、ダブルクリックして Dockerfile を開きます。
次に、このファイルに以下の内容をコピーします。
FROM gcr.io/deeplearning-platform-release/tf2-cpu.2-3
WORKDIR /
# Copies the trainer code to the docker image.
COPY trainer /trainer
# Sets up the entry point to invoke the trainer.
ENTRYPOINT ["python", "-m", "trainer.train"]
この Dockerfile は、Deep Learning Containers TensorFlow Enterprise 2.3 Docker イメージを使用します。Google Cloud の Deep Learning Containers には一般的な ML およびデータ サイエンスのフレームワークが数多くプリインストールされています。使用しているものには、TF Enterprise 2.3、Pandas、Scikit-learn などがあります。該当するイメージをダウンロードした後、この Dockerfile はトレーニング コードのエントリ ポイントを設定します。これは次のステップで追加します。
ステップ 3: モデルのトレーニング コードを追加する
Cloud Shell エディタで train.py
ファイルを開き、以下のコードをコピーします(これは TensorFlow ドキュメントのチュートリアルから引用しています)。
# This will be replaced with your bucket name after running the `sed` command in the tutorial
BUCKET = "BUCKET_NAME"
import numpy as np
import pandas as pd
import pathlib
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
print(tf.__version__)
"""## The Auto MPG dataset
The dataset is available from the [UCI Machine Learning Repository](https://archive.ics.uci.edu/ml/).
### Get the data
First download the dataset.
"""
"""Import it using pandas"""
dataset_path = "https://storage.googleapis.com/io-vertex-codelab/auto-mpg.csv"
dataset = pd.read_csv(dataset_path, na_values = "?")
dataset.tail()
"""### Clean the data
The dataset contains a few unknown values.
"""
dataset.isna().sum()
"""To keep this initial tutorial simple drop those rows."""
dataset = dataset.dropna()
"""The `"origin"` column is really categorical, not numeric. So convert that to a one-hot:"""
dataset['origin'] = dataset['origin'].map({1: 'USA', 2: 'Europe', 3: 'Japan'})
dataset = pd.get_dummies(dataset, prefix='', prefix_sep='')
dataset.tail()
"""### Split the data into train and test
Now split the dataset into a training set and a test set.
We will use the test set in the final evaluation of our model.
"""
train_dataset = dataset.sample(frac=0.8,random_state=0)
test_dataset = dataset.drop(train_dataset.index)
"""### Inspect the data
Have a quick look at the joint distribution of a few pairs of columns from the training set.
Also look at the overall statistics:
"""
train_stats = train_dataset.describe()
train_stats.pop("mpg")
train_stats = train_stats.transpose()
train_stats
"""### Split features from labels
Separate the target value, or "label", from the features. This label is the value that you will train the model to predict.
"""
train_labels = train_dataset.pop('mpg')
test_labels = test_dataset.pop('mpg')
"""### Normalize the data
Look again at the `train_stats` block above and note how different the ranges of each feature are.
It is good practice to normalize features that use different scales and ranges. Although the model *might* converge without feature normalization, it makes training more difficult, and it makes the resulting model dependent on the choice of units used in the input.
Note: Although we intentionally generate these statistics from only the training dataset, these statistics will also be used to normalize the test dataset. We need to do that to project the test dataset into the same distribution that the model has been trained on.
"""
def norm(x):
return (x - train_stats['mean']) / train_stats['std']
normed_train_data = norm(train_dataset)
normed_test_data = norm(test_dataset)
"""This normalized data is what we will use to train the model.
Caution: The statistics used to normalize the inputs here (mean and standard deviation) need to be applied to any other data that is fed to the model, along with the one-hot encoding that we did earlier. That includes the test set as well as live data when the model is used in production.
## The model
### Build the model
Let's build our model. Here, we'll use a `Sequential` model with two densely connected hidden layers, and an output layer that returns a single, continuous value. The model building steps are wrapped in a function, `build_model`, since we'll create a second model, later on.
"""
def build_model():
model = keras.Sequential([
layers.Dense(64, activation='relu', input_shape=[len(train_dataset.keys())]),
layers.Dense(64, activation='relu'),
layers.Dense(1)
])
optimizer = tf.keras.optimizers.RMSprop(0.001)
model.compile(loss='mse',
optimizer=optimizer,
metrics=['mae', 'mse'])
return model
model = build_model()
"""### Inspect the model
Use the `.summary` method to print a simple description of the model
"""
model.summary()
"""Now try out the model. Take a batch of `10` examples from the training data and call `model.predict` on it.
It seems to be working, and it produces a result of the expected shape and type.
### Train the model
Train the model for 1000 epochs, and record the training and validation accuracy in the `history` object.
Visualize the model's training progress using the stats stored in the `history` object.
This graph shows little improvement, or even degradation in the validation error after about 100 epochs. Let's update the `model.fit` call to automatically stop training when the validation score doesn't improve. We'll use an *EarlyStopping callback* that tests a training condition for every epoch. If a set amount of epochs elapses without showing improvement, then automatically stop the training.
You can learn more about this callback [here](https://www.tensorflow.org/api_docs/python/tf/keras/callbacks/EarlyStopping).
"""
model = build_model()
EPOCHS = 1000
# The patience parameter is the amount of epochs to check for improvement
early_stop = keras.callbacks.EarlyStopping(monitor='val_loss', patience=10)
early_history = model.fit(normed_train_data, train_labels,
epochs=EPOCHS, validation_split = 0.2,
callbacks=[early_stop])
# Export model and save to GCS
model.save(BUCKET + '/mpg/model')
上記のコードを mpg/trainer/train.py
ファイルにコピーしたら、Cloud Shell のターミナルに戻り、次のコマンドを実行して独自のバケット名をファイルに追加します。
sed -i "s|BUCKET_NAME|$BUCKET_NAME|g" trainer/train.py
ステップ 4: コンテナをローカルでビルドしてテストする
ターミナルで次のコマンドを実行して、Google Container Registry 内のコンテナ イメージの URI を示す変数を定義します。
IMAGE_URI="gcr.io/$GOOGLE_CLOUD_PROJECT/mpg:v1"
続いて、mpg
ディレクトリのルートで次のように実行してコンテナをビルドします。
docker build ./ -t $IMAGE_URI
コンテナをビルドしたら、Google Container Registry に push します。
docker push $IMAGE_URI
イメージが Container Registry に push されたことを確認するために、コンソールの [Container Registry] セクションに移動すると、次のように表示されます。
コンテナを Container Registry に push したら、カスタムモデルのトレーニング ジョブを開始する準備ができました。
5. Vertex AI でトレーニング ジョブを実行する
Vertex では、次の 2 つの方法でモデルをトレーニングできます。
- AutoML: 最小限の労力と ML の専門知識で高品質なモデルをトレーニングする
- カスタム トレーニング: Google Cloud のビルド済みコンテナまたは独自のコンテナのいずれかを使用して、クラウドでカスタム トレーニング アプリケーションを実行します。
このラボでは、Google Container Registry 上の独自のカスタム コンテナによるカスタム トレーニングを使用します。まず、Cloud コンソールの Vertex で [トレーニング] セクションに移動します。
ステップ 1: トレーニング ジョブを開始する
[作成] をクリックして、トレーニング ジョブとデプロイされたモデルのパラメータを入力します。
- [Dataset] で [マネージド データセットなし] を選択します。
- トレーニング方法として [カスタム トレーニング(上級者向け)] を選択し、[続行] をクリックします。
- [モデル名] に「
mpg
」(または任意のモデル名)を入力します。 - [続行] をクリックする
コンテナの設定ステップで、[カスタム コンテナ] を選択します。
最初のボックス(コンテナ イメージ)で [参照] をクリックし、Container Registry に push したコンテナを見つけます。次のようになります。
残りのフィールドは空白のままにして、[続行] をクリックします。
このチュートリアルではハイパーパラメータ チューニングを使用しないため、[Enable hyperparameter tuning] ボックスはオフのままにして [続行] をクリックします。
[コンピューティングと料金] で、選択されているリージョンはそのままにしておき、マシンタイプとして [n1-standard-4] を選択します。
このデモのモデルは短時間でトレーニングされるため、より小さなマシンタイプを使用しています。
[予測コンテナ] ステップで、[予測コンテナなし] を選択します。
6. モデルのエンドポイントをデプロイする
このステップでは、トレーニング済みモデルのエンドポイントを作成します。これを使用して、Vertex AI API 経由でモデルの予測を取得できます。そのために、エクスポートしたトレーニング済みモデルアセットのバージョンが、GCS の公開バケットで利用できるようになりました。
組織では、1 つのチームまたは個人がモデルの構築を担当し、別のチームがモデルのデプロイを担当するのが一般的です。ここで説明する手順では、すでにトレーニング済みのモデルを取得して、予測用にデプロイする方法を説明します。
ここでは、Vertex AI SDK を使用してモデルを作成し、エンドポイントにデプロイして、予測を取得します。
ステップ 1: Vertex SDK をインストールする
Cloud Shell ターミナルで次のコマンドを実行して、Vertex AI SDK をインストールします。
pip3 install google-cloud-aiplatform --upgrade --user
この SDK を使用すると、Vertex のさまざまな部分を操作できます。
ステップ 2: モデルを作成してエンドポイントをデプロイする
次に、Python ファイルを作成し、SDK を使用してモデルリソースを作成し、エンドポイントにデプロイします。Cloud Shell のファイル エディタで、[File]、[New File] の順に選択します。
ファイルに deploy.py
という名前を付けます。このファイルをエディタで開き、次のコードをコピーします。
from google.cloud import aiplatform
# Create a model resource from public model assets
model = aiplatform.Model.upload(
display_name="mpg-imported",
artifact_uri="gs://io-vertex-codelab/mpg-model/",
serving_container_image_uri="gcr.io/cloud-aiplatform/prediction/tf2-cpu.2-3:latest"
)
# Deploy the above model to an endpoint
endpoint = model.deploy(
machine_type="n1-standard-4"
)
次に、Cloud Shell のターミナルに戻り、cd
でルート ディレクトリに戻り、作成した次の Python スクリプトを実行します。
cd ..
python3 deploy.py | tee deploy-output.txt
リソースが作成されると、ターミナルにログの更新が記録されます。実行には 10 ~ 15 分かかります。正しく動作していることを確認するには、Vertex AI のコンソールで [モデル] セクションに移動します。
[mgp-imported] をクリックすると、そのモデルのエンドポイントが作成されているのが表示されます。
エンドポイントのデプロイが完了すると、Cloud Shell ターミナルに次のようなログが表示されます。
Endpoint model deployed. Resource name: projects/your-project-id/locations/us-central1/endpoints/your-endpoint-id
次のステップでは、デプロイしたエンドポイントの予測を取得するためにこれを使用します。
ステップ 3: デプロイされたエンドポイントで予測を取得する
Cloud Shell エディタで、predict.py
という名前の新しいファイルを作成します。
predict.py
を開き、次のコードを貼り付けます。
from google.cloud import aiplatform
endpoint = aiplatform.Endpoint(
endpoint_name="ENDPOINT_STRING"
)
# A test example we'll send to our model for prediction
test_mpg = [1.4838871833555929,
1.8659883497083019,
2.234620276849616,
1.0187816540094903,
-2.530890710602246,
-1.6046416850441676,
-0.4651483719733302,
-0.4952254087173721,
0.7746763768735953]
response = endpoint.predict([test_mpg])
print('API response: ', response)
print('Predicted MPG: ', response.predictions[0][0])
次に、ターミナルに戻り、次のコマンドを入力して、予測ファイルの ENDPOINT_STRING
を実際のエンドポイントに置き換えます。
ENDPOINT=$(cat deploy-output.txt | sed -nre 's:.*Resource name\: (.*):\1:p' | tail -1)
sed -i "s|ENDPOINT_STRING|$ENDPOINT|g" predict.py
次に、predict.py
ファイルを実行して、デプロイしたモデルのエンドポイントから予測を取得します。
python3 predict.py
テスト予測の予測燃料効率とともに、ログに記録された API のレスポンスが表示されます。
お疲れさまでした
Vertex AI を使って次のことを行う方法を学びました。
- カスタム コンテナにトレーニング コードを提供してモデルをトレーニングする。ここでは例として TensorFlow モデルを使用しましたが、カスタム コンテナを使って任意のフレームワークで構築されたモデルをトレーニングすることができます。
- トレーニングに使用したのと同じワークフローの一環として、ビルド済みコンテナを使用して TensorFlow モデルをデプロイする。
- モデルのエンドポイントを作成し、予測を生成する。
Vertex AI のさまざまな部分について詳しくは、ドキュメントをご覧ください。ステップ 5 で開始したトレーニング ジョブの結果を確認するには、Vertex コンソールのトレーニング セクションに移動します。
7. クリーンアップ
デプロイしたエンドポイントを削除するには、Vertex コンソールの [エンドポイント] セクションに移動し、削除アイコンをクリックします。
ストレージ バケットを削除するには、Cloud コンソールのナビゲーション メニューで [ストレージ] に移動してバケットを選択し、[削除] をクリックします。