はじめに
低コストで高性能な推論が可能なEC2 Inf1インスタンスを使ってみました。
これまでElastic Inferenceは利用したことがあるので、Elastic Inferenceと比較してみました。
Inf1インスタンスとは
AWSのページでは以下のように紹介されています。
同等の現行世代の GPU ベースの Amazon EC2 インスタンスと比較して、スループットが最大 2.3 倍高く、推論あたりのコストが最大 70% 低くなっています。Inf1 インスタンスは機械学習推論アプリケーションをサポートするため、1 から構築されました。同社は、AWS が設計開発した高機能の機械学習推論チップである AWS Inferentia チップを最大 16 個搭載しています。
また、多くのAmazonサービスでもInf1インスタンスが利用されています。
今回実施すること
- Inf1インスタンスを用いて、ECS上に推論サーバを構築する
- Inf1インスタンスとElastic Inferenceを比較する
利用するモデル
モデルとして、物体検出モデルのYOLOを利用します。
Neuron SDK(Inf1で利用するSDK)のチュートリアルにあるYOLOv4を利用します。
モデルのコンパイル
Inf1の推論チップを活用するために、モデルをコンパイルする必要があります。
環境
モデルをコンパイルするためにNeuron SDKをインストールする必要があります。
AWS Deep Learning AMI(DLAMI)には、すでにNeuron SDKがインストールされたAMIが提供されています。
今回はDLAMIを利用します。DLAMI IDは以下のコマンドで取得できます。
aws ec2 describe-images --region ap-northeast-1 --owners amazon \
--filters 'Name=name,Values=Deep Learning AMI (Ubuntu 18.04) Version ??.?' 'Name=state,Values=available' \
--query 'reverse(sort_by(Images, &CreationDate))[:1].ImageId' --output text
コンパイル
YOLOv4のチュートリアルのコードを利用します。以下のコードでは、Neuronランタイムのオーバーヘッドを減らすために、no_fuse_ops
とminimum_segment_size
を指定しています。
import shutil
import tensorflow as tf
import tensorflow.neuron as tfn
def no_fuse_condition(op):
return any(op.name.startswith(pat) for pat in ['reshape', 'lambda_1/Cast', 'lambda_2/Cast', 'lambda_3/Cast'])
model_path = "<your_model_path>"
new_model_path = "<new_model_path>"
with tf.Session(graph=tf.Graph()) as sess:
tf.saved_model.loader.load(sess, ['serve'], model_path)
no_fuse_ops = [op.name for op in sess.graph.get_operations() if no_fuse_condition(op)]
shutil.rmtree(new_model_path, ignore_errors=True)
tfn.saved_model.compile(
model_path,
new_model_path,
no_fuse_ops=no_fuse_ops,
minimum_segment_size=100,
batch_size=1,
dynamic_batch_size=True,
)
コンパイルするだけであれば、以下のコードだけで大丈夫です。new_model_path
で指定したパスに、コンパイルされたモデルが生成されます。
import tensorflow.neuron as tfn
model_path = "<your_model_path>"
new_model_path = "<new_model_path>"
tfn.saved_model.compile(model_path, new_model_path)
ECS環境の構築
Docker Imageの作成
Base Imageは、AWSから提供されているDeep Learning Containers Imagesを用います。
FROM 763104351884.dkr.ecr.ap-northeast-1.amazonaws.com/tensorflow-inference-neuron:1.15.5-neuron-py37-sdk1.19.0-ubuntu18.04
ENV MODEL_CONFIG_FILE /models/models.config
COPY models/yolov4/1 /models/yolov4/1
COPY models.config /models/models.config
COPY entrypoint.sh /usr/bin/entrypoint.sh
ENTRYPOINT ["/usr/bin/entrypoint.sh"]
model_config_list: {
config: {
name: "yolov4",
base_path: "/models/yolov4",
model_platform: "tensorflow",
}
}
tensorflow_model_server
コマンドではなく、tensorflow_model_server_neuron
コマンドを利用してサーバを起動させます。
#!/bin/bash
tensorflow_model_server_neuron --port 8500 --model_config_file=${MODEL_CONFIG_FILE}
EC2 AMI
AWSでは、ECS Optimized Inferentia AMIが提供されています。必要なNeuronパッケージがすべて組み込まれています。そのため、ECS Optimized Inferentia AMIを利用します。
以下のコマンドで、AMI IDを取得できます。
aws ssm get-parameters --names /aws/service/ecs/optimized-ami/amazon-linux-2/inf/recommended
タスク定義
タスク定義では、linuxParameters
パラメータに、Neuron Deviceへのパスを指定する必要があります。
[
{
"name": "inf1",
"image": "${image}:${tag}",
"essential": true,
"portMappings": [
{
"protocol": "tcp",
"hostPort": 8500,
"containerPort": 8500
}
],
"linuxParameters": {
"devices": [
{
"containerPath": "/dev/neuron0",
"hostPath": "/dev/neuron0",
"permissions": [
"read",
"write"
]
}
],
"capabilities": {
"add": [
"IPC_LOCK"
]
}
},
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-region": "ap-northeast-1",
"awslogs-group": "${log_group}"
}
}
}
]
その他
あとは、普段のECSでサービスを作成する場合と同様です。
公式ドキュメントにもInf1インスタンスをECSで動かすやり方が記載されています。
Elastic Inferenceとの比較
Inf1インスタンスとElastic Inferenceの比較評価を行います。
内容
Inf1インスタンスは、inf1.xlarge
を使用します。
Elastic Inferenceは、c5.xlarge
+ eia1.medium
の組み合わせを使用します。
画像1000枚の処理が完了するまでの時間を比較します。
結果
今回の検証では、Inf1インスタンスの方が、高速に処理できることがわかりました。また、料金もInf1インスタンスの方が安く済みます。
1枚あたりの平均処理時間(秒) | 1枚あたりの最大理時間(秒) | 1枚あたりの最小処理時間(秒) | 合計処理時間(秒) | 料金(USD/時間) | |
---|---|---|---|---|---|
Inf1インスタンス(inf1.xlarge) | 0.165 | 0.198 | 0.141 | 165.263 | 0.308 |
Elastic inference(c5.xlarge + eia.medium) | 0.197 | 0.229 | 0.188 | 197.051 | 0.434(0.214+0.220) |
終わりに
Inf1インスタンスをECSで動かしてみました。またElastic Inferenceとの比較を行いました。
処理速度やコスト改善を考えている方は、一度Inf1インスタンスを検討してみてはいかがでしょうか