반응형
Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

테크매니아

libtorch example : Pytroch to C++ sample code 본문

카테고리 없음

libtorch example : Pytroch to C++ sample code

SciomageLAB 2024. 10. 20. 16:44
반응형

개요

Pytorch는 딥러닝 모델 개발에 널리 사용되는 프레임워크 입니다.

Pytorch에서 개발된 모델을 배포 할 때 배포되는 패키지에 딥러닝 개발 프레임워크인 Pytorch를 몽땅 포함해서 배포 하는게 바람직한 일이 아닙니다.

개발된 모델을 onnx로 바꾸거나 CPU, GPU, DSP, NPU에서 제공되는 SDK가 있다면 그것을 이용해서 배포할 수도 있습니다.

이 글에서는 libtorch에 대해서 알아보겠습니다.

libtorch 설치

libtorch를 설치하는 방법에 대해서 설명합니다.

libtorch는 이미 빌드된 바이너리가 공개되어 있기 때문에 일반적인 환경에서 바로 압축파일을 다운을수 있습니다.

링크를 통해 GPU에서 빌드된 버전의 바이너리나 소스코드를 직접 받아서 빌드할 수 있습니다.

wget https://download.pytorch.org/libtorch/nightly/cpu/libtorch-shared-with-deps-latest.zip
unzip libtorch-shared-with-deps-latest.zip

위 스크립트대로 이미 빌드된 libtorch를 다운받아 보겠습니다.

환경은 x64 Ubuntu20.04 버전입니다.

Pytorch에서 모델 export

Pytorch에서 개발된 모델을 torch.jit.trace를 통해 Torch Script로 변환합니다.

torchvision에 있는 resnet18를 그대로 사용합니다.

입출력 텐서의 shape을 잘 확인하고 traced_resnet_model.pt 이름으로 저장합니다.

import torch
import torchvision

# An instance of your model.
model = torchvision.models.resnet18()

# An example input you would normally provide to your model's forward() method.
example = torch.rand(1, 3, 224, 224)

# Use torch.jit.trace to generate a torch.jit.ScriptModule via tracing.
traced_script_module = torch.jit.trace(model, example)

output = traced_script_module(torch.ones(1, 3, 224, 224))

traced_script_module.save("traced_resnet_model.pt")

C++ 샘플 작성

Pytorch에서 저장한 모델을 로드하는 샘플 C++ 코드를 작성합니다.

파일 이름은 main.cpp으로 합니다.

파라미터로 받은 모델을 읽고 오류를 체크 합니다.

#include <torch/script.h> // One-stop header.

#include <iostream>
#include <memory>

int main(int argc, const char* argv[]) {
  if (argc != 2) {
    std::cerr << "usage: example-app <path-to-exported-script-module>\n";
    return -1;
  }

  torch::jit::script::Module module;
  try {
    // Deserialize the ScriptModule from a file using torch::jit::load().
    module = torch::jit::load(argv[1]);
  }
  catch (const c10::Error& e) {
    std::cerr << "error loading the model\n";
    return -1;
  }

  std::cout << "ok\n";
}

CMakeLists 작성

위에서 작성한 C++ 파일을 빌드하기 위해 main.cpp와 같은 디렉토리에 CMakeLists.txt 파일을 작성합니다.

cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(example-app)

find_package(Torch REQUIRED)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TORCH_CXX_FLAGS}")

add_executable(example-app main.cpp)
target_link_libraries(example-app "${TORCH_LIBRARIES}")
set_property(TARGET example-app PROPERTY CXX_STANDARD 14)

Build

cmake에서 CMAKE_PREFIX_PATH를 libtorch의 경로로 설정합니다.

mkdir build
cd build
cmake -DCMAKE_PREFIX_PATH=/home/.../pytorch2cpp/libtorch ..
make -j4

Test

빌드된 바이너리 example-app를 실행합니다.

./example-app 
usage: example-app <path-to-exported-script-module>

./example-app ../traced_resnet_model.pt 
ok

파라미터로 Pytorch에서 저장한 파일을 넣어주면 정상 작동을 확인합니다.

C++에서 Script Module을 실행하기 위해서 다시 main.cpp파일 하단에 아래 코드를 추가 합니다.

입력 shape에 맞게 tensor를 생성하고 forward합니다.

// Create a vector of inputs.
std::vector<torch::jit::IValue> inputs;
inputs.push_back(torch::ones({1, 3, 224, 224}));

// Execute the model and turn its output into a tensor.
at::Tensor output = module.forward(inputs).toTensor();
std::cout << output.slice(/*dim=*/1, /*start=*/0, /*end=*/5) << '\n';

다시 코드를 build하고 실행하면 추론 결과를 확인 할 수 있습니다.

./example-app ../traced_resnet_model.pt 
-0.9616 -0.6217 -0.1954  0.3419 -0.3290
[ CPUFloatType{1,5} ]
ok

전체 코드

Github 링크

참고자료

반응형