LibtorchTutorials
LibtorchTutorials copied to clipboard
使用libtorch训练的pt模型是否能导出onnx
你好,考虑到模型加速的问题,请问下使用libtorch训练得到的pt模型,如何导出onnx?或者如何直接通过tensorRT加速?
能,预先生成同样模型的onnx,把权重赋值进去即可
感谢您的回复,我尝试了下libtorch训练出来的分类模型,发现在推理这块有几个不同的思路:
-
直接用libtorch这套指令,比如如下的方式
torch::load(model,
path); model.forward();` 这种方式是把权重加载到已经有代码结构的model上面,推理的速度非常慢(resnet18分类模型都需要k+ms) 这种方式跟python的方式基本没有什么区别。 -
另外看到一种利用torch::jit的指令,比如
torch::jit::Module model = torch::jit::load(path); model.forward();
这种方式不需要用代码先定义模型结构,加载了就可以跑,在速度上可以通过torch-tensorrt库加速。这种方式我理解就属于torchscript模型了,通过pytorch的torch.jit.trace/script导出的模型可以这样操作。但我发现libtorch训练后用torch::save()模型没法用这个指令加载,那就应该需要把libtorch训练的模型也进行一次jit.trace或者jit.script导出?但这个操作用libtorch的c++ api能完成吗?毕竟都已经用libtorch训练了,就不想再用python做ts模型导出了 -
您提到的方式,那就要先用pytorch/python构建这个模型,然后导出onnx,然后要把libtorch训练得到的torchscript模型权重赋值到onnx模型,不知道有没有合适的demo可以参考?
希望libtorch训练的模型能够真正部署到应用场景、运行速度也能跟onnx模型部署相当,但感觉这块的资料不太多,还请多指教
- 也就比python快一些些,主要是满足某些c++项目
- 没试过,也可以拷贝权重,然后torch-tensorrt加速,可行性应该也ok。
- 没demo,这种要花时间,都没时间弄。但是可行性是验证过的。
尝试了两个简单思路:
-
用libtorch训练出pt模型(该模型也验证过可以在libtorch中做推理),然后尝试在python中用torch.jit.load()加载该pt模型,该步加载可以成功,但jit_model.forward()会报错,AttributeError: 'RecursiveScriptModule' object has no attribute 'forward',看了下导入的这个jit模型在pycharm的变量栏中forward()函数显示为找不到,对应模型子模块也是同样问题(encoder/header),其他正常jit模型都应该有相应的forward函数。
-
用libtorch训练出pt模型,重新通过libtorch的torch::jit::load()加载,forward()同样报错;把该pt模型送入torch_tensorrt做compile转换能够成功得到trt_model,但推理同样报错。
auto device = torch::Device(torch::kCUDA, 0);
auto image = cv::imread("D:\\suliang\\My_Dataset\\misc\\cat.jpg");
cv::resize(image, image, cv::Size(512, 512));
auto input_tensor = torch::from_blob(image.data, { image.rows, image.cols, 3 }, torch::kByte).permute({ 2, 0, 1 }).unsqueeze(0).to(torch::kFloat32) / 255.0;
torch::jit::Module model = torch::jit::load("clas_model_20220419123718_iter13000_acc0.973592.pt");
model.to(device);
model.eval();
auto output = model.forward({ input_tensor.to(device) }).toTensor();
output = torch::softmax(output, 1);
貌似经过libtorch训练后保存得到的torchscript模型跟一般torchscript模型有差异导致。不知道您那边是否有遇到这种情况,还是我这边保存的ts模型有问题?(在github/pytorch论坛上也看到类似issue,但没有解决方案) -
关于您前面提到的torchscript转onnx手动通过权重赋值进去的方式,不知道可行性验证怎么证明,我想这么弄但感觉找不到着手点
这些问题都有遇到,libtorch的api搭建出的网络如果直接torch::save的话确实不同于jit模型,本质上也是不同的类其实。可行性OK是我了解到有公司是这样做的,但是我目前没有demo开源出来。
翻了半天的libtorch论坛,就看到这个:
我理解下来libtorch c++的定位就是用来部署torchscript,而libtorch c++训练出来的模型基本没有什么途径转为静态图的部署模型,甚至不能转自家的torchscript模型,那封装出来这些训练相关的api到底有什么实际用处,太不理解了? 把libtorch保存的pt模型要转换到真正的torchscript或者onnx,除了权重要转,还有op这种东西都要转,而pt的文件结构又不清楚,难度不是一般大啊,大佬给点思路啊,要不然真的只能弃疗了~
onnx模型预先是保存好的,结构和libtorch的一致,然后权重更新进去。固定了模型就没几行代码
而且也可以写得通用,只是预先要有onnx模型文件。
onnx模型我在python里边预先建好了也可以导出来,onnx的proto结构也是可以查到,但libtorch的这种pt模型结构是什么样的呢,我尝试探索了下libtorch_model的结构,发现libtorch_model.graph都解析不出来...
我也没具体代码,只知道可行性.....最近都没时间弄这些。遍历下api吧
哦,pt模型是个压缩文件,可以解压缩...
不知道是不是要把data.pkl跟data文件夹里边的东西解析出来...
可以代码解决的问题.....自己探索下吧
ok,感谢! 我先研究下~
thanks
issue 貌似到现在还没有支持