pytorch很好用,但是真实部署还是使用c++较多,因此需要用c++调用训练好的pytorch模型。
1 centos7系统自带gcc和g++版本都是4.8.5,需要升级到8.3.1,
这里采取参考3方法,gcc和g++会被安装在/opt/rh/devtoolset-8/root/usr/bin目录下,使用命令
/opt/rh/devtoolset-8/root/usr/bin/g++ -v进行查看验证。使用这种方法升级好处是比较简单,另外不会覆盖原来版本,而且可以自由切换gcc版本。
参考1: CentOS 7 升级gcc/g++编译器
参考2: Centos 7 升级gcc
参考3: CentOS 7升级gcc版本
参考4:Ubuntu问题——Ubuntu18.04 更新gcc和g++的版本号
2 从pytorch官网下载libtorch源码
根据需要在pytorch官网下载libtorch源码,这里下载pytorch1.7cpu版本为例。
libtorch源码有两个版本,一个是“Pre-cxx11 ABI”,一个是“cxx11 ABI”。
For guidance on how to install and link with libtorch (the library that contains all of the above C++ APIs), please see: https://pytorch.org/cppdocs/installing.html. Note that on Linux there are two types of libtorch binaries provided: one compiled with GCC pre-cxx11 ABI and the other with GCC cxx11 ABI, and you should make the selection based on the GCC ABI your system is using.
这里需要下载Pre-cxx11 ABI版本的,否则编译不过去。
3 使用python生成pytorch模型
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)
traced_script_module.save("model.pt")
4 在c++使用python生成pytorch模型
参考1:[SOLVED] Build the C++ frontend using g++ or any other compiler (no cmake)
参考2: 使用C++调用并部署pytorch模型
参考3: PyTorch C++ libtorch的使用方法(1)-nightly 版本的 libtorch
参考4: c++ 部署libtorch 时对Tensor块的常用操作API (例如vector转换为torch、squeeze、select、select_indxe、max等
这里采取参考1的方案使用g++进行编译而不是cmake。先编辑testtorch.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;
}
// Deserialize the ScriptModule from a file using torch::jit::load().
torch::jit::script::Module module = torch::jit::load(argv[1]);
// 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'; //与前面python的输出是一样的!
std::cout << "ok\n";
}
1.编译cpp文件:/opt/rh/devtoolset-8/root/usr/bin/g++ testtorch.cpp -o test -std=c++17 -D_GLIBCXX_USE_CXX11_ABI=0 -I /path/to/libtorch/include -I /path/to/libtorch/include/torch/csrc/api/include -L/path/to/libtorch/libtorch/lib -lc10 -ltorch_cpu -lpthread
2 export共享库(动态链接库): export LD_LIBRARY_PATH=/path/to/libtorch/lib:$LD_LIBRARY_PATH
3 执行./test model.pt