C/C++ API를 사용한 이미지 분류¶
이 튜토리얼은 RBLN SDK C/C++ API
를 사용하여 파이토치 ResNet50 모델을 배포하는 방법을 소개합니다. 모델 컴파일은 RBLN SDK Python API
를 통해 수행할 수 있으며, 결과로 나온 *.rbln
파일은 RBLN SDK C/C++ API
를 사용하여 추론을 실행 할 수 있습니다.
이는 Python API의 간편한 모델 준비와 C/C++의 빠른 추론 성능을 결합한 접근 방식입니다. 튜토리얼에서 사용된 전체 코드는 RBLN Model Zoo에서 확인할 수 있습니다.
이 튜토리얼은 두 부분으로 나누어져 있습니다:
- Python API로 PyTorch
ResNet50
을 컴파일하고, 컴파일된 모델을 저장하는 방법 - 컴파일된 모델을 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
를 사용합니다.
모델 준비¶
먼저 TorchVision 라이브러리에서 ResNet50
모델을 가져올 수 있습니다.
모델 컴파일¶
torch 모델 torch.nn.Module
이 준비되면, rebel.compile_from_torch()
메서드를 사용하여 간단히 모델을 컴파일할 수 있습니다.
NPU가 호스트 머신에 장착되어 있다면, rebel.compile_from_torch()
함수에서 npu
인자를 생략할 수 있습니다. 이 경우 함수가 자동으로 장착되어 있는 NPU를 감지하여 NPU 종류에 맞게 컴파일을 진행합니다. 만약 NPU가 호스트 머신에 장착되어 있지 않다면, 오류를 방지하기 위해 npu
인자를 사용하여 대상 NPU를 지정해야 합니다.
현재 지원되는 NPU 이름은 RBLN-CA02
, RBLN-CA12
두 가지입니다. 대상 NPU의 이름을 모르는 경우, NPU가 설치된 호스트 머신의 명령어 창에서 rbln-stat
명령을 실행하여 확인할 수 있습니다.
컴파일된 모델 저장¶
컴파일된 모델을 로컬 저장소에 저장하려면, compiled_model.save()
메서드를 사용할 수 있습니다.
이 함수를 사용하면 배포를 위해 컴파일된 모델을 저장할 수 있습니다:
컴파일 진행¶
위의 컴파일 코드는 compile.py에 포함되어 있습니다. 모델을 컴파일하고 *.rbln
파일을 생성하려면 다음 명령으로 compile.py를 실행하세요:
이 과정이 성공적으로 완료되면 로컬 저장소에서 resnet50.rbln
을 찾을 수 있습니다. 이 파일은 컴파일된 ResNet50
모델을 포함하고 있으며,RBLN SDK C/C++ API
를 사용하여 배포할 준비가 된 상태입니다.
2단계. RBLN SDK C/C++ API를 사용한 배포 방법¶
이제 RBLN SDK C/C++ API
를 사용하여 컴파일된 모델을 로드하고, 추론을 실행하고, 출력 결과를 확인할 수 있습니다.
CMake 빌드 스크립트 준비¶
이 튜토리얼은 이미지 전/후처리를 위해 OpenCV를 사용하고, 명령줄 인터페이스(CLI)에서 사용자 매개변수를 파싱하기 위해 argparse를 사용합니다.
다음 CMake 스크립트는 외부 패키지에 대한 의존성과 이들을 예제 애플리케이션 코드와 연결하는 방법을 설명합니다.
입력 준비¶
사전 훈련된 ResNet50
모델에 필요한 전처리된 이미지를 입력 데이터로 준비해야 합니다. 여기서는 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 사용법에 대해서는 다음 두 가지 예제를 참고해 주세요:
-
동기 실행
-
비동기 실행
후처리¶
출력 logits
는 크기가 (1, 1000)인 float32 데이터 배열로, 각 요소는 ImageNet 데이터셋의 해당 카테고리의 점수를 나타냅니다. 이 logits에서 top-1 인덱스를 도출하고, 이 top-1 인덱스를 사용하여 미리 정의된 Top1 클래스에서 해당 카테고리를 검색할 수 있습니다.
리소스 해제¶
CMake를 사용하여 빌드하는 방법¶
위의 API 예제들에 대한 전체 코드는 RBLN Model Zoo C++ 예제에 포함되어 있습니다. 다음 명령어를 사용하여 코드를 쉽게 컴파일하고 실행 가능한 바이너리를 생성할 수 있습니다:
${SAMPLE_PATH}
는 예제 애플리케이션의 경로를 나타냅니다. (예: rbln-model-zoo/cpp/image_classification)
Note
앞서 언급했듯이, 예제 애플리케이션은 이미지 처리 작업을 위해 OpenCV API를 사용합니다. 이를 위해, CMake 빌드 시스템이 OpenCV를 소스에서 직접 가져와 설치합니다. 이 과정은 시스템 사양과 인터넷 연결 속도에 따라 5분 이상 소요될 수 있습니다.
실행 파일 실행 방법¶
위의 모든 단계를 완료했다면, cmake
디렉토리 아래에서 동기식과 비동기식 추론을 위한 image_classification
과 image_classification_async
라는 이름의 실행 가능한 바이너리들을 찾을 수 있습니다.
-
동기 실행
-
비동기 실행
출력 결과는 다음과 같습니다: