Pytorch 在TorchScript中跟踪张量大小

Pytorch 在TorchScript中跟踪张量大小,pytorch,jit,torchscript,Pytorch,Jit,Torchscript,我正在通过TorchScript跟踪导出PyTorch模型,但我面临一些问题。具体来说,我必须对张量大小执行一些操作,但JIT编译器将变量形状硬编码为常量,从而阻止了与不同大小张量的兼容性 例如,创建类: Foo类(nn.Module): “”“玩弄张量形状以展示跟踪问题的玩具类。”。 它创建了一个与输入张量形状相同的新张量,除了 对于最后一个维度,它是双倍的。这个新的张量被填充 基于输入的值。 """ 定义初始化(自): nn.模块初始化(自) def前进(自身,x): 新的_形=(x.sha

我正在通过TorchScript跟踪导出PyTorch模型,但我面临一些问题。具体来说,我必须对张量大小执行一些操作,但JIT编译器将变量形状硬编码为常量,从而阻止了与不同大小张量的兼容性

例如,创建类:

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
之外,没有其他方法可以做到这一点,因为它必须理解您的代码。通过跟踪,它只记录对张量执行的操作,不知道依赖于数据(或数据形状)的控制流


无论如何,这应该涵盖大多数情况,如果没有,你应该更具体。

这非常有效,谢谢。