LoginSignup
1
0

More than 1 year has passed since last update.

EC2 Inf1インスタンスを使ってみた

Last updated at Posted at 2022-06-22

はじめに

低コストで高性能な推論が可能な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_opsminimum_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"]
models.config
model_config_list: {
  config: {
    name: "yolov4",
    base_path: "/models/yolov4",
    model_platform: "tensorflow",
  }
}

tensorflow_model_serverコマンドではなく、tensorflow_model_server_neuronコマンドを利用してサーバを起動させます。

entrypoint.sh
#!/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インスタンスを検討してみてはいかがでしょうか

参考

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0