C/C++ API를 사용한 객체 인식¶
이 튜토리얼에서는 RBLN SDK C/C++ API
를 사용하여 PyTorch YOLOv8 모델을 배포하는 방법을 배우게 됩니다. 모델은 RBLN SDK Python API
를 사용하여 컴파일되며, 그 결과로 생성된 *.rbln
파일은 RBLN SDK C/C++ API
를 사용하여 배포됩니다.
이러한 접근 방식은 Python API를 사용한 간편한 모델 준비와 C/C++의 빠른 추론 성능을 결합합니다. 튜토리얼에서 사용된 전체 코드는 RBLN Model Zoo에서 확인할 수 있습니다.
이 튜토리얼은 다음 단계들을 포함합니다:
- Python API를 사용하여
YOLOv8m
모델을 컴파일하고 로컬 저장소에 저장하는 방법 - 컴파일된 모델을 C/C++ 런타임 기반 추론 환경에서 배포하는 방법
전제 조건¶
시작하기 전에, 다음 패키지들이 설치되어 있는지 확인해 주세요:
-
모델 컴파일
-
RBLN SDK C/C++ API
- cmake >= 3.26.0
- RBLN SDK C/C++ API
1단계. 컴파일 방법¶
RBLN Python API
는 RBLN SDK 내에서 컴파일과 추론을 모두 처리할 수 있는 포괄적인 기능을 제공하지만, RBLN SDK C/C++ API
는 추론 작업만 지원합니다. 따라서 본 튜토리얼에서는 모델 컴파일에는 RBLN Python API
를 사용하고, 추론 작업에는 RBLN C/C++ API
를 사용합니다.
모델 준비¶
먼저 ultralytics에서 Yolov8m
모델을 가져올 수 있습니다.
모델 컴파일¶
torch 모델 torch.nn.Module
이 준비되면, rebel.compile_from_torch()
메서드를 사용하여 간단히 컴파일할 수 있습니다.
NPU가 호스트 머신에 설치되어 있다면, rebel.compile_from_torch()
함수에서 npu
인자를 생략할 수 있습니다. 이 경우 함수가 자동으로 설치된 NPU를 감지하고 사용합니다. 그러나 NPU가 호스트 머신에 설치되어 있지 않다면, 오류를 방지하기 위해 npu
인자를 사용하여 대상 NPU를 지정해야 합니다.
현재 지원되는 NPU 이름은 RBLN-CA02
, RBLN-CA12
두 가지입니다. 대상 NPU의 이름을 모르는 경우, NPU가 설치된 호스트 머신의 명령어 입력창에서 rbln-stat
명령을 실행하여 확인할 수 있습니다.
컴파일된 모델 저장¶
컴파일된 모델을 로컬 저장소에 저장하려면, compiled_model.save()
메서드를 사용할 수 있습니다.
이 함수를 사용하면 배포를 위해 컴파일된 모델을 저장할 수 있습니다:
컴파일 진행¶
앞서 설명된 컴파일 코드는 compile.py에 포함되어 있습니다. 모델을 컴파일하고 rbln 파일을 생성하려면 다음 명령으로 compile.py를 실행하세요:
이 과정이 성공적으로 완료하면, 로컬 저장소에서 yolov8m.rbln
을 찾을 수 있습니다. 이 파일은 컴파일된 YOLOv8m
모델을 포함하고 있으며, RBLN SDK C/C++ API
를 사용하여 배포할 준비가 된 상태입니다.
2단계. RBLN SDK C/C++ API를 사용한 배포 방법¶
이제 RBLN SDK C/C++ API
를 사용하여 컴파일된 모델을 로드하고, 추론을 실행하고, 출력 결과를 확인할 수 있습니다.
CMake 빌드 스크립트 준비¶
이 튜토리얼은 이미지 전/후처리를 위해 OpenCV를 사용하고, 명령줄 인터페이스(CLI)에서 사용자 매개변수를 파싱하기 위해 argparse를 사용합니다.
다음 CMake 스크립트는 외부 패키지에 대한 의존성과 이들을 예제 애플리케이션 코드와 연결하는 방법을 설명합니다.
입력 준비¶
사전 훈련된 Yolov8m
모델에 필요한 전처리된 이미지를 입력 데이터로 준비해야 합니다. OpenCV
가 제공하는 다양한 비전 API를 사용하여 입력 이미지에 대한 전처리를 수행합니다.
추론 실행¶
RBLN SDK C/C++ API
는 동기와 비동기 추론 방식을 지원합니다. 간략화된 API들에 대한 설명은 아래를 참조하세요.
RBLN API rbln_create_model
은 저장된 모델의 경로를 입력 인자로 전달하여 컴파일된 모델을 로드하는 데 사용됩니다.
또한, rbln_create_runtime
을 사용하여 RBLNModel
, 모듈 이름, 장치 ID로부터 동기 런타임을 생성할 수 있습니다.
비동기 동작을 위해서는 동기식 런타임에 사용한 것과 동일한 인자들을 rbln_create_async_runtime
에 전달하여 비동기 런타임을 생성할 수 있습니다.
런타임에 입력 이미지를 할당하기 위해 rbln_set_input
을 사용합니다. 이 API는 RBLNRuntime
, 입력 버퍼의 인덱스, 전처리된 버퍼의 주소를 인자로 받습니다. 해당 API는 동기식 동작에서만 해당됩니다.
모든 입력이 업데이트되면, RBLNRuntime
을 인자로 rbln_run
을 호출하여 동기 추론을 수행할 수 있습니다.
비동기 동작의 경우 rbln_async_run
에 입력 버퍼와 출력 버퍼를 전달함으로써 비동기 추론이 수행 가능합니다.
마지막으로, rbln_get_output
을 사용하여 추론 결과가 포함된 출력 버퍼를 검색할 수 있습니다. 이 API는 RBLNRuntime
과 출력 인덱스를 인자로 받습니다. 비동기식 동작의 경우, rbln_run
을 호출할 때 입력 버퍼와 출력 버퍼를 전달했으므로, 해당 출력 버퍼들을 직접 참조하면 됩니다.
각 추론 모드에서 필요한 API 사용법에 대해서는 다음 두 가지 예제를 참조해 주세요:
-
동기 실행
-
비동기 실행
후처리¶
출력 data
는 (1, 84, 8400) 형태의 float32 데이터 배열로, 각 요소는 검출된 객체의 좌표, 클래스 ID, 그리고 신뢰도 점수를 나타냅니다.
이 출력은 처리 과정에서 박스, 신뢰도, 클래스 ID으로 분리됩니다. 그 다음, 비최대값 억제(NMS) 과정을 진행합니다. NMS가 완료된 후, 검출 결과는 박스 출력을 위한 후처리 과정을 거칩니다.
아래의 샘플 코드는 다음 순서로 진행됩니다:
- 모델 출력 데이터를 OpenCV Mat 형식으로 변환합니다.
- 검출된 객체들에 대해 반복:
- 경계 박스 좌표를 계산합니다.
- 클래스 신뢰도 점수를 찾고 가장 높은 점수의 클래스를 선택합니다.
- 이 정보를 배열에 저장합니다.
- 중복 검출 정보를 제거하기 위해 NMS를 적용합니다.
- NMS 후 남은 각 검출에 대해:
- 원본 이미지에 경계 박스를 그립니다.
- 해당 카테고리에서 일치하는 클래스 이름과 신뢰도 점수를 박스 위에 텍스트로 추가합니다.
- 결과 이미지를 로컬 저장소에 저장합니다.
리소스 해제¶
CMake를 사용하여 빌드하는 방법¶
위의 API 예제들에 대한 전체 코드는 RBLN Model Zoo C++ 예제에 포함되어 있습니다. 다음 명령어를 사용하여 코드를 쉽게 컴파일하고 실행 가능한 바이너리를 생성할 수 있습니다:
${SAMPLE_PATH}
는 예제 애플리케이션의 경로를 나타냅니다. (예: rbln-model-zoo/cpp/object_detection)
Note
앞서 언급했듯이, 예제 애플리케이션은 이미지 처리 작업을 위해 OpenCV API를 사용합니다. 이를 위해, CMake 빌드 시스템이 OpenCV를 소스에서 직접 가져와 설치합니다. 이 과정은 시스템 사양과 인터넷 연결 속도에 따라 5분 이상 소요될 수 있습니다.
실행 파일 실행 방법¶
위의 모든 단계를 완료했다면, cmake
디렉토리 아래에서 동기식과 비동기식 추론을 위한 object_detection
과 object_detectionn_async
라는 이름의 실행 가능한 바이너리들을 찾을 수 있습니다.
- 동기 실행
- 비동기 실행
출력 결과는 다음과 같습니다: