プログラムを中心とした個人的なメモ用のブログです。 タイトルは迷走中。
内容の保証はできませんのであしからずご了承ください。

2023/05/27

Telegraf で Jetson の GPU 情報を取得する

event_note2023/05/27 6:36

Telegraf で GPU 情報を取得しよううとしたのですが、Jetson には nvidia-smi のコマンドがありません。

どうしようかなと思っていたら、以下の記事に Jetson で GPU 情報を取得する方法が書いてありました。

これを参考に、InfluxDB にデータを保存し、Grafana で可視化まで行いました。
尚、TIG Stack (Telegraf, InfluxDB, Grafana) については以下を参考にしてください。

環境

  • Jetson Xavier NX
  • Ubuntu 18.04
  • Telegraf 1.23.0

Telegraf, InfluxDB, Grafana は Docker で動作させています。

Jetson Stats のインストール

まずはホストに Jetson Stats をインストールします。

$ sudo apt-get update
$ sudo apt-get install python3-pip
$ sudo -H python3 -m pip install -U jetson-stats

インストール後、一度ログアウト or 再起動します。

jtop を実行して動作確認します。

Telegraf の設定

Jetson Stats を使って GPU の情報を取得する python スクリプトを作成し、それを Telegraf から定期的に実行するようにします。
ただし、今回 Telegraf は Docker コンテナで動かしているので、上記の記事そのままでは上手く行きません。

Python スクリプトの作成

上記の記事にある以下のスクリプトを jetson_stats.py という名前で保存しました。

# Import jtop python library. We will use this to access the Jetson_Stats service.
from jtop import jtop
import json, datetime

if __name__ == "__main__":

    with jtop() as jetson:
        # jetson.stats provides our system measurements as type dict.
        tmp = jetson.stats
        # time and uptime are proved as time objects. These needed to be converted before passing as a JSON string,
        tmp["time"] = str(tmp["time"].strftime('%m/%d/%Y'))
        tmp["uptime"] = str(tmp["uptime"])
        # We then convert our dict -> Json string
        influx_json= {"jetson": tmp}
        print(json.dumps(influx_json))

このスクリプトを Telegraf から定期的に実行することになります。

Dockerfile の作成

今までは Telegraf の Docker イメージをそのまま使っていましたが、このコンテナには Python の実行環境が入っていないため、上記の Python スクリプトを動かすことができません。
そこで、以下のような Dockerfile を作成しました。

FROM telegraf:1.23.0

ARG DEBIAN_FRONTEND=noninteractive

COPY jetson_stats.py /usr/local/bin/

RUN apt update && \
    apt install -y --no-install-recommends \
    python3 \
    python3-pip \
    python3-setuptools \
    python3-wheel && \
    apt autoremove && apt clean && rm -rf /var/lib/apt/lists/*

RUN pip3 install \
    jetson-stats

jetson_stats.py をイメージ内にコピーし、あとは Python の実行環境と Jetson Stats をインストールしています。

docker-compose.yml の変更

コンテナ内で Jetson Stats を使うためには、/run/jtop.sock をマウントする必要があるようです。
ただ、それだけではアクセス権限の関係で以下のようなエラーが表示されました。

jtop.core.exceptions.JtopException: I can't access jetson_stats.service.

Docker コンテナの実行ユーザーを /run/jtop.sock の所有グループに加えたら解決できたので、group_add のプロパティを追加します。

以上を踏まえ、docker-compose.yml を以下のように変更しました(今回に関連する部分のみ抜粋)。

services:
  telegraf:
    image: telegraf-python:latest
    container_name: telegraf
    hostname: ${HOSTNAME:?}
    environment:
      - NVIDIA_VISIBLE_DEVICES=all
      - NVIDIA_DRIVER_CAPABILITIES=all
    deploy:
      resources:
        reservations:
          devices:
            - capabilities: [gpu]
    restart: unless-stopped
    ports:
      - 6514:6514
    volumes:
      - ./telegraf.conf:/etc/telegraf/telegraf.conf:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - /usr/bin/nvidia-smi:/usr/bin/nvidia-smi:ro
      # 以下は Jetson Xavier NX 用
      - /run/jtop.sock:/run/jtop.sock:ro # https://github.com/rbonghi/jetson_stats
    user: ${TELEGRAF_UID_GID:?}
    group_add:
      - "${JTOP_GID:?}"

環境変数の追加

上記の docker-compose.yml 内にある JTOP_GID という環境変数を定義します。
~/.bashrc に以下を追記します。

export JTOP_GID=$(stat -c '%g' /run/jtop.sock)

再読み込みします。

~$ source .bashrc

これで、/run/jtop.sock の所有グループを JTOP_GID で参照できます。

telegraf.conf の設定

telegraf.conf に以下を追記します。

[[inputs.exec]]
  ## Commands array
  commands = [
    "python3 /usr/local/bin/jetson_stats.py"
  ]

  ## Timeout for each command to complete.
  timeout = "5s"

  ## measurement name suffix (for separating different commands)
  name_suffix = "_jetson_stats"

  ## Data format to consume.
  ## Each data format has its own unique set of configuration options, read
  ## more about them here:
  ## https://github.com/influxdata/telegraf/blob/master/docs/DATA_FORMATS_INPUT.md
  data_format = "json"
  ## Array of glob pattern strings or booleans keys that should be added as string fields.
  json_string_fields = ["jetson_uptime", "jetson_nvp model", "jetson_NVENC",  "jetson_NVDEC",  "jetson_NVJPG"]

内容は前述の参考記事の中身そのままです。

テスト

Docker コンテナに入って、以下のコマンドを実行します。

python3 jetson_stats.py

json が取得できていれば OK です。

Grafana のダッシュボードを作成

Jetson Stats 用のテンプレートがないかなと探してみましたが、見つかりませんでした。
どうやら自分で作成するしかなさそうです。

参考として、jetson_stats.py を実行したら以下のような出力が得られます(わかりやすいように整形しています)。

{
    "jetson": {
        "time": "09/14/2022",
        "uptime": "0:40:39.970000",
        "jetson_clocks": "OFF",
        "nvp model": "MODE_10W_DESKTOP",
        "CPU1": 16,
        "CPU2": 13,
        "CPU3": 13,
        "CPU4": 14,
        "CPU5": "OFF",
        "CPU6": "OFF",
        "GPU": 0,
        "MTS FG": 0,
        "MTS BG": 0,
        "RAM": 1413804,
        "EMC": 1413804,
        "SWAP": 0,
        "APE": 150,
        "NVENC": "OFF",
        "NVDEC": "OFF",
        "NVJPG": "OFF",
        "fan": 0.0,
        "Temp AO": 42.0,
        "Temp AUX": 42.0,
        "Temp CPU": 42.5,
        "Temp GPU": 41.5,
        "Temp thermal": 42.15,
        "power cur": 4166,
        "power avg": 4166
    }
}

これらの値が InfluxDB に格納されているはずなので、その値を使ってダッシュボードを作成していきます。
尚、各プロパティの説明は以下にありました。

単位くらい書いておいてほしいなぁ〜。