TorchScript is PyTorch’s way of taking your dynamic Python models and making them static, optimized, and deployable outside of Python.

Let’s see it in action. Imagine you have a simple PyTorch model:

import torch
import torch.nn as nn

class SimpleNet(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc = nn.Linear(10, 2)

    def forward(self, x):
        return torch.relu(self.fc(x))

model = SimpleNet()
input_data = torch.randn(1, 10)
output = model(input_data)
print(output)

This is a standard PyTorch model. To make it TorchScript-compatible, we can use torch.jit.script or torch.jit.trace.

torch.jit.script analyzes your Python code directly and converts it into TorchScript. This is great for models with control flow (like if statements or loops) that depend on the values of tensors.

scripted_model = torch.jit.script(model)
output_script = scripted_model(input_data)
print(output_script)

torch.jit.trace records the operations performed by your model when run with a specific input. It’s simpler but can fail if your model’s execution path changes based on input values.

traced_model = torch.jit.trace(model, input_data)
output_trace = traced_model(input_data)
print(output_trace)

Both scripted_model and traced_model are now TorchScript ScriptModule objects. You can save them and load them in environments without Python.

# Save the traced model
traced_model.save("traced_model.pt")

# Load the model elsewhere (e.g., C++ application)
loaded_model = torch.jit.load("traced_model.pt")
loaded_model.eval() # Set to evaluation mode
output_loaded = loaded_model(input_data)
print(output_loaded)

The core problem TorchScript solves is the impedance mismatch between Python’s dynamic nature and the static, optimized execution required for production inference. Python’s flexibility is a double-edged sword: it makes research and experimentation fast but introduces overhead and dependencies that are problematic for deployment. TorchScript bridges this gap by creating a serializable, performant representation of your model.

Internally, TorchScript compiles your Python code into an Abstract Syntax Tree (AST), then into an Intermediate Representation (IR) called the TorchScript IR. This IR is a graph-like representation that can be optimized and executed by a standalone C++ runtime. The process involves type inference, dead code elimination, constant folding, and other compiler optimizations.

When you torch.jit.script a model, the TorchScript compiler walks through your Python code, generating TorchScript IR. It has its own dialect of Python, and certain Python constructs might not be supported or might behave differently. For instance, dynamic shape inference can be tricky. If your model’s behavior (like the size of a tensor it produces or the path it takes in an if statement) depends on the values of intermediate tensors, torch.jit.trace will likely fail because it only records operations for a single given input. torch.jit.script is generally more robust for such cases.

The primary levers you control are how you script/trace your model (torch.jit.script vs. torch.jit.trace) and how you write your Python code to be TorchScript-compatible. For example, instead of dynamically resizing tensors with Python lists, you should use PyTorch tensor operations that maintain static shapes or use torch.jit.script to handle control flow that depends on tensor values. You can also annotate your methods with type hints, which helps the TorchScript compiler with type inference.

One thing most people don’t realize is that TorchScript IR is not a fixed format; it evolves with PyTorch. When you save a TorchScript model, you’re saving it in a specific version of the TorchScript IR. Loading it with a significantly newer or older version of PyTorch might lead to compatibility issues, especially if major internal changes have occurred. This is why it’s crucial to ensure your saving and loading environments use compatible PyTorch versions, or to re-script/re-trace your model with the target deployment version of PyTorch.

The next hurdle you’ll likely face is understanding how to integrate TorchScript models into different deployment environments, such as C++ applications or mobile devices.

Want structured learning?

Take the full Pytorch course →