在要求低延迟、脚本部署的生存环境,C++是更被青睐的语言。在之前版本的PyTorch
提供的都是Python
语言的接口,PyTorch1.0版本的发布带来了C++的前端,为生产环境的部署带来了极大的方便。目前PyTorch1.3.0的稳定版本已经可以在官网下载了,本文的所有代码均运行在 cuda 10.1, cudnn 7 LibTorch1.3.0环境下。
Pytorch Model
转换为Torch Script
首先,C++能够理解的模型不是原生的Python版本的模型,而是需要通过Torch Script
编译和序列化Python模型,C++调用序列化后的模型进行预测。
官方给出了两种将PyTorch
模型转换为Torch Script
的方法,第一种是通过torch.jit.trace
方法,该方法缺点是在forward()
中不能有复杂的条件控制,优点是操作比较方便;第二种是通过torch.jit.script
方法进行转换,该方法允许forward()
中有条件控制。
torch.jit.trace
方法转换我们先新建一个简单的线性模型
class MyModel(nn.Module):
def __init__(self, N, M):
super(MyModel, self).__init__()
self.linear = nn.Linear(N, M)
def forward(self, inputs):
output = self.linear(inputs)
return output
接下来我们仅需一行代码即可完成转换
B, N, M = 64, 32, 8
model = MyModel(N, M)
data = torch.rand(B, N)
# Use torch.jit.trace to generate a torch.jit.ScriptModule via tracing.
traced_script_module = torch.jit.trace(model, data)
traced_script_module
即为转换好的C++需要的模型。可以调用save()
函数保存模型。
traced_script_module.save("[model.pt](<http://model.pt/>)")
torch.jit.script
方法在1.0.0
的版本中,该方法需要重新写一个类,这个类继承torch.jit.ScriptModule
,同时对需要使用的方法添加@torch.jit.script_method
装饰器,较为麻烦。在最新的1.3.0
版本中已经简化模型仍然继承的是torch.nn.Module
,且不需要使用装饰器,直接使用torch.jit.script
方法即可,非常方便。
模型代码不变:
class MyModel(nn.Module):
def __init__(self, N, M):
super(MyModel, self).__init__()
self.linear = nn.Linear(N, M)
def forward(self, inputs):
output = self.linear(inputs)
return output
保存模型之前需要调用torch.jit.script
将模型转换为ScriptModule
:
B, N, M = 64, 32, 8
model = MyModel(N, M)
traced_script_module = torch.jit.script(model)
traced_script_module.save("model.pt")
PyTorch的C++接口官方包名为LibTorch
,可以在官网下载,无需编译即可使用。