Amazon Web Services ブログ

AutoGluonのコンテナをSageMaker上で動かして高度なAutoMLを実現

機械学習を自動化するための OSS である AutoGluon のコンテナイメージが公開されました。
このブログでは、Amazon SageMaker の pre-built deep learning containers を適用して AutoGluon-Tabular を使用する方法について解説します。

AutoGluon は OSS であり、様々な環境で利用することができます。しかし、プロダクションでの利用や柔軟なクラウドリソースを活用することで学習時間を削減したい場合、開発環境をコンテナ化したいという要望がでてくるかと思います。従来、こういったシーンではAWS上でAutoGluonを動かすためにコンテナイメージを自作いただく必要がありました。しかし、今回ご紹介する pre-built deep learning containers が登場したことでその必要は無くなりました。 pre-built deep learning containers では予め AutoGluon-Tabular が実行できる環境が整えられており、 例えばSageMaker上でAutoGluon-Tabular を使った学習や推論を行なうことが格段に容易となりました。

本記事ではSageMaker 上で pre-built deep learning containers を用いてAutoGluon-Tabular を実行するサンプルノートブックをJupyter Notebookで実行しながら解説を行っていきます。そして、環境設定からモデルの学習、推論エンドポイントのデプロイやバッチ推論を行なう一連の流れをご説明します。

※ 2021年12月22日現在でのサンプルノートブックの内容を解説しています。

環境構築

本記事では、SageMakerノートブックインスタンスにてAutoGluonのコンテナイメージを利用し、AutoGluon-Tabularを実行してみたいと思います。その為、まず最初にSageMakerノートブックインスタンスを作成します。

[ ノートブックインスタンス名 ] に名前を入力し、[ ノートブックインスタンスのタイプ ] ではコストの低い「 ml.t2.medium 」インスタンスを選びます。

次に、IAM ロールの選択を行います。
本記事では「 AmazonSageMakerFullAccess 」を持った IAM ロールを作成します。

[ IAM ロール ] にて「新しいロールの作成」を選択してください。
(既に作成済みの IAM ロールをお持ちの方はそちらを選択していただいても問題ございません。)

IAM ロールを作成するという画面が出てきます。
[ 指定する S3 バケット ] にて「任意の S3 バケット」が選択されていることを確認し、右下の 「ロールの作成」を押してください。

下記のように「成功! IAM ロールを作成しました。」と表示されましたら完了です。

最後に画面右下にある「ノートブックインスタンスの作成」を押してください。
ノートブックインスタンスの作成が開始されます。

作成したノートブックインスタンスのステータスが inService となりましたら準備が完了していますので、画面右側にある「 JupyterLab を開く」を選択して Jupyter Lab を起動します。

Jupyter Lab が立ち上がりましたら、サイドバーの SageMaker アイコンを押してください。

「 AMAZON SAGEMAKER SAMPLE NOTEBOOKS 」のメニューが表示されますので、「 Advanced Functionality 」にある、「 AutoGluon_Tabular_SageMaker_Containers.ipynb 」を開き、画面右上にある「 Create a Copy 」ボタンを押してください。

下図のような画面が表示されますので、「 Create Copy 」を押してください。

今回利用する pre-built deep learning containers は こちらのリンクにもあるように Python3.7 のバージョンが必要です。

また、本記事では Pandas や NumPy などのライブラリも利用しますので、ノートブックインスタンスのカーネルは「 conda_mxnet_latest_py37 」を選択してください。

これで今回使用するサンプルノートブックの準備ができました。

環境設定

では、ここからは環境設定を行います。以下では Jupyter ベースで解説をしていきます。

まず、pre-built deep learning containers にて AutoGluon-Tabular を利用するためには SageMaker Python SDK のバージョンが 2.66 以上である必要があります。以下のコマンドは上記を考慮し、アップデートが必要な場合のみ最新化を行いますので実行してください。

# Ensure autogluon images information is available in SageMaker Python SDK
!pip install -q -U 'sagemaker>=2.66'

次に以下のコードを実行することで、今回使用するライブラリのインポートや先ほど作成した IAM ロールの取得などを行います。

