Ultralytics YOLO27: ウェイトリストに登録する。
Get Started
本番環境でのUltralytics YOLO·最適化·レッスン 3/9
レッスン中級

TensorRTで最適化する

FP16のTensorRTエンジンをビルドし、INT8が精度低下に見合うかを判断して、リリース前にエンジンをゲート審査します。

NVIDIA GPUでは、TensorRT FP16エンジンは通常、最も手軽に得られる高速化です。UltralyticsのA100ベンチマークでは、mAPを変えずに約1.5倍高速化しました。INT8ではさらに高速化できますが、学習後にINT8へ変換すると、COCOでYOLO26sからYOLO26mのmAPが4~6ポイント低下しました。このレッスンでは、どのステップを選択しているのかを把握し、ユーザーが気づく前に計測する方法を学びます。

成果

FP16のTensorRTエンジンをビルドし、INT8が見合うかどうかを書面で定めたゲート基準に基づいて判断し、mAPとp95レイテンシを基準に各エンジンを採用または却下します。

短期集中コース
すでに使い方をご存じの方は、こちらをご覧ください。
  1. まずFP16を使用します。実行するGPU上でyolo export model=best.pt format=engine quantize=16を実行してください。

  2. FP16で予算を満たせない場合のみINT8を使用します。500枚以上の本番環境に近い画像を含むquantize=8 data=your.yamlを追加してください。

  3. すべてのエンジンを審査します。mAP50-95が0.5ポイント以内(FP16)、または設定したINT8の予算内であり、p95レイテンシが予算を下回ることを確認します。

  4. INT8の精度低下が大きすぎますか?量子化認識トレーニング(QAT)(train quantize=8)で、その大部分を回復できます。

実践的

NVIDIA GPUが必要です

このレッスンのコードを実行するには、TensorRTをインストールしたNVIDIA GPUが必要です。ここで示す引数はすべて、エクスポートモードのドキュメントでformat=engine向けに説明されています。

FP16は安全な第一歩です#

Volta以降のNVIDIA GPUにはFP16 Tensor Coreが搭載されており、検出モデルの推論でFP32が必要になることはほとんどありません。まずは次の手順を実行してください。

from ultralytics import YOLO

model = YOLO("yolo26n.pt")  # or runs/detect/pills_v1/weights/best.pt
model.export(format="engine", quantize=16, workspace=4)  # FP16エンジン、ビルダーワークスペースは最大4 GiB

workspaceは、ビルド中にTensorRTが使用できるGPUメモリの上限を設定します。TensorRTに任せる場合は設定しないでください。TensorRT統合のページでは、次のA100の結果を公開しています(YOLOv8n、640 px)。

適合率推論、バッチサイズ8(ms)COCO val mAP50-95
FP320.520.37
FP160.340.37
INT80.280.33

モデルはYOLO26より古いものですが、トレードオフの傾向は同じです。FP16は追加コストなしで約1.5倍高速化し、INT8ではさらに1.2倍高速化する代わりに4ポイント低下しました。FP16で予算を満たせるなら、そのままリリースしてください。

ローカルにNVIDIA GPUがありませんか?Ultralytics PlatformのExportタブでは、選択したクラウドGPU上でエンジンをビルドできます。画像サイズ、精度、バッチサイズ、動的形状、NMS、ワークスペースの各オプションは同じです。

TorchScript、ONNX、OpenVINO、TensorRT、CoreMLを一覧表示するUltralytics PlatformのモデルExportタブ。RTX 5090上でimgsz 640、FP16を指定してエクスポート済みのTensorRTエンジンが1つ表示されています

デプロイ先のGPUファミリーを選択してください。画像のエンジンはRTX 5090上でビルドされており、そのファミリーのGPUでのみ実行できます。

INT8にはキャリブレーションデータが必要です#

INT8量子化では、各レイヤーの活性化値を256段階にマッピングします。その範囲を決めるため、エクスポーターはキャリブレーション画像をモデルに入力し、観測した活性化値を記録します。そのため、画像は本番環境のデータに似ている必要があります。

from ultralytics import YOLO

model = YOLO("yolo26n.pt")
model.export(
    format="engine",
    quantize=8,
    data="coco128.yaml",  # キャリブレーション画像はこのデータセットのvalスプリットから取得します。my_dataset/data.yamlを使用してください
    fraction=1.0,  # 使用する画像の割合(または枚数)
    batch=8,  # キャリブレーションバッチを大きくすると、範囲がより安定します
    dynamic=True,  # batch=8の場合、エンジンは1~8のバッチを受け付けます
    workspace=4,
)

INT8による精度低下はモデルによって異なります。Exportモードのドキュメントでは、COCO valでのYOLO26 TensorRTエンジンの測定結果(mAP50-95)を公開しています。

モデルFP32エンジンキャリブレーション済みINT8(PTQ)量子化認識トレーニング(QAT)後のINT8
YOLO26n0.40320.39340.3935
YOLO26s0.47940.44120.4711
YOLO26m0.52690.46960.5137

キャリブレーションのみでもYOLO26nでは1ポイント、大きいモデルでは4~6ポイント低下します。QATではquantize=8をtrainで使用してモデルをファインチューニングし、重みがINT8に耐えられるようにします。チェックポイントには独自の範囲が含まれるため、INT8エクスポートにキャリブレーションデータは不要で、FP32からの低下を1~2ポイント以内に抑えられます。判断基準は次のとおりです。

