TensorRT
TensorRT kompiluje graf do silnika dostrojonego pod jedno GPU. LibreYOLO najpierw eksportuje pośredni plik ONNX, parsuje go parserem ONNX z TensorRT, buduje silnik i zapisuje obok metadane modelu w pliku sidecar JSON.
- Flaga
export(format="tensorrt")- Zapisuje
- Jeden plik .engine oraz plik sidecar .engine.json z metadanymi
- Dodatkowo
pip install "libreyolo[onnx,tensorrt]"- Wczytywanie z powrotem
LibreYOLO("weights/LibreYOLO9t.engine")- Kształty
- Domyślnie stałe; dynamic=True dodaje profil optymalizacji dla osi batcha
- Precyzja
- FP32, FP16 (half=True), INT8 (int8=True z data=)
- Wymagania
- GPU NVIDIA podczas budowania i podczas uruchamiania. Silniki nie przenoszą się między architekturami GPU.
Instalacja
Zarówno budowanie, jak i uruchamianie wymagają GPU NVIDIA z działającym stosem CUDA. Ten format nie ma awaryjnej ścieżki na CPU.
# Silnik jest budowany z pośredniego pliku ONNX, więc potrzebne są oba dodatki.pip install "libreyolo[onnx,tensorrt]"python -c "import tensorrt, torch; print(tensorrt.__version__, torch.cuda.is_available())"Dodatek tensorrt przypina tensorrt-cu12 i pycuda, a marker pomija oba na
macOS. Na urządzeniu Jetson nie należy używać tego dodatku: przypina on build dla
CUDA 12 na platformie z CUDA 13. Zamiast tego należy użyć TensorRT instalowanego
przez JetPack, jak opisano na stronie NVIDIA Jetson.
Eksport
from libreyolo import LibreYOLO model = LibreYOLO("LibreYOLO9t.pt") # Zapisuje weights/LibreYOLO9t_fp16.engine i weights/LibreYOLO9t_fp16.engine.jsonpath = model.export(format="tensorrt", half=True)print(path)libreyolo export --model LibreYOLO9t.pt --format tensorrt --halfmodel.export( format="tensorrt", imgsz=640, batch=1, half=False, int8=False, data=None, # wymagane, gdy int8=True dynamic=False, workspace=4.0, # pamięć robocza budowania w GiB min_batch=1, # granice profilu dynamicznego opt_batch=1, max_batch=8, hardware_compatibility="none", # albo "ampere_plus" gpu_device=0, # urządzenie budowania na hoście z wieloma GPU verbose=False,)Eksport przebiega w dwóch krokach. Pierwszy zapisuje pośredni plik ONNX w ścieżce
tymczasowej, drugi parsuje go i buduje silnik, a plik pośredni jest potem
usuwany. workspace to pamięć robocza używana podczas budowania, podana w GiB;
większa wartość pozwala builderowi wypróbować więcej kerneli i nie wpływa na
pamięć podczas inferencji.
Plik sidecar z metadanymi jest zapisywany obok silnika jako <engine>.json i
odnotowuje precyzję, którą build faktycznie zrealizował. Gdy GPU nie ma szybkiego
FP16 ani szybkiego INT8, builder ostrzega i schodzi niżej, a plik sidecar podaje
precyzję, która wyszła, a nie tę, o którą poproszono.
Przy FP16 backbone ViT w grafie jest wykrywany, a jego warstwy
zmiennoprzecinkowe zostają przypięte do FP32. Bloki backbone w stylu DINOv2
przepełniają się w FP16 i dają NaN, więc build ustawia
OBEY_PRECISION_CONSTRAINTS i raportuje FP16 (FP32 ViT backbone). Dla bloków
backbone typu CNN ten krok nic nie zmienia.
Dynamiczny batch
from libreyolo import LibreYOLO # Pośredni plik ONNX musi mieć dynamiczną oś batcha, aby profil# miał się do czego przypiąć.LibreYOLO("LibreYOLO9t.pt").export( format="tensorrt", dynamic=True, min_batch=1, opt_batch=4, max_batch=8, half=True,)dynamic=True dodaje jeden profil optymalizacji obejmujący zakres od
min_batch do max_batch, zoptymalizowany dla opt_batch, i zapisuje te trzy
wartości w pliku sidecar. Profil jest dodawany tylko wtedy, gdy pośredni plik
ONNX rzeczywiście ma dynamiczny wymiar batcha; w przeciwnym razie build zapisuje
w logu, że używa optymalizacji statycznej, i kontynuuje.
INT8
from libreyolo import LibreYOLO LibreYOLO("LibreYOLO9t.pt").export( format="tensorrt", int8=True, data="coco128.yaml", # wymagane: ten format nie ma wartości domyślnej fraction=1.0,)INT8 korzysta z kalibratora entropijnego z TensorRT nałożonego na loader
kalibracyjny LibreYOLO, a data jest obowiązkowe: ten format nie ma awaryjnej
ścieżki z ośmioma obrazami. Kalibracja wymaga cuda-python lub pycuda do
bufora na urządzeniu. Kluczem pamięci podręcznej kalibracji jest hash bajtów
ONNX, więc skale z jednego modelu nigdy nie są ponownie używane dla innego,
który akurat zapisuje do tej samej ścieżki wyjściowej.
half=True i int8=True naraz powodują ostrzeżenie i build w INT8, który
zachowuje awaryjną ścieżkę FP16 dla warstw, których TensorRT nie potrafi
skwantyzować.
Uruchamianie artefaktu
from libreyolo import LibreYOLO, SAMPLE_IMAGE model = LibreYOLO("weights/LibreYOLO9t_fp16.engine")result = model.predict(SAMPLE_IMAGE)print(result.boxes.xyxy[:3])import json import tensorrt as trt path = "weights/LibreYOLO9t_fp16.engine"runtime = trt.Runtime(trt.Logger(trt.Logger.WARNING))with open(path, "rb") as handle: engine = runtime.deserialize_cuda_engine(handle.read()) for i in range(engine.num_io_tensors): name = engine.get_tensor_name(i) print(engine.get_tensor_mode(name), name, engine.get_tensor_shape(name)) # Nazwy klas, zadanie i rozmiar wejścia są w pliku sidecar, nie w silniku.# Alokacja buforów, wstępne i końcowe przetwarzanie są tu po stronie użytkownika.print(json.load(open(path + ".json"))["names"])LibreYOLO() rozpoznaje sufiks .engine, odczytuje z pliku sidecar nazwy klas,
zadanie i schemat pozy oraz zwraca ten sam obiekt Results co checkpoint. Gdy
nie ma urządzenia z CUDA, zgłasza błąd natychmiast.
Drugi fragment kodu to ścieżka samego środowiska uruchomieniowego. Alokacja buforów po stronie hosta i urządzenia, wstępne przetwarzanie, dekodowanie, NMS i przeskalowanie współrzędnych są tam po stronie użytkownika, a sam silnik nie zawiera nazw klas, więc plik sidecar musi mu towarzyszyć.
Ograniczenia
Zserializowany silnik jest związany z architekturą GPU, stosem sterowników i
wersją TensorRT, która go zbudowała. Silnik zbudowany na stacji roboczej nie
wczyta się na innej architekturze i dlatego krok budowania uruchamia się na
maszynie docelowej. hardware_compatibility="ampere_plus" oddaje część
wydajności w zamian za przenośność w obrębie Ampere i nowszych. Wartość
"same_compute_capability" mapuje się na NONE i powoduje ostrzeżenie: silnik
jest zoptymalizowany wyłącznie pod bieżące GPU, a eksport mówi to wprost, zamiast
deklarować przenośność, której nie zastosował.
Profilowana jest wyłącznie oś batcha. Build z dynamicznymi wymiarami przestrzennymi nie należy do tego kontraktu i dlatego FCOS jest zablokowany: potrzebuje dynamicznej, dopełnionej wysokości i szerokości, aby zachować swoje przekształcenie proporcji 800 na 1333.
Zablokowane przed trasowaniem: segmentacja w YOLO9, segmentacja w RTMDet-Ins,
detekcja w SSD, Faster R-CNN i RetinaNet oraz matting w BiRefNet lub FeyNobg,
gdzie TensorRT 10.16 dochodzi do wspólnego węzła ONNX DeformConv i nie potrafi
go sparsować, ponieważ ModulatedDeformConv2d nie ma w rejestrze pluginów.
Gdy kombinacja nie jest ani zwalidowana, ani zablokowana, ścieżka konwertera jest dostępna, a projekt nie odnotował dla niej zgodności środowiska uruchomieniowego TensorRT. To stwierdzenie o dowodach, a nie o tym, czy build się powiedzie.
Pełną siatkę rodzin i zadań zawiera macierz eksportu. Dla jednej kombinacji:
libreyolo formats --family yolo9 --task detect