LoginSignup
3

More than 5 years have passed since last update.

ABEJA Platformからエッジデバイス(NVIDIA Jetson)にモデルデプロイをする

Last updated at Posted at 2018-12-19

はじめに

はじめまして。おおたぐろです。ABEJAのエンジニアです。
これは、ABEJA Platform AdventCalendar 2018 12日目の記事です。
(ごめんなさい。遅くなりました :bow: )

今回は、ABEJA Platformからエッジデバイス(Jetson TX2)にモデルをデプロイする方法をお話したいと思います。どうぞよろしくお願いいたしますmm

20180820130526.jpg

手順

流れ

  1. 本体(Jetson)の設定
  2. Platformへのデバイス登録作業
  3. Device Agentのインストール・設定
  4. モデルの作成
  5. デバイス上にモデルデプロイ
  6. テスト

本体(Jetson)の設定

L4Tのインストール

Jetson に L4T 28.2 をインストールします。 L4T 28.2 は JetPack 3.2 に含まれています。

スクリーンショット 2018-12-19 17.08.01.png

Dockerのインストール


# Update libs, install prereqs for commands
nvidia@tegra-ubuntu:~$ sudo apt-get update && sudo apt-get upgrade && sudo apt-get -y install curl apt-transport-https

# Install Docker-CE
nvidia@tegra-ubuntu:~$ echo "deb [arch=$(dpkg --print-architecture)] https://download.docker.com/linux/ubuntu xenial edge" >/etc/apt/sources.list.d/docker.list
nvidia@tegra-ubuntu:~$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -qq - >/dev/null
nvidia@tegra-ubuntu:~$ sudo apt-get update && sudo apt-get install docker-ce
nvidia@tegra-ubuntu:~$ sudo systemctl enable docker

# Test Docker install
nvidia@tegra-ubuntu:~$ sudo docker run --rm -it arm64v8/ubuntu:16.04 cat /etc/issue
Ubuntu 16.04.5 LTS \n \l

PlatformとJetsonの接続

デバイス登録

ここからは、JetsonのターミナルではなくPlatformの画面上での操作になりますm
まずはじめにデバイスに名前・説明を付けて、デバイス認証用のキー:key:を発行します。

1-edge-device-top.png
2-edge-device-create.png
3-edge-device-created.png

ここで表示されるDevice ID及び鍵は、は、次のステップでデバイス側に埋め込みます。
Device IDはあとから参照できますが、鍵はこのページでしか表示されないので注意が必要です。
Downloadボタンを押すことで、zip圧縮された鍵ファイルを直接ダウンロードする事ができます。

ダウンロードしたzipは次の工程で使うので、Jetson側のファイルシステムに転送しておきます。
筆者はscpを使ってzipファイルを移動しました( ̄ー ̄)

taguro@main:~/Download$ scp device_XXXXXXXXXXXXX_certifications.zip nvidia@172.16.XXX.XXX:~/device_XXXXXXXXXXXXX_certifications.zip

ここまでの作業が終わると、Edge Devicesに登録したデバイスが表示されます。

スクリーンショット_2018-12-19_17_55_00.png

ABEJA Device Agentのインストール

ABEJA Device Agentは、ABEJA Platformと接続してデプロイを担ったり&メトリクス・ログをクラウド上に送信してくれるデーモンです。これを入れる事によって、ユーザーはクラウド上のモデルをデバイスに直接デプロイしたり、デバイス本体のモニタリングをする事ができます。(要するに大事なヤツです)


nvidia@tegra-ubuntu:~$ wget https://s3-ap-northeast-1.amazonaws.com/abeja-device-resources/0.7.1/abeja-device-agent.deb
nvidia@tegra-ubuntu:~$ sudo dpkg -i abeja-device-agent.deb

エッジデバイスがABEJA Platformが接続して認証する為に、/etc/abeja/keysを作ってそこに鍵を配置します。
ここで先程生成した鍵(zipファイル)を使います。


nvidia@tegra-ubuntu:~$ sudo mkdir /etc/abeja
nvidia@tegra-ubuntu:~$ sudo unzip device_xxxxxxxxxxxxx_certifications.zip -d /etc/abeja/keys

