2019の20日目の記事です。21日目は@sizukutamagoさんです。こんにちは、技術開発室の藤野です。APIを作った話についてです。APIとして使えるようにしたい、というものです。APIはリクエストに対して推論結果を返すシンプルなもので、なるべく早く構築しデプロイや運用の手間は省きたいと思っていました。これに対して、Herokuは下記の利点があります。運用のための仕組みがあらかじめ提供されているCI/CDの機能を利用できる一方で、ディープラーニングのアルゴリズムはGPU等を使って高速化することが一般的だと思います。Herokuではこのようなアクセラレータは利用できず、CPUのみで推論処理を行うことになります。そこで、今回はこのような推論処理を含むAPIをHeroku上で動かしたときのパフォーマンスはどのくらいなのか?を主眼に見ていきたいと思います。作り物の構成タスクとモデルタスクは数十クラスの画像分類、フレームワークはTensorFlow1.14です。Modelから転移学習を行ったものです。CPUで53ms/inferenceの速度が出ています。このくらい出ればOKとします。(転移学習については、弊社の岡田が記事を書いているのでご覧ください。v4の転移学習)Bucketeerでのモデルファイルの保持Herokuのアプリケーションはビルド時にSlugというパッケージにまとめられます。これには500MBの上限があり、諸々のリソースを含めてこの中に収める必要があります。devcenter.heroku.comこれに対して、TensorFlowで使用するモデルファイルのサイズはMB以上のオーダーになるため、直接Slug内に入れるのは望ましくありません。一つのアプリケーションから複数モデルを使い分けたり、モデルのバージョニングを行うこともしばしばあります。S3バケットを利用できるHerokuアドオンのBucketeerでモデルファイルを保持するようにしました。APIアプリケーションはPython+Gunicorn+Flaskで構築しました。システム及びAPI構成は下図のとおりです。API構成リクエスト、レスポンスの流れは下記のとおりです。Request高速化のためにurllib3を使っています。)要求されるDynoDynoの選定ですが、TensorFlowライブラリ+モデルをロードするため、かなりのメモリが必要になります。V1の場合、メモリ使用量が少なくとも500MB以上必要だったため、Standard-2Xを使用しました。下図はアプリケーション動作中の、メモリ使用量のメトリクスです。下記の条件で計測を行いました。計測にはsiegeを使いました。github.com実行設定は下記のような感じで、クライアントを1から100まで増やしつつ60秒間送り続けるようにしました。計測結果は下図のとおりです。各値は平均値を取っています。Dynoでも十分な速度が出ています。先に書いたベンチマークの2倍の時間がかかっていますが、これはリクエストが集中した場合も合わせて平均しているためで、1クライアントの場合は60ms前後で推論できます。まとめHeroku上でディープラーニングによる推論APIを構築し、パフォーマンスを計測しました。推論結果を1s未満で返せるので、アプリケーション上で静止画を分類するなどの目的には十分足りていると思います。一方で以下のような場合は、別途検証が必要になるかと思います。複雑なモデルを使いたい複数モデルを同時に使いたい動画のリアルタイム判定のような高頻度の推論を行いたい複数モデルを使いたい場合は、恐らくメモリ使用量が大きくなるため、Dynoのアップグレードで対応できるかなと思います。