Ultralytics YOLO27:

GPU-beschleunigte Vorverarbeitung mit NVIDIA DALI#

Beim produktiven Einsatz von Ultralytics YOLO-Modellen wird die Vorverarbeitung häufig zum Engpass. TensorRT kann die Modell-Inferenz zwar in nur wenigen Millisekunden ausführen, doch die CPU-basierte Vorverarbeitung (Skalierung, Auffüllen, Normalisierung) kann pro Bild 2–10 ms dauern, insbesondere bei hohen Auflösungen. NVIDIA DALI (Bibliothek zum Laden von Daten) löst dieses Problem, indem die gesamte Vorverarbeitungspipeline auf die GPU verlagert wird.

Diese Anleitung führt dich durch den Aufbau von DALI-Pipelines, die die Vorverarbeitung von Ultralytics YOLO exakt nachbilden, deren Integration mit model.predict(), die Verarbeitung von Videostreams und die durchgängige Bereitstellung mit dem Triton Inference Server.

Für wen ist diese Anleitung gedacht?

Diese Anleitung richtet sich an Entwickler, die YOLO-Modelle in Produktionsumgebungen einsetzen, in denen die CPU-Vorverarbeitung nachweislich einen Engpass darstellt – typischerweise bei TensorRT-Bereitstellungen auf NVIDIA-GPUs, Videopipelines mit hohem Durchsatz oder Triton Inference Server-Konfigurationen. Wenn du mit model.predict() eine gewöhnliche Inferenz ausführst und keinen Engpass bei der Vorverarbeitung hast, funktioniert die standardmäßige CPU-Pipeline gut.

Kurzfassung
  • Du baust eine DALI-Pipeline? Verwende fn.resize(mode="not_larger") + fn.crop(out_of_bounds_policy="pad") + fn.crop_mirror_normalize, um YOLOs Letterbox-Vorverarbeitung auf der GPU nachzubilden.
  • Du integrierst DALI mit Ultralytics? Übergebe die DALI-Ausgabe als torch.Tensor an model.predict() – Ultralytics überspringt die Bildvorverarbeitung automatisch.
  • Du stellst mit Triton bereit? Verwende das DALI-Backend mit einem TensorRT-Ensemble, um die Vorverarbeitung vollständig ohne CPU auszuführen.

Warum DALI für die YOLO-Vorverarbeitung verwenden?#

In einer typischen YOLO-Inferenzpipeline werden die Vorverarbeitungsschritte auf der CPU ausgeführt:

  1. Dekodieren des Bildes (JPEG/PNG)
  2. Skalieren unter Beibehaltung des Seitenverhältnisses
  3. Auffüllen auf die Zielgröße (Letterbox)
  4. Normalisieren der Pixelwerte von [0, 255] auf [0, 1]
  5. Umwandeln des Layouts von HWC in CHW

Mit DALI laufen all diese Vorgänge auf der GPU, wodurch der CPU-Engpass entfällt. Das ist besonders vorteilhaft, wenn:

SzenarioWarum DALI hilft
Schnelle GPU-InferenzTensorRT-Engines mit Inferenzzeiten unter einer Millisekunde machen die CPU-Vorverarbeitung zum größten Kostenfaktor
Eingaben mit hoher Auflösung1080p- und 4K-Videostreams erfordern aufwendige Skalierungsvorgänge
Große BatchgrößenInferenz auf dem Server, bei der viele Bilder parallel verarbeitet werden
Begrenzte CPU-KerneEdge-Geräte wie NVIDIA Jetson oder GPU-Server mit hoher Dichte und wenigen CPU-Kernen pro GPU

Voraussetzungen#

Nur für Linux

NVIDIA DALI unterstützt nur Linux. Unter Windows oder macOS ist es nicht verfügbar.

Installiere die erforderlichen Pakete:

pip install ultralytics
pip install --extra-index-url https://pypi.nvidia.com nvidia-dali-cuda130

Anforderungen:

  • NVIDIA-GPU (Compute Capability 5.0+ / Maxwell oder neuer)
  • CUDA 11.0+, 12.0+ oder 13.0+
  • Python 3.10–3.14
  • Linux-Betriebssystem

YOLO-Vorverarbeitung verstehen#

