AI/활용

PyTorch 모델을 C++ 에 빌드 및 컴파일하기

모딩 2021. 1. 24. 14:56
반응형

 

PyTorch 모델을 Python에서부터 C++로 변환하여 빌드 및 컴파일 해보려한다.

맥 환경에서 비주얼 스튜디오를 사용할 수 없기 때문에, VSCode를 사용했다. C++을 빌드하기 위해 해당 블로그를 참고하여 g++로 진행했다.
**CLion으로 C++ 빌드하는 것이 VSCode보다 간편하다고 한다! 

 

LibTorch 다운로드

pytorch.org/

LibTorch부터 다운로드해서 로컬에서 사용할 수 있게 세팅해야 한다. 

MacOS에서는 CUDA가 지원되지 않아 아래처럼 나와있다.

MacOS Binaries dont support CUDA, install from source if CUDA is needed

 

Libtorch를 다운받은 후, 아래 주소를 참고하여 차근차근 따라해보았다. 

tutorials.pytorch.kr/advanced/cpp_export.html#annotation-torchscript

 

한가지 유의해야 할 것은 디렉토리 구조인데, 

메인이 되는 폴더가 libtorch-build 라면, libtorch는 메인 폴더 밖에 구성했다. 

libtorch-build/

     CMakeLists.txt

     test.cpp

libtorch/

     ...

CMakeLists.txt 

cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(test)
set(CMAKE_CXX_COMPILER g++)
find_package(Torch REQUIRED)

add_executable(libtorch-build test.cpp)
target_link_libraries(libtorch-build "${TORCH_LIBRARIES}")
set_property(TARGET libtorch-build PROPERTY CXX_STANDARD 14)

 

cmake 실행 

mkdir build 
# cd build 실행하지 말것! 
$ cmake -DCMAKE_PREFIX_PATH=libtorch가 있는 경로
make
$ ./libtorch-build

 

⭐️libiomp5.dylib, libmklml.dylib 추가 ⭐️

Cmake로 빌드하고 실행하다보면 막히는 부분이 있다. 아래처럼 뜨면서 안된다.......

dyld: Library not loaded: @rpath/libmklml.dylibReferenced from: /libtorch/lib/libtorch.1.dylibReason: image not foundAbort trap: 6

libmklml.dylib이 없다는 것인데 이건 https://github.com/intel/mkl-dnn/releases/tag/v0.20 에서 다운로드 받을 수 있다. 

libiomp5.dylib, libmklml.dylib 두 라이브러리 파일을 libtorch가 있는 폴더의 lib안에 넣어주면 된다.

 

 

모델 적용하여 빌드 

이제 trace된 MobileNetV2 모델인 scripted_trace_model.pt 경로를 libtorch-build 바이너리에 입력한다.

make 명령어를 실행한 후, 결과값을 확인할 수 있다.

 

Script 모듈을  C++에서 실행하기

MobileNetV2을 C++에서 성공적으로 로딩했으니, 모듈을 실행해보자!

아래는 실행을 위한 C++어플리케이션의 main() 함수의 일부 코드이다. 

// 입력값 벡터를 생성합니다.
std::vector<torch::jit::IValue> inputs;
inputs.push_back(torch::ones({1, 3, 224, 224}));

// 모델을 실행한 뒤 리턴값을 텐서로 변환합니다.
at::Tensor output = module.forward(inputs).toTensor();
std::cout << output.slice(/*dim=*/1, /*start=*/0, /*end=*/5) << '\n';

첫 두줄은 모델의 입력값을 생성한다. 

torch::jit::IValue의 벡터를 만들고 그 벡터에 하나의 입력값을 추가한다.

여기서 벡터는, script::Module 메소드들이 입력받고 또 리턴할 수 있는 타입이 소거된 자료형을 말한다.

입력값 텐서를 만들기 위해서 우리는 torch::ones() 을 사용한다. 이 함수는 torch.ones 의 C++ API 버전이다.

이제 script::Module  forward 메소드에 입력값 벡터를 넘겨주어 실행하면, 새로운 IValue 를 리턴받게되고, 이 값을 toTensor() 를 통해 텐서로 변환할 수 있다.

 

어플리케이션을 다시 컴파일하고 직렬화된 모델에 대해 실행해보았다. 

$ /libtorch-build/build# make
$ /libtorch-build/build# ./libtorch-build scripted_trace_model.pt

 

마지막 줄에서 출력값의 첫 다섯 값들을 프린트하여 결과값을 리턴하는 것을 확인할 수 있다.

0.5421  0.2192  0.3782
 0.5388  0.7200  0.8694
[ CPUFloatType{2,3} ]

 

전체 test.cpp 코드 

#include <torch/script.h> // 필요한 단 하나의 헤더파일.

#include <iostream>
#include <memory>

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


  torch::jit::script::Module module;
  try {
    // torch::jit::load()을 사용해 ScriptModule을 파일로부터 역직렬화
    module = torch::jit::load(argv[1]);
  }
  catch (const c10::Error& e) {
    std::cerr << "error loading the model\n";
    return -1;
  }

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

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

	// 모델을 실행한 뒤 리턴값을 텐서로 변환합니다.
	at::Tensor output = module.forward(inputs).toTensor();
	std::cout << output.slice(/*dim=*/1, /*start=*/0, /*end=*/5) << '\n';
}

 

전체 실행 명령어

cd /Users/hyojin/Documents/git/libtorch-build
cmake -DCMAKE_PREFIX_PATH=/Users/hyojin/Documents/git/libtorch
make
./libtorch-build scripted_trace_model.pt

 

실행 결과

 

Last login: Sun Jan 24 15:09:30 on ttys001

The default interactive shell is now zsh.
To update your account to use zsh, please run `chsh -s /bin/zsh`.
For more details, please visit https://support.apple.com/kb/HT208050.
(base) Hyojinui-MacBookPro:~ hyojin$ cd /Users/hyojin/Documents/git/libtorch-build
(base) Hyojinui-MacBookPro:libtorch-build hyojin$ cmake -DCMAKE_PREFIX_PATH=/Users/hyojin/Documents/git/libtorch
CMake Warning:
  No source or binary directory provided.  Both will be assumed to be the
  same as the current working directory, but note that this warning will
  become a fatal error in future CMake releases.


-- Configuring done
-- Generating done
-- Build files have been written to: /Users/hyojin/Documents/git/libtorch-build
(base) Hyojinui-MacBookPro:libtorch-build hyojin$ make
Scanning dependencies of target libtorch-build
[ 50%] Building CXX object CMakeFiles/libtorch-build.dir/test.cpp.o
[100%] Linking CXX executable libtorch-build
[100%] Built target libtorch-build
(base) Hyojinui-MacBookPro:libtorch-build hyojin$ ./libtorch-build scripted_trace_model.pt
ok
-0.2579  0.0892 -0.4700 -0.4527 -0.2887
[ CPUFloatType{1,5} ]
(base) Hyojinui-MacBookPro:libtorch-build hyojin$ 

 

 

참고자료 

medium.com/@albertsundjaja/installing-pytorch-c-api-d52c722f47ec

jeongukjae.github.io/posts/libtorch-setting-in-macos/

반응형

'AI > 활용' 카테고리의 다른 글

Pytorch로 Fashion MNIST 구현하기  (0) 2021.03.03