機械学習モデルを使ったWebサービスの公開(AbejaPlatform試用報告)

普段、独自に学習した機械学習モデルをどのように活用していますか?

こんにちは、GliaComputing 研究員の時田です。

本記事は、機械学習モデルを利用したサービスを[検討している/運用している]企業の方向けに、株式会社ABEJA様が提供する「ABEJA Platform」を利用したWebサービスの公開と運用方法を紹介します。
Webサービスを構築し公開するにはいくつか方法がありますが、「ABEJA Platform」でどのようなことができるのか、どういうところが良いのかを第3者の視点でまとめていきます。なお本記事ではWebサービスの公開部分に対象を絞るので、データの前処理やモデルの学習については触れません。そのため、ABEJA Platform全体の評価ではありませんのでご注意下さい。データ蓄積、学習については、レポートを別の記事として当ブログにまとめる予定です。

はじめに

ここ数年で機械学習を試行するハードルは一気に下がったように思います。特に、PythonにはScikit-learnやchainer, tensorflowなど沢山のライブラリが充実しており、理論面を知らなくても機械学習モデルを構築するだけなら誰でもできてしまいます。[1] … Continue reading

しかし、趣味でやっている場合は別として、ビジネスの場においてはモデルを構築しただけでは何の意味もありませんね。学習したモデルを活用し、ビジネスへの貢献が求められます。[2]弊社ではこの部分を特に重要視しています。ビジネス課題に沿った手法の提案とビジネスアプリケーションへの実装までお手伝いいたします。

では、どうしたら活用できるでしょうか?
構築したモデルによって使い所は異なると思いますが、最終的には何らかのサービスに実装したいはずです。

本記事では、ビジネスの場に於いて機械学習モデルをWebサービスとして実装するケースを想定します。Webサービスは汎用性が高く、手軽なテストとしても本格的なアプリとしても使うことができます。Webサービス実装の手段として、株式会社ABEJA様が提供するPaaSである「ABEJA Platform」を利用した実装例を紹介します。

機械学習モデル活用としてのWebサービス開発

サービス化のハードル

機械学習エンジニアやデータサイエンティストと呼ばれる方々の中には、実際にWebサービスを作るとなると途端に手が止まってしまう方、結構いらっしゃるんじゃないかと想像します。機械学習モデルをWebサービスとして実装するには機械学習とは違う部分で検討しなければならない事がたくさんあり、これらがWebサービスを実装しようとする機械学習エンジニアの前に大きなハードルとして立ち塞がっています[3]弊社ではAI関連プロジェクトのPoCからアプリケーションの実装までご相談を受けております。お気軽にご連絡ください。

機械学習モデルを活用するWebサービスの概略図

機械学習モデルを活用したWebサービスを構築するには、上図のように通常のWebアプリケーションサーバ(上図中央)とは別に、データを入力し機械学習モデルの推論処理を実行するサーバ(上図右)が必要となります。このサーバを運用するには、次のような検討項目が必要となるでしょう。

  • インフラ
    • サーバ/回線の検討、設置場所の検討(スペース、電源、空調)
    • 負荷の見積もりと分散(スケールイン/スケールアウト)
    • Web/DBサーバ構築、運用、監視
    • セキュリティ対策
  • 機能実装/運用
    • 機械学習モデルの推論処理を行うAPI実装
    • モデルのバージョン管理/更新
    • 推論結果等のロギング

機械学習モデルを活用したWebサービスを開発/運用していくために、上図右のバックエンドサーバが必要となりますが、ここを株式会社ABEJA様が提供する「ABEJA Platform」を利用することで容易に構築できます。

ABEJA Platform

ABEJA Platform」とは、株式会社ABEJA様が提供する「AI」向けのPaaSで、データの蓄積、アノテーション、学習、そして、運用までを一貫して実装可能なプラットフォームです。
ABEJA Platformについての詳細は以下の公式ページを参照ください。

ABEJA Platformの構造としては、ローカルの開発マシンとモデルのデプロイ先(エッジデバイス等)に仮想化した環境を利用することで、様々な環境で学習したモデルと同じモデルが動作できます[4]開発時のモデル精度を保証できるという点で重要。仮想環境が構築できればどのようなデバイスにもデプロイが容易で、これは実用上とても重要なことだと考えています。
記事作成時点(2018年2月)では、仮想環境としてDockerを利用しています。しかし、Dockerの利用はあくまでも現時点での実装形態とのことで、今後他の環境の追加も検討されているようです。