Bevor du eine DALI-Pipeline erstellst, solltest du genau verstehen, was Ultralytics bei der Vorverarbeitung macht. Die zentrale Klasse ist LetterBox in ultralytics/data/augment.py:

from ultralytics.data.augment import LetterBox

letterbox = LetterBox(
    new_shape=(640, 640),  # Zielgröße
    center=True,  # Bild zentrieren (auf beiden Seiten gleichmäßig auffüllen)
    stride=32,  # Ausrichtung am Stride
    padding_value=114,  # Graues Padding (114, 114, 114)
)

Die vollständige Vorverarbeitungspipeline in ultralytics/engine/predictor.py führt diese Schritte aus:

SchrittVorgangCPU-FunktionDALI-Entsprechung
1Letterbox-Skalierungcv2.resizefn.resize(mode="not_larger")
2Zentriertes Auffüllencv2.copyMakeBorderfn.crop(out_of_bounds_policy="pad")
3BGR → RGBim[..., ::-1]fn.decoders.image(output_type=types.RGB)
4HWC → CHW + Normalisierung /255np.transpose + tensor / 255fn.crop_mirror_normalize(std=[255,255,255])

Der Letterbox-Vorgang erhält das Seitenverhältnis durch folgende Schritte:

  1. Skalierung berechnen: r = min(target_h / h, target_w / w)
  2. Auf (round(w * r), round(h * r)) skalieren
  3. Den verbleibenden Platz mit Grau auffüllen (114), um die Zielgröße zu erreichen
  4. Das Bild zentrieren, sodass das Padding gleichmäßig auf beide Seiten verteilt wird

DALI-Pipeline für YOLO#

Die empfohlene DALI-Pipeline bildet das standardmäßige Verhalten von Ultralytics LetterBox(center=True) nach, das bei der gewöhnlichen YOLO-Inferenz verwendet wird.

Zentrierte Pipeline (empfohlen, entspricht Ultralytics LetterBox)#

Diese Variante bildet die standardmäßige Vorverarbeitung von Ultralytics mit zentriertem Padding exakt nach und entspricht LetterBox(center=True):

DALI-Pipeline mit zentriertem Padding (empfohlen)
from nvidia import dali
from nvidia.dali import fn, types

@dali.pipeline_def(batch_size=8, num_threads=4, device_id=0)
def yolo_dali_pipeline_centered(image_dir, target_size=640):
    """DALI pipeline replicating YOLO preprocessing with centered padding.

    Matches Ultralytics LetterBox(center=True) behavior exactly.
    """
    # Bilder auf der GPU lesen und dekodieren
    jpegs, _ = fn.readers.file(file_root=image_dir, random_shuffle=False, name="Reader")
    images = fn.decoders.image(jpegs, device="mixed", output_type=types.RGB)

    # Skalierung unter Beibehaltung des Seitenverhältnisses
    resized = fn.resize(
        images,
        resize_x=target_size,
        resize_y=target_size,
        mode="not_larger",
        interp_type=types.INTERP_LINEAR,
        antialias=False,  # Entspricht cv2.INTER_LINEAR (kein Antialiasing)
    )

    # Zentriertes Auffüllen mit fn.crop und out_of_bounds_policy
    # Wenn die Zuschnittgröße größer als die Bildgröße ist, zentriert fn.crop das Bild und füllt es symmetrisch auf
    padded = fn.crop(
        resized,
        crop=(target_size, target_size),
        out_of_bounds_policy="pad",
        fill_values=114,  # YOLO-Paddingwert
    )

    # Normalisieren und Layout umwandeln
    output = fn.crop_mirror_normalize(
        padded,
        dtype=types.FLOAT,
        output_layout="CHW",
        mean=[0.0, 0.0, 0.0],
        std=[255.0, 255.0, 255.0],
    )
    return output
Wann reicht `fn.pad` aus?

Wenn du keine exakte Übereinstimmung mit LetterBox(center=True) benötigst, kannst du den Auffüllschritt vereinfachen und statt fn.crop(..., out_of_bounds_policy="pad") einfach fn.pad(...) verwenden. Diese Variante füllt nur den rechten und unteren Rand auf. Das kann für benutzerdefinierte Bereitstellungspipelines ausreichen, entspricht aber nicht exakt dem standardmäßigen zentrierten Letterbox-Verhalten von Ultralytics.

Warum `fn.crop` für zentriertes Auffüllen verwenden?

