|
1 | 1 | (beta) Efficient mobile interpreter in Android and iOS |
2 | 2 | ================================================================== |
3 | 3 |
|
4 | | -**Author**: `Chen Lai <https://github.com/cccclai>`_, `Martin Yuan <https://github.com/iseeyuan>`_ |
| 4 | +PyTorch Mobile is no longer actively supported. Please check out ExecuTorch. |
5 | 5 |
|
6 | | -.. warning:: |
7 | | - PyTorch Mobile is no longer actively supported. Please check out `ExecuTorch <https://pytorch.org/executorch-overview>`_, PyTorch’s all-new on-device inference library. You can also review our new documentation to learn more about how to build `iOS <https://pytorch.org/executorch/stable/demo-apps-ios.html>`_ and `Android <https://pytorch.org/executorch/stable/demo-apps-android.html>`_ apps with ExecuTorch. |
| 6 | +Redirecting in 3 seconds... |
8 | 7 |
|
9 | | -Introduction |
10 | | ------------- |
| 8 | +.. raw:: html |
11 | 9 |
|
12 | | -This tutorial introduces the steps to use PyTorch's efficient interpreter on iOS and Android. We will be using an Image Segmentation demo application as an example. |
13 | | - |
14 | | -This application will take advantage of the pre-built interpreter libraries available for Android and iOS, which can be used directly with Maven (Android) and CocoaPods (iOS). It is important to note that the pre-built libraries are the available for simplicity, but further size optimization can be achieved with by utilizing PyTorch's custom build capabilities. |
15 | | - |
16 | | -.. note:: If you see the error message: `PytorchStreamReader failed locating file bytecode.pkl: file not found ()`, likely you are using a torch script model that requires the use of the PyTorch JIT interpreter (a version of our PyTorch interpreter that is not as size-efficient). In order to leverage our efficient interpreter, please regenerate the model by running: `module._save_for_lite_interpreter(${model_path})`. |
17 | | - |
18 | | - - If `bytecode.pkl` is missing, likely the model is generated with the api: `module.save(${model_psth})`. |
19 | | - - The api `_load_for_lite_interpreter(${model_psth})` can be helpful to validate model with the efficient mobile interpreter. |
20 | | - |
21 | | -Android |
22 | | -------------------- |
23 | | -Get the Image Segmentation demo app in Android: https://github.com/pytorch/android-demo-app/tree/master/ImageSegmentation |
24 | | - |
25 | | -1. **Prepare model**: Prepare the mobile interpreter version of model by run the script below to generate the scripted model `deeplabv3_scripted.pt` and `deeplabv3_scripted.ptl` |
26 | | - |
27 | | -.. code:: python |
28 | | -
|
29 | | - import torch |
30 | | - from torch.utils.mobile_optimizer import optimize_for_mobile |
31 | | - model = torch.hub.load('pytorch/vision:v0.7.0', 'deeplabv3_resnet50', pretrained=True) |
32 | | - model.eval() |
33 | | -
|
34 | | - scripted_module = torch.jit.script(model) |
35 | | - # Export full jit version model (not compatible mobile interpreter), leave it here for comparison |
36 | | - scripted_module.save("deeplabv3_scripted.pt") |
37 | | - # Export mobile interpreter version model (compatible with mobile interpreter) |
38 | | - optimized_scripted_module = optimize_for_mobile(scripted_module) |
39 | | - optimized_scripted_module._save_for_lite_interpreter("deeplabv3_scripted.ptl") |
40 | | -
|
41 | | -2. **Use the PyTorch Android library in the ImageSegmentation app**: Update the `dependencies` part of ``ImageSegmentation/app/build.gradle`` to |
42 | | - |
43 | | -.. code:: gradle |
44 | | -
|
45 | | - repositories { |
46 | | - maven { |
47 | | - url "https://oss.sonatype.org/content/repositories/snapshots" |
48 | | - } |
49 | | - } |
50 | | -
|
51 | | - dependencies { |
52 | | - implementation 'androidx.appcompat:appcompat:1.2.0' |
53 | | - implementation 'androidx.constraintlayout:constraintlayout:2.0.2' |
54 | | - testImplementation 'junit:junit:4.12' |
55 | | - androidTestImplementation 'androidx.test.ext:junit:1.1.2' |
56 | | - androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' |
57 | | - implementation 'org.pytorch:pytorch_android_lite:1.9.0' |
58 | | - implementation 'org.pytorch:pytorch_android_torchvision:1.9.0' |
59 | | -
|
60 | | - implementation 'com.facebook.fbjni:fbjni-java-only:0.0.3' |
61 | | - } |
62 | | -
|
63 | | -
|
64 | | -
|
65 | | -3. **Update model loader api**: Update ``ImageSegmentation/app/src/main/java/org/pytorch/imagesegmentation/MainActivity.java`` by |
66 | | - |
67 | | - 4.1 Add new import: `import org.pytorch.LiteModuleLoader` |
68 | | - |
69 | | - 4.2 Replace the way to load pytorch lite model |
70 | | - |
71 | | -.. code:: java |
72 | | -
|
73 | | - // mModule = Module.load(MainActivity.assetFilePath(getApplicationContext(), "deeplabv3_scripted.pt")); |
74 | | - mModule = LiteModuleLoader.load(MainActivity.assetFilePath(getApplicationContext(), "deeplabv3_scripted.ptl")); |
75 | | -
|
76 | | -4. **Test app**: Build and run the `ImageSegmentation` app in Android Studio |
77 | | - |
78 | | -iOS |
79 | | -------------------- |
80 | | -Get ImageSegmentation demo app in iOS: https://github.com/pytorch/ios-demo-app/tree/master/ImageSegmentation |
81 | | - |
82 | | -1. **Prepare model**: Same as Android. |
83 | | - |
84 | | -2. **Build the project with Cocoapods and prebuilt interpreter** Update the `PodFile` and run `pod install`: |
85 | | - |
86 | | -.. code-block:: podfile |
87 | | -
|
88 | | - target 'ImageSegmentation' do |
89 | | - # Comment the next line if you don't want to use dynamic frameworks |
90 | | - use_frameworks! |
91 | | -
|
92 | | - # Pods for ImageSegmentation |
93 | | - pod 'LibTorch_Lite', '~>1.9.0' |
94 | | - end |
95 | | -
|
96 | | -3. **Update library and API** |
97 | | - |
98 | | - 3.1 Update ``TorchModule.mm``: To use the custom built libraries project, use `<Libtorch-Lite.h>` (in ``TorchModule.mm``): |
99 | | - |
100 | | -.. code-block:: swift |
101 | | -
|
102 | | - #import <Libtorch-Lite.h> |
103 | | - // If it's built from source with xcode, comment out the line above |
104 | | - // and use following headers |
105 | | - // #include <torch/csrc/jit/mobile/import.h> |
106 | | - // #include <torch/csrc/jit/mobile/module.h> |
107 | | - // #include <torch/script.h> |
108 | | -
|
109 | | -.. code-block:: swift |
110 | | -
|
111 | | - @implementation TorchModule { |
112 | | - @protected |
113 | | - // torch::jit::script::Module _impl; |
114 | | - torch::jit::mobile::Module _impl; |
115 | | - } |
116 | | -
|
117 | | - - (nullable instancetype)initWithFileAtPath:(NSString*)filePath { |
118 | | - self = [super init]; |
119 | | - if (self) { |
120 | | - try { |
121 | | - _impl = torch::jit::_load_for_mobile(filePath.UTF8String); |
122 | | - // _impl = torch::jit::load(filePath.UTF8String); |
123 | | - // _impl.eval(); |
124 | | - } catch (const std::exception& exception) { |
125 | | - NSLog(@"%s", exception.what()); |
126 | | - return nil; |
127 | | - } |
128 | | - } |
129 | | - return self; |
130 | | - } |
131 | | -
|
132 | | -3.2 Update ``ViewController.swift`` |
133 | | - |
134 | | -.. code-block:: swift |
135 | | -
|
136 | | - // if let filePath = Bundle.main.path(forResource: |
137 | | - // "deeplabv3_scripted", ofType: "pt"), |
138 | | - // let module = TorchModule(fileAtPath: filePath) { |
139 | | - // return module |
140 | | - // } else { |
141 | | - // fatalError("Can't find the model file!") |
142 | | - // } |
143 | | - if let filePath = Bundle.main.path(forResource: |
144 | | - "deeplabv3_scripted", ofType: "ptl"), |
145 | | - let module = TorchModule(fileAtPath: filePath) { |
146 | | - return module |
147 | | - } else { |
148 | | - fatalError("Can't find the model file!") |
149 | | - } |
150 | | -
|
151 | | -4. Build and test the app in Xcode. |
152 | | - |
153 | | -How to use mobile interpreter + custom build |
154 | | ---------------------------------------------- |
155 | | -A custom PyTorch interpreter library can be created to reduce binary size, by only containing the operators needed by the model. In order to do that follow these steps: |
156 | | - |
157 | | -1. To dump the operators in your model, say `deeplabv3_scripted`, run the following lines of Python code: |
158 | | - |
159 | | -.. code-block:: python |
160 | | -
|
161 | | - # Dump list of operators used by deeplabv3_scripted: |
162 | | - import torch, yaml |
163 | | - model = torch.jit.load('deeplabv3_scripted.ptl') |
164 | | - ops = torch.jit.export_opnames(model) |
165 | | - with open('deeplabv3_scripted.yaml', 'w') as output: |
166 | | - yaml.dump(ops, output) |
167 | | -
|
168 | | -In the snippet above, you first need to load the ScriptModule. Then, use export_opnames to return a list of operator names of the ScriptModule and its submodules. Lastly, save the result in a yaml file. The yaml file can be generated for any PyTorch 1.4.0 or above version. You can do that by checking the value of `torch.__version__`. |
169 | | - |
170 | | -2. To run the build script locally with the prepared yaml list of operators, pass in the yaml file generate from the last step into the environment variable SELECTED_OP_LIST. Also in the arguments, specify BUILD_PYTORCH_MOBILE=1 as well as the platform/architechture type. |
171 | | - |
172 | | -**iOS**: Take the simulator build for example, the command should be: |
173 | | - |
174 | | -.. code-block:: bash |
175 | | -
|
176 | | - SELECTED_OP_LIST=deeplabv3_scripted.yaml BUILD_PYTORCH_MOBILE=1 IOS_PLATFORM=SIMULATOR ./scripts/build_ios.sh |
177 | | -
|
178 | | -**Android**: Take the x86 build for example, the command should be: |
179 | | - |
180 | | -.. code-block:: bash |
181 | | -
|
182 | | - SELECTED_OP_LIST=deeplabv3_scripted.yaml ./scripts/build_pytorch_android.sh x86 |
183 | | -
|
184 | | -
|
185 | | -
|
186 | | -Conclusion |
187 | | ----------- |
188 | | - |
189 | | -In this tutorial, we demonstrated how to use PyTorch's efficient mobile interpreter, in an Android and iOS app. |
190 | | - |
191 | | -We walked through an Image Segmentation example to show how to dump the model, build a custom torch library from source and use the new api to run model. |
192 | | - |
193 | | -Our efficient mobile interpreter is still under development, and we will continue improving its size in the future. Note, however, that the APIs are subject to change in future versions. |
194 | | - |
195 | | -Thanks for reading! As always, we welcome any feedback, so please create an issue `here <https://github.com/pytorch/pytorch/issues>` - if you have any. |
196 | | - |
197 | | -Learn More |
198 | | ----------- |
199 | | - |
200 | | -- To learn more about PyTorch Mobile, please refer to `PyTorch Mobile Home Page <https://pytorch.org/mobile/home/>`_ |
201 | | -- To learn more about Image Segmentation, please refer to the `Image Segmentation DeepLabV3 on Android Recipe <https://pytorch.org/tutorials/beginner/deeplabv3_on_android.html>`_ |
| 10 | + <meta http-equiv="Refresh" content="3; url='https://pytorch.org/executorch/stable/index.html'" /> |
0 commit comments