Meet YOLO26: next-gen vision AI.

Link to this sectionالمعالجة الأولية المسرعة بواسطة GPU باستخدام NVIDIA DALI#

Link to this sectionمقدمة#

عند نشر نماذج Ultralytics YOLO في بيئات الإنتاج، غالباً ما تصبح المعالجة الأولية هي عنق الزجاجة. بينما يمكن لـ TensorRT تشغيل الاستدلال للنموذج في بضعة أجزاء من الألف من الثانية، فإن المعالجة الأولية المستندة إلى CPU (تغيير الحجم، الحشو، التطبيع) يمكن أن تستغرق 2-10 مللي ثانية لكل صورة، خاصة عند الدقات العالية. تحل NVIDIA DALI (مكتبة تحميل البيانات) هذه المشكلة عن طريق نقل خط معالجة البيانات بالكامل إلى الـ GPU.

يرشدك هذا الدليل خلال بناء خطوط معالجة DALI التي تكرر بدقة المعالجة الأولية لـ Ultralytics YOLO، ودمجها مع model.predict()، ومعالجة تدفقات الفيديو، والنشر الشامل باستخدام Triton Inference Server.

لمن هذا الدليل؟

هذا الدليل مخصص للمهندسين الذين ينشرون نماذج YOLO في بيئات الإنتاج حيث تُعد معالجة CPU الأولية عنق زجاجة ملموساً — عادة في عمليات نشر TensorRT على NVIDIA GPUs، أو خطوط معالجة الفيديو ذات الإنتاجية العالية، أو إعدادات Triton Inference Server. إذا كنت تقوم بتشغيل استدلال قياسي باستخدام model.predict() ولا تواجه عنق زجاجة في المعالجة الأولية، فإن خط معالجة CPU الافتراضي يعمل بشكل جيد.

ملخص سريع
  • هل تبني خط معالجة DALI؟ استخدم fn.resize(mode="not_larger") + fn.crop(out_of_bounds_policy="pad") + fn.crop_mirror_normalize لتكرار معالجة YOLO التي تعتمد على letterbox على GPU.
  • هل تدمجها مع Ultralytics؟ مرر مخرجات DALI كـ torch.Tensor إلى model.predict() — سيتخطى Ultralytics المعالجة الأولية للصورة تلقائياً.
  • هل تنشر باستخدام Triton؟ استخدم الواجهة الخلفية لـ DALI مع مجموعة TensorRT لتحقيق معالجة أولية بدون CPU.

Link to this sectionلماذا تستخدم DALI لمعالجة YOLO الأولية؟#

في خط استدلال YOLO النموذجي، يتم تشغيل خطوات المعالجة الأولية على CPU:

  1. فك تشفير الصورة (JPEG/PNG)
  2. تغيير الحجم مع الحفاظ على نسبة العرض إلى الارتفاع
  3. الحشو إلى الحجم المستهدف (letterbox)
  4. تطبيع قيم البكسل من [0, 255] إلى [0, 1]
  5. تحويل التنسيق من HWC إلى CHW

مع DALI، تعمل كل هذه العمليات على GPU، مما يلغي عنق زجاجة الـ CPU. هذا قيم بشكل خاص عندما:

السيناريولماذا يساعد DALI
استدلال GPU سريعمحركات TensorRT ذات استدلال أقل من مللي ثانية تجعل معالجة CPU الأولية هي التكلفة المهيمنة
مدخلات عالية الدقةتتطلب تدفقات الفيديو 1080p و 4K عمليات تغيير حجم مكلفة
أحجام دفعات كبيرةمعالجة الاستدلال من جانب الخادم للعديد من الصور بالتوازي
أنوية CPU محدودةأجهزة الحافة مثل NVIDIA Jetson، أو خوادم GPU الكثيفة التي تحتوي على عدد قليل من أنوية CPU لكل GPU

Link to this sectionالمتطلبات الأساسية#

Linux فقط

يدعم NVIDIA DALI نظام Linux فقط. إنه غير متاح على Windows أو macOS.

