デバイス上で動作する画像認識可能な WebAPI を作成

はじめに

このドキュメントでは、ABEJA Platform の GUI を利用して、 Jetson 上で MXNet のモデルを動かし、WebAPIとして画像識別の設定について説明します。

このガイドの流れ

このガイド内では、 Jetson に ABEJA Platform のエージェントをインストールし、 管理コンソールから画像識別のモデルを Jetson 上に WebAPI としてデプロイする流れを説明します。

モデルはサンプルとして ResNet50 を用いたモデルを利用します。あらかじめ こちら よりモデルをダウンロードしてください。

このサンプルモデルは下記の構成になっています。 MXNet のアプリケーション上で resnet50 のモデルを動かす画像識別モデルです。

$ ls -l
total 207728
-rw-r--r--@ 1 abeja  staff         62 12 21 21:09 README.md
-rw-r--r--@ 1 abeja  staff       1516 12 21 21:43 main.py
-rw-r--r--@ 1 abeja  staff  102395376 12 21 21:08 resnet-50-0000.params
-rw-r--r--@ 1 abeja  staff      76172 12 21 21:08 resnet-50-symbol.json
-rw-r--r--@ 1 abeja  staff      31675 12 21 21:08 synset.txt
-rw-r--r--@ 1 abeja  staff       5284 12 21 21:08 test.jpg

Jetson の設定

L4T のインストール

NVIDIA DEVELOPER サイト に沿って、Jetson に L4T 28.2 をインストールします。 L4T 28.2JetPack 3.2 に含まれており、こちらから取得できます。

Docker のインストール

Jetson にログインします。

Universe リポジトリを追加するため、 /etc/apt/sources.list にて、以下の行のコメントを解除します。

# deb http://ports.ubuntu.com/ubuntu-ports/ xenial universe
# deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial universe
# deb http://ports.ubuntu.com/ubuntu-ports/ xenial-updates universe
# deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-updates universe

docker と依存パッケージをインストールします。

$ sudo apt-get update
$ sudo apt-get install ca-certificates curl -y
$ curl https://get.docker.com | bash
$ sudo usermod -aG docker nvidia
$ echo "DOCKER_OPTS=\"--storage-driver=overlay\"" | sudo tee /etc/default/docker
$ sudo systemctl restart docker
$ sudo docker ps  # make sure docker is running

デバイスの作成

管理コンソールへのログイン

管理コンソールへのログイン方法 に従って管理コンソールへのログインを行ってください。

デバイスの作成

新たにデバイスを作成します。

エッジデバイス一覧画面

デバイスの名前と説明を入力します。

エッジデバイス登録画面

作成が完了したら、証明書と公開鍵・秘密鍵をダウンロード出来るようになります。 表示された Device ID を記録し、証明書と公開鍵・秘密鍵を必ずダウンロードしてください。

エッジデバイス登録後画面

abeja-device-agent のインストールと設定

Jetson 上にて、以下を実行して abeja-device-agent をインストールします。

$ wget https://s3-ap-northeast-1.amazonaws.com/abeja-device-resources/0.9.0/abeja-device-agent.deb
$ sudo dpkg -i abeja-device-agent.deb

ダウンロードした zip ファイルを Jetson にコピーし、証明書と公開鍵・秘密鍵を /etc/abeja/keys に展開します。

$ sudo mkdir /etc/abeja
$ sudo unzip device_xxxxxxxxxxxxx_certifications.zip -d /etc/abeja/keys

次に、 /etc/default/abeja-device-agent に記述されているデバイスの設定を更新します。 設定ファイル内の DEVICE_NAME の値に管理コンソールに表示されていた Device ID を設定します。また、 DEVICE_TYPE の値に jetson_tx2 を設定します。

Device ID 以外を設定した場合はエラーとなり起動できません。その場合は コンテナのキャッシュクリア方法 の手順に従いキャッシュをクリアしてください。

$ sudo vim /etc/default/abeja-device-agent
DEVICE_NAME=1234566789
DEVICE_TYPE=jetson_tx2
LOCAL_LOGGING=1

変更した設定を反映させるため、 abeja-device-agent を再起動します。

$ sudo systemctl restart abeja-device-agent.service
$ sudo systemctl status abeja-device-agent.service

サンプルのモデルの作成

モデル一覧画面を表示し、Create を選択

サイドメニューより、 Model を選択し、モデル一覧画面から Create Model を選択します。

モデル一覧画面

作成するモデルの詳細を入力

作成するモデルの詳細情報を入力します。

モデル新規追加画面

