pytorch模型从训练到LibTorch部署(标贝科技)

1、pytorch和libtorch安装(标贝科技)

PyTorch 是Torch7 团队开发的,从它的名字就可以看出,其与Torch 的不同之处在于PyTorch 使用了Python 作为开发语言。所谓“Python first”,同样说明它是一个以Python 优先的深度学习框架,不仅能够实现强大的GPU 加速,同时还支持动态神经网络,这是现在很多主流框架比如Tensorflow 等都不支持的。
  PyTorch 既可以看做加入了GPU 支持的numpy,同时也可以看成一个拥有自动求导功能的强大的深度神经网络,除了Facebook 之外,它还已经被Twitter、CMU 和Salesforce 等机构采用。
pytorch是一个强大的机器学习库,其中集成了很多方法,但从python本身角度讲,它的速度还不够快,虽然对于许多需要动态性和易迭代性的场景来说,Python是一种合适且首选的语言,但在同样的情况下,Python的这些特性恰恰是不利的。它常常应用于生产环境,这是一个低延迟和有严格部署要求的领域,一般选择C++。

1)安装pytorch

两种方式安装pytorch:根据实际cuda版本和需求安装对应版本pytorch,这里安装的是1.5.0版本。

a.查看cuda版本

cat /usr/local/cuda/version.txt
在这里插入图片描述

得到cuda版本,安装合适版本的pytorch。

b.使用pip安装

pip install torch==1.5.0 -i https://pypi.tuna.tsinghua.edu.cn/simple

c.使用conda安装

下载anaconda
wget https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/Anaconda3-5.2.0-Linux-x86_64.sh
安装anconda
bash Anaconda3-5.2.0-Linux-x86_64.sh
创建test_torch虚拟环境,python版本=3.6
conda create -n test_torch python=3.6
激活test_torch虚拟环境
conda activate test_torch
安装pytorch
conda install torch=1.5.0

d.torch测试

import torch
torch.version

2)安装libtorch

a.确定libtorch版本

使用libtorch调用c++接口,要保证下载的libtorch的版本和pytorch的版本对应,使用低版本的pytorch和高版本的libtorch是没法成功的。根据pytorch和cuda版本确认libtorch版本
查看libtorch版本
https://blog.csdn.net/lxx4610/article/details/105806017/
https://pytorch.org/get-started/locally/

b.从官网下载编译好的文件

获取libtorch有两种方式:
• 从官网下载编译好的文件
https://pytorch.org/ 下载对应版本
在这里插入图片描述

c.自己进行源码编译

码云下载
git clone https://gitee.com/mirrors/pytorch.git
查看libtorch版本
git tag
查看当前分支
git branch
根据cuda和pytorch版本切换到适配的版本
git checkout v1.2.0
更新第三方库
git submodule update --init --recursive
编译
mkdir build
cd build
python ../tools/build_libtorch.py

2、使用pytorch训练模型

这里就不展开介绍

3、将Pytorch模型转化为Torch Script

Torch Script可以完好的表达pytorch模型,而且也能被C++头文件所理解。有两种方法可以将pytorch模型转换成TorchScript,Tracing和Annotation。

1)Tracing

这种方法需要你给模型传入一个sample input,它会跟踪在模型的forward方法中的过程。
例如,加载一个torchvision.models.resnet18()模型
model = torchvision.models.resnet18()
使用 torch.rand(),生成一个随机样例输入
example = torch.rand(1, 3, 224, 224)
torch.jit.trace()方法对根据样例输入跟踪模型的forward方法中的过程
traced_script_module = torch.jit.trace(model, example)
最后导出TorchScript模型。
traced_script_module.save("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) traced_script_module.save("traced_resnet_model.pt") 

2)Annotation

如果forward方法中具有判断语句,Tracing方法就行不通了,Annotation方法则可以处理模型里有判断语句的情形,使用torch.jit.script。
模型定义:

class MyModule(torch.nn.Module): 
	def __init__(self, N, M): 
		super(MyModule, self).__init__()
		self.weight = torch.nn.Parameter(torch.rand(N, M)) 
	def forward(self, input): 
		if input.sum() > 0: 
			output = self.weight.mv(input) 
		else: 
			output = self.weight + input return output 

定义了一个模型结构,在forward方法中使用了判断语句,这种模型在转化为Torch Script时,不能Tracing方法,这时可以使用 torch.jit.script()方法:

my_module = MyModule(10,20) 
traced_script_module = torch.jit.script(my_module) 
traced_script_module.save("traced_resnet_model.pt") 

4、在C++中加载Model

将pytorch训练好的模型导出成torch script形式并保存,C++能够理解,编译并序列化torch script格式的模型。
使用libtorch中torch::jit::load()加载导出的模型。

#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";
 } 

torch::jit::load()函数用来加载模形,参数为模型文件名,返回torch::jit::script::Module类,<torch/script.h>头文件包含了需要的类和方法,这个文件通过安装libtorch得到。

5、运行模型

模型已经导入成功,使用libtorch中的一些方法,你就可以像在python中一样去跑你的模型了,并根据c++模型的输出与python模型的输出,对比结果。

// 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'; 

欢迎体验标贝语音开放平台
地址:https://ai.data-baker.com/#/?source=qaz123
(注:填写邀请码hi25d7,每日免费调用量还可以翻倍)
​​​​​​在这里插入图片描述
在这里插入图片描述

posted @ 2022-01-07 14:41  DataBaker  阅读(1391)  评论(0编辑  收藏  举报