GPU - Xử lý sơ bộ được tăng tốc với NVIDIA DALI
Giới thiệu
Khi triển khai các mô hình Ultralytics YOLO trong môi trường sản xuất, quá trình tiền xử lý thường trở thành điểm nghẽn. Mặc dù TensorRT có thể chạy suy luận mô hình chỉ trong vài mili giây, nhưng CPU Quá trình tiền xử lý dựa trên (thay đổi kích thước, thêm đệm, chuẩn hóa) có thể mất từ 2-10ms cho mỗi hình ảnh, đặc biệt là ở độ phân giải cao. NVIDIA DALI (Data Loading Library) giải quyết vấn đề này bằng cách chuyển toàn bộ quy trình tiền xử lý sang bộ nhớ đệm. GPU .
Hướng dẫn này sẽ hướng dẫn bạn xây dựng các pipeline DALI mô phỏng chính xác quá trình này. Ultralytics YOLO xử lý sơ bộ, tích hợp chúng với model.predict()xử lý luồng video và triển khai từ đầu đến cuối với Triton Inference Server.
Hướng dẫn này dành cho ai?
Hướng dẫn này dành cho các kỹ sư triển khai. YOLO các mô hình trong môi trường sản xuất nơi CPU Xử lý trước là một nút thắt cổ chai có thể đo lường được — điển hình là TensorRT triển khai trên NVIDIA GPU, hệ thống xử lý video tốc độ cao, hoặc Triton Inference Server thiết lập. Nếu bạn đang chạy suy luận tiêu chuẩn với model.predict() và không gặp phải tắc nghẽn trong quá trình tiền xử lý, theo mặc định. CPU Hệ thống vận hành tốt.
Tóm tắt nhanh
- Đang xây dựng đường dẫn DALI? Sử dụng
fn.resize(mode="not_larger")+fn.crop(out_of_bounds_policy="pad")+fn.crop_mirror_normalizeđể sao chép YOLO xử lý trước hộp thư của trên GPU . - Tích hợp với Ultralytics ? Truyền đầu ra DALI dưới dạng
torch.Tensorđếnmodel.predict()— Ultralytics Tự động bỏ qua bước xử lý ảnh trước khi chụp. - Triển khai với Triton ? Sử dụng phần phụ trợ DALI với... TensorRT tập hợp cho số không- CPU tiền xử lý.
Tại sao nên sử dụng DALI cho YOLO Tiền xử lý
Trong một trường hợp điển hình YOLO quy trình suy luận, các bước tiền xử lý được chạy trên CPU :
- Giải mã hình ảnh (JPEG/PNG)
- Thay đổi kích thước trong khi vẫn giữ nguyên tỷ lệ khung hình
- Chèn thêm khoảng trống để đạt kích thước mục tiêu (letterbox)
- Chuẩn hóa giá trị pixel từ
[0, 255]đến[0, 1] - Chuyển đổi bố cục từ HWC sang CHW
Với DALI, tất cả các hoạt động này đều được thực hiện trên nền tảng này. GPU , loại bỏ CPU nút thắt cổ chai. Điều này đặc biệt có giá trị khi:
| Kịch bản | Vì sao DALI lại hữu ích |
|---|---|
| Nhanh GPU suy luận | Các công cụ TensorRT với khả năng suy luận dưới mili giây giúp tạo ra CPU xử lý trước chi phí chiếm ưu thế |
| Đầu vào độ phân giải cao | Luồng video 1080p và 4K yêu cầu các thao tác thay đổi kích thước tốn kém. |
| Kích thước lô lớn | Xử lý suy luận phía máy chủ xử lý nhiều hình ảnh song song |
| Giới hạn CPU lõi | Các thiết bị biên như NVIDIA Jetson , hoặc mạng mật độ cao. GPU máy chủ với một vài CPU lõi trên mỗi GPU |
Điều Kiện Tiên Quyết
Chỉ dành cho Linux
NVIDIA DALI chỉ hỗ trợ Linux . Nó không khả dụng trên Windows hoặc macOS.
Cài đặt các gói cần thiết:
pip install ultralytics
pip install --extra-index-url https://pypi.nvidia.com nvidia-dali-cuda120
pip install ultralytics
pip install --extra-index-url https://pypi.nvidia.com nvidia-dali-cuda110
Yêu cầu:
- NVIDIA GPU (Khả năng tính toán 5.0 trở lên / Maxwell hoặc mới hơn)
- CUDA 11.0+ hoặc 12.0+
- Python 3.10-3.14
- Hệ điều hành Linux
Hiểu biết YOLO Tiền xử lý
Trước khi xây dựng đường dẫn DALI, điều quan trọng là phải hiểu chính xác những gì cần hiểu. Ultralytics thực hiện trong quá trình tiền xử lý. Lớp chính là LetterBox trong 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)
)
Toàn bộ quy trình tiền xử lý trong ultralytics/engine/predictor.py thực hiện các bước sau:
| Bước chân | Hoạt động | CPU Chức năng | Tương đương DALI |
|---|---|---|---|
| 1 | Thay đổi kích thước hộp thư | cv2.resize | fn.resize(mode="not_larger") |
| 2 | Đệm ở giữa | cv2.copyMakeBorder | fn.crop(out_of_bounds_policy="pad") |
| 3 | BGR → RGB | im[..., ::-1] | fn.decoders.image(output_type=types.RGB) |
| 4 | HWC → CHW + chuẩn hóa /255 | np.transpose + tensor / 255 | fn.crop_mirror_normalize(std=[255,255,255]) |
Chế độ hiển thị ảnh đen trắng (letterbox) giữ nguyên tỷ lệ khung hình bằng cách:
- Tính toán quy mô:
r = min(target_h / h, target_w / w) - Thay đổi kích thước thành
(round(w * r), round(h * r)) - Lấp đầy khoảng trống còn lại bằng màu xám (
114) để đạt được kích thước mục tiêu - Căn giữa hình ảnh sao cho phần đệm được phân bổ đều ở cả hai phía.
Đường ống DALI cho YOLO
Hãy sử dụng đường ống căn giữa bên dưới làm tham chiếu mặc định. Nó khớp với... Ultralytics LetterBox(center=True) hành vi, đó là tiêu chuẩn YOLO Ứng dụng suy luận.
Đường dẫn trung tâm (Được đề xuất, phù hợp) Ultralytics Hộp thư)
Phiên bản này sao chép chính xác phiên bản mặc định. Ultralytics xử lý trước với phần đệm ở giữa, khớp LetterBox(center=True):
Đường dẫn DALI với phần đệm ở giữa (khuyến nghị)
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
Khi nào fn.pad đủ?
Nếu bạn không cần chính xác LetterBox(center=True) Để đảm bảo tính chẵn lẻ, bạn có thể đơn giản hóa bước đệm bằng cách sử dụng fn.pad(...) thay vì fn.crop(..., out_of_bounds_policy="pad")Biến thể đó chỉ đệm bên phải và phía dưới Các cạnh, điều này có thể chấp nhận được đối với các quy trình triển khai tùy chỉnh, nhưng nó sẽ không khớp. Ultralytics ' Chính xác là hành vi căn giữa khung hình mặc định.
Tại sao fn.crop Để căn giữa?
của DALI fn.pad Toán tử chỉ thêm phần đệm vào bên phải và phía dưới các cạnh. Để có được khoảng đệm ở giữa (phù hợp với Ultralytics LetterBox(center=True)), sử dụng fn.crop với out_of_bounds_policy="pad"Với cài đặt mặc định crop_pos_x=0.5 và crop_pos_y=0.5Hình ảnh được tự động căn giữa với khoảng đệm đối xứng.
Sự không khớp khử răng cưa
của DALI fn.resize bật tính năng khử răng cưa theo mặc định (antialias=True), trong khi OpenCV 'S cv2.resize với INTER_LINEAR làm không Áp dụng khử răng cưa. Luôn luôn thiết lập antialias=False trong DALI để phù hợp với CPU đường ống. Việc bỏ qua bước này gây ra những khác biệt nhỏ về số liệu có thể ảnh hưởng đến độ chính xác của mô hình.
Vận hành đường ống
Xây dựng và vận hành quy trình 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}]")
Sử dụng DALI với Ultralytics Dự đoán
Bạn có thể truyền vào một dữ liệu đã được xử lý trước. PyTorch tensor trực tiếp tới model.predict()Khi một torch.Tensor đã được thông qua, Ultralytics bỏ qua bước tiền xử lý ảnh (chuyển đổi định dạng letterbox, BGR→RGB, HWC→CHW và chuẩn hóa /255) và chỉ thực hiện chuyển đổi thiết bị và ép kiểu dtype trước khi gửi đến mô hình.
Từ Ultralytics Trong trường hợp này, vì không có quyền truy cập vào kích thước ảnh gốc, tọa độ hộp phát hiện được trả về trong không gian letterboxed 640×640. Để ánh xạ chúng trở lại tọa độ ảnh gốc, hãy sử dụng... scale_boxes điều này xử lý logic làm tròn chính xác được sử dụng bởi 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))
Điều này áp dụng cho tất cả các đường dẫn tiền xử lý bên ngoài — trực tiếp tensor đầu vào, luồng video và Triton triển khai.
DALI + Ultralytics dự đoán
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")
Không tốn chi phí xử lý trước
Khi bạn đi qua một torch.Tensor đến model.predict()Bước tiền xử lý hình ảnh mất khoảng ~0,004ms (gần như bằng không) so với khoảng ~1-10ms khi sử dụng phương pháp khác. CPU tiền xử lý. Cái tensor phải ở định dạng BCHW, float32 (hoặc float16) và được chuẩn hóa thành [0, 1]. Ultralytics Sẽ vẫn tự động xử lý việc chuyển thiết bị và chuyển đổi kiểu dữ liệu.
DALI với luồng video
Để xử lý video theo thời gian thực, hãy sử dụng fn.external_source để lấy khung hình từ bất kỳ nguồn nào — OpenCV, GStreamer, hoặc các thư viện thu hình tùy chỉnh:
Hệ thống xử lý dữ liệu DALI cho quá trình tiền xử lý luồng video.
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
import cv2
import numpy as np
import torch
from ultralytics import YOLO
model = YOLO("yolo26n.engine") # TensorRT model
pipe = yolo_video_pipeline(target_size=640)
pipe.build()
cap = cv2.VideoCapture("video.mp4")
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
# Feed BGR frame (convert to RGB for DALI)
frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
pipe.feed_input("input", [np.array(frame_rgb)])
(output,) = pipe.run()
# Convert DALI output to torch tensor for inference.
# This is a simple fallback path: using feed_input() with pipe.run() keeps a GPU->CPU->GPU copy.
# For high-throughput deployments, prefer a reader-based pipeline plus DALIGenericIterator to keep data on GPU.
tensor = torch.tensor(output.as_cpu().as_array()).to("cuda")
results = model.predict(tensor, verbose=False)
Triton Máy chủ suy luận với DALI
Để triển khai sản phẩm, hãy kết hợp tiền xử lý DALI với suy luận TensorRT trong Triton Inference Server bằng cách sử dụng mô hình kết hợp. Điều này giúp loại bỏ... CPU Xử lý trước hoàn toàn — dữ liệu JPEG thô được đưa vào, kết quả nhận dạng được đưa ra, và mọi thứ được xử lý trên máy chủ. GPU .
Cấu trúc kho lưu trữ mô hình
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
Bước 1: Tạo đường dẫn DALI
Tuần tự hóa đường dẫn DALI cho Triton Hệ thống phụ trợ DALI:
Tuần tự hóa đường dẫn DALI cho 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")
Bước 2: Xuất khẩu YOLO ĐẾN TensorRT
Xuất khẩu YOLO mô hình tới TensorRT động cơ
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
Bước 3: Cấu hình 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"
}
}
]
}
Cách thức hoạt động của lập bản đồ tổng hợp
Tập hợp này kết nối các mô hình thông qua ảo tensor tên. Các output_map giá trị "preprocessed_image" trong bước DALI khớp với input_map giá trị "preprocessed_image" trong TensorRT bước. Đây là những tên gọi tùy ý liên kết đầu ra của một bước với đầu vào của bước tiếp theo — chúng không cần phải khớp với bất kỳ tên gọi nội bộ nào của mô hình. tensor tên.
Bước 4: Gửi yêu cầu suy luận
Tại sao tritonclient thay vì YOLO(\"http://...\")?
Ultralytics có tích hợp sẵn Triton ủng hộ Nó xử lý tiền/hậu xử lý tự động. Tuy nhiên, nó sẽ không hoạt động với hệ thống DALI vì... YOLO() gửi một giá trị float32 đã được xử lý trước. tensor trong khi tập hợp các tệp tin mong đợi các byte JPEG thô. Sử dụng tritonclient trực tiếp cho các nhóm DALI và tích hợp sẵn Đối với các triển khai tiêu chuẩn không có DALI.
Gửi hình ảnh đến Triton dàn nhạc
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")
Xử lý hàng loạt ảnh JPEG
Khi gửi một loạt ảnh JPEG đến Triton , thêm phần đệm vào tất cả các mảng byte đã mã hóa để có cùng độ dài (số byte tối đa trong lô). Triton yêu cầu hình dạng lô đồng nhất cho đầu vào tensor .
Các Tác Vụ Được Hỗ Trợ
Công cụ tiền xử lý DALI hoạt động với tất cả các loại máy. YOLO các nhiệm vụ sử dụng tiêu chuẩn LetterBox đường ống:
| Tác vụ | Được hỗ trợ | Ghi chú |
|---|---|---|
| Phát hiện vật thể | ✅ | Xử lý trước hộp thư tiêu chuẩn |
| Phân đoạn | ✅ | Quá trình tiền xử lý tương tự như quá trình phát hiện. |
| Ước tính tư thế | ✅ | Quá trình tiền xử lý tương tự như quá trình phát hiện. |
| Phát hiện định hướng (OBB) | ✅ | Quá trình tiền xử lý tương tự như quá trình phát hiện. |
| Phân loại (Classification) | ❌ | Sử dụng phép biến đổi torchvision (cắt giữa), không phải letterbox. |
Hạn chế
- Chỉ dành cho Linux : DALI không hỗ trợ Windows hoặc macOS.
- Yêu cầu GPU NVIDIA : Không CPU -chỉ là phương án dự phòng
- Quy trình xử lý tĩnh : Cấu trúc quy trình xử lý được định nghĩa tại thời điểm biên dịch và không thể thay đổi động.
fn.padchỉ bên phải/dưới: Sử dụngfn.cropvớiout_of_bounds_policy="pad"để căn giữa- Không có chế độ chỉnh lưu: Các đường dẫn DALI tạo ra đầu ra có kích thước cố định (ví dụ: 640×640).
auto=TrueChế độ hình chữ nhật tạo ra đầu ra có kích thước thay đổi (ví dụ: 384×640) không được hỗ trợ. Lưu ý rằng trong khi TensorRT Hỗ trợ các dạng đầu vào động, đường dẫn DALI kích thước cố định kết hợp tự nhiên với công cụ kích thước cố định để đạt được thông lượng tối đa. - Bộ nhớ với nhiều phiên bản: Sử dụng
instance_groupvớicount> 1 trong Triton có thể gây ra tình trạng sử dụng bộ nhớ cao. Hãy sử dụng nhóm phiên bản mặc định cho mô hình DALI.
Câu hỏi thường gặp
Quá trình tiền xử lý DALI so với... thì như thế nào? CPU Tốc độ xử lý trước?
Lợi ích phụ thuộc vào quy trình của bạn. Khi nào GPU Quá trình suy luận đã diễn ra nhanh chóng với TensorRT . CPU Quá trình tiền xử lý ở mức 2-10ms có thể trở thành chi phí chiếm ưu thế. DALI loại bỏ nút thắt cổ chai này bằng cách chạy quá trình tiền xử lý trên... GPU Hiệu quả cao nhất được thấy ở các đầu vào độ phân giải cao (1080p, 4K), kích thước lô lớn và các hệ thống có giới hạn về khả năng xử lý. CPU lõi trên mỗi GPU .
Tôi có thể sử dụng DALI với PyTorch mô hình (không chỉ TensorRT )?
Vâng. Sử dụng DALIGenericIterator để được xử lý trước torch.Tensor đầu ra, sau đó chuyển chúng đến model.predict()Tuy nhiên, lợi ích về hiệu suất đạt được lớn nhất với... TensorRT các mô hình mà quá trình suy luận đã rất nhanh và CPU Công đoạn tiền xử lý trở thành nút thắt cổ chai.
Sự khác biệt giữa là gì? fn.pad và fn.crop Để lót đệm?
fn.pad chỉ thêm phần đệm vào bên phải và phía dưới các cạnh. fn.crop với out_of_bounds_policy="pad" Căn giữa hình ảnh và thêm khoảng đệm đối xứng ở tất cả các cạnh, khớp với Ultralytics LetterBox(center=True) hành vi.
Liệu DALI có tạo ra kết quả giống hệt nhau về mặt pixel không? CPU Tiền xử lý?
Gần như giống hệt nhau. Bộ antialias=False trong fn.resize để phù hợp OpenCV 'S cv2.INTER_LINEAR. Minor floating-point differences (< 0.001) may occur due to GPU vs CPU arithmetic, but these have no measurable impact on detection độ chính xác.
Còn về CV thì sao? CUDA Liệu đây có phải là một giải pháp thay thế cho DALI?
CV- CUDA là một cái khác NVIDIA thư viện cho GPU - Xử lý hình ảnh được tăng tốc. Nó cung cấp khả năng điều khiển cho từng người vận hành (như...). OpenCV nhưng trên GPU ) thay vì phương pháp đường ống của DALI. CV- CUDA 'S cvcuda.copymakeborder() Hỗ trợ đệm rõ ràng cho từng cạnh, giúp việc căn giữa khung hình trở nên dễ dàng. Chọn DALI cho các quy trình làm việc dựa trên đường ống (đặc biệt là với Triton), và CV- CUDA Để kiểm soát chi tiết ở cấp độ toán tử trong mã suy luận tùy chỉnh.