قم بتثبيت الحزم المطلوبة:

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

المتطلبات:

  • NVIDIA GPU (قدرة حوسبة 5.0+ / Maxwell أو أحدث)
  • CUDA 11.0+, 12.0+ أو 13.0+
  • Python 3.10-3.14
  • نظام تشغيل Linux

Link to this sectionفهم معالجة YOLO الأولية#

قبل بناء خط معالجة DALI، من المفيد فهم ما يفعله Ultralytics بالضبط أثناء المعالجة الأولية. الفئة الرئيسية هي LetterBox في ultralytics/data/augment.py:

from ultralytics.data.augment import LetterBox

letterbox = LetterBox(
    new_shape=(640, 640),  # Target size
    center=True,  # Center the image (pad equally on both sides)
    stride=32,  # Stride alignment
    padding_value=114,  # Gray padding (114, 114, 114)
)

ينفذ خط المعالجة الأولية الكامل في ultralytics/engine/predictor.py هذه الخطوات:

الخطوةالعمليةوظيفة CPUبديل DALI
1تغيير حجم Letterboxcv2.resizefn.resize(mode="not_larger")
2حشو متمركزcv2.copyMakeBorderfn.crop(out_of_bounds_policy="pad")
3BGR → RGBim[..., ::-1]fn.decoders.image(output_type=types.RGB)
4HWC → CHW + تطبيع /255np.transpose + tensor / 255fn.crop_mirror_normalize(std=[255,255,255])

تحافظ عملية letterbox على نسبة العرض إلى الارتفاع عن طريق:

  1. حساب المقياس: r = min(target_h / h, target_w / w)
  2. تغيير الحجم إلى (round(w * r), round(h * r))
  3. حشو المساحة المتبقية باللون الرمادي (114) للوصول إلى الحجم المستهدف
  4. توسيط الصورة بحيث يتم توزيع الحشو بالتساوي على كلا الجانبين

Link to this sectionخط معالجة DALI لـ YOLO#

استخدم الخط المتمركز أدناه كمرجع افتراضي. إنه يطابق سلوك LetterBox(center=True) في Ultralytics، وهو ما يستخدمه استدلال YOLO القياسي.

Link to this sectionالخط المتمركز (موصى به، يطابق Ultralytics LetterBox)#

هذا الإصدار يكرر بدقة المعالجة الأولية الافتراضية لـ Ultralytics مع حشو متمركز، مطابقة لـ LetterBox(center=True):

