Jetson Orin NanoにJetPack6をインストール

# JetPack6導入についてのメモ

- 2024/05にJetPack6がリリースされていたのに気づかず、今更だけど導入してみた。
- 古いJetson Orin Nanoだとファームウェアのバージョンアップから実施が必要。
- 全てSDカード経由で対応できるようになっていたので、それのメモ。
- その他は、個人的な環境ではあるものの、行ったことについてのメモ。
- 最近は、Jetson Orin Nanoの話題を見かけることが少ないので、探せなくなる前に自身のメモとして残しておく。

## JetPack6に向けてファームウェアのバージョンアップ

- 手順は全て以下のサイトに詳しく記載されている。（この手順に従えばJetPack6の導入まで終了する）
  - https://www.jetson-ai-lab.com/initial_setup_jon.html
  - 英語だが、ブラウザの翻訳機能を使えば問題ない。
  - このサイトの手順に従って、ファームウェアのバージョンアップを行う。
- 記載されていない注意事項
  - 有線LANを繋げてインストールしたため、途中の`apt-get`でファームウェアの指定は問題なく進行したが、インターネットに接続できない場合の挙動については不明
- 新しいJetsonであれば最新のファームウェアが入っているので、そのままJetPack6をインストールすれば良い。

## SSDへJetPack6をインストール

- 上記手順はあくまでもSDカードでの起動まで。
- SSDへのインストールは、SDカードからの起動後に行う。
  - 以下の情報を参考に行った。（というか手順そのままJetPack6でも有効）
  - https://qiita.com/kitazaki/items/da5fb46c03781eb7b406
- 以下、コマンドを転記。（コマンドの詳細は各セクション参照）

```bash
sudo fdisk /dev/nvme0n1
gzip -dc jp60-orin-nano-sd-card-image.zip | sudo dd of=/dev/nvme0n1 bs=4M status=progress
sudo mount /dev/nvme0n1p1 /mnt
cd /mnt/boo/extlinux
sudo cp extlinux.conf extlinux.conf.bak
sudo vi extlinux.conf
```

- SSDのデバイス名が異なるようであれば、環境に合わせて変更すること。

### パーティションの削除

```bash
sudo fdisk /dev/nvme0n1
```

- `d`で全てのパーティションを削除（14個ぐらいパーティションが存在していたので、その全てを削除）
- `w`で保存して終了
- Disklabel typeがGPTであることを確認

### イメージファイルの展開

```bash
gzip -dc jp60-orin-nano-sd-card-image.zip | sudo dd of=/dev/nvme0n1 bs=4M status=progress
```

- イメージファイルはChromeを使ってダウンロードした。
- あらかじめ`sudo apt-get install progress`でプログレスコマンドをインストールした。
  - 何がどう変わったかのかは不明。
- 一旦、イメージを書き込んだ後に再起動を実施した。
  
### ブートパーティションの変更

- 残りのコマンドは、ファイルに指定されているブートパーティションを変更するもの。
- extlinux.confの編集は、`APPEND`の行を`mmcblk0p1`を`nvme0n1p1`に変更するだけ。
- 以下のように変更する。

```extlinux.conf
APPEND ${cbootargs} root=/dev/nvme0n1p1 rw rootwait rootfstype=ext4 console=ttyS0,115200n8 console=tty0 fbcon=map:0 net.ifnames=0
```
- SDカードを抜いて再起動すれば、SSDから起動するようになる。
- JetsonのBIOSの設定でBootメニューの中にSSDが表示されているので問題なく起動される。

## ネットワークの設定

- いつもコマンドで悩むのでGUIがあるうちにIPアドレスを固定化しておく。
- `nmcli`の使い方はよく分かっていない。

### SSHの設定

- クライアント側の端末で秘密鍵を作って、公開鍵を以下のコマンドを使ってJetsonに登録する。
- 個人的にはED25519を使っている。その場合は、`~/.ssh/id_ed25519.pub`を指定する。