import sagemaker
import pandas as pd
import numpy as np
from ag_model import (
 AutoGluonTraining,
 AutoGluonInferenceModel,
 AutoGluonTabularPredictor,
)
from sagemaker import utils
from sagemaker.serializers import CSVSerializer
import os

role = sagemaker.get_execution_role()
sagemaker_session = sagemaker.session.Session()
region = sagemaker_session._region_name

bucket = sagemaker_session.default_bucket()
s3_prefix = f"autogluon_sm/{utils.sagemaker_timestamp()}"
output_path = f"s3://{bucket}/{s3_prefix}/output/"

データの取得

本記事では、成人の国勢調査データセットを利用します。このデータは、1994 年の国勢調査局のデータベースから抽出されたものであり、UCI Machine Learning Repository にて公開されています。本タスクでは、国勢調査データに基づいて収入が年間 5 万ドルを超えるかどうかを分類するモデルを、このデータセットとAutoGluon-Tabular を用いて作成します。

まずは、既に Amazon S3 へ格納されているデータセットを読み込むためのディレクトリを用意します。

!mkdir -p data

本データセットには項目名の記載がないので別途リストを用意します。 ( AutoGluon-Tabular が読み込めるデータは、ヘッダーが付与された適切にフォーマットが行われている CSV ファイル等です。)

columns = ["age","workclass","fnlwgt","education","education-num","marital-status","occupation","relationship","race","sex","capital-gain","capital-loss","hours-per-week","native-country","class",]

トレーニングデータを用意するためにデータセットを読み込み、先ほど用意したヘッダーをセットして CSV 化します。

df_train = pd.read_csv("s3://sagemaker-sample-files/datasets/tabular/uci_adult/adult.data", header=None)
df_train.columns = columns
df_train.to_csv("data/train.csv")

次にテストデータを用意するために、先ほどと同じ操作でデータセットの読み込みとヘッダーの追加を行います。またテストデータでは “class“ の項目がトレーニングデータの表記と異なる為、 Pandas の map 関数を用いて統一します。

df_test = pd.read_csv("s3://sagemaker-sample-files/datasets/tabular/uci_adult/adult.test",header=None,skiprows=1,)
df_test.columns = columns
df_test["class"] = df_test["class"].map({" <=50K.": " <=50K"," >50K.": " >50K",})
df_test.to_csv("data/test.csv")

トレーニング

トレーニングでは Amazon SageMaker を利用します。その為、SageMaker ついて簡単に説明します。下図にSageMaker で学習ジョブや推論を実行する際の基本的なアーキテクチャをお示ししています。

開発は、ノートブックインスタンス上で、Jupyter ベースで行うこともできますし、SageMaker Studioの開発環境上で、ノートブックなどを利用して行なうこともできます。今回は、SageMakerの学習ジョブを使って学習を行い、エンドポイントの立ち上げやバッチ推論の実行を行っていきますので、その仕組みを解説します。

学習ジョブを実行する場合、基本的に学習データなどは Amazon S3 というオブジェクトストレージに保存し、機械学習を行うための実行環境はコンテナイメージとして Amazon ECR という Docker コンテナレジストリへあらかじめ格納しておきます。 ( PyTorch や TensorFlow などについて既に用意されているコンテナイメージもあります)

そして、 学習ジョブ実行時には学習用インスタンスを、推論時には推論用インスタンスをそれぞれ利用することができます。このようにデータ、実行環境、インスタンスを分離する仕組みにより、必要な時に適切なインスタンス上に、必要なコンテナイメージとデータを取得して学習、及び推論を行うことができるようになっています。 (学習用インスタンスではモデルの学習が終わると自動でインスタンスが停止する仕組みとなっており、コスト面でのメリットもあります。)

今回はこの SageMaker を用いて学習、及び推論を行っていきます。

SageMaker Python SDK のサンプルを利用して、独自の学習及び推論用のスクリプトを作成することもできます。

今回のスクリプトを利用することで AutoGluon の構成を YAML で記載することが可能となります。 (今回利用する YAML ファイルは config ディレクトリに格納されています。)

また、 AutoGluon Deep Learning Container images は scripts ディレクトリに格納しているカスタムトレーニングスクリプトにて利用しています。

