Pytorch 在TorchScript中跟踪张量大小
我正在通过TorchScript跟踪导出PyTorch模型,但我面临一些问题。具体来说,我必须对张量大小执行一些操作,但JIT编译器将变量形状硬编码为常量,从而阻止了与不同大小张量的兼容性 例如,创建类:Pytorch 在TorchScript中跟踪张量大小,pytorch,jit,torchscript,Pytorch,Jit,Torchscript,我正在通过TorchScript跟踪导出PyTorch模型,但我面临一些问题。具体来说,我必须对张量大小执行一些操作,但JIT编译器将变量形状硬编码为常量,从而阻止了与不同大小张量的兼容性 例如,创建类: Foo类(nn.Module): “”“玩弄张量形状以展示跟踪问题的玩具类。”。 它创建了一个与输入张量形状相同的新张量,除了 对于最后一个维度,它是双倍的。这个新的张量被填充 基于输入的值。 """ 定义初始化(自): nn.模块初始化(自) def前进(自身,x): 新的_形=(x.sha
Foo类(nn.Module):
“”“玩弄张量形状以展示跟踪问题的玩具类。”。
它创建了一个与输入张量形状相同的新张量,除了
对于最后一个维度,它是双倍的。这个新的张量被填充
基于输入的值。
"""
定义初始化(自):
nn.模块初始化(自)
def前进(自身,x):
新的_形=(x.shape[0],2*x.shape[1])#牵连指令
x2=火炬。空(尺寸=新的形状)
x2[:,::2]=x
x2[:,1::2]=x+1
返回x2
并运行测试代码:
x=torch.randn((3,5))#创建示例输入
foo=foo()
tracked_foo=torch.jit.trace(foo,x)#trace
打印(描摹的_foo(x).shape)#显然这是可行的
打印(跟踪_foo(x[:,:4]).shape)#但使用不同的形状失败!
我可以通过编写脚本来解决这个问题,但在这种情况下,我确实需要使用跟踪。此外,我认为追踪应该能够正确处理张量大小的操作
但在这种情况下,我真的需要使用跟踪
您可以根据需要自由混合使用torch.script
和torch.jit
。例如,可以这样做:
import torch
class MySuperModel(torch.nn.Module):
def __init__(self, *args, **kwargs):
super().__init__()
self.scripted = torch.jit.script(Foo(*args, **kwargs))
self.traced = Bar(*args, **kwargs)
def forward(self, data):
return self.scripted(self.traced(data))
model = MySuperModel()
torch.jit.trace(model, (input1, input2))
您还可以将依赖于形状的部分功能移动到单独的功能,并使用@torch.jit.script
:
@torch.jit.script
def _forward_impl(x):
new_shape = (x.shape[0], 2*x.shape[1]) # incriminated instruction
x2 = torch.empty(size=new_shape)
x2[:, ::2] = x
x2[:, 1::2] = x + 1
return x2
class Foo(nn.Module):
def forward(self, x):
return _forward_impl(x)
除了script
之外,没有其他方法可以做到这一点,因为它必须理解您的代码。通过跟踪,它只记录对张量执行的操作,不知道依赖于数据(或数据形状)的控制流
无论如何,这应该涵盖大多数情况,如果没有,你应该更具体。这非常有效,谢谢。