仮想化環境のイメージズ。開発時点と同じモデルをエッジデバイスにも容易にデプロイ可能。

Webサービス開発視点でのABEJA PlatformのPros/Cons

現在弊社では、株式会社ABEJA様からABEJA Platformの評価用ライセンスを発行してもらっており、弊社社員[5]私(時田)ですが個人で運用するWebサービスをABEJA Platformで運用してみました。本節では、ABEJA Platformを実際に利用してみて、長所/短所と感じた点を列挙します。次章から、具体的に実装した手順を紹介しながらこれらの点について詳しく紹介していきます。
なお、2.2節で述べた通りABEJA Platformはデータの蓄積、学習、運用までを一貫して実装できます。しかし本記事では、Webサービスの構築/運用に絞って話を進めますので、ABEJA Platformの一部の機能のレビューということに注意してください。

Pros

  • インフラを自前で用意する必要がない(3.3
  • 学習済みモデルと推論用Pythonコードを用意するだけでAPIをリリースできる(3.3
  • フレームワークの依存性が無いので柔軟で自由度が高い(3.3.1
  • 複数のモデル、複数のインスタンスタイプでのAPIをサービスを止めることなく容易に切り替えできる(3.5

Cons

  • 柔軟であるが故に機械学習の知識に乏しいユーザがモデル開発までするには敷居が高い(3.3.1
  • デバッグツールが整備されていない(3.3.2
  • モニタリング、ロギングの機能が弱い(3.4.5
  • 現時点ではDockerを前提としているため、Dockerが動く環境に限定される(エッジデバイスが限定される)(2.2)

Consについては、記事作成時点(2019年2月)で我々が触ってみたところの感想です。ABEJAさんに尋ねてみたところ、課題としては認識しており今後解決に向けて進めていくとのことです。今後の公式リリースを注目ください。

Webサービスの実装

実装するサービス

今回実装するWebサービスは、弊社社員[6]私なんですけどねが個人活動として開発した「Chocoball Detector」です。これは、チョコボール画像を入力すると、チョコボールが何個あるのかを認識するためのシステムです。

仕組みは、Faster R-CNNをチョコボールを認識するように追加学習しています(chainercv利用)。認識するオブジェクトはチョコボール[7]いろんな味ありますがピーナツに限定していますとチョコボールのパッケージです。個人ブログですが、仕組みについての詳細は以下の記事を参照ください。検出するオブジェクトを限定しているので、かなり少ない学習データ(22枚!)でそこそこの精度が得られています(以下の記事参照)。

システム構成

今回開発するWebサービスは以下の構成です。

システム構成図

ABEJA Platformを利用して、学習済みモデルを利用した推論用のAPIを実装します。このAPIはチョコボール写真をPOSTするとオブジェクト(チョコボール、パッケージ)の位置座標リストがJSONで返ってきます。
フロント側は、GCEのインスタンスにNginxでWebサーバを立てます。

3.1節で紹介した個人ブログでは、GCEのインスタンスに推論用のAPI(と、Faster R-CNNを動かすための実装)も含めて実装していました。ABEJA Platformを利用して推論部分のAPIを構築するため、Herokuのようなサービスを利用した方が簡単かもしれません。当初はHerokuを利用しようと思ったのですが、扱えるメモリが不足しておりモデルの実装ができなかったのです。

APIの実装/デバッグ

ABEJA Platformを利用すると、2.1で示したBackend Serverと、そのAPIの構築には次の3種類のファイルを用意すれば良いです。

  • 学習済み機械学習モデルファイル
  • 必須ライブラリのリスト(requirements.txt)
  • 推論用Pythonコード

学習済みモデルファイルは既に用意されているとして、推論用Pythonコードの実装とデバッグをしていきましょう。

推論用Pythonコードの実装

推論用のPythonコードの作成については、公式ドキュメントや中の人による以下の記事を参照ください。

既存のgithubにある推論コードをABEJA Platformで動かす方法 – Qiita

推論コードについて、上記の記事を引用します。

ABEJA Platformでは、HTTP Serviceが作成されると、指定したエントリポイントを持つプログラムが先頭から実行されます。この際に、Handlerの外側にある部分が実行されます。通常はここで推論モデル(Deep Learningにおけるネットワーク)を読み込ます。その後、プログラムは待機状態になります。そして、リクエストが来たらHandlerが実行されます。

https://qiita.com/peisuke/items/ade7f7e60849c0c23598

ということなので、モデルをhandler関数の外で読み込み、推論の実際の処理をhandler関数に記載します。なお、handler関数の引数は入力データがイテレータとして渡されます(公式ドキュメント参照)。入力データはMIME Type毎に異なりますが、画像データの場合はイテレータ長1で画像がnumpy.arrayで格納されています。

今回実装した推論コードは以下の通りです(chocoball_counter.pyとして保存)。

# coding: utf-8
from chainercv.links import FasterRCNNVGG16
import numpy as np

# クラス定義
class_file = 'classes.txt'
classes = list()
with open(class_file) as fd:
    for one_line in fd.readlines():
        cl = one_line.split('\n')[0]
        classes.append(cl)

# モデルファイルのロード
pretrain_model = 'snapshot_model.npz'
model_frcnn = FasterRCNNVGG16(
    n_fg_class=len(classes),
    pretrained_model=pretrain_model)

def handler(_itr, ctx):
    for image in _itr:
        image = image.transpose(2, 0, 1)
        bboxes, labels, scores = model_frcnn.predict([image])
        res = {'box': bboxes[0], 'objects': labels[0], 'scores': scores[0]}
        cnt = float(np.sum(res['objects'] == 0))
        result = {
            'num': cnt,
            'score': res['scores'],
            'box': res['box']
        }
        yield result

また、検出する物体のクラス定義をテキストファイルで用意します(classes.txt)。

次いで、requirements.txtは以下のように作成しました。

numpy==1.14.2
chainer==4.5.0
chainercv==0.10.0
Pillow==4.2.1

これらの必須ファイルから想像されるかもしれませんが、ABEJA Platformでは特定のフレームワーク(chainerやtensorflow等)に依存した作りにはなっていません。requirementsで必要なライブラリを指定し、そのライブラリを利用して各自でコードを書いていきます。学習も同様です。そのため、利用者がやりやすいように柔軟に利用できます。一方、自由度が高いためモデル構造の選択と実装などのサポートが無く、自由に使うには機械学習周りの前提知識が必要になってきます。

推論用Pythonコードのデバッグ

次に、3.3.1で作成した推論コードをローカル環境でデバッグします。ABEJA Platform CLI を利用すると、ABEJA Platformにデプロイする前に、ローカル環境でAPI動作を確認できます[8]ABEJA Platform CLIはCLI(Command Line Interface)なので、デバッグツールではありません。CLIでモデルファイルのデプロイやHTTP … Continue reading
推論コードをローカル環境で動作確認するために、run-localコマンドを利用します。

$ abeja model run-local -h chocoball_counter:handler -i abeja/all-cpu:18.10 --input choco_img.jpg

3.3.1で作成したファイルに問題がなければ、想定したJSONが返ってくるはずです。

今回私が作業した中では、ここで少しハマりました。原因は、直接ABEJA Platformとは関係ありませんがローカル環境のDockerでメモリ割り当てが少なかったためにプロセスがkillされるという現象に悩まされました[9]作業はMacで行っており、Mac版のDockerのメモリ割り当てがデフォルトで2GB。メモリを上げることで問題は解決されました。

この問題はABEJA Platformとは関係なかったのですが、デバッグのためのツールが整備されていないというのは、今後に期待する点と感じます。現状のデバッグ作業は、handler関数内にprintfを追加したり、dockerコンテナに直接入って作業するなどの方法になります。また、ABEJAさんが公式に開催していた「ABEJA Platform Advent Calendar 2018」では、PyCharm(有料)を利用してデバッグする方法が紹介されています。

ABEJA Platform向け学習コードのローカル実行とPyCharmを使ったデバッグ – Qiita

APIのリリース

ローカル環境で動作確認できれば、次はいよいよモデルファイルや推論コードをデプロイしAPIをリリースします。ABEJA PlatformでAPIをリリースするには次の3つの手順を踏みます。

  1. モデルをアップロード
  2. サービスを管理する枠(Deployment)を作成
  3. HTTP Requestを作成

以降の作業は管理コンソールを利用しました。ABEJA Platformでは管理コンソールの他、APIとCLIを提供しています。

ABEJA Platform 管理コンソール(Modelメニュー)

モデルのアップロード

ABEJA Platformに必要なファイルをアップロードするには、推論コードと学習済みモデルファイル、requirements.txtをひとまとめにzipファイルに固め、そのzipファイルをアップロードします。下図のグレー部分にドロップするかクリックでファイル選択メニューが出ます。

モデルファイルのアップロード画面

アップロードするモデルにはバージョン番号を設定します。一つのプロジェクトで複数のバージョンのモデルを登録できます。例えば学習条件を変えたり、テスト用のモデルだったりなど複数のモデルをアップロードしておけます。

Deploymentを作成

次いで、サービスを管理するための枠(Deployment)を用意します。コンソールのDeplotmentメニューから「Create Deployment」を選択すると下図のメニューが現れますので、先ほどアップロードしたモデルを選択します(バージョン番号で指定)。

Deploymentの作成画面

HTTP Requestを作成

Deploymentの作成が完了すると、Deploymentメニューから、Deploymentの一覧が確認できるので、作成したDeploymentを選択します。

ここで、「HTTP Service」タブからCreateを選択することで、WebAPIが作成できます。他にもエッジデバイス上で動くデーモンを作成するには「Daemons」タブからCreateするとエッジデバイスに対してデプロイができます(今回我々は試していませんが)。

HTTP ServiceをCreateすると、以下の画面が現れます。利用するモデルのバージョンを選択し、利用するインスタンスタイプと数を指定すれば、これでWebAPIができてしまいます。

ローカル環境で動作確認できていれば、ここまでは簡単に進めることができます。

APIの動作確認

最後に、作成したAPIが想定通りに動作しているか確認してみます。
確認の方法としては、curlコマンドでも良いですし、Python等でコードを書いても良いです。とりあえず確認するだけなら、ABEJA Platformの管理コンソールを使うのが最も簡単と思います。

Deploymentメニューから作成したHTTP Serviceの右端に「Check」というボタンがあります。

Checkボタンを押すと、画像ファイルやJSON等を入力して出力を確認する画面が現れます。これでAPIの動作確認ができます。

チョコボール画像を入力して、検出数、スコアのリスト、座標のリストが返ってくることが確認できました。

監視、モニタリング

サービスの運用が始まれば、APIの挙動の監視・モニタリングが必要です。アクセス数がどのくらいあるのか、どのような入力があって推論結果は何を返したのかなどをチェックすることが求められるでしょう。ABEJA Platformでは、Deploymentメニューからログと以下の指標(メトリクス)を確認できます。

  • CPU 使用率
  • Memory 使用率
  • Hit Count
  • Error Count
  • Latency

3.4.4でAPIの動作確認をしましたが、その横に「Logs」と「Metrics」という項目があるので、それぞれログとメトリクスを確認することができます。

詳しくは公式ドキュメントを参照ください。

https://developers.abeja.io/getting-started-guide/inference-api/use-webapi-by-ui/#メトリクスおよびログの確認

現段階では、監視の機能は上記のもののみです。推論結果を保持しておくような機能はまだ実装されていないようですが、ABEJAさんに確認したところ、今後提供できるように進めているとのお話です。

エンドポイントエイエリアスの設定

API(HTTP Service)はモデルのバージョンや利用するインスタンスタイプ別に複数作成できます。しかし、本番で運用しているWebサービスのAPIを都度変更することは現実的ではないでしょう(ソースコードを変更するなど一旦サービスを停止する必要が生じてくるでしょうから)。そこで、ABEJA Platformでは、エンドポイントに任意のエイリアスを設定でき、エンドポイントをシームレスに切り替えることができます。

https://developers.abeja.io/getting-started-guide/inference-api/use-webapi-by-ui/#エイリアスの作成

エイリアスの作成については上記公式ドキュメントを参照ください。今回は、モデルは一緒(Version0.0.6)でインスタンスタイプ(cpu-4, cpu-2)が異なる二つのAPIを切り替えてみました。
defaultという名称(システム予約語)で作成すると下図のように「primary」と表示されます。ここをクリックして、エンドポイントを選択すると容易に切り替えることができます。

Webフロントの実装と公開

ABEJA Platformを利用してAPIの作成が簡単にできました。では、このAPIを叩くWebサービスを実装していきます。

フロント側の詳細は今回は触れませんが、ソースコードは弊社社員の個人のgithubに上がっています。(abeja-pfブランチ)

https://github.com/tok41/ChocoBallDetector/tree/abeja-pf

Webフロントを公開するためには、別にサーバが必要です。今回はGCEを利用しました(3.2)。3.2に記載の通り、GCEのインスタンスにnginxでwebサーバを構築しています。GCEとABEJA Platformはドメインが当然異なるため、Same-Origin問題で直接APIを叩けないため、FlaskでABEJA PlatformのAPIを叩くAPIを作成しています(上記Github参照)。

成果物

結果としてこのようなWebサービスが構築できました。

http://www.chocolate-ball.net/

シームレスなAPIの切り替え

エンドポイントを切り替えてその効果を見てみます。今回、同一画像を入力して、どのくらいでレスポンスが返ってくるのかを測ってみます。なお、一度しか試行していないので速度の厳密な比較にはなりません。あくまで、APIの切り替えがスムーズにできるというデモだけです。

まずは、インスタンスタイプがcpu-2の場合です。

次に、インスタンスタイプがcpu-4の場合です。エンドポイントの切り替えは3.5の通り、管理コンソールから容易に切り替えることができます。切り替えた結果、約6秒速くなりました。

この間、Webサービスは止めていません。今回はインスタンスタイプの切り替えだけですが、モデルのバージョンアップなど実際の運用時にはかなり役立てられるのではないかと思います。

まとめ

本記事では、ABEJA Platformを利用してWebAPIを作成し、そのAPIを利用したWebアプリを作成してみました。ABEJA Platformを利用することで、学習済みのモデルが用意できていればAPIの作成は非常に簡単にできるのではないかと思います。また今回はChainerを利用したモデルを扱いましたが、ABEJA Platformは特にライブラリに制限はないので、適切なハンドラ関数を用意すればどのようなライブラリでも利用できる柔軟さが良い点だと感じます。

一方、この柔軟さは機械学習周りの知識に乏しいエンジニアには少しハードルが高いと感じます。まだ深くは試していないのですが、モデルの学習部分についてサポート等は特にないので、モデル構築の手軽さは無いと感じました[11]このようなツールは、手軽な分、枠から外れたことをしようとするととても大変だったりするわけですが。また、APIを動かすABEJA Platform側の死活監視などモニタの機能も少し弱いと感じました(この部分はABEJAさんに尋ねてみましたが、課題は認識しており今後実装を検討していくとのことです)。

ABEJA PlatformはAPIの運用だけでなく、データの収集やアノテーション、モデルの学習についても一貫しているので、こちらの機能も使い倒してみたいと思います。

終わりに

ABEJA Platformを利用してみたいと思われた方、問い合わせフォームが用意されていますのでご連絡していただけたらと思います。本記事と合わせて質問等ありましたら弊社でも受けられますので、お気軽にご連絡いただけたらと思います。

弊社では、様々な機械学習手法を扱いますが、最終的に「活用」ができなければ意味がないと考えています。業務に合わせたモデル選択と業務アプリケーションとしての実装までをお手伝いさせていただきます。お気軽にご連絡ください。

また、チョコボールが気になった方は、弊社社員の個人ブログですが、こちらも合わせてご参照いただけたらと思います。

http://chocolate-ball.hatenablog.com/

脚注

脚注
1 「誰でも」は少し言い過ぎかもしれませんね。データの用意とデータの前処理は不可欠な要素で、これが適切に行われなければ良い結果は得られないでしょう。
2 弊社ではこの部分を特に重要視しています。ビジネス課題に沿った手法の提案とビジネスアプリケーションへの実装までお手伝いいたします。
3 弊社ではAI関連プロジェクトのPoCからアプリケーションの実装までご相談を受けております。お気軽にご連絡ください。
4 開発時のモデル精度を保証できるという点で重要
5 私(時田)です
6 私なんですけどね
7 いろんな味ありますがピーナツに限定しています
8 ABEJA Platform CLIはCLI(Command Line Interface)なので、デバッグツールではありません。CLIでモデルファイルのデプロイやHTTP Serviceの作成などほぼ全ての機能が利用できます
9 作業はMacで行っており、Mac版のDockerのメモリ割り当てがデフォルトで2GB。メモリを上げることで問題は解決されました。
10 Mac版Docker。Linuxではデフォルトでメモリ制限がない。
11 このようなツールは、手軽な分、枠から外れたことをしようとするととても大変だったりするわけですが

この投稿へのコメント

コメントはありません。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

この投稿へのトラックバック

トラックバックはありません。

トラックバック URL