Der Operator fn.pad von DALI fügt nur am rechten und unteren Rand Padding hinzu. Um zentriertes Padding zu erhalten, das dem LetterBox(center=True) von Ultralytics entspricht, verwende fn.crop mit out_of_bounds_policy="pad". Mit den Standardwerten crop_pos_x=0.5 und crop_pos_y=0.5 wird das Bild automatisch zentriert und symmetrisch aufgefüllt.

Abweichungen beim Antialiasing

fn.resize von DALI aktiviert standardmäßig Antialiasing (antialias=True), während cv2.resize von OpenCV mit INTER_LINEAR kein Antialiasing anwendet. Setze in DALI immer antialias=False, damit das Ergebnis der CPU-Pipeline entspricht. Wenn du diese Einstellung weglässt, entstehen geringfügige numerische Abweichungen, die sich auf die Modellgenauigkeit auswirken können.

Pipeline ausführen#

DALI-Pipeline erstellen und ausführen
# Build and run the pipeline
pipe = yolo_dali_pipeline_centered(image_dir="/path/to/images", target_size=640)
pipe.build()

# Get a batch of preprocessed images
(output,) = pipe.run()

# Convert to numpy or PyTorch tensors
batch_np = output.as_cpu().as_array()  # Shape: (batch_size, 3, 640, 640)
print(f"Output shape: {batch_np.shape}, dtype: {batch_np.dtype}")
print(f"Value range: [{batch_np.min():.4f}, {batch_np.max():.4f}]")

DALI mit Ultralytics Predict verwenden#

Du kannst einen vorverarbeiteten PyTorch-Tensor direkt an model.predict() übergeben. Wird ein torch.Tensor übergeben, überspringt Ultralytics die Bildvorverarbeitung (Letterbox, BGR→RGB, HWC→CHW und Normalisierung /255) und führt vor der Übergabe an das Modell nur die Geräteübertragung und die Umwandlung des Datentyps aus.

Da Ultralytics in diesem Fall keinen Zugriff auf die Abmessungen des Originalbildes hat, werden die Koordinaten der Erkennungsrahmen im Letterbox-Bereich von 640×640 zurückgegeben. Um sie auf die Koordinaten des Originalbildes abzubilden, verwende scale_boxes. Dabei kommt dieselbe Rundungslogik wie in LetterBox zum Einsatz:

from ultralytics.utils.ops import scale_boxes

# boxes: Tensor der Form (N, 4) im xyxy-Format, Koordinaten im Letterbox-Bereich 640x640
# Rahmen vom Letterbox-Bereich (640, 640) auf das Originalformat (orig_h, orig_w) zurückskalieren
boxes = scale_boxes((640, 640), boxes, (orig_h, orig_w))

Dies gilt für alle externen Vorverarbeitungspfade – direkte Tensor-Eingabe, Videostreams und Triton-Bereitstellung.

DALI + Ultralytics Predict
from nvidia.dali.plugin.pytorch import DALIGenericIterator

from ultralytics import YOLO

# Load model
model = YOLO("yolo26n.pt")

# Create DALI iterator
pipe = yolo_dali_pipeline_centered(image_dir="/path/to/images", target_size=640)
pipe.build()
dali_iter = DALIGenericIterator(pipe, ["images"], reader_name="Reader")

# Run inference with DALI-preprocessed tensors
for batch in dali_iter:
    images = batch[0]["images"]  # Already on GPU, shape (B, 3, 640, 640)
    results = model.predict(images, verbose=False)
    for result in results:
        print(f"Detected {len(result.boxes)} objects")
Kein zusätzlicher Aufwand für die Vorverarbeitung

Wenn du ein torch.Tensor an model.predict() übergibst, dauert die Bildvorverarbeitung etwa ~0.004 ms (praktisch gar nicht), verglichen mit ~1–10 ms bei CPU-basierter Vorverarbeitung. Der Tensor muss das Format BCHW haben, vom Typ float32 (oder float16) und auf [0, 1] normalisiert sein. Ultralytics übernimmt weiterhin automatisch die Geräteübertragung und die Umwandlung des Datentyps.

DALI mit Videostreams#

Für die Echtzeitverarbeitung von Videos kannst du mit fn.external_source Einzelbilder aus beliebigen Quellen einspeisen – etwa von OpenCV, GStreamer oder benutzerdefinierten Erfassungsbibliotheken:

