快捷方式

(beta) Android 和 iOS 上的高效移动解释器

作者: 陈莱袁马丁

警告

PyTorch Mobile 现已不再积极维护。请查看 ExecuTorch,PyTorch 的全新设备上推理库。您还可以查看我们的新文档,以详细了解如何使用 ExecuTorch 构建 iOSAndroid 应用程序。

简介

本教程介绍了在 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

  1. 准备模型:通过运行以下脚本生成脚本化的模型 deeplabv3_scripted.ptdeeplabv3_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")
  1. 在 ImageSegmentation 应用程序中使用 PyTorch Android 库:更新 ImageSegmentation/app/build.gradledependencies 部分,如下所示:

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'
}
  1. 更新模型加载器 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"));
  1. 测试应用程序:在 Android Studio 中构建并运行 ImageSegmentation 应用程序。

iOS

在 iOS 上获取图像分割演示应用程序:https://github.com/pytorch/ios-demo-app/tree/master/ImageSegmentation

  1. 准备模型:与 Android 相同。

  2. 使用 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
  1. 更新库和 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!")
}
  1. 在 Xcode 中构建并测试应用程序。

如何使用移动解释器 + 自定义构建

可以通过创建自定义 PyTorch 解释器库来减小二进制文件大小,该库仅包含模型所需的运算符。为此,请按照以下步骤操作

  1. 要转储模型中的运算符(例如,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__ 的值来实现这一点。

  1. 要在本地使用准备好的 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 的全面开发者文档

查看文档

教程

获取适用于初学者和高级开发人员的深入教程

查看教程

资源

查找开发资源并获得问题的解答

查看资源