まずはトレーニング時の構成を設定するために「 AutoGluonTraining 」のクラスを利用します。
このクラスがあることで、学習時の条件を引数に指定するだけで学習ジョブを実行できるのが利点です。

例えば、実行するコードのパスを [ entry_point ] へ指定したり、インスタンス数を [ instance_count ] 、インスタンスタイプを [ instance_type ]  へ設定するのみで実行が可能となります。 (その他の引数についてはこちらのドキュメントに詳細が載っておりますのでご覧ください。)

ag = AutoGluonTraining(
    role=role,
    entry_point="scripts/tabular_train.py",
    region=region,
    instance_count=1,
    instance_type="ml.m5.2xlarge",
    framework_version="0.3.1",
    base_job_name="autogluon-tabular-train",
)

次に先ほど作成した学習データ、テストデータに加えて、事前に用意している AutoGluon の構成を記載した YAML ファイルの 3 つを S3 へそれぞれアップロードします。

s3_prefix = f"autogluon_sm/{utils.sagemaker_timestamp()}"
train_input = ag.sagemaker_session.upload_data(
    path=os.path.join("data", "train.csv"), key_prefix=s3_prefix
)
eval_input = ag.sagemaker_session.upload_data(
    path=os.path.join("data", "test.csv"), key_prefix=s3_prefix
)
config_input = ag.sagemaker_session.upload_data(
    path=os.path.join("config", "config-med.yaml"), key_prefix=s3_prefix
)

モデルの学習

モデルの学習はノートブックインスタンス、または学習インスタンスでの実行を選択できます。学習用インスタンスで学習を実行する場合は、先ほどの「 AutoGluonTraining 」クラスの引数にある [ instance_type ] にて「 ml.m5.2xlarge 」を選択することが推奨されています。現在コードを実行しているノートブックインスタンス上でモデルの学習を行う場合は [ instance_type ] を「 local 」に設定してください。

job_name = utils.unique_name_from_base("test-autogluon-image")
ag.fit(
 {"config": config_input, "train": train_input, "test": eval_input},
 job_name=job_name,
)

モデルのエクスポート

AutoGluon にて作成したモデルはエクスポートが可能です。モデル学習後に出力されるアーティファクトは EC2 や ECS ,  EKS ,  SageMaker の推論インスタンスなどにホスティングして推論環境を構築することができます。

!aws s3 cp {ag.model_data} .
!ls -alF model.tar.gz

エンドポイントへのデプロイ

本記事では先ほど作成したモデルを推論インスタンス、またはノートブックインスタンス上へデプロイします。

まずはモデルをアップロードします。

endpoint_name = sagemaker.utils.unique_name_from_base("sagemaker-autogluon-serving-trained-model")

model_data = sagemaker_session.upload_data(
 path=os.path.join(".", "model.tar.gz"), key_prefix=f"{endpoint_name}/models"
)

次にモデルをデプロイします。

推論インスタンスにモデルをデプロイする場合は [ instance_type ] に「 ml.m5.2xlarge 」の指定を推奨しています。 (もしノートブックインスタンスにデプロイする場合は「 local 」を指定します)

instance_type = "ml.m5.2xlarge"
# instance_type = 'local'
model = AutoGluonInferenceModel(
    model_data=model_data,
    role=role,
    region=region,
    framework_version="0.3.1",
    instance_type=instance_type,
    source_dir="scripts",
    entry_point="tabular_serve.py",
)
predictor = model.deploy(
    initial_instance_count=1, serializer=CSVSerializer(), instance_type=instance_type
)

ラベルを削除したテストデータで推論実施

まずテストデータのターゲット変数となる「 Class 」 (収入が年間 5 万ドルを超えるかどうかのラベル) を削除し、そこから 100 レコードを抽出します。この作業によりラベルのないテストデータが準備できましたので、先ほど作成したエンドポイントで推論を実施します。

df = pd.read_csv("data/test.csv")
data = df.drop(columns="class")[:100].values
preds = predictor.predict(data)
p = pd.DataFrame({"preds": pd.DataFrame(preds)[0], "actual": df["class"][: len(preds)]})
p.head()
print(f"{(p.preds==p.actual).astype(int).sum()}/{len(p)} are correct")

