Amazon Web Services ブログ
Amazon Elastic Inference — GPUを利用した深層学習推論の高速化
近年の AI や深層学習の発展には、Graphics Processing Units (GPU) の素晴らしい処理能力が重要な役割を果たしてきました。 10年程前、研究者は機械学習や High Performance Computing (HPC) に対して、大規模なハードウェア並列演算能力を活用する方法を編み出しました。興味のある方は、2009年にスタンフォード大から発表され大きな影響を与えた、この論文 (PDF) をご覧ください。
現在では、GPU のおかげで開発者やデータサイエンティストは複雑なモデルを医療画像分析や自動運転の大量のデータで学習できています。例えば、Amazon EC2 P3 ファミリーを利用すると1インスタンスあたり最大8枚の NVIDIA V100 GPU、つまり混合精度演算で最大 1PFLOPS を利用できます。これが10年前の最速のスーパーコンピューターと同じパフォーマンスだなんて信じられるでしょうか?
もちろん、モデルの学習は話の半分に過ぎません。推論、すなわちモデルによる新しいデータサンプルに対する予測についてはどうでしょう?残念ながら開発者は、インスタンスタイプやサイズを選ぶ際にたびたび頭を抱えています。実際のところ、大きなモデルの場合、CPU による推論のレイテンシーは、オンラインアプリケーションの要求に合致しないかもしれませんし、本格的な GPU を利用するのは採算が合わないかもしれません。更に、あなたのアプリケーション全体のパフォーマンスにとっては、推論速度そのものより、RAM や CPU などのリソースの方が大切かもしれません。
例えば、あなたの処理の重いアプリケーションには 1台の c5.9xlarge インスタンス(バージニア北部リージョンで1時間あたり$1.53)が必要だとします。SSDモデルの一回の推論には 400ms 程かかりますが、これはリアルタイムな処理には間違いなく遅すぎます。そのアプリケーションを1台の p2.xlarge インスタンス(最も手頃な汎用GPUインスタンスで、バージニア北部リージョンでは1時間あたり$0.90) に移行すると、推論のパフォーマンスは180msまで改善しますが、p2.xlargeではvCPUやRAMの搭載量がより減少するためアプリケーションのパフォーマンスに影響を与えることになります。
さて、もうそのような妥協は必要ありません。本日、Amazon Elastic Inference という、どの Amazon EC2 インスタンスにも適切な量の GPU による推論アクセラレーターを取り付けることができるサービスを発表でき、非常に嬉しく思います。加えてこの機能は Amazon SageMaker のノートブックインスタンスとエンドポイントにも利用可能で、ビルトインアルゴリズムや深層学習環境にアクセラレーターを適用できます。
アプリケーションに最適な CPU インスタンスタイプを選択し、適切な量の GPU アクセラレーターを取り付け、最適な環境を作りましょう!もちろん、EC2 Auto Scaling を使用すれば、高速化されたインスタンスを必要な時に追加、削除することができます。
Amazon Elastic Inferenceとは
Amazon Elastic Inference は有名な機械学習フレームワークである TensorFlow や Apache MXNet、そして ONNX (MXNet 経由で適用)をサポートします。既存のコードの変更は最小限ですが、 AWS に最適化してビルドされたフレームワークを使用する必要があり、そこでは、インスタンスに取り付けられたアクセラレーターを自動で検出し、承認されたアクセスのみ許可し、計算をローカル CPU リソースや取り付けられたアクセラレーターに分散させています。これらは、Amazon S3 上の AWS Deep Learning AMI 上で利用可能で、それを元にご自身のイメージやコンテナにビルドすることもできます。また、Amazon SageMaker 利用時は自動的に提供されます。
Amazon Elastic Inference は3つのサイズが利用可能で、画像処理や自然言語処理、発話認識などの様々な種類の推論モデルに対して効率的に使い分けることができます。
- eia1.medium: 8TFLOPS の混合精度演算
- eia1.large: 16TFLOPS の混合精度演算
- eia1.xlarge: 32TFLOPS の混合精度演算
これにより、アプリケーションに最適な料金/パフォーマンスの比率を選ぶことができます。例えば、eia1.medium アクセラレーターが設定された c5.large インスタンスは、バージニア北部リージョンで1時間あたり$0.22になります。この組み合わせは p2.xlarge インスタンスより10-15%程度遅くなるだけで、 p2.xlarge は1台の NVIDIA K80 GPU を専有しているため、バージニア北部リージョンで1時間あたり$0.90かかります。つまり、アプリケーションに適したインスタンスタイプを選択することで、同等のGPUパフォーマンスに対して75%ものコストを削減できます。
それでは早速 Amazon EC2 インスタンス上での Apache MXNet やTensorFlow の例を詳しく見てみましょう。
Amazon Elastic Inference の設定
Amazon EC2 インスタンスでこのサービスを利用するために必要な手順の概要を示します。
- インスタンス用に、インバウンドのSSHトラフィックのみを許可したセキュリティグループを作成する。
- インスタンスに割り当てるIAMロールを作成し、Amazon Elastic Inference サービスへの接続を許可する。
- インスタンスが起動するVPCに、Amazon Elastic Inference への VPC エンドポイントを作成し、そのインスタンスからのインバウンドの HTTPS トラフィックのみを許可するセキュリティグループを関連付ける。ただし、VPCごとに一度だけこの設定を行う必要があり、エンドポイントの料金はアクセラレーターの料金に含まれることにご留意下さい。
アクセラレーターの割り当てられたインスタンスの作成
さて、エンドポイントが利用可能になったところで、AWS CLI を利用して AWS Deep Learning AMI から c5.large インスタンスを立ち上げましょう。
aws ec2 run-instances --image-id $AMI_ID \
--key-name $KEYPAIR_NAME --security-group-ids $SG_ID \
--subnet-id $SUBNET_ID --instance-type c5.large \
--elastic-inference-accelerator Type=eia1.large
たったこれだけです!Amazon Elastic Inferenceを利用するために新しいAPIを学ぶ必要はありません。アクセラレーターのタイプを記述するパラメータを追加で渡すだけです。数分後、インスタンスが起動し接続することができます。
Apache MXNetの高速化
この典型的な例では、Amazon Elastic Inference Accelerator 上にに大規模な事前学習済みの畳み込みニューラルネットワークを読み込みます(事前学習済みモデルにあまり詳しくない場合は、前回の投稿で私がそのトピックをカバーしたのでご覧ください)。具体的には、ImageNet データセットで学習した ResNet-512 ネットワークを使用します。
それでは、シンプルにAmazon Elastic Inference Accelerator上で1枚の画像分類を行います。
import mxnet as mx
import numpy as np
from collections import namedtuple
Batch = namedtuple('Batch', ['data'])
# Download model (ResNet-152 trained on ImageNet) and ImageNet categories
path='http://data.mxnet.io/models/imagenet/'
[mx.test_utils.download(path+'resnet/152-layers/resnet-152-0000.params'),
mx.test_utils.download(path+'resnet/152-layers/resnet-152-symbol.json'),
mx.test_utils.download(path+'synset.txt')]
# Set compute context to Elastic Inference Accelerator
# ctx = mx.gpu(0) # This is how we'd predict on a GPU
ctx = mx.eia() # This is how we predict on an EI accelerator
# Load pre-trained model
sym, arg_params, aux_params = mx.model.load_checkpoint('resnet-152', 0)
mod = mx.mod.Module(symbol=sym, context=ctx, label_names=None)
mod.bind(for_training=False, data_shapes=[('data', (1,3,224,224))],
label_shapes=mod._label_shapes)
mod.set_params(arg_params, aux_params, allow_missing=True)
# Load ImageNet category labels
with open('synset.txt', 'r') as f:
labels = [l.rstrip() for l in f]
# Download and load test image
fname = mx.test_utils.download('https://github.com/dmlc/web-data/blob/master/mxnet/doc/tutorials/python/predict_image/dog.jpg?raw=true')
img = mx.image.imread(fname)
# Convert and reshape image to (batch=1, channels=3, width, height)
img = mx.image.imresize(img, 224, 224) # Resize to training settings
img = img.transpose((2, 0, 1)) # Channels
img = img.expand_dims(axis=0) # Batch size
# img = img.as_in_context(ctx) # Not needed: data is loaded automatically to the EIA
# Predict the image
mod.forward(Batch([img]))
prob = mod.get_outputs()[0].asnumpy()
# Print the top 3 classes
prob = np.squeeze(prob)
a = np.argsort(prob)[::-1]
for i in a[0:3]:
print('probability=%f, class=%s' %(prob[i], labels[i]))
ご覧の通り、2つ程違いがあります。
- context に mx.eia() をセットしています。Amazon EC2 インスタンスには1つのAmazon Elastic Inference Acceleratorのみ紐付けられているのでナンバリングは不要です。
- GPUを利用する場合のように Amazon Elastic Inference Accelerator にあるイメージを明示的に読み込むことはしません。これは自動で処理されます。
この例を実行すると以下のような結果が得られます。
probability=0.979113, class=n02110958 pug, pug-dog
probability=0.003781, class=n02108422 bull mastiff
probability=0.003718, class=n02112706 Brabancon griffon
パフォーマンスについてはどうでしょうか? 私達の c5.large インスタンス上では、この推論に CPU で 230ms かかりますが、eia1.large アクセラレーターだと 31ms しかかかりません。ちなみに、本格的な NVIDIA V100 GPU の搭載された p3.2xlarge インスタンスでは 15ms で処理できます。もし代わりに eai1.medium アクセラレーターを使用すれば、推論に 46ms かかりますが、これはp2.xlarge (42ms)と同等の速度にもかかわらず、75%コストが削減できます。
TensorFlowの高速化
高速な推論を提供するため、TensorFlow Serving を利用することができます。TensorFlow Serving とは、保存したモデルを読み込み、REST API や gRPC 経由でハイパフォーマンスな推論を提供するモデルサーバーです。
Amazon Elastic Inference は TensorFlow Serving の高速化されたバージョンを含んでおり、以下のように利用できます。
$ ei_tensorflow_model_server --model_name=resnet --model_base_path=$MODEL_PATH --port=9000
$ python resnet_client.py --server=localhost:9000
今すぐご利用可能です
この記事がお役に立てれば幸いです。Amazon Elastic Inference は、米国東部 (バージニア北部、オハイオ)、欧州 (アイルランド)、アジアパシフィック (ソウル、東京) でご利用可能です。本日からこのサービスを利用してアプリケーションを構築できます!
– ジュリアン
翻訳は SA の石見・宇都宮が担当しました。原文は こちら