خط معالجة DALI مع حشو متمركز (موصى به)
import nvidia.dali as dali
import nvidia.dali.fn as fn
import nvidia.dali.types as 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.
    """
    # Read and decode images on GPU
    jpegs, _ = fn.readers.file(file_root=image_dir, random_shuffle=False, name="Reader")
    images = fn.decoders.image(jpegs, device="mixed", output_type=types.RGB)

    # Aspect-ratio-preserving resize
    resized = fn.resize(
        images,
        resize_x=target_size,
        resize_y=target_size,
        mode="not_larger",
        interp_type=types.INTERP_LINEAR,
        antialias=False,  # Match cv2.INTER_LINEAR (no antialiasing)
    )

    # Centered padding using fn.crop with out_of_bounds_policy
    # When crop size > image size, fn.crop centers the image and pads symmetrically
    padded = fn.crop(
        resized,
        crop=(target_size, target_size),
        out_of_bounds_policy="pad",
        fill_values=114,  # YOLO padding value
    )

    # Normalize and convert layout
    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
متى تكون `fn.pad` كافية؟

إذا كنت لا تحتاج إلى تطابق تام مع LetterBox(center=True)، يمكنك تبسيط خطوة الحشو باستخدام fn.pad(...) بدلاً من fn.crop(..., out_of_bounds_policy="pad"). ذلك البديل يقوم بحشو الحواف اليمنى والسفلية فقط، وهو ما قد يكون مقبولاً لخطوط نشر مخصصة، ولكنه لن يطابق سلوك letterbox المتمركز الافتراضي لـ Ultralytics بدقة.

لماذا نستخدم `fn.crop` للحشو المتمركز؟

مشغل fn.pad في DALI يضيف الحشو فقط إلى الحواف اليمنى والسفلية. للحصول على حشو متمركز (مطابق لـ LetterBox(center=True) في Ultralytics)، استخدم fn.crop مع out_of_bounds_policy="pad". مع القيم الافتراضية crop_pos_x=0.5 و crop_pos_y=0.5، يتم توسيط الصورة تلقائياً مع حشو متماثل.

عدم تطابق التنعيم (Antialias)

تعمل خاصية fn.resize في DALI على تمكين التنعيم افتراضياً (antialias=True)، بينما لا يقوم cv2.resize في OpenCV مع INTER_LINEAR بتطبيق التنعيم. اضبط دائماً antialias=False في DALI لمطابقة خط معالجة CPU. التغاضي عن هذا يسبب اختلافات رقمية دقيقة يمكن أن تؤثر على دقة النموذج.

Link to this sectionتشغيل خط المعالجة#

بناء وتشغيل خط معالجة DALI
# 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}]")

Link to this sectionاستخدام DALI مع Ultralytics Predict#

يمكنك تمرير موتر PyTorch تمت معالجته مسبقاً مباشرة إلى model.predict(). عند تمرير torch.Tensor، يتخطى Ultralytics المعالجة الأولية للصورة (letterbox، BGR→RGB، HWC→CHW، والتطبيع /255) ويقوم فقط بنقل الجهاز وتحويل نوع البيانات قبل إرساله إلى النموذج.

نظراً لأن Ultralytics لا يمكنه الوصول إلى أبعاد الصورة الأصلية في هذه الحالة، يتم إرجاع إحداثيات صندوق الكشف في مساحة letterbox بحجم 640×640. لتعيينها مرة أخرى إلى إحداثيات الصورة الأصلية، استخدم scale_boxes الذي يتعامل مع منطق التقريب الدقيق المستخدم بواسطة LetterBox:

from ultralytics.utils.ops import scale_boxes

# boxes: tensor of shape (N, 4) in xyxy format, in 640x640 letterboxed coords
# Scale boxes from letterboxed (640, 640) back to original (orig_h, orig_w)
boxes = scale_boxes((640, 640), boxes, (orig_h, orig_w))

ينطبق هذا على جميع مسارات المعالجة الأولية الخارجية — مدخل الموتر المباشر، تدفقات الفيديو، ونشر Triton.

DALI + استدلال Ultralytics
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")
صفر حمل للمعالجة الأولية

عندما تمرر torch.Tensor إلى model.predict()، تستغرق خطوة معالجة الصورة ~0.004 مللي ثانية (صفرياً في الأساس) مقارنة بـ ~1-10 مللي ثانية مع معالجة CPU. يجب أن يكون الموتر بتنسيق BCHW، ونوع float32 (أو float16)، ومطبعاً إلى [0, 1]. سيستمر Ultralytics في التعامل مع نقل الجهاز وتحويل نوع البيانات تلقائياً.

Link to this sectionDALI مع تدفقات الفيديو#

لمعالجة الفيديو في الوقت الفعلي، استخدم fn.external_source لتغذية الإطارات من أي مصدر — OpenCV، أو GStreamer، أو مكتبات التقاط مخصصة:

خط معالجة DALI لمعالجة تدفق الفيديو الأولية
import nvidia.dali as dali
import nvidia.dali.fn as fn
import nvidia.dali.types as 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."""
    # External source for feeding frames from OpenCV, GStreamer, etc.
    frames = fn.external_source(device="cpu", name="input")
    frames = fn.reshape(frames, layout="HWC")

    # Move to GPU and preprocess
    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

Link to this sectionTriton Inference Server مع DALI#

للنشر في الإنتاج، ادمج المعالجة الأولية لـ DALI مع استدلال TensorRT في Triton Inference Server باستخدام نموذج مجمع. هذا يلغي معالجة CPU الأولية تماماً — تدخل بايتات JPEG الخام وتخرج الكشوفات، مع معالجة كل شيء على GPU.