最後まで実施すると下記のように推論結果が得られ、私の環境では 100 レコード中 94 レコードが正解という結果となりました。

エンドポイントのクリーンアップ

推論実施が終わったら、エンドポイントを削除します。エンドポイントが起動している間は課金対象となりますので、ご注意ください。

predictor.delete_endpoint()

バッチ推論

推論インスタンスでは、先ほどのリアルタイム推論だけでなくバッチ推論も行うことが可能です。ウェブサイトやモバイルアプリなど、リアルタイムに予測が必要なサービスの場合はリアルタイム推論が適しているでしょう。しかし、レイテンシーが気にならないケースや大規模なデータセットでの推論処理が必要な場合はバッチ推論の方がおそらくより適しているでしょう。

バッチ推論に関する詳細な情報についてはこちらをご覧ください。

endpoint_name = sagemaker.utils.unique_name_from_base(
    "sagemaker-autogluon-batch_transform-trained-model"
)

model_data = sagemaker_session.upload_data(
    path=os.path.join(".", "model.tar.gz"), key_prefix=f"{endpoint_name}/models"
)

instance_type = "ml.m5.2xlarge"

model = AutoGluonInferenceModel(
    model_data=model_data,
    role=role,
    region=region,
    framework_version="0.3.1",
    instance_type=instance_type,
    entry_point="tabular_serve-batch.py",
    source_dir="scripts",
    predictor_cls=AutoGluonTabularPredictor,
)

transformer = model.transformer(
    instance_count=1,
    instance_type=instance_type,
    strategy="MultiRecord",
    max_payload=6,
    max_concurrent_transforms=1,
    output_path=output_path,
    accept="application/json",
    assemble_with="Line",
)

バッチ推論を行う為のデータを準備します。

pd.read_csv(f"data/test.csv")[:100].to_csv("data/test_no_header.csv", header=False, index=False)

S3にデータをアップロードします。

test_input = transformer.sagemaker_session.upload_data(
    path=os.path.join("data", "test_no_header.csv"), key_prefix=s3_prefix
)

transformer.transform(
    test_input,
    input_filter="$[:14]",  # filter-out target variable
    split_type="Line",
    content_type="text/csv",
    output_filter="$['class']",  # keep only prediction class in the output
)

transformer.wait()

バッチ推論を行なった推論結果を取得します。

!aws s3 cp {transformer.output_path[:-1]}/test_no_header.csv.out .

p = pd.concat(
    [
        pd.read_json("test_no_header.csv.out", orient="index")
        .sort_index()
        .rename(columns={0: "preds"}),
        pd.read_csv("data/test.csv")[["class"]].iloc[:100].rename(columns={"class": "actual"}),
    ],
    axis=1,
)
p.head()

print(f"{(p.preds==p.actual).astype(int).sum()}/{len(p)} are correct")

まとめ

本記事では AutoGluon を活用してモデルを自動的に作成し、その後に SageMaker にてモデルをデプロイする方法について学んでいただきました。また、この記事内では、トレーニング、リアルタイム推論、バッチ推論とそれぞれの実施手順をご説明しましたが、全てのフェーズにおいてローカル環境、または SageMaker 上で実施するかをお選びいただけます。たとえば、ローカルで学習しSageMakerにデプロイするといったことが可能です。ご利用の要件に応じて選択ください。

また、AutoGluon についてさらに詳細をご覧になりたい方は、こちらのドキュメントチュートリアルをご確認ください。加えて、SageMaker での推論についてもドキュメントがありますのでご覧ください。
AutoGluon の解説記事としてはこちらのブログ記事、「99 % のデータサイエンティストの精度を超えた AutoML ライブラリ、AutoGluon-Tabular を使ってみる」 もご覧ください。


著者について

澤亮太は AWS のソリューションアーキテクトです。西日本を中心に、様々な業種のお客様へ AWS の導入やご活用における技術的なご支援をしております。

 

 

 

 


藤川のぞみは AWS の機械学習ソリューションアーキテクトです。さまざまな業界のお客様の課題を機械学習を活用して解決するご支援をしています。