DALI-Pipeline zur Vorverarbeitung von Videostreams
from nvidia import dali
from nvidia.dali import fn, types

@dali.pipeline_def(batch_size=1, num_threads=4, device_id=0)
def yolo_video_pipeline(target_size=640):
    """DALI pipeline for processing video frames from external source."""
    # Externe Quelle zum Einspeisen von Einzelbildern aus OpenCV, GStreamer usw.
    frames = fn.external_source(device="cpu", name="input")
    frames = fn.reshape(frames, layout="HWC")

    # Auf die GPU übertragen und vorverarbeiten
    frames_gpu = frames.gpu()
    resized = fn.resize(
        frames_gpu,
        resize_x=target_size,
        resize_y=target_size,
        mode="not_larger",
        interp_type=types.INTERP_LINEAR,
        antialias=False,
    )
    padded = fn.crop(
        resized,
        crop=(target_size, target_size),
        out_of_bounds_policy="pad",
        fill_values=114,
    )
    output = fn.crop_mirror_normalize(
        padded,
        dtype=types.FLOAT,
        output_layout="CHW",
        mean=[0.0, 0.0, 0.0],
        std=[255.0, 255.0, 255.0],
    )
    return output

Triton Inference Server mit DALI#

Kombiniere für den produktiven Einsatz die DALI-Vorverarbeitung mit der TensorRT-Inferenz im Triton Inference Server mithilfe eines Ensemble-Modells. Dadurch entfällt die CPU-Vorverarbeitung vollständig: Rohe JPEG-Bytes werden eingespeist, Erkennungen ausgegeben und alles auf der GPU verarbeitet.

Struktur des Modell-Repositorys#

model_repository/
├── dali_preprocessing/
│   ├── 1/
│   │   └── model.dali
│   └── config.pbtxt
├── yolo_trt/
│   ├── 1/
│   │   └── model.plan
│   └── config.pbtxt
└── ensemble_dali_yolo/
    ├── 1/                  # Empty directory (required by Triton)
    └── config.pbtxt

Schritt 1: DALI-Pipeline erstellen#

Serialisiere die DALI-Pipeline für das Triton-DALI-Backend:

DALI-Pipeline für Triton serialisieren
from nvidia import dali
from nvidia.dali import fn, types

@dali.pipeline_def(batch_size=8, num_threads=4, device_id=0)
def triton_dali_pipeline():
    """DALI preprocessing pipeline for Triton deployment."""
    # Eingabe: rohe, codierte Bild-Bytes von Triton
    images = fn.external_source(device="cpu", name="DALI_INPUT_0")
    images = fn.decoders.image(images, device="mixed", output_type=types.RGB)

    resized = fn.resize(
        images,
        resize_x=640,
        resize_y=640,
        mode="not_larger",
        interp_type=types.INTERP_LINEAR,
        antialias=False,
    )
    padded = fn.crop(
        resized,
        crop=(640, 640),
        out_of_bounds_policy="pad",
        fill_values=114,
    )
    output = fn.crop_mirror_normalize(
        padded,
        dtype=types.FLOAT,
        output_layout="CHW",
        mean=[0.0, 0.0, 0.0],
        std=[255.0, 255.0, 255.0],
    )
    return output

# Pipeline ins Modell-Repository serialisieren
pipe = triton_dali_pipeline()
pipe.serialize(filename="model_repository/dali_preprocessing/1/model.dali")

Schritt 2: YOLO nach TensorRT exportieren#

YOLO-Modell als TensorRT-Engine exportieren
from pathlib import Path

from ultralytics import YOLO

model = YOLO("yolo26n.pt")
engine_path = model.export(
    format="engine", imgsz=640, quantize=16, batch=8, dynamic=True, nms=False
)  # Ohne NMS (N, 300, 6); TensorRT >= 8.5

# Ultralytics fügt .engine-Dateien einen Metadaten-Header hinzu. Entferne ihn, damit Triton den unverarbeiteten TensorRT-Plan laden kann
with open(engine_path, "rb") as f:
    meta_len = int.from_bytes(f.read(4), byteorder="little")  # Länge des JSON-Metadaten-Headers
    f.seek(4 + meta_len)
    plan = f.read()
Path("model_repository/yolo_trt/1").mkdir(parents=True, exist_ok=True)
Path("model_repository/yolo_trt/1/model.plan").write_bytes(plan)