鍵の配置が完了したら、次にデバイスの情報を /etc/default/abeja-device-agentに設定します。
先程Platform上で払い出されたDevice IDを、DEVICE_NAMEという所に入れておきます。
Device IDは、Edge Devices一覧から確認できます。


nvidia@tegra-ubuntu:~$ sudo vim /etc/default/abeja-device-agent
DEVICE_NAME=XXXXXXXXXXXX
DEVICE_TYPE=jetson_tx2
LOCAL_LOGGING=1

最後に、これらの設定を反映させる為にデーモン再起動をします。


nvidia@tegra-ubuntu:~$ sudo systemctl restart abeja-device-agent.service
nvidia@tegra-ubuntu:~$ sudo systemctl status abeja-device-agent.service

デバイス連携確認

Edge DevicesページにあるMetricsボタンを押すと、下記のようなメトリクス情報が表示されます。
これが表示されていれば、デバイスとPlatformが正しく通信できており、初期設定は全て完了です。 :tada:

スクリーンショット_2018-12-19_17_55_00-2.png

スクリーンショット_2018-12-19_20_11_43.png

余談

ABEJA Device Agentのインストール・設定が正しく完了すると、下記のようにコンテナが立ち始めます。
合計で3つのシステムコンテナが立ち上がれば成功です。


nvidia@tegra-ubuntu:~$ docker ps
CONTAINER ID        IMAGE                                                                                   COMMAND                  CREATED             STATUS                 PORTS                                              NAMES
9069eb198afe        xxxx.dkr.ecr.ap-northeast-1.amazonaws.com/device-logger-fluentd:0.6.4-aarch64   "/bin/entrypoint.sh …"   3 hours ago         Up 3 hours             0.0.0.0:5140->5140/tcp, 0.0.0.0:24224->24224/tcp   device-logger
d1541745ea3a        abeja/docker-dd-agent:latest-arm64v8                                                    "/entrypoint.sh supe…"   3 hours ago         Up 3 hours (healthy)   8125/udp, 8126/tcp                                 dd-agent
9fd99a29f77d        abeja/abeja-device-agent:latest-aarch64                                                 "/bin/sh -c abeja-de…"   3 hours ago         Up 3 hours

モデル作成

次にモデルの作成に移ります。基本的にはモデル名・バージョン・Runtime設定といった基本情報設定と・動かすモデル(ファイル)をアップロードする事で完了します。今回は、Runtimeにabeja-inc/mxnet:0.1.0-arm64v8を利用し、モデルのソースコードとしてABEJAで用意しているResnet50のサンプルを使いました。
※FYIですが、Deploy after creatingにチェックを入れておくと、エッジデプロイをする為のリソースが自動でつくられます。

スクリーンショット 2018-12-19 20.18.35.png

スクリーンショット 2018-12-19 20.19.06.png

余談

今回モデルとして動かすのは下記のコードです。モデルのコードを変更する事で、細かいふるまいや後述するAPIのResponseの変更が可能です。


import numpy as np
import cv2
import mxnet as mx
import argparse
import os


def ch_dev(arg_params, aux_params, ctx):
    new_args = dict()
    new_auxs = dict()
    for k, v in arg_params.items():
        new_args[k] = v.as_in_context(ctx)
    for k, v in aux_params.items():
        new_auxs[k] = v.as_in_context(ctx)
    return new_args, new_auxs

synset = [l.strip() for l in open('synset.txt').readlines()]
if os.environ.get('USE_CPU', 1):
    ctx = mx.cpu()
else:
    ctx = mx.gpu(0)
sym, arg_params, aux_params = mx.model.load_checkpoint('resnet-50', 0)
arg_params, aux_params = ch_dev(arg_params, aux_params, ctx)


def handler(iter, _ctx):
    for img in iter:
        img = cv2.resize(img, (224, 224))  # resize to 224*224 to fit model
        img = np.swapaxes(img, 0, 2)
        img = np.swapaxes(img, 1, 2)  # change to (c, h,w) order
        img = img[np.newaxis, :]  # extend to (n, c, h, w)
        arg_params["data"] = mx.nd.array(img, ctx)
        arg_params["softmax_label"] = mx.nd.empty((1,), ctx)
        exe = sym.bind(ctx, arg_params ,args_grad=None, grad_req="null", aux_states=aux_params)
        exe.forward(is_train=False)

        prob = np.squeeze(exe.outputs[0].asnumpy())
        pred = np.argsort(prob)[::-1]
        yield {'result': [synset[pred[i]] for i in range(5)]}