Link to this sectionهيكل مستودع النموذج#

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

Link to this sectionالخطوة 1: إنشاء خط معالجة DALI#

تسلسل خط معالجة DALI للواجهة الخلفية لـ Triton DALI:

تسلسل خط معالجة DALI لـ Triton
import nvidia.dali as dali
import nvidia.dali.fn as fn
import nvidia.dali.types as types

@dali.pipeline_def(batch_size=8, num_threads=4, device_id=0)
def triton_dali_pipeline():
    """DALI preprocessing pipeline for Triton deployment."""
    # Input: raw encoded image bytes from 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

# Serialize pipeline to model repository
pipe = triton_dali_pipeline()
pipe.serialize(filename="model_repository/dali_preprocessing/1/model.dali")

Link to this sectionالخطوة 2: تصدير YOLO إلى TensorRT#

تصدير نموذج YOLO إلى محرك TensorRT
from ultralytics import YOLO

model = YOLO("yolo26n.pt")
model.export(format="engine", imgsz=640, half=True, batch=8)
# Copy the .engine file to model_repository/yolo_trt/1/model.plan

Link to this sectionالخطوة 3: تكوين Triton#

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"
      }
    }
  ]
}
كيف يعمل تعيين التجميع

يقوم التجميع (ensemble) بربط النماذج من خلال أسماء الموترات الافتراضية (virtual tensor names). تطابق قيمة output_map التي تحمل الاسم "preprocessed_image" في خطوة DALI قيمة input_map التي تحمل الاسم "preprocessed_image" في خطوة TensorRT. هذه أسماء اختيارية تربط مخرجات خطوة واحدة بمدخلات الخطوة التالية — ولا يلزم أن تطابق أسماء الموترات الداخلية لأي نموذج.

Link to this sectionالخطوة 4: إرسال طلبات الاستدلال#

!!! info "لماذا tritonclient بدلاً من YOLO(\"http://...\")؟"

Ultralytics has [built-in Triton support](triton-inference-server.md#running-inference) that handles pre/postprocessing automatically. However, it won't work with the DALI ensemble because `YOLO()` sends a preprocessed float32 tensor while the ensemble expects raw JPEG bytes. Use `tritonclient` directly for DALI ensembles, and the [built-in integration](triton-inference-server.md) for standard deployments without DALI.
إرسال الصور إلى تجميع Triton
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 — YOLO26 is end-to-end)
detections = detections[0]  # First image
detections = detections[detections[:, 4] > 0.25]  # Confidence threshold
print(f"Detected {len(detections)} objects")
تجميع صور JPEG في دفعات

عند إرسال دفعة من صور JPEG إلى Triton، قم بحشو (pad) جميع مصفوفات البايت المشفرة لتصل إلى نفس الطول (أقصى عدد للبايتات في الدفعة). يتطلب Triton أشكال دفعات متجانسة لموتر الإدخال.

Link to this sectionالمهام المدعومة#

يعمل المعالجة المسبقة باستخدام DALI مع جميع مهام YOLO التي تستخدم خط أنابيب LetterBox القياسي:

المهمةمدعومملاحظات
الكشفالمعالجة المسبقة القياسية بأسلوب Letterbox
تجزئة المثيلنفس المعالجة المسبقة كما في الكشف
التجزئة الدلاليةنفس المعالجة المسبقة للصور كما في الكشف
تقدير الوضعنفس المعالجة المسبقة كما في الكشف
الكشف الموجه (OBB)نفس المعالجة المسبقة كما في الكشف
التصنيفيستخدم تحويلات torchvision (القص المركزي)، وليس Letterbox