Schritt 3: Triton konfigurieren#

dali_preprocessing/config.pbtxt:

name: "dali_preprocessing"
backend: "dali"
max_batch_size: 8
input [
  {
    name: "DALI_INPUT_0"
    data_type: TYPE_UINT8
    dims: [ -1 ]
  }
]
output [
  {
    name: "DALI_OUTPUT_0"
    data_type: TYPE_FP32
    dims: [ 3, 640, 640 ]
  }
]

yolo_trt/config.pbtxt:

name: "yolo_trt"
platform: "tensorrt_plan"
max_batch_size: 8
input [
  {
    name: "images"
    data_type: TYPE_FP32
    dims: [ 3, 640, 640 ]
  }
]
output [
  {
    name: "output0"
    data_type: TYPE_FP32
    dims: [ 300, 6 ]
  }
]

ensemble_dali_yolo/config.pbtxt:

name: "ensemble_dali_yolo"
platform: "ensemble"
max_batch_size: 8
input [
  {
    name: "INPUT"
    data_type: TYPE_UINT8
    dims: [ -1 ]
  }
]
output [
  {
    name: "OUTPUT"
    data_type: TYPE_FP32
    dims: [ 300, 6 ]
  }
]
ensemble_scheduling {
  step [
    {
      model_name: "dali_preprocessing"
      model_version: -1
      input_map {
        key: "DALI_INPUT_0"
        value: "INPUT"
      }
      output_map {
        key: "DALI_OUTPUT_0"
        value: "preprocessed_image"
      }
    },
    {
      model_name: "yolo_trt"
      model_version: -1
      input_map {
        key: "images"
        value: "preprocessed_image"
      }
      output_map {
        key: "output0"
        value: "OUTPUT"
      }
    }
  ]
}
So funktioniert die Zuordnung im Ensemble

Das Ensemble verbindet Modelle mithilfe von virtuellen Tensor-Namen. Der Wert "preprocessed_image" von output_map im DALI-Schritt entspricht dem Wert "preprocessed_image" von input_map im TensorRT-Schritt. Das sind beliebige Namen, die die Ausgabe eines Schritts mit der Eingabe des nächsten Schritts verknüpfen – sie müssen nicht mit den internen Tensor-Namen eines Modells übereinstimmen.

Schritt 4: Inferenzanfragen senden#

Warum `tritonclient` statt `YOLO('http://...')`?

Ultralytics bietet eine integrierte Triton-Unterstützung, die die Vor- und Nachverarbeitung automatisch übernimmt. Sie funktioniert jedoch nicht mit dem DALI-Ensemble, da YOLO() einen vorverarbeiteten float32-Tensor sendet, während das Ensemble rohe JPEG-Bytes erwartet. Verwende für DALI-Ensembles direkt tritonclient und für Standardbereitstellungen ohne DALI die integrierte Integration.

Bilder an das Triton-Ensemble senden
import numpy as np
import tritonclient.http as httpclient

client = httpclient.InferenceServerClient(url="localhost:8000")

# Load image as raw bytes (JPEG/PNG encoded)
image_data = np.fromfile("image.jpg", dtype="uint8")
image_data = np.expand_dims(image_data, axis=0)  # Add batch dimension

# Create input
input_tensor = httpclient.InferInput("INPUT", image_data.shape, "UINT8")
input_tensor.set_data_from_numpy(image_data)

# Run inference through the ensemble
result = client.infer(model_name="ensemble_dali_yolo", inputs=[input_tensor])
detections = result.as_numpy("OUTPUT")  # Shape: (1, 300, 6) -> [x1, y1, x2, y2, conf, class_id]

# Filter by confidence (no NMS needed for the nms=False export)
detections = detections[0]  # First image
detections = detections[detections[:, 4] > 0.25]  # Confidence threshold
print(f"Detected {len(detections)} objects")
JPEG-Bilder stapelweise verarbeiten

Wenn du einen Stapel von JPEG-Bildern an Triton sendest, fülle alle codierten Byte-Arrays auf dieselbe Länge auf (die maximale Byte-Anzahl im Stapel). Triton benötigt für den Eingabetensor einheitliche Stapelformen.

Unterstützte Aufgaben#

