在c++中加载TorchScript模型

在c++中加载TorchScript模型

一、运行环境
win 10
vs 2015
OpenCV 3.4.1
cmake
libtorch
二、opencv环境搭建
详情请见https://blog.csdn.net/qq_41175905/article/details/80560429
这位博客是vs2017我用到我的vs2015上同样适用
三、libtorch安装
1.官网下载地址(选择适合自己的版本)
https://pytorch.org/get-started/locally/
因为我个人使用的cuda10.0,如果嫌弃官网下载缓慢可以在百度云获取链接如下:
链接:https://pan.baidu.com/s/1jTYNGbH9aC72fkdtGVZY3g
提取码:8ikt
四、案例测试:
官网英文文档:https://pytorch.org/docs/stable/cpp_index.html
中文文档1。2版本:https://pytorch.apachecn.org/docs/1.2/advanced/cpp_export.html
1.通过跟踪转换为 Torch Script
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)

ScriptModule现在可以与常规PyTorch模块相同地评估被跟踪的对象:

In[1]: output = traced_script_module(torch.ones(1, 3, 224, 224))
In[2]: output[0, :5]
Out[2]: tensor([-0.2698, -0.0381,  0.4023, -0.3010, -0.0448], grad_fn=<SliceBackward>)

2.将脚本模块序列化为文件
一旦有了对ScriptModule PyTorch模型的跟踪或注释,就可以将其序列化为文件了。稍后,您将能够使用C++从此文件加载模块并执行它,而无需依赖Python。假设我们要序列化ResNet18先前在跟踪示例中显示的模型。要执行此序列化,只需 在模块上调用 save 并传递一个文件名即可:

traced_script_module.save("traced_resnet_model.pt")

3.因为官方文档写的比较繁杂,自己改进官方案例如下:
想要知道每一步代表的含义,请对照官方文档中相应代码的解释。
(1)pytorch模型转换为Torch脚本

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")

运行该脚本,会生成一个 model.pt 文件,该文件就是C++需要调用的模型。
(2)准备c++测试代码和CMakelists.txt文件
首先自己选取一个路径新建一个文件夹,个人选择桌面新建一个build的文件夹,之后在该文件夹下创建c++测试代码。(例如:example-app.cpp)和CMakelists.txt文件以及名为build的文件夹。
CMakelists.txt 内容如下:

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

find_package(Torch REQUIRED)
find_package(OpenCV REQUIRED)

if(NOT Torch_FOUND)
    message(FATAL_ERROR "Pytorch Not Found!")
endif(NOT Torch_FOUND)

message(STATUS "Pytorch status:")
message(STATUS "    libraries: ${TORCH_LIBRARIES}")

message(STATUS "OpenCV library status:")
message(STATUS "    version: ${OpenCV_VERSION}")
message(STATUS "    libraries: ${OpenCV_LIBS}")
message(STATUS "    include path: ${OpenCV_INCLUDE_DIRS}")


add_executable(example-app example-app.cpp)
target_link_libraries(example-app ${TORCH_LIBRARIES} ${OpenCV_LIBS})
set_property(TARGET example-app PROPERTY CXX_STANDARD 11)

C++测试代码文件(example-app.cpp)内容如下:

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

int main() {
  // Deserialize the ScriptModule from a file using torch::jit::load().
  std::shared_ptr<torch::jit::script::Module> module = torch::jit::load("C:\Users\workAI\Desktop\build/model.pt");

  assert(module != nullptr);
  std::cout << "ok\n";
  // 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';
  while (1);
}

build文件夹的具体文件如下:
在这里插入图片描述
(3)应用程序编译
在新建文件夹的目录下的自己建立的build文件夹中启动cmd命令窗口,执行命令:

cmake -DCMAKE_PREFIX_PATH=E:\OpenCV\opencv\build\x64\vc14\lib;E:\libtorch -DCMAKE_BUILD_TYPE=Release -G "Visual Studio 14 Win64" ..

注意:上面的指令需要根据自己实际配置进行修改,第一个是opencv的路径,第二个是libtorch的路径,第三个是使用的VS版本。我这里下载的是release版本的libtorch,使用的是VS2017,所以参数如上设置,如果使用的是VS2015,则需要将Visual Studio 15 Win64 改为 Visual Studio 14 Win64 ,opencv/build/x64/vc15/bin 改为 opencv/build/x64/vc14/bin。不出错的话应该输出类似下图的内容:
具体运行结果如下:
在这里插入图片描述
具体build文件夹中生成的目录如下:
在这里插入图片描述
使用vs2015打开example-app.vcxproj,在vs中将debug模式更改为release模式
然后将该项目设置为启动项目
之后进行运行。
最终的运行结果如下:
在这里插入图片描述

五、坑之路
1.error C2440: “初始化”: 无法从“torch::jit::script::Module”转换为“std::shared_ptrtorch::jit::script::Module”
解决方法为:原因是std::shared_ptr这个是libtorch测试版本使用的变量类型,现在已经变更,将 std::shared_ptrtorch::jit::script::Module module = torch::jit::load("…/xxx.pt"); 修改为 torch::jit::script::Module module = torch::jit::load("…/xxx.pt");同时,module已经不是指针,将 at::Tensor output = module->forward(inputs).toTensor();修改为 torch::Tensor output = module.forward(std::move(inputs)).toTensor();
2.在这里插入图片描述
这时需要到libtorch的lib路径下将torch.dll文件复制到工程build\build\Release中,然后再运行,然后这时又报缺少caffe2.dll文件,接着重复同样的问题,接连报缺少nvToolsExt64_1.dll、caffe2_gpu.dll、c10_cuda.dll文件,开始没办法,只能一一将其复制添加到工程build\build\Release中,最后运行才成功。

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值