Ultralytics YOLO27: Tham gia danh sách chờ.
Get Started
Bài họcngười mới bắt đầu

Export để triển khai

Export best.pt sang ONNX, OpenVINO, TensorRT, CoreML, LiteRT hoặc QNN, sau đó chứng minh bản export khớp với model PyTorch trước khi triển khai.

best.pt cần Python và PyTorch để chạy; điện thoại, trình duyệt, Jetson và máy chủ production thường không có các thành phần này. Export mode chuyển model thành một tệp độc lập cho các runtime đó chỉ bằng một lệnh gọi. Tuy nhiên, tệp export tải được không có nghĩa là tệp đó chính xác; so sánh thiếu cẩn trọng có thể khiến bản export đúng trông như bị lỗi hoặc che giấu lỗi trong bản export.

Trong bài học này, bạn sẽ export model viên thuốc sang ONNX, chạy model qua cùng API YOLO, chứng minh kết quả khớp với PyTorch về bounding box và mAP trên tập validation khi các thiết lập được đồng bộ, rồi chọn định dạng phù hợp với mục tiêu triển khai: ONNX, OpenVINO, TensorRT, CoreML, LiteRT hoặc QNN.

Kết quả

Bạn có thể export model đã huấn luyện sang định dạng phù hợp với mục tiêu triển khai và chứng minh bằng phép kiểm tra tương đương trực tiếp cùng validation rằng bản export khớp với best.pt.

Lộ trình cấp tốc
Nếu bạn đã nắm rõ cách thực hiện, đây là phiên bản tóm tắt.
  1. yolo export model=runs/detect/pills_v1/weights/best.pt format=onnx — bắt đầu tại đây.

  2. OpenVINO dành cho CPU Intel; TensorRT dành cho GPU NVIDIA và Jetson; CoreML dành cho Apple; LiteRT dành cho Android; QNN dành cho NPU Snapdragon.

  3. So sánh .pt và bản export trên cùng một ảnh, với rect=False ở phía .pt.

  4. Validation cả hai ở imgsz dùng khi huấn luyện; mAP50-95 phải khớp.

Thực hành

Ví dụ minh họa: Export sang ONNX#

Tab Export model trên Ultralytics Platform liệt kê các định dạng triển khai như ONNX, TensorRT, CoreML và OpenVINO

yolo export model=runs/detect/pills_v1/weights/best.pt format=onnx
PyTorch: starting from 'runs/detect/pills_v1/weights/best.pt' with input shape (1, 3, 320, 320) BCHW and output shape(s) (1, 5, 2100) (5.2 MB)
ONNX: export success ✅ 0.9s, saved as 'runs/detect/pills_v1/weights/best.onnx' (9.3 MB)
Predict:         yolo predict task=detect model=runs/detect/pills_v1/weights/best.onnx imgsz=320
Validate:        yolo val task=detect model=runs/detect/pills_v1/weights/best.onnx imgsz=320 data=my_dataset/data.yaml

Giải thích từng dòng:

  • input shape (1, 3, 320, 320): một ảnh, 3 kênh màu, hình vuông cố định 320×320 — imgsz dùng khi huấn luyện được tích hợp sẵn trong tệp.
  • output shape(s) (1, 5, 2100): 4 giá trị hộp cộng với 1 điểm số lớp cho 2.100 hộp ứng viên; theo mặc định, NMS chạy bên ngoài graph.
  • 9.3 MB: tệp ONNX lưu trọng số FP32 nên lớn hơn .pt FP16.
  • Predict: / Validate:: các lệnh dựng sẵn cho tệp đã export, với imgsz phù hợp.

Một vài tham số đáp ứng phần lớn nhu cầu; hướng dẫn tích hợp ONNX liệt kê các tham số còn lại.

Đối sốMặc địnhDùng để
imgszKích thước khi huấn luyệnExport với kích thước đầu vào cố định khác, ví dụ imgsz=640
dynamicFalseChấp nhận kích thước đầu vào thay đổi thay vì một shape cố định
quantizeKhông có (FP32)16 cho trọng số FP16 (yolo26n.onnx giảm dung lượng từ 9.5 MB xuống 4.8 MB); 8 cho INT8 nếu định dạng hỗ trợ
nmsKhông cónms=True tích hợp NMS trong graph, vì vậy runtime trả về các hộp cuối cùng

Ví dụ minh họa: Chứng minh bản export khớp#

Lớp YOLO cũng tải được các tệp đã export, vì vậy mã predict ở phần trước hoạt động nguyên trạng. So sánh cả hai tệp trên cùng một ảnh validation:

from ultralytics import YOLO

image = "my_dataset/images/val/Frame_144.jpg"
pt = YOLO("runs/detect/pills_v1/weights/best.pt")(image, rect=False, verbose=False)[0]  # square input, like ONNX
onnx = YOLO("runs/detect/pills_v1/weights/best.onnx")(image, verbose=False)[0]