Die DALI-Vorverarbeitung funktioniert mit allen YOLO-Aufgaben, die die standardmäßige LetterBox-Pipeline verwenden:

AufgabeUnterstütztHinweise
Detektion✅Standardmäßige Letterbox-Vorverarbeitung
Instanzsegmentierung✅Dieselbe Vorverarbeitung wie bei der Erkennung
Semantische Segmentierung✅Dieselbe Bildvorverarbeitung wie bei der Erkennung
Tiefenschätzung✅Dieselbe Bildvorverarbeitung wie bei der Erkennung
Klassifizierung❌Verwendet torchvision-Transformationen (zentriertes Zuschneiden) statt Letterbox
Pose-Schätzung✅Dieselbe Vorverarbeitung wie bei der Erkennung
Erkennung orientierter Objekte (OBB)✅Dieselbe Vorverarbeitung wie bei der Erkennung

Einschränkungen#

  • Nur Linux: DALI unterstützt weder Windows noch macOS
  • NVIDIA-GPU erforderlich: Keine Ausweichlösung nur mit CPU
  • Statische Pipeline: Die Pipeline-Struktur wird beim Erstellen festgelegt und kann nicht dynamisch geändert werden
  • fn.pad fügt Padding nur rechts und unten hinzu: Verwende fn.crop mit out_of_bounds_policy="pad" für zentriertes Padding
  • Kein Rect-Modus: DALI-Pipelines erzeugen Ausgaben mit fester Größe (z. B. 640×640). Der auto=True-Rect-Modus, der Ausgaben variabler Größe (z. B. 384×640) erzeugt, wird nicht unterstützt. Beachte: Zwar unterstützt TensorRT dynamische Eingabeformen, aber eine DALI-Pipeline mit fester Größe lässt sich für maximalen Durchsatz am besten mit einer Engine mit fester Größe kombinieren.
  • Speicherverbrauch bei mehreren Instanzen: Die Verwendung von instance_group mit count > 1 in Triton kann zu einem hohen Speicherverbrauch führen. Verwende für das DALI-Modell die standardmäßige Instanzgruppe.

Häufig gestellte Fragen#

  • Der Vorteil hängt von deiner Pipeline ab. Wenn die GPU-Inferenz mit TensorRT bereits schnell ist, können 2–10 ms CPU-Vorverarbeitung zum größten Kostenfaktor werden. DALI beseitigt diesen Engpass, indem die Vorverarbeitung auf der GPU ausgeführt wird. Die größten Verbesserungen zeigen sich bei Eingaben mit hoher Auflösung (1080p, 4K), großen Batch-Größen und Systemen mit wenigen CPU-Kernen pro GPU.

  • Ja. Verwende DALIGenericIterator, um vorverarbeitete Ausgaben vom Typ torch.Tensor zu erhalten, und übergib sie anschließend an model.predict(). Der Leistungsvorteil ist jedoch bei TensorRT-Modellen am größten, bei denen die Inferenz bereits sehr schnell ist und die CPU-Vorverarbeitung zum Engpass wird.

  • fn.pad fügt nur an den rechten und unteren Rändern Padding hinzu. fn.crop mit out_of_bounds_policy="pad" zentriert das Bild und fügt auf allen Seiten symmetrisch Padding hinzu, entsprechend dem Verhalten von Ultralytics LetterBox(center=True).

  • Nahezu identisch. Setze antialias=False in fn.resize, damit es mit cv2.INTER_LINEAR von OpenCV übereinstimmt. Aufgrund der Berechnungen auf der GPU und CPU kann es zu geringfügigen Gleitkommaabweichungen (< 0.001) kommen, die sich jedoch nicht messbar auf die Genauigkeit der Erkennung auswirken.

  • CV-CUDA ist eine weitere NVIDIA-Bibliothek für GPU-beschleunigte Bildverarbeitung. Sie bietet eine Steuerung auf Ebene einzelner Operatoren (wie OpenCV, aber auf der GPU) statt des Pipeline-Ansatzes von DALI. cvcuda.copymakeborder() von CV-CUDA unterstützt explizites Padding pro Seite und erleichtert so zentriertes Letterbox. Wähle DALI für pipelinebasierte Workflows (insbesondere mit Triton) und CV-CUDA für eine fein abgestufte Steuerung einzelner Operatoren in benutzerdefiniertem Inferenzcode.

Kommentare