Skip to content
This repository was archived by the owner on Aug 28, 2024. It is now read-only.

Commit cedae91

Browse files
authored
Merge pull request #67 from jeffxtang/lite_updates
Demo app updates for Lite Interpreter: scripts, iOS code, and README
2 parents b18baca + 98da094 commit cedae91

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+186
-188
lines changed

D2Go/D2Go.xcodeproj/project.pbxproj

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@
88

99
/* Begin PBXBuildFile section */
1010
260F86432627C445008F2567 /* classes.txt in Resources */ = {isa = PBXBuildFile; fileRef = 260F86422627C445008F2567 /* classes.txt */; };
11+
26A8C10A26DFEC4700F4A58D /* d2go_optimized.ptl in Resources */ = {isa = PBXBuildFile; fileRef = 26A8C10926DFEC4700F4A58D /* d2go_optimized.ptl */; };
1112
26C3345C26210C3E00C37AD3 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26C3345B26210C3E00C37AD3 /* AppDelegate.swift */; };
1213
26C3345E26210C3E00C37AD3 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26C3345D26210C3E00C37AD3 /* SceneDelegate.swift */; };
1314
26C3346026210C3E00C37AD3 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26C3345F26210C3E00C37AD3 /* ViewController.swift */; };
1415
26C3346326210C3E00C37AD3 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 26C3346126210C3E00C37AD3 /* Main.storyboard */; };
1516
26C3346526210C3F00C37AD3 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 26C3346426210C3F00C37AD3 /* Assets.xcassets */; };
1617
26C3346826210C3F00C37AD3 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 26C3346626210C3F00C37AD3 /* LaunchScreen.storyboard */; };
17-
26C3347626211FC900C37AD3 /* d2go_optimized.pt in Resources */ = {isa = PBXBuildFile; fileRef = 26C3347526211FC900C37AD3 /* d2go_optimized.pt */; };
1818
26C3348C262120CB00C37AD3 /* PrePostProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26C3347D262120CB00C37AD3 /* PrePostProcessor.swift */; };
1919
26C3348D262120CB00C37AD3 /* UIImage+Helper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26C3347E262120CB00C37AD3 /* UIImage+Helper.swift */; };
2020
26C3348F262120CB00C37AD3 /* ObjectDetector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26C33483262120CB00C37AD3 /* ObjectDetector.swift */; };
@@ -30,6 +30,7 @@
3030