print(f"pt:   {len(pt.boxes)} pills, mean conf {pt.boxes.conf.mean():.3f}")
print(f"onnx: {len(onnx.boxes)} pills, mean conf {onnx.boxes.conf.mean():.3f}")
print(f"max box difference: {(pt.boxes.xyxy - onnx.boxes.xyxy).abs().max():.4f} px")
pt:   25 pills, mean conf 0.870
onnx: 25 pills, mean conf 0.870
max box difference: 0.0002 px

Số lượng giống nhau, confidence giống nhau, các hộp giống nhau đến từng phần nhỏ của pixel. Tiếp theo là phép kiểm tra chặt chẽ hơn: validation trên toàn bộ tập:

from ultralytics import YOLO

pt = YOLO("runs/detect/pills_v1/weights/best.pt").val(data="my_dataset/data.yaml", rect=False, verbose=False)
onnx = YOLO("runs/detect/pills_v1/weights/best.onnx").val(data="my_dataset/data.yaml", verbose=False)
print(f".pt   mAP50-95 {pt.box.map:.4f}")
print(f".onnx mAP50-95 {onnx.box.map:.4f}")
.pt   mAP50-95 0.6570
.onnx mAP50-95 0.6570

Giống hệt nhau. (Validation hình chữ nhật mặc định trên tệp .pt đạt 0.659: chênh lệch nhỏ do padding đầu vào, không phải do quá trình export.)

Sau khi khớp, hãy đo thời gian bằng yolo benchmark trên thiết bị mục tiêu để biết tốc độ thực tế trước khi triển khai.

Chọn định dạng cho mục tiêu triển khai#

Vòng đời trên Ultralytics Platform: chú thích bằng tính năng chú thích thông minh SAM, huấn luyện trên GPU đám mây và triển khai trên toàn cầu, cùng logo các đối tác tích hợp

Mục tiêuĐịnh dạngGhi chú
Lựa chọn mặc định có tính di động cao: máy chủ và máy tính để bàn chạy Linux, Windows và MaconnxONNX Runtime trên CPU hoặc GPU; định dạng export dễ kiểm chứng nhất
GPU NVIDIA và Jetsonengine (TensorRT)Nhanh nhất trên NVIDIA; export trực tiếp trên thiết bị. Xem Tối ưu hóa với TensorRT
CPU và iGPU IntelopenvinoTăng tốc CPU thực sự nhờ kernel Intel. Xem OpenVINO trên CPU
Ứng dụng cho iPhone, iPad và MaccoremlNative; sử dụng Apple Neural Engine
Android và các thiết bị di động hoặc nhúng kháclitertKhuyến nghị INT8 cho thiết bị di động
NPU SnapdragonqnnTăng tốc Hexagon HTP; mặc định dùng trọng số INT8 với activation 16-bit; chọn kiến trúc HTP bằng name
Trình duyệt webonnx với ONNX Runtime WebCác model nhỏ hơn là lựa chọn khả thi: n và s
from ultralytics import YOLO

model = YOLO("runs/detect/pills_v1/weights/best.pt")

model.export(format="onnx")  # đa nền tảng: ONNX Runtime
model.export(format="openvino")  # CPU / iGPU Intel
model.export(format="engine", quantize=16)  # NVIDIA TensorRT, FP16 (chạy trên GPU đích)
model.export(format="coreml")  # Apple iOS / macOS
model.export(format="litert", quantize=8, data="my_dataset/data.yaml")  # Android / edge, INT8
model.export(format="qnn", name="73", data="my_dataset/data.yaml")  # NPU Qualcomm Snapdragon (HTP v73); hiệu chỉnh trên dữ liệu của riêng bạn

Mỗi lần export sẽ ghi các tệp bên cạnh trọng số: best.onnx, best_openvino_model/, best.engine, v.v. Hãy bắt đầu với ONNX ngay cả khi cuối cùng bạn dùng định dạng khác: đây là định dạng dễ kiểm tra nhất và là đầu vào cho một số toolchain khác. Hướng dẫn các tùy chọn triển khai so sánh mọi định dạng, còn Chọn mục tiêu triển khai hướng dẫn bạn đưa ra quyết định.

Lượng tử hóa model đánh đổi độ chính xác để giảm kích thước và tăng tốc độ. FP16 (quantize=16) giảm một nửa dung lượng tệp mà hầu như không ảnh hưởng đến độ chính xác. INT8 (quantize=8) còn nhỏ và nhanh hơn, nhưng cần ảnh hiệu chỉnh — các frame đại diện được chạy qua trong quá trình export để chọn phạm vi giá trị; Ultralytics khuyến nghị tối thiểu 300 ảnh. Luôn đánh giá model INT8 trước khi phát hành: mức suy giảm có thể không đáng kể hoặc rất lớn, tùy thuộc vào model và tập hiệu chỉnh.

Tránh những lỗi này#

So sánh các đầu vào khác nhau

Triệu chứng: model .pt phát hiện 35 viên thuốc trong Frame_144.jpg, còn tệp ONNX phát hiện 25 viên, khiến bạn nghĩ export bị lỗi. Nguyên nhân: suy luận PyTorch padding mỗi ảnh thành hình chữ nhật nhỏ nhất có kích thước căn theo stride (192×320 cho các frame 16:9 này), trong khi model ONNX tĩnh luôn nhận ảnh vuông 320×320. Đầu vào khác nhau dẫn đến các detection có độ tin cậy thấp khác nhau. Cách khắc phục: truyền rect=False cho model .pt khi so sánh, như trong parity.py.

Export tĩnh bỏ qua imgsz bạn đặt

Triệu chứng: bạn truyền imgsz=640 cho best.onnx nhưng log vẫn ghi 320x320. Nguyên nhân: export tĩnh có một kích thước đầu vào duy nhất, được đặt tại thời điểm export. Cách khắc phục: export ở kích thước bạn sẽ dùng (imgsz=640) hoặc export với dynamic=True.

TensorRT engine phụ thuộc vào thiết bị

.engine được tạo trên A100 sẽ không chạy trên Jetson Orin và có thể không tương thích sau khi nâng cấp TensorRT. Hãy export trên thiết bị đích bằng phiên bản TensorRT mà thiết bị sẽ chạy. ONNX có tính di động; engine thì không.

INT8 mặc định hiệu chuẩn trên COCO8 nếu bạn không chỉ định khác

Không truyền data khi export INT8, Ultralytics sẽ cảnh báo rồi hiệu chuẩn trên mẫu COCO8 mặc định — tám ảnh không giống các viên thuốc của bạn chút nào. Hãy truyền dataset của bạn: model.export(format="litert", quantize=8, data="my_dataset/data.yaml").

Bạn đã triển khai#

Giờ đây, bạn đã có một best.pt được huấn luyện, bằng chứng đánh giá đặt cạnh baseline, một tệp đã export cho runtime và xác nhận rằng bản export khớp với bản gốc. Đó là toàn bộ quy trình — dữ liệu, huấn luyện, đánh giá, export, triển khai — và các nhóm vận hành production thực hiện quy trình này theo lịch. Ultralytics YOLO trong môi trường production tiếp nối từ bản export đã được xác minh của bạn, bao quát các runtime được tối ưu hóa, pipeline tracking, phục vụ đa luồng và giám sát.

Dùng thử

Export pills_v1/weights/best.pt sang ONNX, sau đó chạy parity.py và val_export.py. Chạy lại parity.py mà không dùng rect=False và ghi lại mức thay đổi của số lượng .pt. Bàn giao bốn mục: số lượng detection khớp nhau, độ chênh lệch box tối đa, hai giá trị mAP50-95 và một dòng nêu định dạng mà mục tiêu triển khai thực tế của bạn cần cùng lý do.

Commit
git add -A && git commit -m "feat(deploy): exported best.pt to onnx for production runtime"
Điều kiện hoàn thành
Bạn đã hoàn thành bài học khi tất cả các điều kiện sau đều đúng.
  • runs/detect/pills_v1/weights/best.onnx tồn tại và thực hiện dự đoán thông qua YOLO().

  • Với rect=False, số lượng detection khớp nhau và độ chênh lệch box tối đa nhỏ hơn 1 px.

  • mAP50-95 khi đánh giá ONNX và .pt khớp nhau trong cùng điều kiện, và bạn đã nêu định dạng mục tiêu cùng lý do.

Hiển thị lời giải
from ultralytics import YOLO

# Train
model = YOLO("yolo26n.pt")
model.train(data="my_dataset/data.yaml", epochs=10, imgsz=320, name="pills_e2e")

# Validate
metrics = model.val()
print(f"mAP50-95 = {metrics.box.map:.3f}")  # 0.659

# Export
model.export(format="onnx")
parity.py:      pt 25 pills, onnx 25 pills, max box difference 0.0002 px
without rect:   pt 35 pills (192x320 input) vs onnx 25 (320x320): input mismatch, not an export bug
val_export.py:  .pt 0.6570, .onnx 0.6570
Target:         Intel laptop CPU -> openvino, for faster CPU inference than ONNX Runtime
Tiếp theo là gì

Hoàn thành khóa học — làm bài kiểm tra cuối khóa để nhận chứng chỉ Huấn luyện model YOLO đầu tiên của bạn, sau đó tiếp tục với Ultralytics YOLO trong môi trường production.

Đăng nhập để lưu tiến độ