Jetson Orin Nano TensorRT高速化チュートリアル

Jetson Orin Nano TensorRT高速化チュートリアル

Jetson Orin NanoでAIモデルを動かすなら、TensorRTによる高速化は避けて通れない。本記事では実機を使ってTensorRTの基本から変換・推論の実行まで、初心者でも再現できる手順を丁寧に解説する。

この記事でわかること

  • TensorRTとは何か、なぜJetsonで重要なのか
  • PyTorchモデルをTensorRTエンジンに変換する手順
  • 変換前後の推論速度を実際に比較した結果
  • つまずきやすいポイントと対処法
  • 実用的なPythonコードの書き方
  • 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を使った高速化の手順をまとめると以下のとおりだ。

  • JetPackインストール済みであればTensorRTは追加インストール不要
  • 変換の流れは「PyTorch → ONNX → TensorRTエンジン」の2段階
  • FP16変換でPyTorchの約3〜5倍の速度向上が現実的に得られる
  • エンジンファイルはデバイス固有のため使いまわし不可
  • 長時間稼働には冷却対策が必須
  • DLAコアの活用でさらなる高速化も可能
  • TensorRTの導入は最初の設定にやや手間がかかるが、一度動けばその速度向上の恩恵は大きい。本記事の手順を参考に、ぜひ自分のモデルで試してみてほしい。

    次はこちら

    TensorRTで高速化したモデルを実際のアプリケーションに活用するなら、次の記事も参考にしてほしい。

  • Jetson Orin NanoでYOLOv8をリアルタイム物体検出する方法
  • Jetson Orin Nano 熱対策・冷却方法まとめ
  • Jetson Orin Nano 初期設定 JetPackインストール手順
  • コメント

    タイトルとURLをコピーしました