pytorch runtime_error ai_generated true

RuntimeError: TorchScript supports tracing only for tensors. This function cannot be traced because it uses dynamic control flow (e.g., if/else or loops).

ID: pytorch/torchscript-dynamic-control-flow

Also available as: JSON · Markdown · 中文
90%Fix Rate
88%Confidence
1Evidence
2023-02-10First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
torch 1.9.0 active
torch 2.0.0 active
python 3.9 active

Root Cause

TorchScript tracing (torch.jit.trace) cannot handle Python control flow that depends on tensor values; it records operations on specific inputs and fails when the path changes.

generic

中文

TorchScript 跟踪(torch.jit.trace)无法处理依赖于张量值的 Python 控制流;它记录特定输入上的操作,并在路径更改时失败。

Official Documentation

https://pytorch.org/docs/stable/jit.html#mixing-tracing-and-scripting

Workarounds

  1. 90% success Use torch.jit.script instead of trace for models with dynamic control flow: @torch.jit.script def forward(self, x): if x.sum() > 0: return x * 2 else: return x / 2 # Then script the model: scripted_model = torch.jit.script(model)
    Use torch.jit.script instead of trace for models with dynamic control flow:
    @torch.jit.script
    def forward(self, x):
        if x.sum() > 0:
            return x * 2
        else:
            return x / 2
    # Then script the model: scripted_model = torch.jit.script(model)
  2. 85% success Refactor the model to avoid dynamic control flow in the traced function, e.g., use torch.where or masked operations: def forward(self, x): mask = (x.sum(dim=1, keepdim=True) > 0).float() return x * (1 + mask) # equivalent to if-else
    Refactor the model to avoid dynamic control flow in the traced function, e.g., use torch.where or masked operations:
    def forward(self, x):
        mask = (x.sum(dim=1, keepdim=True) > 0).float()
        return x * (1 + mask)  # equivalent to if-else

中文步骤

  1. Use torch.jit.script instead of trace for models with dynamic control flow:
    @torch.jit.script
    def forward(self, x):
        if x.sum() > 0:
            return x * 2
        else:
            return x / 2
    # Then script the model: scripted_model = torch.jit.script(model)
  2. Refactor the model to avoid dynamic control flow in the traced function, e.g., use torch.where or masked operations:
    def forward(self, x):
        mask = (x.sum(dim=1, keepdim=True) > 0).float()
        return x * (1 + mask)  # equivalent to if-else

Dead Ends

Common approaches that don't work:

  1. 80% fail

    Using torch.jit.trace with a large set of example inputs may still fail if control flow depends on runtime values not present in examples.

  2. 70% fail

    Adding more concrete inputs to trace may cover some paths but not all, leading to incomplete traces.