從TorchScript生成模型到windows+vs2019+LibTorch調用模型
Pytorch官方已經把自己的廣告語打成了:From Research To Production,可見Pytorch已經計劃從一個純研究環境,向可以支持落地的產品環境轉變支持。
從2020年5月5日官方發佈1.5.0版本開始,支持C++部署的版本終於姍姍來遲,這爲工業深度學習應用吹響了號角。
但是目前在windows環境下部署libtorch的文檔還較少,還需要我們進一步摸索,在此把自己踩過的坑分享出來,以饗志同道合的同學們。
如有錯誤,敬請指正。謝謝!
文章目錄
References
Loading a TorchScript Model in C++
環境配置
-
windows系統下配置NVIDIA CUDA(>= 9.2) & cuDNN(適配CUDA版本)
1)前往NVIDIA官網CUDADownload頁面下載CUDA安裝包,傻瓜式安裝,無坑,經驗證,最新版cuda自動配置環境變量,如需配置環境變量,請參看如下圖片,注意:支持torchscript和libtorch的cuda版本至少需要9.2以上;
安裝完畢後可以查看版本,如圖,我安裝的是cuda10.2版本
2)在NVIDIA官網cuDNN頁面下載對應CUDA版本的cuDNN包;
3)解壓安裝包,把cuDNN下的幾個包按路徑分別放置在CUDA安裝路徑下的對應路徑下;
cuDNN包下的三個路徑如下:
對應的CUDA路徑如下:
-
windows系統下配置Visual Studio & Anaconda
1)下載並在線安裝visual studio(省略)
2)下載並安裝Anaconda(省略) -
windows系統下配置Pytorch version >= 1.5.0
1)首先建立虛擬環境:conda create -n <envname> python=3.6
2)安裝pytorch 1.5.0包:
conda install pytorch torchvision cudatoolkit=10.2 -c pytorch
-
windows系統下配置LibTorch: PyTorch C++ API
按要求下載
下載後解壓縮備用
Windows+VS2019+LibTorch配置項目調用模型
A 第一步:將你的Pytorch模型轉換成Torch Script
假設你已經有一個python環境下訓練得到的Pytorch模型,有兩種方式進行轉換,一種稱之爲Tracing,另一種是通過註解:
1)第一種方法,Tracing
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)
2)第二種方法,註解法
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
my_module = MyModule(10,20)
sm = torch.jit.script(my_module)
B 第二步:將你的Script模型序列化成文件
1)Tracing下的文件轉換
my_module.save("my_module.pt")
2)Annotation下的文件轉換
traced_script_module.save("traced_resnet_model.pt")
C 第三步:在Visual Studio下新建一個項目並配置包含文件目錄各鏈接庫目錄
1)首先選定x64平臺,由於libtorch庫的預編譯是由x64平臺實現的,所以一定要選定x64平臺;
2)VC++目錄 -> 包含目錄,添加LibTorch庫的路徑:
E:\libtorch-win-shared-with-deps-debug-1.5.0\libtorch\include
3)C/C++ -> 附加包含目錄,添加LibTorch庫的路徑:
E:\libtorch-win-shared-with-deps-debug-1.5.0\libtorch\include
4)鏈接器 -> 附加庫目錄,添加LibTorch依賴文件的路徑:
E:\libtorch-win-shared-with-deps-debug-1.5.0\libtorch\include
5)鏈接器 -> 輸入 -> 附加依賴項,添加依賴文件名:
asmjit.lib
c10.lib
c10_cuda.lib
caffe2_detectron_ops_gpu.lib
caffe2_module_test_dynamic.lib
caffe2_nvrtc.lib
clog.lib
cpuinfo.lib
fbgemm.lib
libprotobufd.lib
libprotobuf-lited.lib
libprotocd.lib
mkldnn.lib
torch_cpu.lib
torch_cuda.lib
torch.lib
Ps: 這裏的文件可能並不是都需要,我比較懶,全扔進去
6)C/C++ -> 語言 -> 符合模式 ,改成“否”
到這一步爲止,編譯已經沒有問題,但是實際運行時可能會報錯,報c10.dll文件找不到的錯誤
7)重要的一步,在LibTorch沒有改良之前,需要將丟失的.dll文件直接放進項目debug文件夾下,這樣做的後果可能會使單個項目文件比較大,但考慮我們部署時原本就需要將dll文件打包到安裝目錄下,因此這也不是什麼問題。
D 第四步:新建Minimal C++ 應用
#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";
}
E 第五步:編譯生成可執行文件
這個程序需要傳入模型文件參數,因此先編譯生成可執行文件