Link to this sectionالقيود#

  • Linux فقط: لا يدعم DALI نظامي Windows أو macOS
  • مطلوب NVIDIA GPU: لا يوجد بديل يعمل باستخدام CPU فقط
  • خط أنابيب ثابت: يتم تحديد هيكل خط الأنابيب في وقت البناء ولا يمكن تغييره ديناميكيًا
  • fn.pad يعمل لليمين/الأسفل فقط: استخدم fn.crop مع out_of_bounds_policy="pad" للحصول على حشو مركزي
  • لا يوجد وضع مستطيل (rect mode): تنتج خطوط أنابيب DALI مخرجات ثابتة الحجم (مثل 640×640). وضع المستطيل auto=True الذي ينتج مخرجات متغيرة الحجم (مثل 384×640) غير مدعوم. لاحظ أنه على الرغم من أن TensorRT يدعم أشكال المدخلات الديناميكية، إلا أن خط أنابيب DALI ثابت الحجم يتوافق بشكل طبيعي مع محرك ثابت الحجم لتحقيق أقصى قدر من الإنتاجية
  • الذاكرة مع مثيلات متعددة: يمكن أن يؤدي استخدام instance_group مع count > 1 في Triton إلى استخدام مرتفع للذاكرة. استخدم مجموعة المثيلات الافتراضية لنموذج DALI

Link to this sectionالأسئلة الشائعة#

Link to this sectionكيف تقارن سرعة المعالجة المسبقة لـ DALI بسرعة المعالجة على CPU؟#

تعتمد الفائدة على خط الأنابيب الخاص بك. عندما يكون استدلال GPU سريعًا بالفعل باستخدام TensorRT، يمكن أن تصبح المعالجة المسبقة على CPU التي تستغرق 2-10 مللي ثانية هي العائق الرئيسي. يقضي DALI على هذا الاختناق عن طريق تشغيل المعالجة المسبقة على GPU. تظهر أكبر المكاسب مع المدخلات عالية الدقة (1080p, 4K)، وأحجام الدفعات الكبيرة، والأنظمة ذات الأنوية المحدودة لـ CPU لكل GPU.

Link to this sectionهل يمكنني استخدام DALI مع نماذج PyTorch (ليس فقط TensorRT)؟#

نعم. استخدم DALIGenericIterator للحصول على مخرجات torch.Tensor المعالجة مسبقًا، ثم مررها إلى model.predict(). ومع ذلك، تكون فائدة الأداء أكبر مع نماذج TensorRT حيث يكون الاستدلال سريعًا جدًا بالفعل وتصبح المعالجة المسبقة على CPU هي العائق.

Link to this sectionما الفرق بين fn.pad و fn.crop للحشو؟#

تضيف fn.pad حشوًا فقط إلى الحواف اليمنى والسفلية. بينما تقوم fn.crop مع out_of_bounds_policy="pad" بتوسيط الصورة وإضافة الحشو بشكل متماثل على جميع الجوانب، مما يطابق سلوك LetterBox(center=True) الخاص بـ Ultralytics.

Link to this sectionهل ينتج DALI نتائج متطابقة بكسلًا بكسل مع المعالجة المسبقة على CPU؟#

متطابقة تقريبًا. اضبط antialias=False في fn.resize لتطابق cv2.INTER_LINEAR في OpenCV. قد تحدث اختلافات طفيفة في الفاصلة العائمة (< 0.001) بسبب حسابات GPU مقابل CPU، ولكن ليس لها تأثير ملموس على دقة الكشف.

Link to this sectionماذا عن CV-CUDA كبديل لـ DALI؟#

CV-CUDA هي مكتبة أخرى من NVIDIA لمعالجة الرؤية المتسارعة بواسطة GPU. إنها توفر تحكمًا لكل عامل (مثل OpenCV ولكن على GPU) بدلاً من نهج خط الأنابيب الخاص بـ DALI. تدعم cvcuda.copymakeborder() في CV-CUDA حشوًا صريحًا لكل جانب، مما يجعل Letterbox المركزي أمرًا مباشرًا. اختر DALI لسير العمل القائم على خط الأنابيب (خاصة مع Triton)، وCV-CUDA للتحكم الدقيق على مستوى العامل في كود الاستدلال المخصص.

تعليقات