Amazon Elastic InferenceをアタッチしたエンドポイントでMXNetの手書き数字分類モデルの推論を試してみる – Amazon SageMaker Advent Calendar 2018

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、大阪DI部の大澤です。 この記事は「クラスメソッド Amazon SageMaker Advent Calendar」の6日目の記事となります。

今回はMXNetで作成したニューラルネットワークの分類モデルで手書き数字のデータセット(MNIST)を学習させます。Amazon Elastic Inference(EI)をアタッチした推論用エンドポイントで学習させた分類モデルをホストさせて、推論を試してみたいと思います。

Amazon Elastic Inferenceとは

Amazon Elastic InferenceはEC2とSageMakerのインスタンスにGPUを付与することができる機能です。例えば、c5.largeインスタンスにElastic Inferenceのeia1.mediumをアタッチすることでGPUによる計算能力を得ることができます。

Amazon Elastic Inferenceのよくある質問では次のように書かれています。

Q: Amazon Elastic Inference とは何ですか?

A: Amazon Elastic Inference (Amazon EI) は、Amazon EC2 または Amazon SageMaker のインスタンスタイプに適切な量の GPU による推論アクセラレーションをアタッチさせる、高速コンピューティングサービスです。つまり、アプリケーションの全体的なコンピューティング、メモリ、およびストレージのニーズに最も適したインスタンスタイプを選択し、必要な推論アクセラレーションの程度を個別に構成できます。

Q: Amazon Elastic inference アクセラレーターとは何ですか?

A: Amazon Elastic inference アクセラレーターは、低コストで深層学習の推論ワークロードを加速するために、あらゆる EC2 インスタンスタイプと連携するように設計された GPU によるハードウェアデバイスです。Amazon Elastic Inference を使用してインスタンスを起動すると、アクセラレーターがプロビジョニングされ、ネットワーク経由でインスタンスにアタッチされます。Amazon Elastic Inference で有効になっている TensorFlow Serving や Apache MXNet のような深層学習ツールやフレームワークでは、モデル計算を自動的に検出し、アタッチされたアクセラレーターにオフロードできます。

料金

東京リージョンの料金は次の通りです。

例えば、c5.largeのインスタンスにeia1.mediumをアタッチした場合には1時間あたり...0.107 + 0.220 = 0.327USDで計算能力の高いGPUを使うことが出来ます。 GPUインスタンスのp2.xlargeの場合だと1.542USD/時間なので、Elastic Inferenceを利用することで非常に安く済みます。

詳細については料金ページをご覧ください。

やってみる

IAMロールの取得

SageMakerでモデルの学習やモデルをホストするエンドポイントを作成するために、その権限を持ったIAMロールが必要となります。 まずは各操作で利用するIAMロールを指定しておきます。今回はノートブックインスタンスに関連づけられたIAMロールを使います。

import sagemaker

role = sagemaker.get_execution_role()

学習用スクリプトの確認

SageMakerでMNISTの学習を行う際にはmnist.pyのようなスクリプトをentry_pointとして設定する必要があります。

今回は抜粋して、モデル部分のみ紹介します。 モデルは3層の全結合層で構成されるニューラルネットワーク です。

def build_graph():
    data = mx.sym.var('data')
    data = mx.sym.flatten(data=data)
    fc1 = mx.sym.FullyConnected(data=data, num_hidden=128)
    act1 = mx.sym.Activation(data=fc1, act_type="relu")
    fc2 = mx.sym.FullyConnected(data=act1, num_hidden=64)
    act2 = mx.sym.Activation(data=fc2, act_type="relu")
    fc3 = mx.sym.FullyConnected(data=act2, num_hidden=10)
    return mx.sym.SoftmaxOutput(data=fc3, name='softmax')

SageMakerでのMXNetの学習に関する詳細についてはSDKのリポジトリにある説明をご覧ください。

学習

学習周りをハンドルするMXNet用のEstimatorを作成します。IAMロールや先ほど紹介した学習用スクリプト、インスタンスタイプやハイパーパラメータの設定などを行います。

from sagemaker.mxnet import MXNet

mnist_estimator = MXNet(entry_point='mnist.py',
                        role=role,
                        train_instance_count=1,
                        train_instance_type='ml.m4.xlarge',
                        framework_version='1.3.0',
                        hyperparameters={'learning-rate': 0.1})

学習用データを設定し、学習処理を開始します。

%%time
import boto3

region = boto3.Session().region_name
train_data_location = 's3://sagemaker-sample-data-{}/mxnet/mnist/train'.format(region)
test_data_location = 's3://sagemaker-sample-data-{}/mxnet/mnist/test'.format(region)

mnist_estimator.fit({'train': train_data_location, 'test': test_data_location})

推論用エンドポイントの作成

先ほど学習させたモデルをホストするエンドポイントを作成します。ベースとなるインスタンスにはm4.xlargeを指定し、Elastic Inferrenceのタイプml.eia1.mediumaccelerator_typeとして設定します。これだけでエンドポイントにElastic Inferenceをアタッチして使う事ができます。

%%time

predictor = mnist_estimator.deploy(initial_instance_count=1,
                                   instance_type='ml.m4.xlarge',
                                   accelerator_type='ml.eia1.medium')

推論

実際に数字を書いてそれがどの数字かを推論してみます。

input.htmlを読み込んで描画する事で、数字を書くフォームが作られます。

from IPython.display import HTML
HTML(open("input.html").read())

このフォームに数字を書くと、書いた数字のデータはdataという変数に自動的に入力されます。

※ JupyterLabから実行している場合は、数字を書いてもdataにデータが入らない事があります。Jupyterノートブックで実行するとちゃんと動くようなのでそちらで試してみると良さそうです。

先ほど作成したエンドポイントにリクエストを投げて、推論結果を受け取ります。

%%time
response = predictor.predict(data)
print('Raw prediction result:')
print(response)

labeled_predictions = list(zip(range(10), response[0]))
print('Labeled predictions: ')
print(labeled_predictions)

labeled_predictions.sort(key=lambda label_and_prob: 1.0 - label_and_prob[1])
print('Most likely answer: {}'.format(labeled_predictions[0]))

推論が出来ています。速度もおよそ20msと速いです。

ちなみにElastic Inferenceをアタッチせずにエンドポイントを作成し、推論した場合の速度は次のような感じでした。

今回試したモデルは小さいのでElastic Inferenceをアタッチせずともレスポンスが速く、効果は薄かったです。CPUだと推論に数秒かかるようなモデルの場合にはElastic Inferenceをエンドポイントにアタッチする事で著しく効果が現れるかと思います。

エンドポイントの削除

最後に余計な課金が発生しないよう、使っていたエンドポイントを削除します。

import sagemaker

predictor.delete_endpoint()

さいごに

今回は 「クラスメソッド Amazon SageMaker Advent Calendar」 の6日目として、「Amazon Elastic InferenceをアタッチしたエンドポイントでのMXNetの手書き数字分類モデルの推論」についてお送りしました。Amazon Elastic Inferenceを利用することで柔軟にGPUリソースとその他の計算リソースを簡単に組み合わせることができ、コストの最適化が可能となります。この機会に試してみてはいかがでしょうか。

お読みくださりありがとうございました〜!明日もお楽しみに〜!

参考