(beta) Android 和 iOS 上的高效移动解释器¶
警告
PyTorch Mobile 现已不再积极维护。请查看 ExecuTorch,PyTorch 的全新设备上推理库。您还可以查看我们的新文档,以详细了解如何使用 ExecuTorch 构建 iOS 和 Android 应用程序。
简介¶
本教程介绍了在 iOS 和 Android 上使用 PyTorch 高效解释器的步骤。我们将使用图像分割演示应用程序作为示例。
此应用程序将利用为 Android 和 iOS 提供的预构建解释器库,这些库可以直接与 Maven (Android) 和 CocoaPods (iOS) 一起使用。需要注意的是,预构建库是为了简单起见,但通过利用 PyTorch 的自定义构建功能,可以实现进一步的尺寸优化。
注意
如果您看到错误消息:PytorchStreamReader 无法找到文件 bytecode.pkl:文件未找到 (),则可能是您使用的是需要使用 PyTorch JIT 解释器(我们 PyTorch 解释器的一个版本,其尺寸效率不高)的 torch 脚本模型。为了利用我们高效的解释器,请通过运行以下命令重新生成模型:module._save_for_lite_interpreter(${model_path})。
如果缺少 bytecode.pkl,则可能是该模型使用 api 生成:module.save(${model_psth})。
api _load_for_lite_interpreter(${model_psth}) 可以帮助您使用高效的移动解释器验证模型。
Android¶
在 Android 上获取图像分割演示应用程序:https://github.com/pytorch/android-demo-app/tree/master/ImageSegmentation
准备模型:通过运行以下脚本生成脚本化的模型 deeplabv3_scripted.pt 和 deeplabv3_scripted.ptl,准备模型的移动解释器版本。
import torch
from torch.utils.mobile_optimizer import optimize_for_mobile
model = torch.hub.load('pytorch/vision:v0.7.0', 'deeplabv3_resnet50', pretrained=True)
model.eval()
scripted_module = torch.jit.script(model)
# Export full jit version model (not compatible mobile interpreter), leave it here for comparison
scripted_module.save("deeplabv3_scripted.pt")
# Export mobile interpreter version model (compatible with mobile interpreter)
optimized_scripted_module = optimize_for_mobile(scripted_module)
optimized_scripted_module._save_for_lite_interpreter("deeplabv3_scripted.ptl")
在 ImageSegmentation 应用程序中使用 PyTorch Android 库:更新
ImageSegmentation/app/build.gradle
的 dependencies 部分,如下所示:
repositories {
maven {
url "https://oss.sonatype.org/content/repositories/snapshots"
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
implementation 'org.pytorch:pytorch_android_lite:1.9.0'
implementation 'org.pytorch:pytorch_android_torchvision:1.9.0'
implementation 'com.facebook.fbjni:fbjni-java-only:0.0.3'
}
更新模型加载器 API:通过以下操作更新
ImageSegmentation/app/src/main/java/org/pytorch/imagesegmentation/MainActivity.java
:
4.1 添加新的导入:import org.pytorch.LiteModuleLoader
4.2 替换加载 PyTorch Lite 模型的方式
// mModule = Module.load(MainActivity.assetFilePath(getApplicationContext(), "deeplabv3_scripted.pt"));
mModule = LiteModuleLoader.load(MainActivity.assetFilePath(getApplicationContext(), "deeplabv3_scripted.ptl"));
测试应用程序:在 Android Studio 中构建并运行 ImageSegmentation 应用程序。
iOS¶
在 iOS 上获取图像分割演示应用程序:https://github.com/pytorch/ios-demo-app/tree/master/ImageSegmentation
准备模型:与 Android 相同。
使用 Cocoapods 和预构建解释器构建项目:更新 PodFile 并运行 pod install
target 'ImageSegmentation' do
# Comment the next line if you don't want to use dynamic frameworks
use_frameworks!
# Pods for ImageSegmentation
pod 'LibTorch_Lite', '~>1.9.0'
end
更新库和 API
3.1 更新
TorchModule.mm
:要使用自定义构建的库项目,请使用 <Libtorch-Lite.h>(在TorchModule.mm
中)
#import <Libtorch-Lite.h>
// If it's built from source with xcode, comment out the line above
// and use following headers
// #include <torch/csrc/jit/mobile/import.h>
// #include <torch/csrc/jit/mobile/module.h>
// #include <torch/script.h>
@implementation TorchModule {
@protected
// torch::jit::script::Module _impl;
torch::jit::mobile::Module _impl;
}
- (nullable instancetype)initWithFileAtPath:(NSString*)filePath {
self = [super init];
if (self) {
try {
_impl = torch::jit::_load_for_mobile(filePath.UTF8String);
// _impl = torch::jit::load(filePath.UTF8String);
// _impl.eval();
} catch (const std::exception& exception) {
NSLog(@"%s", exception.what());
return nil;
}
}
return self;
}
3.2 更新 ViewController.swift
// if let filePath = Bundle.main.path(forResource:
// "deeplabv3_scripted", ofType: "pt"),
// let module = TorchModule(fileAtPath: filePath) {
// return module
// } else {
// fatalError("Can't find the model file!")
// }
if let filePath = Bundle.main.path(forResource:
"deeplabv3_scripted", ofType: "ptl"),
let module = TorchModule(fileAtPath: filePath) {
return module
} else {
fatalError("Can't find the model file!")
}
在 Xcode 中构建并测试应用程序。
如何使用移动解释器 + 自定义构建¶
可以通过创建自定义 PyTorch 解释器库来减小二进制文件大小,该库仅包含模型所需的运算符。为此,请按照以下步骤操作
要转储模型中的运算符(例如,deeplabv3_scripted),请运行以下 Python 代码行
# Dump list of operators used by deeplabv3_scripted:
import torch, yaml
model = torch.jit.load('deeplabv3_scripted.ptl')
ops = torch.jit.export_opnames(model)
with open('deeplabv3_scripted.yaml', 'w') as output:
yaml.dump(ops, output)
在上面的代码段中,您首先需要加载 ScriptModule。然后,使用 export_opnames 返回 ScriptModule 及其子模块的运算符名称列表。最后,将结果保存到 YAML 文件中。可以为任何 PyTorch 1.4.0 或更高版本生成 YAML 文件。您可以通过检查 torch.__version__ 的值来实现这一点。
要在本地使用准备好的 YAML 运算符列表运行构建脚本,请将从上一步生成的 YAML 文件传递到环境变量 SELECTED_OP_LIST 中。此外,在参数中,请指定 BUILD_PYTORCH_MOBILE=1 以及平台/架构类型。
iOS:以模拟器构建为例,命令应为
SELECTED_OP_LIST=deeplabv3_scripted.yaml BUILD_PYTORCH_MOBILE=1 IOS_PLATFORM=SIMULATOR ./scripts/build_ios.sh
Android:以 x86 构建为例,命令应为
SELECTED_OP_LIST=deeplabv3_scripted.yaml ./scripts/build_pytorch_android.sh x86
结论¶
在本教程中,我们演示了如何在 Android 和 iOS 应用程序中使用 PyTorch 高效的移动解释器。
我们通过图像分割示例演示了如何转储模型、从源代码构建自定义 Torch 库以及使用新 API 运行模型。
我们高效的移动解释器仍在开发中,我们将继续在未来改进其大小。但是请注意,API 在未来版本中可能会发生变化。
感谢您的阅读!一如既往,我们欢迎任何反馈,因此如果您有任何问题,请在此处创建问题 here <https://github.com/pytorch/pytorch/issues>。
了解更多¶
要详细了解 PyTorch Mobile,请参阅 PyTorch Mobile 主页
要详细了解图像分割,请参阅 图像分割 DeepLabV3 在 Android 上的食谱