デバイス上にモデルデプロイ

ABEJA Platformでは、ユーザーが用意(学習)したモデルを使って推論APIを展開する事ができます。
クラウド上にもエッジ上にもAPIを作成する事ができるのですが、今回はエッジ上にAPIを作成してみます。
(エッジデバイスに対してAPI作成すると、クラウド上に置かれているモデル等が勝手にダウンロードされます :wink: )

まず、Modelに紐づくDeploymentというページにいきます。
(Deploy after creatingという所にチェックをいれると、自動でDeploymentが作られるはずです)

スクリーンショット_2018-12-19_20_19_59.png

Create HTTP Serviceをクリックすると、下記の様なWizardが表示されます。
Edge側のタブを選択すると、デプロイ先のデバイス・APIのポート設定等が表示されるので、入力します。
※今回はポート8000でResnet50を使った推論APIを展開します

スクリーンショット_2018-12-19_20_27_26.png

設定が完了すると下記のように、HTTP Serviceの一覧に新たな項目が増えます。

スクリーンショット_2018-12-19_20_28_40.png

あとは放置でOKです。
ABEJA Device AgentとABEJA Platformがよしなに通信してくれて、先程作ったモデルが自動ダウンロード&自動でAPIが作成されます。

簡単すぎて、あまりエッジデプロイした気にならないかもしれませんが、内部のメトリクス・コンテナ数を見ると動いてる感を肌で感じることができます。
下記はデプロイ前後のメトリクスの様子です。

スクリーンショット_2018-12-19_20_49_30-2.png

デプロイが終わるとモデル作成時に指定したコンテナイメージabeja-inc/mxnet:0.1.0-arm64v8が立ち上がっている事が確認できます。ここまで確認できればシステム的にも全く問題なしです。


root@tegra-ubuntu:~# docker ps
CONTAINER ID        IMAGE                                                                                   COMMAND                  CREATED             STATUS                 PORTS                                              NAMES
46da842d25cc        xxxx.dkr.ecr.ap-northeast-1.amazonaws.com/abeja-inc/mxnet:0.1.0-arm64v8         "/bin/bash -l -c 'cd…"   23 minutes ago      Up 23 minutes          0.0.0.0:8000->8000/tcp                             edge-xxxx
9069eb198afe        xxxx.dkr.ecr.ap-northeast-1.amazonaws.com/device-logger-fluentd:0.6.4-aarch64   "/bin/entrypoint.sh …"   3 hours ago         Up 3 hours             0.0.0.0:5140->5140/tcp, 0.0.0.0:24224->24224/tcp   device-logger
d1541745ea3a        abeja/docker-dd-agent:latest-arm64v8                                                    "/entrypoint.sh supe…"   3 hours ago         Up 3 hours (healthy)   8125/udp, 8126/tcp                                 dd-agent
9fd99a29f77d        abeja/abeja-device-agent:latest-aarch64                                                 "/bin/sh -c abeja-de…"   3 hours ago         Up 3 hours                                                                abeja-device-agent

テスト

cat_thumb.jpg

テスト用の画像をJetsonにダウンロードします。

nvidia@tegra-ubuntu:~$ wget https://console.abeja.io/images/cat_thumb.jpg

localhost:8000に下記のように画像を投げると、JSONで推論結果が帰ってくる事が確認できます。
あとはビジネスロジックの乗ったコードを作り推論APIと結合する事によって、やりたい事を自由に叶える事ができます :muscle:

nvidia@tegra-ubuntu:~$ curl -X POST -H 'Content-Type:image/jpeg' --data-binary @cat_thumb.jpg -XPOST http://localhost:8000
{"result": ["n02123045 tabby, tabby cat", "n02123159 tiger cat", "n02124075 Egyptian cat", "n02127052 lynx, catamount", "n03958227 plastic bag"]}

最後に

今回はABEJA Platformを使って、エッジデバイスに対してモデルデプロイをする流れについて解説させていただきました :muscle:
ハンズオンイベントも来年1月に企画しておりますので、ご興味がアレばぜひご参加いただければと思います。
ありがとうございました :bow:

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
3