3131
/* Begin PBXFileReference section */
3232
260F86422627C445008F2567 /* classes.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = classes.txt; sourceTree = "<group>"; };
33+
26A8C10926DFEC4700F4A58D /* d2go_optimized.ptl */ = {isa = PBXFileReference; lastKnownFileType = file; path = d2go_optimized.ptl; sourceTree = "<group>"; };
3334
26C3345826210C3E00C37AD3 /* D2Go.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = D2Go.app; sourceTree = BUILT_PRODUCTS_DIR; };
3435
26C3345B26210C3E00C37AD3 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
3536
26C3345D26210C3E00C37AD3 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
@@ -38,7 +39,6 @@
3839
26C3346426210C3F00C37AD3 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
3940
26C3346726210C3F00C37AD3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
4041
26C3346926210C3F00C37AD3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
41-
26C3347526211FC900C37AD3 /* d2go_optimized.pt */ = {isa = PBXFileReference; lastKnownFileType = file; path = d2go_optimized.pt; sourceTree = "<group>"; };
4242
26C3347D262120CB00C37AD3 /* PrePostProcessor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PrePostProcessor.swift; sourceTree = "<group>"; };
4343
26C3347E262120CB00C37AD3 /* UIImage+Helper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImage+Helper.swift"; sourceTree = "<group>"; };
4444
26C33483262120CB00C37AD3 /* ObjectDetector.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObjectDetector.swift; sourceTree = "<group>"; };
@@ -105,7 +105,7 @@
105105
26C3348A262120CB00C37AD3 /* test1.png */,
106106
26C33484262120CB00C37AD3 /* test2.jpg */,
107107
26C3348B262120CB00C37AD3 /* test3.png */,
108-
26C3347526211FC900C37AD3 /* d2go_optimized.pt */,
108+
26A8C10926DFEC4700F4A58D /* d2go_optimized.ptl */,
109109
260F86422627C445008F2567 /* classes.txt */,
110110
);
111111
path = D2Go;
@@ -204,10 +204,10 @@
204204
26C33490262120CB00C37AD3 /* test2.jpg in Resources */,
205205
26C3346526210C3F00C37AD3 /* Assets.xcassets in Resources */,
206206
26C3346326210C3E00C37AD3 /* Main.storyboard in Resources */,
207-
26C3347626211FC900C37AD3 /* d2go_optimized.pt in Resources */,
208207
26C33495262120CB00C37AD3 /* test1.png in Resources */,
209208
26C33496262120CB00C37AD3 /* test3.png in Resources */,
210209
260F86432627C445008F2567 /* classes.txt in Resources */,
210+
26A8C10A26DFEC4700F4A58D /* d2go_optimized.ptl in Resources */,
211211
);
212212
runOnlyForDeploymentPostprocessing = 0;
213213
};
@@ -401,9 +401,9 @@
401401
"-l\"torch_cpu\"",
402402
"-l\"torchvision_ops\"",
403403
"-force_load",
404-
"$(PODS_ROOT)/LibTorch/install/lib/libtorch.a",
404+
"$(PODS_ROOT)/LibTorch-Lite/install/lib/libtorch.a",
405405
"-force_load",
406-
"$(PODS_ROOT)/LibTorch/install/lib/libtorch_cpu.a",
406+
"$(PODS_ROOT)/LibTorch-Lite/install/lib/libtorch_cpu.a",
407407
"-force_load",
408408
"$(PODS_ROOT)/LibTorchvision/install/lib/libtorchvision_ops.a",
409409
);
@@ -445,9 +445,9 @@
445445
"-l\"torch_cpu\"",
446446
"-l\"torchvision_ops\"",
447447
"-force_load",
448-
"$(PODS_ROOT)/LibTorch/install/lib/libtorch.a",
448+
"$(PODS_ROOT)/LibTorch-Lite/install/lib/libtorch.a",
449449
"-force_load",
450-
"$(PODS_ROOT)/LibTorch/install/lib/libtorch_cpu.a",
450+
"$(PODS_ROOT)/LibTorch-Lite/install/lib/libtorch_cpu.a",
451451
"-force_load",
452452
"$(PODS_ROOT)/LibTorchvision/install/lib/libtorchvision_ops.a",
453453
);

D2Go/D2Go/Inference/InferenceModule.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
// LICENSE file in the root directory of this source tree.
66

77
#import <Foundation/Foundation.h>
8+
#import <UIKit/UIKit.h>
89

910
NS_ASSUME_NONNULL_BEGIN
1011

D2Go/D2Go/Inference/InferenceModule.mm

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,22 @@
55
// LICENSE file in the root directory of this source tree.
66

77
#import "InferenceModule.h"
8-
#import <LibTorch.h>
8+
#import <Libtorch-Lite/Libtorch-Lite.h>
99

1010
const int input_width = 640;
1111
const int input_height = 640;
1212
const int threshold = 0.5;
1313

1414

1515
@implementation InferenceModule {
16-
@protected torch::jit::script::Module _impl;
16+
@protected torch::jit::mobile::Module _impl;
1717
}
1818

