PyTorch 모델을 Python에서부터 C++로 변환하여 빌드 및 컴파일 해보려한다.
맥 환경에서 비주얼 스튜디오를 사용할 수 없기 때문에, VSCode를 사용했다. C++을 빌드하기 위해 해당 블로그를 참고하여 g++로 진행했다.
**CLion으로 C++ 빌드하는 것이 VSCode보다 간편하다고 한다!
LibTorch 다운로드
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
'AI > 활용' 카테고리의 다른 글
Pytorch로 Fashion MNIST 구현하기 (0) | 2021.03.03 |
---|