객체 감지
Overview
이 튜토리얼에서는 RBLN SDK C/C++ Runtime API
를 사용하여 PyTorch YOLOv8 모델로 추론을 실행하는 방법을 배웁니다.
모델은 RBLN SDK Python API
를 사용해 컴파일하며, 생성된 *.rbln
파일은 RBLN SDK C/C++ Runtime API
로 추론에 사용됩니다.
이 접근 방식은 Python에서 모델 준비의 편의성과 C/C++의 성능 이점을 결합합니다.
튜토리얼에 사용된 전체 코드는 RBLN Model Zoo에서 확인할 수 있습니다.
Setup & Installation
시작하기 전에 시스템 환경이 올바르게 구성되어 있으며, 필요한 모든 필수 패키지가 설치되어 있는지 확인하십시오. 다음 항목이 포함됩니다:
- System Requirements:
- Packages Requirements:
- Installation Command:
| pip install torch ultralytics cmake
pip install --extra-index-url https://pypi.rbln.ai/simple/ rebel-compiler>=0.7.4
|
Note
RBLN SDK는 .whl
패키지로 배포됩니다. RBLN 컴파일러와 런타임을 사용하려면 RBLN Portal 계정이 필요합니다.
RBLN Python API
를 사용한 컴파일
모델 준비
ultralytics 라이브러리에서 YOLOv8m
모델을 임포트하고 포워드 패스를 실행하여 모델을 초기화합니다.
| from ultralytics import YOLO
import rebel
import torch
model_name = "yolov8m"
yolo = YOLO(f"{model_name}.pt")
model = yolo.model.eval()
model(torch.zeros(1, 3, 640, 640))
|
모델 컴파일
Torch 모델(torch.nn.Module
)이 준비되면 rebel.compile_from_torch()
로 컴파일합니다.
compiled_model.save()
로 컴파일된 모델을 저장합니다.
| # Compile the model
compiled_model = rebel.compile_from_torch(model, [ ("x", [1, 3, 640, 640], "float32") ])
# Save the compiled model to local storage
compiled_model.save(f"{model_name}.rbln")
|
컴파일 실행
컴파일 코드는 compile.py에 포함되어 있습니다.
다음 명령으로 스크립트를 실행하여 .rbln
파일을 생성하세요:
| $ python compile.py --model-name=yolov8m
|
RBLN SDK C/C++ Runtime API
를 사용한 추론
CMake 빌드 스크립트 준비
예제 애플리케이션은 OpenCV로 이미지 전/후처리를 수행하고, argparse로 CLI 파라미터를 파싱합니다.
아래 CMake 스크립트는 외부 패키지 종속성과 링크 설정을 설명합니다.
| # Define dependencies for external Package
include(FetchContent)
include(cmake/opencv.cmake)
include(cmake/argparse.cmake)
# Define the name of executable
add_executable(object_detection main.cc)
# Update link info for package dependencies: OpenCV
find_package(OpenCV CONFIG REQUIRED)
target_link_libraries(object_detection ${OpenCV_LIBS})
# Update link info for dependencies: RBLN
find_package(rbln CONFIG REQUIRED)
target_link_libraries(object_detection rbln::rbln_runtime)
# Update including dependencies: argparse
target_include_directories(object_detection PRIVATE ${argparse_INCLUDE_DIRS})
|
입력 데이터 준비
OpenCV API를 사용하여 입력 이미지를 전처리합니다. 아래 코드에서는 이미지를 읽고 전처리하는 과정을 보여줍니다.
| std::string input_path = "${SAMPLE_PATH}/people4.jpg";
cv::Mat image;
try {
image = cv::imread(input_path);
} catch (const cv::Exception &err) {
std::cerr << err.what() << std::endl;
std::exit(1);
}
cv::Mat blob = cv::dnn::blobFromImage(GetSquareImage(image, 640), 1./255., cv::Size(), cv::Scalar(), true, false, CV_32F);
|
동기식 추론 실행
아래 코드는 동기식 추론 예시를 보여줍니다.
| std::string model_path = "${SAMPLE_PATH}/yolov8m.rbln";
RBLNModel *mod = rbln_create_model(model_path.c_str());
RBLNRuntime *rt = rbln_create_runtime(mod, "default", 0, 0);
// Set input data
rbln_set_input(rt, 0, blob.data);
// Run sync inference
rbln_run(rt);
// Get output results
void *data = rbln_get_output(rt, 0);
|
비동기식 추론 실행
아래 코드는 비동기식 추론 예시를 보여줍니다.
| std::string model_path = "${SAMPLE_PATH}/yolov8m.rbln";
RBLNModel *mod = rbln_create_model(model_path.c_str());
RBLNRuntime *rt = rbln_create_async_runtime(mod, "default", 0, 0);
// Alloc output buffer
auto buf_size = rbln_get_layout_nbytes(rbln_get_output_layout(rt, 0));
std::vector<float> logits(buf_size/sizeof(float));
// Run async inference
int rid = rbln_async_run(rt, blob.data, logits.data());
// Wait inference done
rbln_async_wait(rt, rid, 1000);
|
후처리(Post Processing)
출력 데이터(float32
배열, shape=(1,84,8400))에 대해 NMS를 수행하고 바운딩 박스를 그립니다.
아래 코드는 처리 과정을 개략적으로 보여줍니다:
| // Postprocessing for NMS
const RBLNTensorLayout *layout = rbln_get_output_layout(rt, 0);
cv::Mat logits{layout->ndim, layout->shape, CV_32F};
memcpy(logits.data, data, rbln_get_layout_nbytes(layout));
std::vector<cv::Rect> nms_boxes;
std::vector<float> nms_confidences;
std::vector<size_t> nms_class_ids;
for (size_t i = 0; i < layout->shape[2]; i++) {
auto cx = logits.at<float>(0, 0, i);
auto cy = logits.at<float>(0, 1, i);
auto w = logits.at<float>(0, 2, i);
auto h = logits.at<float>(0, 3, i);
auto x = cx - w / 2;
auto y = cy - h / 2;
cv::Rect rect{static_cast<int>(x), static_cast<int>(y), static_cast<int>(w), static_cast<int>(h)};
float confidence = std::numeric_limits<float>::min();
int cls_id;
for (size_t j = 4; j < layout->shape[1]; j++) {
if (confidence < logits.at<float>(0, j, i)) {
confidence = logits.at<float>(0, j, i);
cls_id = j - 4;
}
}
nms_boxes.push_back(rect);
nms_confidences.push_back(confidence);
nms_class_ids.push_back(cls_id);
}
std::vector<int> nms_indices;
cv::dnn::NMSBoxes(nms_boxes, nms_confidences, 0.25f, 0.45f, nms_indices);
cv::Mat output_img = image.clone();
for (size_t i = 0; i < nms_indices.size(); i++) {
auto idx = nms_indices[i];
auto class_id = nms_class_ids[idx];
auto scaled_box = ScaleBox(nms_boxes[idx], output_img.size(), 640);
cv::rectangle(output_img, scaled_box, cv::Scalar(255, 0, 0));
std::stringstream ss;
ss << COCO_CATEGORIES[class_id] << ": " << nms_confidences[idx];
cv::putText(output_img, ss.str(), scaled_box.tl() - cv::Point(0, 1), cv::FONT_HERSHEY_DUPLEX, 1, cv::Scalar(255, 0, 0));
}
cv::imwrite("result.jpg", output_img);
|
리소스 해제
런타임과 모델을 해제합니다.
| rbln_destroy_runtime(rt);
rbln_destroy_model(mod);
|
CMake 빌드 방법
예제 코드는 RBLN Model Zoo C++ 예제에 포함되어 있습니다.
아래 명령으로 컴파일하고 실행 파일을 생성하세요:
| $ mkdir ${SAMPLE_PATH}/build
$ cd ${SAMPLE_PATH}/build
$ cmake ..
$ make
|
실행 파일 사용 방법
모든 단계가 완료된 후, 빌드 디렉토리에서 실행 파일을 확인할 수 있습니다.
| # Synchronous execution
$ ${SAMPLE_PATH}/build/object_detection -i ${SAMPLE_PATH}/people4.jpg -m ${SAMPLE_PATH}/yolov8m.rbln
# Asynchronous execution
$ ${SAMPLE_PATH}/build/object_detection_async -i ${SAMPLE_PATH}/people4.jpg -m ${SAMPLE_PATH}/yolov8m.rbln
|
결과는 다음과 같이 표시됩니다:

Summary and References
이 튜토리얼에서는 RBLN SDK Python API
를 사용하여 PyTorch YOLOv8 모델을 컴파일하고,
RBLN SDK C/C++ Runtime API
로 추론을 실행하는 방법을 보여주었습니다.
References: