NVIDIA Jetson NanoでHello AI WorldをAnsibleってみた。

AWS事業本部 梶原@福岡オフィスです。 今日は7月7日で弊社のクラスメソッドの創立記念日となります。
今日はなな月なの日、N月Nano日ということで、NVIDIA Jetson NanoでAIを始めてみたいと思います。(強引・・・
とはいえ、普通にやってもつまんないので、Jetsonで紹介されている。Hello AI WorldをAnsibleで流してみました。

はっきり言いますが、普通の人は、下記公式サイトを参考に普通にjetson Nanoに乗り込んで実行したほうがいいと思います。

https://github.com/dusty-nv/jetson-inference#hello-ai-world-inference-only

では、サクサクと。

環境設定

jetson Nanoへの鍵配置

IPアドレスはコンソール等で確認をお願いします。 今回jetson Nanoの

  • IPアドレスは192.168.6.17
  • ユーザ名はjetson

でセットアップずみのjetson Nanoに対して実施していきます。

接続確認

$ ssh jetson@192.168.6.17
jetson@192.168.6.17's password:
Welcome to Ubuntu 18.04.2 LTS (GNU/Linux 4.9.140-tegra aarch64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

This system has been minimized by removing packages and content that are
not required on a system that users do not log into.

To restore this content, you can run the 'unminimize' command.

450 packages can be updated.
210 updates are security updates.

Last login: Sun Jul  7 00:29:45 2019 from 192.168.6.XX
jetson@jetson-nano:~$

鍵配置

接続用の鍵を配置します。

$ ssh-copy-id jetson@192.168.6.17
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/hoge/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
jetson@192.168.6.17's password:

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'jetson@192.168.6.17'"
and check to make sure that only the key(s) you wanted were add

秘密鍵での接続確認

接続の際にパスワードを聞かれない事を確認してください

$ ssh 'jetson@192.168.6.17'
Welcome to Ubuntu 18.04.2 LTS (GNU/Linux 4.9.140-tegra aarch64)
<<省略>>
jetson@jetson-nano:~$

ssh_configを使用した接続確認

ssh_config ファイルを記載して、Ansibleで使用します。

Host jetson-nano
  HostName     192.168.6.17 <<= Jetnon NanoのIPを入れてください
  User         jetson
  StrictHostKeyChecking no
  UserKnownHostsFile /dev/null
  IdentityFile ~/.ssh/id_rsa
$ ssh -F ssh_config jetson-nano
Welcome to Ubuntu 18.04.2 LTS (GNU/Linux 4.9.140-tegra aarch64)
<<省略>>
jetson@jetson-nano:~$

ここまで、できれば、普通はjetson-nanoに乗り込んでHello AI Worldすればいいんですが、天邪鬼なのでPlyabookにまとめます・・・

Ansbile での接続設定

hosts設定

hosts

[jetson]
jetson-nano

ansible.cfg

[defaults]
inventory = hosts

[privilege_escalation]
become = True

[ssh_connection]
ssh_args = -F ssh_config -o ControlMaster=auto -o ControlPersist=15m
scp_if_ssh = True

Ansibleからの接続実施

$ export ANSIBLE_CONFIG=./ansible.cfg
$ ansible jetson -m ping
jetson-nano | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

AnsibleでHello AI Worldを実行

基本的にはビルド部分は下記URLの内容のAnsible-Playbook起こし。
推論部分はほぼシェルです・・・

https://github.com/dusty-nv/jetson-inference/blob/master/docs/building-repo-2.md

Playbookの概要

  1. jetson-inferenceで必要なパッケージをインストール
  2. jetson-inference をclone
  3. jetson-inference をbuild,install
  4. オレンジの画像を推論
  5. 推論結果を取得

をやっています。 Ansible Playbookはこちら

Ansible-Playbookの実行

$ ansible-playbook jetson-hello-ai-world.yml --ask-become-pass
SUDO password: jetsonユーザーでsudoする際のパスワード

PLAY [jetson] ****************************
TASK [Gathering Facts] ******************************************
ok: [jetson-nano]

TASK [apt] *********************
ok: [jetson-nano]

TASK [Only run "update_cache=yes" if the last one is more than 1Day ago] **************************************************************
ok: [jetson-nano]

TASK [Install a list of packages] *************************
ok: [jetson-nano]

TASK [create jetson-inference] **************************
ok: [jetson-nano]

TASK [git clone https://github.com/dusty-nv/jetson-inference.git] *********************
ok: [jetson-nano]

TASK [create build] ****************************
ok: [jetson-nano]

TASK [Configuring with CMake] ****************************
changed: [jetson-nano]

TASK [make all] **********************************
changed: [jetson-nano]

TASK [make install] *********************************
changed: [jetson-nano]

TASK [imagenet-console] **********************************
changed: [jetson-nano]

TASK [fetch] *************************************
ok: [jetson-nano]

PLAY RECAP *************************
jetson-nano                : ok=12   changed=4    unreachable=0    failed=0

上記の結果は、何回実施した後の結果なので、changeがでていませんが、途中の環境構築にに15分くらいかかります。
ただ、推論自体は、数秒で実施できます。nanoでもかなり速いですね。
もしタイムアウトした場合は、再実施してください。

うまくいくと、実行したフォルダにjetson-nano上で推論したファイルが保存されています(output_0.jpg)

97%くらい、オレンジだと推論できました。(個人的にはみかんが好きです)

まとめ

勢いでやっちゃったので、Ansibleの冪等性をあまり考えてなく、ほぼシェルじゃんで大変申し訳ないですが、AnsibleのPlaybookを実行して、jetson-nano上でに推論して、推論した結果を取得することができました。
Hello AI Worldというのも、Nanoするのも初めはHello Worldでしょってことで、創業記念でいい感じに整いそうなのでここらへんで

Ansible PlayBook

# jetson-hello-ai-world.yml
- hosts: "jetson"
  vars:
    git_repo: "https://github.com/dusty-nv/jetson-inference.git"
    work_dir: "jetson-inference"

  tasks:
    # 構築環境整備
    - apt:
        name: python-pip
      become: yes

    - name: Only run "update_cache=yes" if the last one is more than 1Day ago
      apt:
        update_cache: yes
        cache_valid_time: 86400

    - name: Install a list of packages
      apt:
        name: "{{ packages }}"
      vars:
        packages:
          - git
          - cmake
      become: yes

    # jetson-inferenceのクローン
    - name: create {{ work_dir }}
      file:
        path: "{{ work_dir }}"
        state: directory

    - name: git clone {{ git_repo }}
      git:
        repo: "{{ git_repo }}"
        dest: "{{ work_dir }}"
        clone: yes

    # jetson-inferenceのbuild,install
    - name: create build
      file:
        path: "{{ work_dir }}/build"
        state: directory

    - name: Configuring with CMake
      command: "cmake ../"
      args:
        chdir: "{{ work_dir }}/build"
      become: yes

    - name: make all
      make:
        chdir: "{{ work_dir }}/build"
        target: all
      become: yes

    # Run `install` target as root
    - name: make install
      make:
        chdir: "{{ work_dir }}/build"
        target: install
      become: yes

    # オレンジの画像を推論
    - name: imagenet-console
      shell: ./imagenet-console orange_0.jpg ~/output_0.jpg
      args:
        chdir: "{{ work_dir }}/build/aarch64/bin"

    # 結果画像の取得
    - name:
      fetch:
        src: "~/output_0.jpg"
        dest: "./output_0.jpg"
        flat: yes