入力項目

  • Name : 作成するモデル名
  • Description : モデルの概要を入力
  • Model Version : モデルのバージョンを入力。初回なので、 0.0.1 と入力
  • Deploy after creating : チェックを on
  • Source Code
    • Upload
      • Runtime : モデルの実行環境を選択。 abeja-inc/mxnet:0.1.0-arm64v8 を選択
      • Model Handler : モデルを実行に呼び出される関数。 main:handler と入力
      • Training Definition : 学習済みモデルが存在する学習ジョブ定義。今回は、学習済みモデルがダウンロードした zip ファイルに含まれているため入力不要
      • Source Code : ダウンロードした zip ファイルを選択

上記を入力後、 Create Model を選択し、モデルの作成を行います。

Deploy after creatingon の場合、モデル作成後は、作成したモデルのデプロイメントの詳細画面へ遷移します。 デプロイメントとは、作成したモデルを特定のオーガニゼーションで動作させるためのプロジェクトに相当します。

HTTP サービスの作成

作成されたモデルのデプロイメント詳細画面から、 HTTP サービスの追加を行います。

Create HTTP Service を選択

タブ HTTP Services 内の Create Http Service を選択

デプロイメント詳細画面

HTTP サービスの作成

作成する HTTP サービスの詳細情報を入力します。

入力項目

  • Model Version : モデルのバージョンを入力。先に作成した、 0.0.1 を選択
  • Device : 先に作成したデバイスを選択
  • Port : WebAPI で使用するポート番号。8000 と入力。
  • Environments : 環境変数。今回は不要。

HTTP サービスの詳細情報の入力

作成が完了すると下記の表示になります。

デプロイメント詳細画面

サービスの Status は、作成直後は In Progress と表示されます。画面右上の Refresh を選択し、 StatusReady へ変化することを確認してください。

動作確認

curl を利用した Jetson 上での動作確認

Jetson 上からサービスエンドポイントの URL に curl でリクエストを送ることで、動作確認を行います。

テスト用の画像を取得します。

$ curl https://console.abeja.io/images/cat_thumb.jpg -o test.jpg

curl で動作を確認する場合、以下のリクエストを行います。

$ curl -X POST  -H 'Content-Type:image/jpeg' --data-binary @test.jpg -XPOST http://localhost:8000

正常に動作した場合は、以下のレスポンスが表示されます。

[{"result": ["n02123045 tabby, tabby cat", "n02123159 tiger cat", "n02124075 Egyptian cat", "n02127052 lynx, catamount", "n03958227 plastic bag"]}]

コンテナのキャッシュクリア方法

/etc/default/abeja-device-agent に配置するデバイス情報や /etc/abeja/keys に配置する秘密鍵はコンテナ起動時にキャッシュされます。 設定内容を間違えた場合や、別の設定を行いたい場合は次の手順でキャッシュをクリアしてください。

$ sudo docker rm -f abeja-device-agent
$ sudo systemctl restart abeja-device-agent.service

調査Tips

abeja-device-agent を調査する方法は次のような方法があります。

ABEJA Platform上でログを確認する

[Edge]-[Device]にて、確認したいデバイスから Log ボタンを選択し、ログを確認します。どこまで処理が進んでいるか、エラーが発生しているかがわかります。

エッジデバイス一覧画面

デバイス上でコンテナの状態とログを確認する

まず、 docker プロセスを確認し、 STATUSUp となっているか確認します。 次に、 docker プロセスから docker id を確認します。 mxnet を動かしている場合は次のような表示になり、 CONTAINER ID である 3086691fe99d を記録します。

$ docker ps
CONTAINER ID        IMAGE                                                                                   COMMAND                  CREATED              STATUS                          PORTS                NAMES
1644b722d994        123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/device-logger-fluentd:0.6.4-aarch64   "/bin/entrypoint.sh …"   3 days ago           Up 3 days                                            device-logger
3086691fe99d        123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/abeja-inc/mxnet:0.1.0-arm64v8         "bash"                   11 minutes ago       Up 11 minutes                                        determined_wiles
9c2e2c7e18de        abeja/docker-dd-agent:latest-arm64v8                                                    "/entrypoint.sh supe…"   3 days ago           Up 3 days (healthy)             8125/udp, 8126/tcp   dd-agent
72871d93a1a2        abeja/abeja-device-agent:latest-aarch64                                                 "/bin/sh -c abeja-de…"   7 days ago           Up 3 days                                            abeja-device-agent

CONTAINER ID を元にコンテナログを確認します。どこまで処理が進んでいるか、エラーが発生しているかがわかります。

$ docker logs 3086691fe99d