Skip to content

Commit 904ca90

Browse files
authored
Add a note to the torchscript tutorials (#3115)
1 parent 2f3f3fa commit 904ca90

9 files changed

+19
-213
lines changed

advanced_source/cpp_export.rst

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
Loading a TorchScript Model in C++
22
=====================================
33

4+
.. note:: TorchScript is no longer in active development.
5+
46
As its name suggests, the primary interface to PyTorch is the Python
57
programming language. While Python is a suitable and preferred language for
68
many scenarios requiring dynamism and ease of iteration, there are equally many

advanced_source/torch-script-parallelism.rst

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
Dynamic Parallelism in TorchScript
22
==================================
33

4+
.. note:: TorchScript is no longer in active development.
5+
46
In this tutorial, we introduce the syntax for doing *dynamic inter-op parallelism*
57
in TorchScript. This parallelism has the following properties:
68

advanced_source/torch_script_custom_classes.rst

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
Extending TorchScript with Custom C++ Classes
22
===============================================
33

4+
.. note:: TorchScript is no longer in active development.
5+
46
This tutorial is a follow-on to the
57
:doc:`custom operator <torch_script_custom_ops>`
68
tutorial, and introduces the API we've built for binding C++ classes into TorchScript

beginner_source/Intro_to_TorchScript_tutorial.py

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
55
**Authors:** James Reed ([email protected]), Michael Suo ([email protected]), rev2
66
7+
.. note:: TorchScript is no longer in active development.
8+
79
This tutorial is an introduction to TorchScript, an intermediate
810
representation of a PyTorch model (subclass of ``nn.Module``) that
911
can then be run in a high-performance environment such as C++.

beginner_source/deploy_seq2seq_hybrid_frontend_tutorial.py

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
Deploying a Seq2Seq Model with TorchScript
44
==================================================
55
**Author:** `Matthew Inkawhich <https://github.com/MatthewInkawhich>`_
6+
7+
.. note:: TorchScript is no longer in active development.
68
"""
79

810

prototype_source/torchscript_freezing.py

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
Model Freezing in TorchScript
33
=============================
44
5+
.. note:: TorchScript is no longer in active development.
6+
57
In this tutorial, we introduce the syntax for *model freezing* in TorchScript.
68
Freezing is the process of inlining Pytorch module parameters and attributes
79
values into the TorchScript internal representation. Parameter and attribute

recipes_source/distributed_optim_torchscript.rst

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
Distributed Optimizer with TorchScript support
22
==============================================================
33

4-
.. note:: Distributed Optimizer with TorchScript support is introduced in PyTorch 1.8
5-
as a beta feature. This API is subject to change.
4+
.. note:: TorchScript is no longer in active development.
65

76
In this recipe, you will learn:
87

recipes_source/script_optimized.rst

+4-211
Original file line numberDiff line numberDiff line change
@@ -1,218 +1,11 @@
11
Script and Optimize for Mobile Recipe
22
=====================================
33

4-
This recipe demonstrates how to convert a PyTorch model to TorchScript which can run in a high-performance C++ environment such as iOS and Android, and how to optimize the converted TorchScript model for mobile deployment.
4+
This tutorial has been deprecated. There is a new tutorial on this topic.
55

6-
Introduction
7-
------------
6+
Redirecting in 3 seconds...
87

9-
After a PyTorch model is trained and optionally but preferably quantized (see `Quantization Recipe <quantization.html>`_ for more details), one essential step before the model can be used in iOS and Android apps is to convert the Python-dependent model to TorchScript, which can then further be optimized for mobile apps. Conversion to TorchScript can be as simple as a single call, or as complicated as changing the original model in many different places.
8+
.. raw:: html
109

11-
Pre-requisites
12-
--------------
10+
<meta http-equiv="Refresh" content="3; url='https://pytorch.org/executorch/stable/tutorials/export-to-executorch-tutorial.html'" />
1311

14-
PyTorch 1.6.0 or 1.7.0
15-
16-
Conversion to TorchScript
17-
-------------------------
18-
19-
There are two basic ways to convert a PyTorch model to TorchScript, using `trace` and `script`. Mixing `trace` and `script` may also be needed in some cases - see `here <https://pytorch.org/tutorials/beginner/Intro_to_TorchScript_tutorial.html#mixing-scripting-and-tracing>`_ for more information.
20-
21-
Use the `trace` Method
22-
^^^^^^^^^^^^^^^^^^^^^^
23-
24-
To use the `trace` method on a model, an example or dummy input for the model needs to be specified, the actual input size needs to be the same as the example input size, and the model definition cannot have control flow such as `if` or `for`. The reason for these constraints is that running `trace` on a model with an example input simply calls the model's `forward` method with the input and all operations executed in the model layers are recorded, creating the trace of the model.
25-
26-
::
27-
28-
import torch
29-
30-
dummy_input = torch.rand(1, 3, 224, 224)
31-
torchscript_model = torch.jit.trace(model_quantized, dummy_input)
32-
33-
34-
Use the `script` Method
35-
^^^^^^^^^^^^^^^^^^^^^^^
36-
37-
For the example above, calling `script` below makes no difference:
38-
39-
::
40-
41-
torchscript_model = torch.jit.script(model_quantized)
42-
43-
But if a model has some flow control, then `trace` won't correctly record all the possible traces. Take some code snippet of an example model definition from `here <https://pytorch.org/tutorials/beginner/Intro_to_TorchScript_tutorial.html>`_ for example:
44-
45-
::
46-
47-
import torch
48-
49-
class MyDecisionGate(torch.nn.Module):
50-
def forward(self, x):
51-
if x.sum() > 0:
52-
return x
53-
else:
54-
return -x
55-
56-
x = torch.rand(3, 4)
57-
traced_cell = torch.jit.trace(MyDecisionGate(), x)
58-
print(traced_cell.code)
59-
60-
The code above will output:
61-
62-
::
63-
64-
TracerWarning: Converting a tensor to a Python boolean might cause the trace to be incorrect. We can''t record the data flow of Python values, so this value will be treated as a constant in the future. This means that the trace might not generalize to other inputs!
65-
66-
if x.sum() > 0:
67-
def forward(self,
68-
x: Tensor) -> Tensor:
69-
return x
70-
71-
72-
Note that "the trace might not generalize to other inputs" warning above means that if the model has any kind of data-dependent control flow, `trace` is not the right answer. But if we replace the last two lines of the Python code snippet above (before the code output) with:
73-
74-
::
75-
76-
scripted_cell = torch.jit.script(MyDecisionGate())
77-
print(scripted_cell.code)
78-
79-
The scripted model as shown by the `print` result below will be covering all possible inputs, thus generalizing to other inputs:
80-
81-
::
82-
83-
def forward(self,
84-
x: Tensor) -> Tensor:
85-
_0 = bool(torch.gt(torch.sum(x, dtype=None), 0))
86-
if _0:
87-
_1 = x
88-
else:
89-
_1 = torch.neg(x)
90-
return _1
91-
92-
93-
This is another example of using `trace` and `script` - it converts the model trained in the PyTorch tutorial `NLP FROM SCRATCH: TRANSLATION WITH A SEQUENCE TO SEQUENCE NETWORK AND ATTENTION <https://pytorch.org/tutorials/intermediate/seq2seq_translation_tutorial.html>`_:
94-
95-
::
96-
97-
encoder = EncoderRNN(input_lang.n_words, hidden_size)
98-
decoder = AttnDecoderRNN(hidden_size, output_lang.n_words)
99-
100-
# method 1: using trace with example inputs
101-
102-
encoder_input=torch.tensor([1])
103-
encoder_hidden=torch.zeros(1, 1, hidden_size)
104-
105-
decoder_input1=torch.tensor([[0]])
106-
decoder_input2=torch.zeros(1, 1, hidden_size)
107-
decoder_input3=torch.zeros(MAX_LENGTH, hidden_size)
108-
109-
traced_encoder = torch.jit.trace(encoder, (encoder_input, encoder_hidden))
110-
traced_decoder = torch.jit.trace(decoder, (decoder_input1, decoder_input2, decoder_input3))
111-
112-
# method 2: using script
113-
114-
scripted_encoder = torch.jit.script(encoder)
115-
scripted_decoder = torch.jit.script(decoder)
116-
117-
So is it true that one can simply always use the `script` call and the model is converted to TorchScript? The answer is no, because TorchScript is actually a subset of Python and to make `script` work, the PyTorch model definition must only use the language features of that TorchScript subset of Python. `TorchScript Language Reference <https://pytorch.org/docs/master/jit_language_reference.html#language-reference>`_ covers all the details of what is supported in TorchScript. Below we will describe some of the common errors when using the `script` method.
118-
119-
120-
Fix Common Errors When Using the `script` Method
121-
----------------------------------------------------
122-
123-
If you apply the `script` method to a non-trivial model, chances are you may encounter several types of errors. Check out `this tutorial <https://pytorch.org/tutorials/beginner/deploy_seq2seq_hybrid_frontend_tutorial.html>`_ for a complete example of converting a chatbot model to TorchScript. But follow the steps below to fix common errors when you run the `script` method:
124-
125-
1. RuntimeError `attribute lookup is not defined on python value of type`
126-
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
127-
128-
For this error, pass the value of the model as a parameter in the constructor. This is because when calling `script` on a model that accepts another model as a parameter, the model passed is actually of type `TracedModule` or `ScriptModule`, not of type `Module`, making the the model attribute not defined when scripting.
129-
130-
For example, the `LuongAttnDecoderRNN` module in the tutorial above has an attribute `n_layers`, and the `GreedySearchDecoder` module refers to the `n_layers` attribute of a `decoder` instance of the `LuongAttnDecoderRNN` module, so in order to make `script` work, the `GreedySearchDecoder` module's constructor needs to be changed from:
131-
132-
::
133-
134-
def __init__(self, encoder, decoder):
135-
136-
to:
137-
138-
::
139-
140-
def __init__(self, encoder, decoder, decoder_n_layers):
141-
...
142-
self._decoder_n_layers = decoder_n_layers
143-
144-
145-
and the `GreedySearchDecoder`'s `forward` method needs to refer `self._decoder_n_layers` instead of `decoder.n_layers`.
146-
147-
2. RuntimeError `python value of type '...' cannot be used as a value.`
148-
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
149-
150-
The complete error message for this one continues with `Perhaps it is a closed over global variable? If so, please consider passing it in as an argument or use a local variable instead.`, store global variables' values as attributes in the model constructor (there's no need to add them to a special list called `__constants__`). The reason is that global values can be used conveniently in normal model training and inference, but the global values are not accessible during the scripting.
151-
152-
For example, `device` and `SOS_token` are global variables, and to make `script` work, they need to be added to the `GreedySearchDecoder`'s constructor:
153-
154-
::
155-
156-
self._device = device
157-
self._SOS_token = SOS_token
158-
159-
and referred to as `self._device` and `self._SOS_token` instead of `device` and `SOS_token` in the `GreedySearchDecoder`'s `forward` method.
160-
161-
3. RuntimeError `all inputs of range must be '...', found Tensor (inferred) in argument`
162-
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
163-
164-
The error message continues with: `add type definitions for each of the module's forward method arguments. Because all parameters to a TorchScript function are of the `torch.Tensor` type by default, you need to specifically declare the type for each parameter that is not of type 'Tensor'. For a complete list of TorchScript-supported types, see `here <https://pytorch.org/docs/master/jit_language_reference.html#supported-type>`_.
165-
166-
For example, the `GreedySearchDecoder`'s `forward` method signature needs to be changed from:
167-
168-
::
169-
170-
def forward(self, input_seq, input_length, max_length):
171-
172-
to:
173-
174-
::
175-
176-
def forward(self, input_seq, input_length, max_length : int):
177-
178-
After using the `trace` or `script` method above, and fixing possible errors, you should have a TorchScript model ready to be optimized for mobile.
179-
180-
181-
Optimize a TorchScript Model
182-
--------------------------------------
183-
184-
Simply run the following code snippet to optimize a TorchScript model generated with the `trace` and/or `script` method:
185-
186-
::
187-
188-
from torch.utils.mobile_optimizer import optimize_for_mobile
189-
optimized_torchscript_model = optimize_for_mobile(torchscript_model)
190-
191-
The optimized model can then be saved and deployed in mobile apps:
192-
193-
::
194-
195-
optimized_torchscript_model.save("optimized_torchscript_model.pth")
196-
197-
By default, for the CPU backend, `optimize_for_mobile` performs the following types of optimizations:
198-
199-
* `Conv2D and BatchNorm fusion` which folds Conv2d-BatchNorm2d into Conv2d;
200-
201-
* `Insert and fold prepacked ops` which rewrites the model graph to replace 2D convolutions and linear ops with their prepacked counterparts.
202-
203-
* `ReLU and hardtanh fusion` which rewrites graph by finding ReLU/hardtanh ops and fuses them together.
204-
205-
* `Dropout removal` which removes dropout nodes from this module when training is false.
206-
207-
* `Conv packed params hoisting` which moves convolution packed params to the root module, so that the convolution structs can be deleted. This decreases model size without impacting numerics.
208-
209-
For the Vulkan backend,`optimize_for_mobile` performs the following type of optimization:
210-
211-
* `Automatic GPU transfer` which rewrites the graph so that moving input and output data to and from the GPU becomes part of the model.
212-
213-
Optimization types can be disabled by passing an optimization blocklist as an argument to `optimize_for_mobile`.
214-
215-
Learn More
216-
-----------------
217-
1. The official `TorchScript Language Reference <https://pytorch.org/docs/stable/jit_language_reference.html>`_.
218-
2. The `torch.utils.mobile_optimizer` `API documentation <https://pytorch.org/docs/stable/mobile_optimizer.html>`_.

recipes_source/torchscript_inference.rst

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
TorchScript for Deployment
22
==========================
33

4+
.. note:: TorchScript is no longer in active development.
5+
46
In this recipe, you will learn:
57

68
- What TorchScript is

0 commit comments

Comments
 (0)