1919
- (nullable instancetype)initWithFileAtPath:(NSString*)filePath {
2020
self = [super init];
2121
if (self) {
2222
try {
23-
_impl = torch::jit::load(filePath.UTF8String);
24-
_impl.eval();
23+
_impl = torch::jit::_load_for_mobile(filePath.UTF8String);
2524
} catch (const std::exception& exception) {
2625
NSLog(@"%s", exception.what());
2726
return nil;
@@ -33,14 +32,18 @@ - (nullable instancetype)initWithFileAtPath:(NSString*)filePath {
3332
- (NSArray<NSNumber*>*)detectImage:(void*)imageBuffer {
3433
try {
3534
at::Tensor tensor = torch::from_blob(imageBuffer, { 3, input_width, input_height }, at::kFloat);
36-
torch::autograd::AutoGradMode guard(false);
37-
at::AutoNonVariableTypeMode non_var_type_mode(true);
38-
35+
c10::InferenceMode guard;
36+
3937
std::vector<torch::Tensor> v;
4038
v.push_back(tensor);
41-
39+
40+
41+
CFTimeInterval startTime = CACurrentMediaTime();
4242
auto outputTuple = _impl.forward({ at::TensorList(v) }).toTuple();
43-
43+
CFTimeInterval elapsedTime = CACurrentMediaTime() - startTime;
44+
NSLog(@"inference time:%f", elapsedTime);
45+
46+
4447
auto outputDict = outputTuple->elements()[1].toList().get(0).toGenericDict();
4548
auto boxesTensor = outputDict.at("boxes").toTensor();
4649
auto scoresTensor = outputDict.at("scores").toTensor();
@@ -58,7 +61,7 @@ - (nullable instancetype)initWithFileAtPath:(NSString*)filePath {
5861
if (!labelsBuffer) {
5962
return nil;
6063
}
61-
64+
6265
NSMutableArray* results = [[NSMutableArray alloc] init];
6366
long num = scoresTensor.numel();
6467
for (int i = 0; i < num; i++) {
@@ -72,9 +75,9 @@ - (nullable instancetype)initWithFileAtPath:(NSString*)filePath {
7275
[results addObject:@(scoresBuffer[i])];
7376
[results addObject:@(labelsBuffer[i])];
7477
}
75-
78+
7679
return [results copy];
77-
80+
7881
} catch (const std::exception& exception) {
7982
NSLog(@"%s", exception.what());
8083
}

D2Go/D2Go/Inference/ObjectDetector.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import UIKit
88

99
class ObjectDetector {
1010
lazy var module: InferenceModule = {
11-
if let filePath = Bundle.main.path(forResource: "d2go_optimized", ofType: "pt"),
11+
if let filePath = Bundle.main.path(forResource: "d2go_optimized", ofType: "ptl"),
1212
let module = InferenceModule(fileAtPath: filePath) {
1313
return module
1414
} else {

D2Go/D2Go/d2go_optimized.pt

384 Bytes
Binary file not shown.

D2Go/D2Go/d2go_optimized.ptl

4.07 MB
Binary file not shown.

D2Go/Podfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ target 'D2Go' do
44
# Comment the next line if you don't want to use dynamic frameworks
55
use_frameworks!
66

7-
pod 'LibTorch', '1.9.0'
7+
pod 'LibTorch-Lite', '~>1.9.0'
88
pod 'LibTorchvision', '0.10.0'
99

1010
end

D2Go/README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,22 @@
22

33
## Introduction
44

5-
[Detectron2](https://github.com/facebookresearch/detectron2) is one of the most widely adopted open source projects and implements state-of-the-art object detection, semantic segmentation, panoptic segmentation, and human pose prediction. [D2Go](https://github.com/facebookresearch/d2go) is powered by PyTorch 1.9.0, torchvision 0.10.0, and Detectron2 with built-in SOTA networks for mobile - the D2Go model is very small (only 2.15MB) and runs very fast on iOS.
5+
[Detectron2](https://github.com/facebookresearch/detectron2) is one of the most widely adopted open source projects and implements state-of-the-art object detection, semantic segmentation, panoptic segmentation, and human pose prediction. [D2Go](https://github.com/facebookresearch/d2go) is powered by PyTorch 1.9, torchvision 0.10, and Detectron2 with built-in SOTA networks for mobile - the D2Go model is very small (only 2.15MB) and runs very fast on iOS.
66

77
This D2Go iOS demo app shows how to prepare and use the D2Go model on iOS with the newly released LibTorchvision Cocoapods. The code is based on a previous PyTorch iOS [Object Detection demo app](https://github.com/pytorch/ios-demo-app/tree/master/ObjectDetection) that uses a pre-trained YOLOv5 model, with modified pre-processing and post-processing code required by the D2Go model.
88

99
## Prerequisites
1010

1111
* PyTorch 1.9 and torchvision 0.10 (Optional)
1212
* Python 3.8 or above (Optional)
13-
* iOS Cocoapods LibTorch 1.9.0 and LibTorchvision 0.10.0
13+
* iOS Cocoapods LibTorch-Lite 1.9.0 and LibTorchvision 0.10.0
1414
* Xcode 12.4 or later
1515

1616
## Quick Start
1717

1818
This section shows how to create and use the D2Go model in an iOS app. To just build and run the app without creating the D2Go model yourself, go directly to Step 4.
1919

20-
1. Install PyTorch 1.9.0 and torchvision 0.10.0, for example:
20+
1. Install PyTorch 1.9 and torchvision 0.10, for example:
2121

2222
```
2323
conda create -n d2go python=3.8.5
@@ -50,6 +50,7 @@ Run the following command to create the optimized D2Go model `d2go_optimized.pt`
5050
```
5151
python create_d2go.py
5252
```
53+
Both the optimized JIT model and the Lite Interpreter model will be created and saved in the project folder.
5354

5455
4. Build and run the D2Go iOS app
5556

D2Go/create_d2go.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ def forward(self, inputs: List[torch.Tensor]):
7070
scripted_model = torch.jit.script(wrapped_model)
7171
optimized_model = optimize_for_mobile(scripted_model)
7272
optimized_model.save("D2Go/d2go_optimized.pt")
73+
optimized_model._save_for_lite_interpreter("D2Go/d2go_optimized.ptl")
7374

7475
if __name__ == '__main__':
7576
test_export_torchvision_format()

ImageSegmentation/ImageSegmentation/TorchModule.mm

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ - (nullable instancetype)initWithFileAtPath:(NSString*)filePath {
2020
if (self) {
2121
try {
2222
_impl = torch::jit::_load_for_mobile(filePath.UTF8String);
23-
_impl.eval();
2423
} catch (const std::exception& exception) {
2524
NSLog(@"%s", exception.what());
2625
return nil;
@@ -40,9 +39,6 @@ - (unsigned char*)segmentImage:(void *)imageBuffer withWidth:(int)width withHeig
4039

4140
at::Tensor tensor = torch::from_blob(imageBuffer, { 1, 3, width, height }, at::kFloat);
4241

43-
torch::autograd::AutoGradMode guard(false);
44-
at::AutoNonVariableTypeMode non_var_type_mode(true);
45-
4642
float* floatInput = tensor.data_ptr<float>();
4743
if (!floatInput) {
4844
return nil;
@@ -52,8 +48,13 @@ - (unsigned char*)segmentImage:(void *)imageBuffer withWidth:(int)width withHeig
5248
[inputs addObject:@(floatInput[i])];
5349
}
5450

51+
c10::InferenceMode guard;
52+
53+
CFTimeInterval startTime = CACurrentMediaTime();
5554
auto outputDict = _impl.forward({ tensor }).toGenericDict();
56-
55+
CFTimeInterval elapsedTime = CACurrentMediaTime() - startTime;
56+
NSLog(@"inference time:%f", elapsedTime);
57+
5758
auto outputTensor = outputDict.at("out").toTensor();
5859

5960
float* floatBuffer = outputTensor.data_ptr<float>();

0 commit comments

Comments
 (0)