押し入れから 2017年発売世代の Jetson TX2(NVIDIA の小型 AI ボード)が出てきた(ΦωΦ) 2026年のいま、これを叩き起こして画像を生成するマシンにできないか?と思いました。なかなか一筋縄ではいかず、母艦(作業用PC)が新しすぎることでひっかかったりとか。最終的に JetPack を更新して、画像生成ができるところまでできました!
この記事でやったこと
- 古い JetPack 3.1 を、TX2 が公式対応する最終世代 JetPack 4.6 系(L4T 32.7.1 / CUDA 10.2) に焼き直した
- C++ 実装 stable-diffusion.cpp を自前ビルドし、SD1.5 で画像を生成できた
JetPack 4.6 系へ焼き直す
今回は TX2 にモニタもキーボードも繋がず、母艦から SSH だけで操作します(headless)。初回起動の設定ウィザードを画面で操作できないので、ユーザー作成を焼き込みより先に済ませておく必要があります(後回しにすると焼き直しのやり直し)。以下の流れで作業をします。
- 配布物(BSP と rootfs)を展開する
- デフォルトユーザーを事前に作る(初回起動のウィザードを飛ばすため)
- 母艦側の互換性対策をする
- TX2 をリカバリーモードにする
flash.shで焼き込む- 初回起動して SSH で入る
なぜ 4.6 系までなのか
元は L4T R28.1(JetPack 3.1相当)で CUDA 未インストール。TX2 が公式対応する JetPack は 4.6 系が最後(5 以降は非対応)なので、この個体で使える上限が CUDA 10.2。画像生成もこの範囲でやる話になります。
用意するもの
- x86_64 の Linux 母艦(焼き込みツールが x86 バイナリのため)。今回は Ubuntu 26.04(今回の沼の原因)
- データ通信対応の「micro-USB(オス) ⇔ USB Type-A(オス)」ケーブル。昔のスマホのデータケーブルです。
焼き込みは手動の flash.sh を使います(GUI の SDK Manager は母艦が 18.04 / 20.04 でないと弾かれる)。配布物(L4T 32.7.1 の BSP と rootfs)は 2026年でも落とせます。展開して apply_binaries.sh → sudo ./flash.sh jetson-tx2 mmcblk0p1。
母艦が新しすぎることで踏む4つの落とし穴
NVIDIA の焼き込みスクリプトは 2022年製。これを 2026年の新しい母艦(Ubuntu 26.04 / OpenSSH 10.x / Python 3.14)で動かすと、4つの落とし穴を踏みます。どれもエラーの見た目と真因がズレていて、素直に読むと誤診する。
落とし穴1: qemu-user-static が無い
- 症状: 準備段階の
apply_binaries.shがqemuを見つけられない。 - 原因: 26.04 では
qemu-user-staticパッケージが廃止済み。 - 対処: 代替を入れ、スクリプトが探す「-static付き」の名前を別名で用意する。
sudo apt-get install -y qemu-user-binfmt qemu-user
sudo ln -sf /usr/bin/qemu-aarch64 /usr/bin/qemu-aarch64-static
落とし穴2: DSA 鍵生成が OpenSSH 10.x で死ぬ
command is failed
- 症状: 最初の
flash.shが「recovery ramdisk の再生成」の途中で上のエラーを出して止まる。 - 原因: スクリプトが内部で
ssh-keygen -t dsaを呼ぶが、いまの OpenSSH 10.x は DSA を完全撤廃していて失敗する。それが全体を巻き添えにする。 - 対処: DSA ホスト鍵は現行 sshd では使われないので、該当行を無害化(
|| true)して先へ進める。
落とし穴3: 「probing failed」の正体は “UIDは1回きり”
flash.sh の前に tegrarcm_v2 --uid を実行しないこと。
Error: probing the target board failed
- 症状: リカバリーモードには入れている(
lsusbに見えている)のに、ボードの探索で上のエラーが出て止まる。 - 原因: Tegra の bootrom は、1回のリカバリーセッションにつき UID(基板の識別子)を一度しか返さない。デバッグのつもりで自分で
tegrarcm_v2 --uidを叩くと、その唯一の応答を消費してしまい、直後のflash.shの問い合わせが空になる。 - 紛らわしさ:
dmesgに USB エラーは出ないので「ケーブル不良かな」と誤診しやすい。 - 対処: リカバリーモードに入れた直後、最初に通信させるプログラムを
flash.shにする(自分でtegrarcmを先に実行しない)。UID はセッションで1回しか返らないので、その1回をflash.shに使わせる。
落とし穴4: python が無い
env: 'python': No such file or directory
- 症状: 実書き込み直前の署名処理で上のエラー。
- 原因: ツールの shebang が
#!/usr/bin/env pythonなのに、26.04 にはpython3しか無い。名前だけの問題。 - 対処: symlink を1本張る。
sudo ln -sf /usr/bin/python3 /usr/local/bin/python
この4つを越えると、ようやく成功メッセージが出ます。
*** The target t186ref has been flashed successfully. ***
覚えておくと楽な2つ
- リカバリーモードは SSH から。ボタン操作(REC+RST)でタイミングに悩むより、旧OSに SSH して
sudo reboot --force forced-recoveryが確実です。 - ユーザーの事前作成は
l4t_create_default_user.shで。焼く前に流しておけば、headless でも初回起動でそのまま SSH に入れます。
CUDA と GPU の動作を確認する
焼けても、GPU が計算に使えなければ意味がない。CUDA ツールキット(nvcc)を apt で入れて(リポジトリは 2026年でも生きている)、公式サンプルで実測しました。
| 種別 | テスト | 結果 | 何が分かるか |
|---|---|---|---|
| 必須 | deviceQuery | PASS | CUDA から GPU を認識できる(Tegra X2 / CC 6.2 / 256コア / 8GB共有) |
| 必須 | vectorAdd | PASS | GPU 計算と検算が通る |
| 必須 | GPU使用率 | 99% | 負荷時に実際に GPU が回る(アイドルは0%) |
| 参考 | matrixMul | 71 GFlop/s | おおよその演算性能 |
| 参考 | bandwidthTest | H2D 10.2 / D2H 17.0 / D2D 30.6 GB/s | メモリ転送性能 |
特に重要なのが Compute Capability 6.2(GPU の世代を表す番号。sm_62)。この後 stable-diffusion.cpp をビルドするとき、GPU アーキテクチャに 62 を指定する必要があります(よく参考にされる Jetson Nano は 53 で、ここが違う)。
stable-diffusion.cpp で画像を生成する
なぜ stable-diffusion.cpp なのか
最新の PyTorch / Diffusers / ComfyUI は CUDA 11 以降が前提で、TX2 の CUDA 10.2 では動きません。そこで、PyTorch を使わない軽量な C++ 実装 stable-diffusion.cpp を使います。さらに Jetson 向けに CUDA 10.2 でビルドできる派生版をベースにしました。
ビルドで踏む落とし穴
cmakeが古い。OS 標準のaptのcmakeは 3.10 でバージョン不足。公式の aarch64 バイナリ(3.28 系)を落として使う。- CUDA アーキテクチャを 62 に。ベースが Nano 向けで
53にハードコードされているので62へ。configure でUsing CUDA architectures: 62が出るのを確認する(黙って53でビルドされると、実行時のカーネル起動で初めて失敗する)。 - NEON 組み込み関数の不足。量子化コードが使う一部の NEON 命令(x4ロード)は gcc 9 以降にしか無い。ところが CUDA 10.2 が使えるホストコンパイラは
gcc-8が上限で、板挟みになる。該当の関数だけをgcc-8でも通る形に手当てして回避した。
要点だけ抜き出すと、ビルドはこんな指定になります。
# CUDA アーキテクチャを 62 に(Nano の 53 ではない)
sed -i 's/CMAKE_CUDA_ARCHITECTURES "53"/CMAKE_CUDA_ARCHITECTURES "62"/' CMakeLists.txt
# CUDA 10.2 のホストコンパイラ上限は gcc-8
cmake .. -DSD_CUDA=ON -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_COMPILER=gcc-8 -DCMAKE_CXX_COMPILER=g++-8 \
-DCMAKE_CUDA_HOST_COMPILER=g++-8
cmake --build . -j4
これで CUDA(GPU)を使う sd バイナリができます。
最初の作例(SD1.5)
最初に試したのは、扱いが軽い SD1.5(Stable Diffusion 1.5)。いくつか生成してみたのが下の3枚です。
3枚とも生成条件は共通です。
| 項目 | 値 |
|---|---|
| モデル | Stable Diffusion 1.5 (f16) |
| 解像度 | 768 × 512 |
| ステップ数 | 20 |
| サンプラー / CFG | dpm++2m / 8 |
| VAE | フルVAE(--vae-tiling) |
| 電力モード | MAXN + jetson_clocks |
| 生成時間 | 1枚あたり約6分(実測で385秒前後) |



まとめ
- TX2 の最終世代は JetPack 4.6 系(CUDA 10.2 /
sm_62)。配布物もaptも 2026年でまだ生きている。 - 詰まるのは母艦が新しすぎるところ。
qemu/ DSA /python/ UID の4つは、どれもエラーの見た目と真因がズレている。 - 今回の「probing failed」の原因は、
flash.shより先にtegrarcm_v2 --uidを自分で叩いたことだった。ボードが UID を返すのはリカバリーモードに入ってから1回だけなので、先に叩くとflash.shが UID を受け取れなくなる。リカバリーモードに入れたら、最初に通信させるのはflash.shにする。 - 成功の確認はドライバの有無で終わらせない。
deviceQuery/vectorAddの PASS と GPU 使用率まで見る。 - 焼き直し → CUDA → ビルド と進めて、SD1.5 で最初の1枚まで到達できた。

コメントを残す