```bash
ssh-copy-id -i ~/.ssh/id_rsa.pub <login>@<ip>
```

## 外付けHDDの設定

- 外付けHDDを使用しているので、自動マウントの設定を行う。

```bash
lsblk -f
sudo vi /etc/fstab
```

### UUIDの確認

- `lsblk -f`で確認したUUIDを`/etc/fstab`に追記する。

```/etc/fstab
UUID=xxxx-xxxx-xxxx-xxxx /mnt/usb ext4 defaults 0 2
```

### ファイルチェック

- 以前にシステムがクラッシュして、外付けHDDを接続したままでは起動しなくなっていたので、今回合わせて対応
- 以下は起動時のメンテナンスモードにて実施。

```bash
fsck /dev/sda1
```

- リカバリが済めば、再起動して問題なく起動した。（マウントも問題なく行えた）

## Dockerの設定

- Dockerの設定は、以下のサイトを参考に行った。(以下のページにはSSDをマウントして使う手順も記載されているが、上記で既にSSDからの起動を行っているので、その手順は無視)
  - https://www.jetson-ai-lab.com/tips_ssd-docker.html#docker

```bash
sudo apt update
sudo apt install nvidia-container
sudo systemctl stop docker
sudo usermod -aG docker $USER
newgrp docker
sudo vi /etc/docker/daemon.json
sudo systemctl daemon-reload
sudo systemctl start docker
```

### daemon.jsonの設定

- 以下のように編集する。（dockerのフォルダは以前に使用していたフォルダがあるため、そのまま利用）

```/etc/docker/daemon.json
{
    "runtimes": {
        "nvidia": {
            "args": [],
            "path": "nvidia-container-runtime"
        }
    },
    "default-runtime": "nvidia",
    "data-root": "/mnt/usb/docker"
}
```

### Dockerの動作確認

- 一度、SSHは切断して、再度ログインして以下のコマンドを実行。
- コンテナイメージとして、jetson-containersのPyTorchを利用。

```bash
docker run --rm -it dustynv/l4t-pytorch:r36.2.0
```

- コンテナ内のPythonを起動して、PyTorchがCUDAを認識しているか確認。

```python
import torch
torch.cuda.is_available()
```

## メモリ最適化

- 以下のページに従って、メモリ最適化を行った。
  - https://www.jetson-ai-lab.com/tips_ram-optimization.html

### GUIの無効化

- 以下のコマンドでGUIを無効化する。
- なお`sudo init 3`を叩いた後はX-Windowが落ちるため画面が映らなくなる。（再起動後はCUI画面は表示される）

```bash
sudo init 3
sudo systemctl set-default multi-user.target
```

### その他サービスの停止

- 以下のサービスを停止する。

```bash
sudo systemctl disable nvargus-daemon.service
```

### スワップ作成

- 以下のコマンドでスワップを作成する。

```bash
sudo systemctl disable nvzramconfig
sudo fallocate -l 16G /mnt/16GB.swap
sudo chmod 600 /mnt/16GB.swap
sudo mkswap /mnt/16GB.swap
sudo swapon /mnt/16GB.swap
```

- 作成したスワップを`/etc/fstab`に追記する。

```/etc/fstab
/mnt/16GB.swap none swap sw 0 0
```

### ZRAMの停止

- 恐らく再起動すればZRAMは停止されるはずだが、念のため以下のコマンドで停止する。

```bash
sudo swapoff /dev/zram0
```

- zramは0～6まであった。（全て`swapoff`にした）

## jetson containersの利用

- メインの実行環境、開発環境になるjetson containersを利用する。
  - https://github.com/dusty-nv/jetson-containers

```bash
mkdir workspaces
cd workspaces
git clone https://github.com/dusty-nv/jetson-containers.git
cd jetson-containers
./install.sh
./jetson-containers build --name=allbase pytorch transformers llama_cpp ros:humble-ros-core
```