リリース前にエンジンをゲート審査する#

すべてのエンジンについて、デプロイ先のGPU上で同じチェックを行います。

チェック項目審査項目
検証用データセットのmAP50-95FP16ではFP32から0.5ポイント以内、INT8では書面で定めた予算内
クラスごとのAPどのクラスも約1ポイントを超えて低下しないこと(小規模クラスで変動が最も大きくなります)
p95レイテンシ本番環境のバッチサイズで予算を下回ること
運用時の閾値エンジン独自のF1カーブからconfを再選定します
決定性同じ画像を2回処理したとき、まったく同じBBoxが得られること
yolo val model=yolo26n.engine data=coco8.yaml  # or my_dataset/data.yaml
yolo benchmark model=yolo26n.pt data=coco8.yaml imgsz=640 format=engine quantize=16

高速化の仕組み#

TensorRTのレイヤーフュージョン:最適化前のネットワークにある個別の畳み込み、バイアス、ReLUレイヤーが、TensorRTで最適化されたネットワークでは単一の融合CBRレイヤーになります

TensorRTは畳み込み、バイアス、ReLUを1つのカーネルに融合し(右側の「CBR」ブロック)、結合処理を省略します。そのため、GPUが起動するカーネル数が大幅に減り、データ移動も少なくなります。YOLO26では、ネットワーク全体にあるconv-BN-activationチェーン、バックボーンのattention(PSA)ブロック、検出ヘッドにある多数の小さな演算で効果が得られます。エンジンがまだ遅い場合は、trtexecまたはNVIDIA Nsightでプロファイリングしてください。多くの場合、1つのレイヤーが処理時間の30%以上を占めています。

よくある落とし穴#

誤ったデータでキャリブレーションする

症状: INT8ではCOCOのスコアが1ポイント低下しますが、カメラのデータでは6ポイント低下します。 対処: 自分の検証セットから取り分けたデータでキャリブレーションします。NVIDIAは代表性のある画像を少なくとも500枚使用することを推奨しています。キャリブレーション結果はデバイスによっても異なるため、デプロイ先のGPUでキャリブレーションしてください。

FP32の確信度しきい値をそのまま使う

症状: 同じconfを使用していても、INT8に切り替えると再現率が低下します。 対処: INT8では確信度の値が変わることがあります。INT8エンジン独自のF1曲線からconfを選び直してください。

別のGPUでビルドされたエンジン

症状: デプロイ先のマシンでエンジンのデシリアライズに失敗するか、予想より遅くなります。 対処: デプロイ先と同じGPUファミリーで、TensorRTとCUDAランタイムのバージョンを一致させてビルドし、デバイスで再ビルドできるように.onnxを同梱します。ビルド中にキャリブレーションがクラッシュする場合は、workspaceを増やすか、imgszまたはbatchを減らします。

Jetsonでは、DeepStreamがハードウェアアクセラレーション対応のビデオパイプラインで生成されたエンジンを実行します。データセンターでは、Triton Inference Serverがエンジンを提供します。

試してみる

NVIDIA GPU(ローカルまたはPlatformのExportタブ)で、モデルのFP16エンジンをビルドしてください。データセットYAMLを指定し、エンジンと.ptに対してyolo valを実行します。デプロイ先のGPUでエンジンをベンチマークし、1ページのゲートレポートを作成してください。レポートには、両方のmAP50-95、その差、予算に対するp95レイテンシ、判断(FP16をリリース、INT8を試す、またはモデルサイズを変更)を記載します。

完了条件
以下のすべてを満たすと、レッスンは完了です。
  • FP16エンジンが存在し、実行予定のGPUファミリー上でビルドされています。

  • ゲートレポートに、エンジンとPyTorchのmAP50-95およびp95レイテンシが並べて示されています。

  • 判断がゲート表に基づいており、審査に不合格だった場合に次に試す内容が示されています。

解答を表示
from ultralytics import YOLO

if __name__ == "__main__":  # validation starts worker processes on Windows
    data = "coco8.yaml"  # or my_dataset/data.yaml
    model = YOLO("yolo26n.pt")
    engine = model.export(format="engine", quantize=16, workspace=4)

    base = model.val(data=data, plots=False).box.map
    fp16 = YOLO(engine).val(data=data, plots=False).box.map
    print(f"PyTorch {base:.4f}  FP16 engine {fp16:.4f}  gap {abs(base - fp16) * 100:.2f} points")

    # Only if FP16 misses the latency budget:
    # model.export(format="engine", quantize=8, data=data, batch=8, dynamic=True, workspace=4)

合格レポートは、差が0.5ポイント未満、p95が予算内、判断がFP16をリリースとなります。p95が基準を満たさない場合は、独自のキャリブレーションYAMLを使ってINT8をエクスポートし、同じ2つのコマンドを再実行してください。INT8をリリースするのは、開始前に設定した予算内に差が収まる場合のみです。それ以外の場合はQATまたは小さいモデルを試してください。

次のステップ

NVIDIA以外をお使いですか?次はIntelのCPU向けの代替技術であるOpenVINOと、ターゲット上で計測する必要がある理由です。