Jetson Orin Nano TensorRT高速化チュートリアル
Jetson Orin NanoでAIモデルを動かすなら、TensorRTによる高速化は避けて通れない。本記事では実機を使ってTensorRTの基本から変換・推論の実行まで、初心者でも再現できる手順を丁寧に解説する。
この記事でわかること
—
TensorRTとは何か
TensorRT(テンサーアールティー)はNVIDIAが開発した推論高速化ライブラリだ。学習済みのニューラルネットワークモデルを、特定のGPUに最適化された形式(エンジンファイル)に変換することで推論速度を大幅に向上させる。
Jetson Orin Nanoに搭載されているOrinアーキテクチャのGPUは、TensorRTとの相性が非常に良い。筆者の環境では、YOLOv8のモデルをそのまま動かした場合と比べてTensorRT変換後は約3〜5倍の速度向上を確認している。
JetPackをインストールした状態であれば、TensorRTはすでにシステムに含まれている。バージョンを確認するには以下のコマンドを実行する。
dpkg -l | grep tensorrt
JetPack 6.x系ではTensorRT 10.x以上がインストールされているはずだ。JetPack 5.1.3以降を使用している場合は、事前にUEFI Firmwareを最新版(36.3以上)に更新することを推奨する。
—
変換前の準備と環境確認
Jetsonの動作モードを最大性能に設定する
変換作業と速度計測は同じ動作モードで行う必要がある。まず最大性能モードに切り替えておこう。
sudo nvpmodel -m 0
sudo jetson_clocks
nvpmodel -m 0 は最大電力モード(MAXN)への切り替え、jetson_clocks は全クロックを最大に固定するコマンドだ。速度計測のたびにこれを実行することで、計測結果のばらつきを抑えられる。
必要なPythonパッケージの確認
python3 -c "import tensorrt; print(tensorrt.__version__)"
python3 -c "import torch; print(torch.__version__)"
python3 -c "import onnx; print(onnx.__version__)"
onnxがインストールされていない場合は追加する。
pip3 install onnx onnxruntime
—
PyTorchモデルをTensorRTエンジンに変換する手順
変換の流れは「PyTorchモデル → ONNXファイル → TensorRTエンジン」の2段階になる。
ステップ1: PyTorchモデルをONNXに変換する
ここではResNet-18を例に解説する。自分のモデルに置き換える場合は入力テンソルのshapeを適切に変更すること。
import torch
import torchvision.models as models
# モデルのロード
model = models.resnet18(weights=models.ResNet18_Weights.IMAGENET1K_V1)
model.eval()
model = model.cuda()
# ダミーの入力テンソルを作成(バッチサイズ1、224x224のRGB画像)
dummy_input = torch.randn(1, 3, 224, 224).cuda()
# ONNXへのエクスポート
torch.onnx.export(
model,
dummy_input,
"resnet18.onnx",
export_params=True,
opset_version=18,
do_constant_folding=True,
input_names=["input"],
output_names=["output"],
dynamic_axes={"input": {0: "batch_size"}, "output": {0: "batch_size"}}
)
print("ONNXエクスポート完了")
ステップ2: ONNXからTensorRTエンジンに変換する
trtexec コマンドはJetPackに含まれているTensorRT付属のツールで、最も手軽に変換できる方法だ。JetPack 6ではデフォルトでパスが通っているため、フルパスの指定は不要になった。
# FP16精度で変換(推奨)
trtexec \
--onnx=resnet18.onnx \
--saveEngine=resnet18_fp16.trt \
--fp16 \
--minShapes=input:1x3x224x224 \
--optShapes=input:1x3x224x224 \
--maxShapes=input:8x3x224x224
# INT8精度で変換(さらに高速だが精度は落ちる)
trtexec \
--onnx=resnet18.onnx \
--saveEngine=resnet18_int8.trt \
--int8
変換には数分かかる場合がある。Jetson Orin Nanoの場合、筆者の環境では約3〜5分程度かかった。変換が完了すると末尾に [I] Throughput: xxx qps という形でスループットが表示される。
—
TensorRTエンジンを使って推論する
変換したエンジンファイルをPythonから呼び出す基本的なコードを示す。
import tensorrt as trt
import numpy as np
import pycuda.driver as cuda
import pycuda.autoinit
import time
# ロガーの設定
TRT_LOGGER = trt.Logger(trt.Logger.WARNING)
def load_engine(engine_path):
with open(engine_path, "rb") as f:
runtime = trt.Runtime(TRT_LOGGER)
return runtime.deserialize_cuda_engine(f.read())
def infer(engine, input_data):
context = engine.create_execution_context()
# 入出力バッファの準備
input_shape = input_data.shape
output_shape = (1, 1000) # ResNet-18の出力クラス数
h_input = np.ascontiguousarray(input_data, dtype=np.float32)
h_output = np.empty(output_shape, dtype=np.float32)
d_input = cuda.mem_alloc(h_input.nbytes)
d_output = cuda.mem_alloc(h_output.nbytes)
cuda.memcpy_htod(d_input, h_input)
context.execute_v2(bindings=[int(d_input), int(d_output)])
cuda.memcpy_dtoh(h_output, d_output)
d_input.free()
d_output.free()
return h_output
# エンジンのロードと推論実行
engine = load_engine("resnet18_fp16.trt")
dummy_input = np.random.rand(1, 3, 224, 224).astype(np.float32)
# ウォームアップ(最初の数回は遅いため)
for _ in range(10):
result = infer(engine, dummy_input)
# 速度計測
start = time.time()
for _ in range(100):
result = infer(engine, dummy_input)
elapsed = time.time() - start
print(f"平均推論時間: {elapsed / 100 * 1000:.2f} ms")
print(f"スループット: {100 / elapsed:.1f} FPS")
—
変換前後の速度比較
実機(Jetson Orin Nano 8GB、JetPack 6.1)で計測した結果を示す。
| モデル形式 | 平均推論時間 | スループット |
|—|—|—|
| PyTorch(FP32) | 18.2 ms | 55 FPS |
| ONNX Runtime | 11.8 ms | 85 FPS |
| TensorRT FP16 | 4.8 ms | 208 FPS |
| TensorRT INT8 | 3.5 ms | 286 FPS |
FP16変換だけでPyTorchの約3.8倍、INT8ではほぼ5倍以上の速度向上が得られた。なお、INT8変換は精度の低下が発生するため、用途に応じて選択してほしい。精度が重要なケースではFP16が現実的な選択肢になる。
—
つまずきやすいポイントと対処法
エンジンファイルは他のJetsonで使いまわせない
TensorRTエンジンはビルドしたデバイスに最適化されるため、別のJetsonや別のJetPackバージョンでは動作しない。本番環境と同じ機材・同じJetPackバージョンで変換する必要がある。
変換時に “InvalidGraph” エラーが出る場合
一部のPyTorchの演算子がONNXに正しく変換されないことがある。opset_version を下げる(例: 18→13)か、問題の演算子を別の実装に置き換えることで解決するケースが多い。
pycuda のインストールでエラーになる場合
pip3 install pycuda --no-cache-dir
--no-cache-dir オプションを追加してインストールし直すと解決することがある。それでも失敗する場合は、apt 経由でインストールする方法も試してほしい。
推論が遅い場合はウォームアップを忘れずに
TensorRTは最初の数回の推論でGPUの初期化処理が走るため、速度計測はウォームアップ後に行うこと。上記のコードにもウォームアップ処理を含めているので参考にしてほしい。
DLA(Deep Learning Accelerator)の活用
Jetson Orin Nanoに搭載されているDLAコアを活用することで、さらなる高速化が可能だ。YOLO26などの最新モデルではDLA対応が進んでいる。変換時に --useDLACore=0 オプションを追加することで、DLAコアを使用できる。
—
Jetson Orin Nanoで長時間動かすための注意点
TensorRT推論を長時間連続稼働させると、Jetsonの発熱が問題になる。筆者の環境では連続推論の30分後にサーマルスロットリング(熱によるクロック低下)が発生し、推論速度が落ちた。
冷却ファン Noctua NF-A4x10 5V PWMファン(Amazon) の導入や、NVMe SSD Western Digital SN770 500GB NVMe(Amazon) をストレージとして使う構成にすることで、microSDカードの読み書きによる発熱も抑えられる。本番運用前に必ず熱対策を検討してほしい。
—
まとめ
Jetson Orin NanoでTensorRTを使った高速化の手順をまとめると以下のとおりだ。
TensorRTの導入は最初の設定にやや手間がかかるが、一度動けばその速度向上の恩恵は大きい。本記事の手順を参考に、ぜひ自分のモデルで試してみてほしい。
—
次はこちら
TensorRTで高速化したモデルを実際のアプリケーションに活用するなら、次の記事も参考にしてほしい。

コメント