Xuất Hailo cho các model YOLO của Ultralytics
Hailo HEF không được hỗ trợ chính thức như một đích đến trực tiếp của model.export(format="hailo") trong Ultralytics. Luồng công việc dưới đây xuất sang ONNX trước, sau đó sử dụng bộ công cụ Dataflow Compiler bên ngoài của Hailo để tạo tệp .hef. Để có hiệu suất trên mỗi watt tốt hơn so với các triển khai Hailo HEF cũ, hãy sử dụng các định dạng xuất trực tiếp mới hơn của Ultralytics như Axelera AI hoặc DeepX.
Bộ công cụ Hailo sử dụng các tệp HEF cho các nền tảng nhúng, bao gồm Raspberry Pi AI Kit và AI HAT+, camera công nghiệp, gateway biên và AI PC.
Hướng dẫn này trình bày cách xuất các model phát hiện Ultralytics YOLO sang định dạng HEF (Hailo Executable Format) của Hailo bằng SDK Hailo Dataflow Compiler (DFC). Luồng công việc bắt đầu từ một model YOLO .pt, xuất sang ONNX, biên dịch bằng các công cụ của Hailo và tạo ra tệp .hef sẵn sàng cho các bộ tăng tốc Hailo-8, Hailo-8L và Hailo-15.
Khi nào nên sử dụng Hailo HEF
HEF là artifact đã biên dịch được sử dụng bởi HailoRT trên các thiết bị đích của Hailo. Chỉ sử dụng hướng dẫn này khi phần cứng triển khai của bạn yêu cầu cụ thể Hailo HEF. Nếu bạn vẫn đang lựa chọn phần cứng biên hoặc định dạng xuất, hãy bắt đầu với các định dạng xuất trực tiếp mới hơn của Ultralytics như Axelera AI hoặc DeepX, cung cấp luồng công việc model.export(...) được hỗ trợ và các tùy chọn hiệu suất trên mỗi watt tốt hơn so với các triển khai Hailo cũ.
HEF có vai trò triển khai tương tự như các định dạng đặc thù phần cứng như RKNN cho NPU của Rockchip, IMX500 cho Camera AI của Raspberry Pi và Qualcomm QNN cho NPU của Snapdragon, nhưng hiện tại nó không được tạo trực tiếp bởi Ultralytics.
Luồng công việc này liên quan khi bạn cần:
- Khả năng tương thích với Raspberry Pi AI Kit: Hailo-8L được sử dụng trong Raspberry Pi AI Kit và AI HAT+ chính thức.
- Xử lý hậu kỳ bằng HailoRT: HailoRT có thể bao gồm non-maximum suppression (NMS) của YOLO trong pipeline suy luận đã biên dịch.
- Biên dịch INT8: Hailo DFC thực hiện lượng tử hóa model với các hình ảnh hiệu chuẩn đại diện để tạo đồ thị INT8 cho phần cứng Hailo. Tìm hiểu thêm về model quantization.
Định dạng xuất Hailo HEF
HEF là tệp thực thi đặc thù phần cứng được tạo bởi Hailo Dataflow Compiler. Nó chứa đồ thị model đã lượng tử hóa, phân bổ bộ nhớ, lập lịch và xử lý hậu kỳ tùy chọn được cấu hình cho kiến trúc Hailo mục tiêu. Khác với các định dạng Export mode tiêu chuẩn của YOLO được tạo trực tiếp bởi model.export(format=...), quá trình biên dịch HEF hiện sử dụng luồng hai giai đoạn:
- Xuất YOLO sang ONNX với Ultralytics.
- Sử dụng các công cụ Hailo DFC để phân tích, tối ưu hóa, lượng tử hóa và biên dịch model ONNX thành HEF.
Luồng công việc đầy đủ mở rộng thành pipeline sau:
YOLO (.pt) -> ONNX -> HAR (parse) -> HAR (optimize/quantize) -> HEF (compile)- Xuất sang ONNX sử dụng Export mode của Ultralytics
- Phân tích model ONNX thành định dạng HAR trung gian của Hailo
- Tải tập lệnh model (
.alls) với các chỉ thị chuẩn hóa và xử lý hậu kỳ - Hiệu chuẩn và lượng tử hóa sử dụng các hình ảnh đại diện
- Biên dịch thành tệp HEF có thể triển khai
Các tác vụ được hỗ trợ
Hướng dẫn này tập trung vào các model object detection của Ultralytics YOLO, vì tập lệnh model và cấu hình NMS của Hailo dành riêng cho đầu phát hiện (detection-head).
| Tác vụ | Được hỗ trợ |
|---|---|
| Object Detection | ✅ Có |
| Instance Segmentation | ❌ Không |
| Semantic Segmentation | ❌ Không |
| Pose Estimation | ❌ Không |
| OBB Detection | ❌ Không |
| Classification | ❌ Không |
Đối với triển khai instance segmentation, semantic segmentation, pose, OBB và classification, hãy so sánh các định dạng biên khác trong bảng Export mode hoặc sử dụng pipeline ONNX chung nếu runtime mục tiêu của bạn hỗ trợ tác vụ đó.
Lưu ý về khả năng tương thích
Khả năng tương thích xuất Hailo phụ thuộc vào đầu model, kích thước hình ảnh đầu vào, số lượng lớp, kiến trúc Hailo, tập lệnh model (.alls) và cấu hình NMS. Các tệp tĩnh từ Hailo Model Zoo là tài liệu tham khảo hữu ích, nhưng chúng không phải là mẫu áp dụng toàn cầu. Ví dụ: một tệp JSON NMS được tạo cho model YOLO11n 80 lớp COCO sẽ không chính xác cho model tùy chỉnh 3 lớp hoặc cho một imgsz cố định khác.
| Phạm vi | Mức hỗ trợ dự kiến | Ghi chú |
|---|---|---|
| Phát hiện YOLOv8 / YOLO11, các model gốc | ✅ Tốt | Chia sẻ đầu phát hiện tách biệt; .alls, các nút kết thúc và cấu hình NMS vẫn cần khớp với đồ thị đã xuất và imgsz cố định. |
| Phát hiện YOLOv8 / YOLO11 tùy chỉnh | ✅ Khả thi | Yêu cầu cấu hình NMS cho từng model được tạo từ số lượng lớp, bước nhảy (strides) và bố cục đầu phát hiện; tệp JSON Model Zoo tĩnh sẽ không khớp. |
| Phát hiện YOLOv9 | ⚠️ Cần xác thực | Mô hình đầu phát hiện tương tự, nhưng quá trình biên dịch và phân tích cú pháp đầu ra cần được kiểm tra trước khi coi là được hỗ trợ hoàn toàn. |
| Phát hiện end-to-end YOLOv10 / YOLO26 | ❌ Không được hỗ trợ | Các tệp xuất end-to-end/không NMS không khớp với đường dẫn xử lý hậu kỳ NMS của Hailo; hãy sử dụng đầu phát hiện truyền thống nếu kiểm tra thủ công. |
| Kích thước hình ảnh động hoặc tùy ý | ❌ Không được hỗ trợ | Quá trình biên dịch Hailo sử dụng hình dạng đầu vào cố định; các cài đặt .alls và NMS phải khớp với imgsz đã xuất. |
Cài đặt
Bước 1: Cài đặt Ultralytics
pip install ultralyticsBước 2: Cài đặt SDK Hailo DFC
Hailo DFC là bắt buộc để phân tích, tối ưu hóa và biên dịch. Tải xuống Python wheel từ Hailo Developer Zone (yêu cầu đăng ký miễn phí) và cài đặt:
pip install /path/to/hailo_sdk_client-*.whlSDK Hailo DFC yêu cầu máy Linux x86_64. Quá trình xuất và biên dịch không thể thực hiện trên các thiết bị ARM như Raspberry Pi. Hãy sao chép tệp .hef kết quả vào thiết bị hỗ trợ Hailo của bạn để triển khai với HailoRT.
Ví dụ xuất HEF cho YOLO11n
Tập lệnh dưới đây biên dịch một model phát hiện YOLO11n từ .pt sang .hef tại kích thước đầu vào cố định 640 pixel. Nó xuất sang ONNX bằng Ultralytics, sau đó biên dịch với Hailo DFC sử dụng COCO128 làm tập dữ liệu hiệu chuẩn nhỏ.
Trước khi chạy tập lệnh, hãy tải xuống tệp cấu hình NMS YOLO11n tương ứng từ Hailo Model Zoo hoặc tạo tệp JSON NMS Hailo của riêng bạn cho model. Sử dụng lại tập lệnh này như một điểm bắt đầu YOLO11n đã biết; các model tùy chỉnh cần các nút kết thúc, chỉ thị .alls và cài đặt NMS khớp nhau.
import random
import numpy as np
from hailo_sdk_client import ClientRunner
from PIL import Image
from ultralytics import YOLO
from ultralytics.data.utils import check_det_dataset
from ultralytics.utils import DATASETS_DIR
# Configuration
MODEL = "yolo11n"
HW_ARCH = "hailo8" # hailo8 | hailo8l | hailo15h
IMGSZ = 640
CALIB_IMAGES = 128
NMS_CONFIG = "yolo11n_nms_config.json" # Download or generate for your exact model.
# YOLO11 detection head end nodes. See "Supported Models and End Nodes" for YOLOv8 and other families.
END_NODES = [
"/model.23/cv2.0/cv2.0.2/Conv",
"/model.23/cv3.0/cv3.0.2/Conv",
"/model.23/cv2.1/cv2.1.2/Conv",
"/model.23/cv3.1/cv3.1.2/Conv",
"/model.23/cv2.2/cv2.2.2/Conv",
"/model.23/cv3.2/cv3.2.2/Conv",
]
# Step 1: Export to ONNX
model = YOLO(f"{MODEL}.pt")
model.export(format="onnx", imgsz=IMGSZ, opset=11) # creates an ONNX file named after MODEL
# Step 2: Parse ONNX with Hailo DFC
# The DFC prints the detected end nodes after parsing; use them if unsure.
runner = ClientRunner(hw_arch=HW_ARCH)
runner.translate_onnx_model(f"{MODEL}.onnx", end_node_names=END_NODES)
# Step 3: Load model script (normalization + HailoRT NMS)
# The conv layer names are generated by DFC and can change for other model sizes/families.
alls = (
"normalization1 = normalization([0.0, 0.0, 0.0], [255.0, 255.0, 255.0])\n"
"change_output_activation(conv54, sigmoid)\n"
"change_output_activation(conv65, sigmoid)\n"
"change_output_activation(conv80, sigmoid)\n"
f'nms_postprocess("{NMS_CONFIG}", meta_arch=yolov8, engine=cpu)\n'
"allocator_param(width_splitter_defuse=disabled)"
)
runner.load_model_script(alls)
# Step 4: Build calibration dataset (auto-downloads COCO128)
check_det_dataset("coco128.yaml")
calib_dir = DATASETS_DIR / "coco128" / "images" / "train2017"
image_files = list(calib_dir.glob("*.jpg")) + list(calib_dir.glob("*.png"))
if not image_files:
raise FileNotFoundError(f"No calibration images found in {calib_dir}")
calibset = np.zeros((CALIB_IMAGES, IMGSZ, IMGSZ, 3), dtype=np.float32)
for i in range(CALIB_IMAGES):
img = Image.open(random.choice(image_files)).convert("RGB").resize((IMGSZ, IMGSZ))
calibset[i] = np.array(img, dtype=np.float32)
# Step 5: Optimize and quantize
runner.optimize(calibset)
runner.save_har(f"{MODEL}.o.har") # optional intermediate HAR
# Step 6: Compile to HEF
hef = runner.compile()
with open(f"{MODEL}.hef", "wb") as f:
f.write(hef)
print(f"Compiled HEF saved to: {MODEL}.hef")Tệp HEF kết quả, chẳng hạn như yolo11n.hef, đã sẵn sàng để triển khai trên thiết bị Hailo tương thích. Nếu bạn đang biên dịch cho Raspberry Pi AI Kit, hãy đặt HW_ARCH = "hailo8l" trước khi chạy bước biên dịch.
Chi tiết từng bước
Bước 1: Xuất sang ONNX
Ultralytics xuất model đã huấn luyện của bạn sang định dạng ONNX, định dạng mà Hailo DFC tiếp nhận làm đầu vào. Đặt opset=11 để có khả năng tương thích DFC rộng rãi.
from ultralytics import YOLO
MODEL = "yolo11n"
model = YOLO(f"{MODEL}.pt")
model.export(format="onnx", imgsz=640, opset=11)Bước 2: Phân tích model ONNX
Lệnh translate_onnx_model chuyển đổi đồ thị ONNX thành biểu diễn HAR trung gian của Hailo. Danh sách end_node_names cho DFC biết nơi cắt đồ thị trước NMS để Hailo có thể đính kèm xử lý hậu kỳ phần cứng của riêng nó.
from hailo_sdk_client import ClientRunner
runner = ClientRunner(hw_arch="hailo8")
runner.translate_onnx_model(f"{MODEL}.onnx", end_node_names=END_NODES)DFC in ra một gợi ý sau khi phân tích:
[info] In order to use HailoRT post-processing capabilities, these end node names should be used: ...
Sao chép các tên nút đó nếu bạn không chắc chắn nên sử dụng nút nào, hoặc nếu bạn đang làm việc với kiến trúc tùy chỉnh hoặc ít phổ biến hơn.
Bước 3: Tải tập lệnh model
Tập lệnh model (.alls) cấu hình việc chuẩn hóa đầu vào, kích hoạt đầu ra và xử lý hậu kỳ NMS. Cài đặt meta_arch=yolov8 áp dụng cho cả YOLOv8 và YOLO11 vì chúng chia sẻ cùng một bố cục đầu phát hiện.
MODEL = "yolo11n"
NMS_CONFIG = "yolo11n_nms_config.json"
alls = (
"normalization1 = normalization([0.0, 0.0, 0.0], [255.0, 255.0, 255.0])\n"
"change_output_activation(conv54, sigmoid)\n"
"change_output_activation(conv65, sigmoid)\n"
"change_output_activation(conv80, sigmoid)\n"
f'nms_postprocess("{NMS_CONFIG}", meta_arch=yolov8, engine=cpu)\n'
"allocator_param(width_splitter_defuse=disabled)"
)
runner.load_model_script(alls)Các tên lớp change_output_activation (conv54, conv65, conv80) được DFC gán trong quá trình phân tích và đặc thù cho từng model. Nếu bạn đang biên dịch một kích thước hoặc kiến trúc model khác, hãy kiểm tra đầu ra của DFC để có tên chính xác, hoặc sử dụng tệp .alls được xác định trước từ Hailo Model Zoo.
Tệp NMS_CONFIG cũng đặc thù cho từng model. Sử dụng cấu hình khớp với model đã xuất của bạn, hoặc bắt đầu từ cấu hình Hailo Model Zoo cho biến thể YOLO gần nhất.
engine=cpu chạy NMS thông qua HailoRT trên CPU chủ. Chỉ sử dụng engine=nn_core cho các kết hợp model/tập lệnh mà Hailo ghi nhận là được hỗ trợ bởi phần cứng mục tiêu và phiên bản SDK.
Xóa dòng nms_postprocess nếu bạn thích chạy NMS hoàn toàn trong mã ứng dụng của mình. Nếu thực hiện việc này, hãy cập nhật trình phân tích suy luận vì HEF sẽ xuất ra các tensor đầu phát hiện thô thay vì các phát hiện NMS đã được nhóm.
Bước 4: Xây dựng tập dữ liệu hiệu chuẩn
Lượng tử hóa INT8 yêu cầu một tập hợp hình ảnh đại diện. Tập lệnh dưới đây sử dụng COCO128, mà Ultralytics tải xuống tự động thông qua check_det_dataset:
from ultralytics.data.utils import check_det_dataset
from ultralytics.utils import DATASETS_DIR
check_det_dataset("coco128.yaml") # downloads to DATASETS_DIR if not present
calib_dir = DATASETS_DIR / "coco128" / "images" / "train2017"Sử dụng ít nhất 64 hình ảnh để hiệu chuẩn. Nhiều hình ảnh hơn thường cải thiện chất lượng lượng tử hóa. Để có kết quả tốt nhất, hãy sử dụng hình ảnh từ miền triển khai của bạn thay vì COCO128.
Bước 5: Tối ưu hóa và lượng tử hóa
runner.optimize(calibset)
runner.save_har(f"{MODEL}.o.har") # optional intermediate checkpointBước này áp dụng tinh chỉnh nhận biết lượng tử hóa và phân tích nhiễu lớp. Một GPU được khuyến nghị mạnh mẽ; nếu không có, bước này có thể mất vài giờ.
Bước 6: Biên dịch sang HEF
hef = runner.compile()
with open(f"{MODEL}.hef", "wb") as f:
f.write(hef)Các model và nút kết thúc được hỗ trợ
Đối với các model phát hiện, end_node_names xác định các đầu ra đầu phát hiện ONNX mà Hailo nên biên dịch trước khi đính kèm xử lý hậu kỳ NMS của nó. Các tên này thay đổi theo kiến trúc và có thể thay đổi khi đồ thị đã xuất thay đổi.
YOLO11 và YOLOv8
YOLO11 và YOLOv8 chia sẻ cùng một đầu phát hiện tách biệt. Chỉ số lớp khác nhau một đơn vị giữa hai họ này:
| Họ model | Lớp đầu phát hiện | Mẫu nút kết thúc |
|---|---|---|
| YOLO11 (tất cả) | model.23 | /model.23/cv2.0/cv2.0.2/Conv (6 nút) |
| YOLOv8 (tất cả) | model.22 | /model.22/cv2.0/cv2.0.2/Conv (6 nút) |
Các nút kết thúc YOLO11 (tất cả kích thước: n, s, m, l, x):
END_NODES = [
"/model.23/cv2.0/cv2.0.2/Conv",
"/model.23/cv3.0/cv3.0.2/Conv",
"/model.23/cv2.1/cv2.1.2/Conv",
"/model.23/cv3.1/cv3.1.2/Conv",
"/model.23/cv2.2/cv2.2.2/Conv",
"/model.23/cv3.2/cv3.2.2/Conv",
]Các nút kết thúc YOLOv8 (tất cả kích thước: n, s, m, l, x):
END_NODES = [
"/model.22/cv2.0/cv2.0.2/Conv",
"/model.22/cv3.0/cv3.0.2/Conv",
"/model.22/cv2.1/cv2.1.2/Conv",
"/model.22/cv3.1/cv3.1.2/Conv",
"/model.22/cv2.2/cv2.2.2/Conv",
"/model.22/cv3.2/cv3.2.2/Conv",
]Các kiến trúc khác
Đối với các kiến trúc phát hiện khác, hãy chạy bước phân tích cú pháp (parse) mà không cần end_node_names trước, đọc các node được đề xuất từ log đầu ra của DFC, sau đó chạy lại với các node đó:
# First pass: let the DFC suggest end nodes
runner = ClientRunner(hw_arch=HW_ARCH)
runner.translate_onnx_model(f"{MODEL}.onnx")
# Check the printed log for: "[info] In order to use HailoRT post-processing..."Các tập lệnh .alls và tệp cấu hình NMS định sẵn cho nhiều biến thể YOLO có sẵn trong Hailo Model Zoo.
Các kiến trúc phần cứng được hỗ trợ
| Kiến trúc | Thiết bị | Hiệu suất tính toán đỉnh (Thông số nhà cung cấp) | Trường hợp sử dụng phổ biến |
|---|---|---|---|
hailo8 | Hailo-8 | 26 TOPS | Card tăng tốc Hailo |
hailo8l | Hailo-8L | 13 TOPS | Raspberry Pi AI Kit |
hailo15h | Hailo-15H | 20 TOPS | Thiết bị mục tiêu Hailo-15 |
Thiết lập HW_ARCH trong tập lệnh để khớp với thiết bị mục tiêu của bạn trước khi biên dịch.
Chạy suy luận trên phần cứng Hailo
Khi bạn đã có tệp .hef, hãy sao chép nó vào thiết bị chạy Hailo của bạn và thực hiện suy luận bằng Python API HailoRT (gói hailo_platform). Khác với các bước xuất DFC, quá trình suy luận chạy trực tiếp trên thiết bị edge.
Mã suy luận bên dưới chạy trên thiết bị chạy Hailo (ví dụ: Raspberry Pi + AI Kit), không phải trên máy x86 dùng để biên dịch.
Bước 1: Cài đặt HailoRT trên thiết bị
Trên thiết bị mục tiêu, hãy cài đặt HailoRT và các Python bindings. Đối với người dùng Raspberry Pi AI Kit và AI HAT+, hướng dẫn phần mềm AI chính thức của Raspberry Pi sẽ cài đặt HailoRT, driver thiết bị và Python bindings bằng lệnh:
sudo apt install dkms
sudo apt install hailo-allĐối với các thiết bị Hailo không phải Raspberry Pi, hãy cài đặt gói HailoRT phù hợp với thiết bị, driver và phiên bản SDK của bạn từ Hailo Developer Zone.
Các thiết bị AI HAT+ 2 sử dụng gói Raspberry Pi khác (hailo-h10-all) và quy trình làm việc Hailo-10H. Hãy làm theo hướng dẫn phần mềm AI của Raspberry Pi cho thế hệ phần cứng đó.
Bước 2: Kiểm tra nhanh (Sanity Check)
Trước khi chạy suy luận Python, hãy xác nhận thiết bị Hailo đã được nhận diện:
hailortcli fw-control identifyBạn sẽ thấy loại thiết bị, phiên bản firmware và số sê-ri được in ra.
Bước 3: Chạy suy luận
Tập lệnh bên dưới thực hiện phát hiện đối tượng trên một hình ảnh duy nhất bằng cách sử dụng tệp HEF đã biên dịch và Python API hailo_platform. Nó xử lý tiền xử lý, suy luận và vẽ các BBox từ đầu ra NMS của HailoRT.
import numpy as np
from hailo_platform import (
HEF,
ConfigureParams,
FormatType,
HailoStreamInterface,
InferVStreams,
InputVStreamParams,
OutputVStreamParams,
VDevice,
)
from PIL import Image, ImageDraw
# Configuration
MODEL = "yolo11n"
HEF_PATH = f"{MODEL}.hef" # path to your compiled HEF file
SOURCE = "bus.jpg" # image path
IMGSZ = 640
CONF = 0.25
COCO_NAMES = [
"person",
"bicycle",
"car",
"motorcycle",
"airplane",
"bus",
"train",
"truck",
"boat",
"traffic light",
"fire hydrant",
"stop sign",
"parking meter",
"bench",
"bird",
"cat",
"dog",
"horse",
"sheep",
"cow",
"elephant",
"bear",
"zebra",
"giraffe",
"backpack",
"umbrella",
"handbag",
"tie",
"suitcase",
"frisbee",
"skis",
"snowboard",
"sports ball",
"kite",
"baseball bat",
"baseball glove",
"skateboard",
"surfboard",
"tennis racket",
"bottle",
"wine glass",
"cup",
"fork",
"knife",
"spoon",
"bowl",
"banana",
"apple",
"sandwich",
"orange",
"broccoli",
"carrot",
"hot dog",
"pizza",
"donut",
"cake",
"chair",
"couch",
"potted plant",
"bed",
"dining table",
"toilet",
"tv",
"laptop",
"mouse",
"remote",
"keyboard",
"cell phone",
"microwave",
"oven",
"toaster",
"sink",
"refrigerator",
"book",
"clock",
"vase",
"scissors",
"teddy bear",
"hair drier",
"toothbrush",
]
# Load HEF and connect to device
hef = HEF(HEF_PATH)
params = VDevice.create_params()
target = VDevice(params)
configure_params = ConfigureParams.create_from_hef(hef, interface=HailoStreamInterface.PCIe)
network_groups = target.configure(hef, configure_params)
network_group = network_groups[0]
network_group_params = network_group.create_params()
# Setup I/O virtual streams
input_vstreams_params = InputVStreamParams.make(network_group, quantized=False, format_type=FormatType.FLOAT32)
output_vstreams_params = OutputVStreamParams.make(network_group, quantized=False, format_type=FormatType.FLOAT32)
# Preprocess
orig = Image.open(SOURCE).convert("RGB")
ow, oh = orig.size
resized = orig.resize((IMGSZ, IMGSZ))
input_data = np.expand_dims(np.array(resized, dtype=np.float32), axis=0) # (1,640,640,3)
input_name = hef.get_input_vstream_infos()[0].name
# Inference
with InferVStreams(network_group, input_vstreams_params, output_vstreams_params) as pipeline:
with network_group.activate(network_group_params):
pipeline.send({input_name: input_data})
raw = pipeline.recv()
# Parse HailoRT NMS output and draw results
# When compiled with nms_postprocess the HEF outputs detections grouped by
# class: shape (batch, num_classes, max_dets, 5) where 5 = [y1,x1,y2,x2,score]
draw = ImageDraw.Draw(orig)
output_key = next(iter(raw.keys()))
batch_dets = raw[output_key][0] # shape: (num_classes, max_dets, 5)
for cls_idx, cls_dets in enumerate(batch_dets):
for det in cls_dets:
score = float(det[4])
if score < CONF:
continue
y1, x1, y2, x2 = det[:4]
# Scale from model coords (0-640) back to original image size
x1 = int(x1 * ow / IMGSZ)
y1 = int(y1 * oh / IMGSZ)
x2 = int(x2 * ow / IMGSZ)
y2 = int(y2 * oh / IMGSZ)
label = f"{COCO_NAMES[cls_idx]} {score:.2f}"
draw.rectangle([x1, y1, x2, y2], outline="red", width=2)
draw.text((x1 + 2, y1 + 2), label, fill="red")
orig.save("output.jpg")
print("Saved output.jpg")Định dạng đầu ra phát hiện giả định rằng HEF đã được biên dịch với nms_postprocess trong tập lệnh .alls. Nếu bạn biên dịch mà không có NMS, các đầu ra thô sẽ là 6 tensor từ đầu phát hiện và bạn phải tự chạy NMS trong ứng dụng của mình.
Raspberry Pi AI Kit và AI HAT+
Raspberry Pi AI Kit và AI HAT+ 13 TOPS sử dụng Hailo-8L. Để sử dụng một trong hai thiết bị:
- Thiết lập
HW_ARCH = "hailo8l"trước khi biên dịch HEF trên máy x86. - Sao chép tệp
.hefsang Raspberry Pi của bạn. - Cài đặt HailoRT bằng cách làm theo hướng dẫn phần mềm AI chính thức của Raspberry Pi.
- Chạy tập lệnh suy luận ở trên.
Đối với suy luận dựa trên camera trên Raspberry Pi, các ví dụ Hailo cho picamera2 cung cấp các tập lệnh sẵn sàng để sử dụng cho phát hiện trực tiếp với Camera Module. Bạn cũng có thể so sánh các đường dẫn triển khai trên Raspberry Pi trong hướng dẫn Coral Edge TPU trên Raspberry Pi và hướng dẫn tích hợp Sony IMX500.
Suy luận video với TAPPAS
Đối với các pipeline video băng thông cao, TAPPAS cung cấp các phần tử GStreamer để truyền luồng video qua chip Hailo trong thời gian thực:
MODEL=yolo11n
gst-launch-1.0 filesrc location=video.mp4 ! decodebin ! \
hailonet hef-path=${MODEL}.hef ! \
hailofilter function-name=yolov8 ! \
hailooverlay ! autovideosinkXem tài liệu TAPPAS để biết các tùy chọn cấu hình pipeline đầy đủ.
Tóm tắt
Hướng dẫn này đã bao gồm quy trình hoàn chỉnh để xuất các mô hình phát hiện Ultralytics YOLO sang định dạng Hailo HEF:
- Xuất sang ONNX với Ultralytics (
model.export(format="onnx")). - Phân tích cú pháp mô hình ONNX với Hailo DFC và chỉ định các end nodes của đầu phát hiện.
- Cấu hình chuẩn hóa (normalization) và NMS thông qua tập lệnh mô hình.
- Lượng tử hóa với tập dữ liệu hiệu chuẩn (COCO128 thông qua Ultralytics).
- Biên dịch sang tệp
.hefsẵn sàng cho Hailo-8, Hailo-8L hoặc Hailo-15.
Để biết thêm chi tiết, hãy xem Hailo Developer Zone, tài liệu Hailo và Hailo Model Zoo. Đối với các mục tiêu xuất khác của Ultralytics, hãy xem các hướng dẫn liên quan về ONNX, OpenVINO, TensorRT, NCNN, TFLite Edge TPU, RKNN, Sony IMX500 và Qualcomm QNN. Để so sánh tốc độ và độ chính xác của mô hình đã xuất trên các định dạng, hãy sử dụng chế độ Benchmark. Để xem danh sách đầy đủ các định dạng và tùy chọn, hãy truy cập tài liệu Export mode và trang hướng dẫn tích hợp.
Câu hỏi thường gặp (FAQ)
Những thiết bị Hailo nào được hỗ trợ?
Hailo DFC hỗ trợ Hailo-8 (hailo8), Hailo-8L (hailo8l) và Hailo-15H (hailo15h). Xem bảng Các kiến trúc phần cứng được hỗ trợ để biết giá trị HW_ARCH tương ứng.
Những mô hình Ultralytics nào có thể được xuất?
Hướng dẫn này tập trung vào các mô hình phát hiện. Xem Các tác vụ được hỗ trợ cho phạm vi cấp độ tác vụ, Ghi chú tương thích cho các giới hạn tương thích của mô hình và Các mô hình và End Nodes được hỗ trợ cho các ví dụ về end-node của YOLO11 và YOLOv8.
Tại sao tập lệnh mô hình sử dụng meta_arch=yolov8 cho YOLO11?
YOLO11 sử dụng cùng kiến trúc đầu phát hiện tách rời (decoupled detection head) như YOLOv8. Hailo DFC sử dụng meta_arch=yolov8 cho cấu hình NMS cho cả hai dòng mô hình.
Tôi có cần GPU cho bước tối ưu hóa không?
GPU được khuyến nghị mạnh mẽ cho việc tinh chỉnh nhận biết lượng tử hóa (quantization-aware fine-tuning) trong runner.optimize(). Nếu không có GPU, quá trình này vẫn hoạt động nhưng chậm hơn đáng kể (vài giờ so với khoảng 10-20 phút khi có GPU).
Làm thế nào để tìm đúng end nodes cho mô hình của tôi?
Chạy runner.translate_onnx_model(...) mà không chỉ định end_node_names, sau đó sử dụng các node đầu phát hiện được gợi ý bởi DFC. Xem Các kiến trúc khác để biết lệnh ví dụ.
Tôi có thể lấy Hailo DFC SDK và các tệp cấu hình NMS ở đâu?
Python wheel của Hailo DFC SDK có sẵn từ Hailo Developer Zone, trong khi các tập lệnh .alls và tệp cấu hình NMS định sẵn có sẵn từ Hailo Model Zoo.