手元のGPU環境で作成したTensorFlowモデルを、クラウド環境上で動作させたいということは良くあると思います。実際、いま私もそのようなお仕事をしているのですが・・・。
クラウド上で動作させるといっても、方法はいろいろあります。Amazon SageMakerのようなマネージドなクラウドを使用してデプロイすればWeb API化まで簡単に行うことができますし、一方でAmazon EC2のようなIaaSを用いて自分ですべて環境構築するという方法もあります。ちなみに、モデルをGPU環境で作って、それをEC2のようなCPUのみの環境で動作させるということも、もちろん可能です。(ちょっとワーニングが出ますけど。)
構成
EC2環境でTensorFlowモデルをデプロイする方法として、以下の2つが考えられます。
- TensorFlow Servingを使用する
- TensorFlowでモデルを動かし予測処理を行い、Flaskアプリを作ってWeb API化する
前者のTensorFlow Servingは、拙著「使ってわかったAWSのAI」で簡単な使い方を説明しました。きちんと使えば、前処理などの処理もパイプライン的に行えるので良さそうです。
ただ、今回は後者の方法を用いることにしました。
Nginx → uWSGI → Flask → TensorFlow
こんな構成です。
環境構築
まず、Amazon Linux 2環境のEC2インスタンスを準備します。インスタンスタイプはひとまずt2.mediumを選択しました。同時処理数などにもよりますが、この程度の性能の環境でも推論処理は問題なく動作します。
手元の環境がPython 3.8だったので、Amazon Linux 2環境も同様のバージョンにします。
どうやら、バージョンを合わせないとh5ファイル(TensorFlowモデルを保存したファイル形式)の読み込みでエラーになるようです。
Python3.8のpip
を使用可能にします。
requirements.txt
を下記のようにします。
uwsgi
Flask
tensorflow==2.5.0
# 以下は必要に応じて
awscli
boto3
boto
pycryptodome
あとは、このrequirements.txt
を用いてPythonパッケージをインストールします。
Flaskアプリの構築
/home/ec2-user/app/app.py
というファイルを作成し、下記の内容にします。
モデルを保存したh5ファイルは、/home/ec2-user/app/models/model.h5
に保存しました。
label_mapやpreprocessのあたりは、作成したモデルやトレーニング時の設定に合わせます。
uWSGI
/home/ec2-user/app/app.ini
というファイルを作成し、下記の内容にします。
ログの保存場所として、/home/ec2-user/logs
というフォルダを作成しておきます。
[uwsgi]
module = app
callable = app
die-on-term = true
chdir = /home/ec2-user/app
processes = 1
master = false
vacuum = true
socket = /run/uwsgi.sock
chmod-socket = 666
logto = /home/ec2-user/logs/uwsgi.log
uWSGIを起動するため、/etc/systemd/system/uwsgi.service
を作成し、下記の内容にします。
[Unit]
Description = uWSGI
After = syslog.target
[Service]
ExecStart = /usr/local/bin/uwsgi --ini /home/ec2-user/app/app.ini
Restart=always
KillSignal=SIGQUIT
Type=notify
StandardError=syslog
NotifyAccess=all
[Install]
WantedBy=multi-user.target
あとは、下記のとおり起動します。
Nginx
Nginxを導入している場合、/etc/nginx/conf.d/flask.conf
のようなファイルを作成し、下記のようにuWSGIへのリバースプロキシを設定します。
server {
server_name abc.vivinko.com; # 例
location / {
include uwsgi_params;
uwsgi_pass unix:///run/uwsgi.sock;
}
}
OpenCV
OpenCVを使用する場合は、下記のようにインストールするか、上記のrequirements.txt
に書いてまとめてインストールします。
import cv2
でImportError: libGL.so.1: cannot open shared object file: No such file or directory
というエラーが出る場合は、下記のパッケージをインストールします。
参考サイト
- https://qiita.com/meriam_dev/items/2fe225cd46bbae3a0dc2