xref: /aosp_15_r20/external/executorch/backends/apple/mps/setup.md (revision 523fa7a60841cd1ecfb9cc4201f1ca8b03ed023a)
1*523fa7a6SAndroid Build Coastguard Worker# Building and Running ExecuTorch with MPS Backend
2*523fa7a6SAndroid Build Coastguard Worker
3*523fa7a6SAndroid Build Coastguard WorkerIn this tutorial we will walk you through the process of getting setup to build the MPS backend for ExecuTorch and running a simple model on it.
4*523fa7a6SAndroid Build Coastguard Worker
5*523fa7a6SAndroid Build Coastguard WorkerThe MPS backend device maps machine learning computational graphs and primitives on the [MPS Graph](https://developer.apple.com/documentation/metalperformanceshadersgraph/mpsgraph?language=objc) framework and tuned kernels provided by [MPS](https://developer.apple.com/documentation/metalperformanceshaders?language=objc).
6*523fa7a6SAndroid Build Coastguard Worker
7*523fa7a6SAndroid Build Coastguard Worker::::{grid} 2
8*523fa7a6SAndroid Build Coastguard Worker:::{grid-item-card}  What you will learn in this tutorial:
9*523fa7a6SAndroid Build Coastguard Worker:class-card: card-prerequisites
10*523fa7a6SAndroid Build Coastguard Worker* In this tutorial you will learn how to export [MobileNet V3](https://pytorch.org/vision/main/models/mobilenetv3.html) model to the MPS delegate.
11*523fa7a6SAndroid Build Coastguard Worker* You will also learn how to compile and deploy the ExecuTorch runtime with the MPS delegate on macOS and iOS.
12*523fa7a6SAndroid Build Coastguard Worker:::
13*523fa7a6SAndroid Build Coastguard Worker:::{grid-item-card}  Tutorials we recommend you complete before this:
14*523fa7a6SAndroid Build Coastguard Worker:class-card: card-prerequisites
15*523fa7a6SAndroid Build Coastguard Worker* [Introduction to ExecuTorch](intro-how-it-works.md)
16*523fa7a6SAndroid Build Coastguard Worker* [Setting up ExecuTorch](getting-started-setup.md)
17*523fa7a6SAndroid Build Coastguard Worker* [Building ExecuTorch with CMake](runtime-build-and-cross-compilation.md)
18*523fa7a6SAndroid Build Coastguard Worker* [ExecuTorch iOS Demo App](demo-apps-ios.md)
19*523fa7a6SAndroid Build Coastguard Worker* [ExecuTorch iOS LLaMA Demo App](llm/llama-demo-ios.md)
20*523fa7a6SAndroid Build Coastguard Worker:::
21*523fa7a6SAndroid Build Coastguard Worker::::
22*523fa7a6SAndroid Build Coastguard Worker
23*523fa7a6SAndroid Build Coastguard Worker
24*523fa7a6SAndroid Build Coastguard Worker## Prerequisites (Hardware and Software)
25*523fa7a6SAndroid Build Coastguard Worker
26*523fa7a6SAndroid Build Coastguard WorkerIn order to be able to successfully build and run a model using the MPS backend for ExecuTorch, you'll need the following hardware and software components:
27*523fa7a6SAndroid Build Coastguard Worker
28*523fa7a6SAndroid Build Coastguard Worker### Hardware:
29*523fa7a6SAndroid Build Coastguard Worker - A [mac](https://www.apple.com/mac/) for tracing the model
30*523fa7a6SAndroid Build Coastguard Worker
31*523fa7a6SAndroid Build Coastguard Worker### Software:
32*523fa7a6SAndroid Build Coastguard Worker
33*523fa7a6SAndroid Build Coastguard Worker  - **Ahead of time** tracing:
34*523fa7a6SAndroid Build Coastguard Worker    - [macOS](https://www.apple.com/macos/) 12
35*523fa7a6SAndroid Build Coastguard Worker
36*523fa7a6SAndroid Build Coastguard Worker  - **Runtime**:
37*523fa7a6SAndroid Build Coastguard Worker    - [macOS](https://www.apple.com/macos/) >= 12.4
38*523fa7a6SAndroid Build Coastguard Worker    - [iOS](https://www.apple.com/ios) >= 15.4
39*523fa7a6SAndroid Build Coastguard Worker    - [Xcode](https://developer.apple.com/xcode/) >= 14.1
40*523fa7a6SAndroid Build Coastguard Worker
41*523fa7a6SAndroid Build Coastguard Worker## Setting up Developer Environment
42*523fa7a6SAndroid Build Coastguard Worker
43*523fa7a6SAndroid Build Coastguard Worker***Step 1.*** Please finish tutorial [Setting up ExecuTorch](https://pytorch.org/executorch/stable/getting-started-setup).
44*523fa7a6SAndroid Build Coastguard Worker
45*523fa7a6SAndroid Build Coastguard Worker***Step 2.*** Install dependencies needed to lower MPS delegate:
46*523fa7a6SAndroid Build Coastguard Worker
47*523fa7a6SAndroid Build Coastguard Worker  ```bash
48*523fa7a6SAndroid Build Coastguard Worker  ./backends/apple/mps/install_requirements.sh
49*523fa7a6SAndroid Build Coastguard Worker  ```
50*523fa7a6SAndroid Build Coastguard Worker
51*523fa7a6SAndroid Build Coastguard Worker## Build
52*523fa7a6SAndroid Build Coastguard Worker
53*523fa7a6SAndroid Build Coastguard Worker### AOT (Ahead-of-time) Components
54*523fa7a6SAndroid Build Coastguard Worker
55*523fa7a6SAndroid Build Coastguard Worker**Compiling model for MPS delegate**:
56*523fa7a6SAndroid Build Coastguard Worker- In this step, you will generate a simple ExecuTorch program that lowers MobileNetV3 model to the MPS delegate. You'll then pass this Program (the `.pte` file) during the runtime to run it using the MPS backend.
57*523fa7a6SAndroid Build Coastguard Worker
58*523fa7a6SAndroid Build Coastguard Worker```bash
59*523fa7a6SAndroid Build Coastguard Workercd executorch
60*523fa7a6SAndroid Build Coastguard Worker# Note: `mps_example` script uses by default the MPSPartitioner for ops that are not yet supported by the MPS delegate. To turn it off, pass `--no-use_partitioner`.
61*523fa7a6SAndroid Build Coastguard Workerpython3 -m examples.apple.mps.scripts.mps_example --model_name="mv3" --bundled --use_fp16
62*523fa7a6SAndroid Build Coastguard Worker
63*523fa7a6SAndroid Build Coastguard Worker# To see all options, run following command:
64*523fa7a6SAndroid Build Coastguard Workerpython3 -m examples.apple.mps.scripts.mps_example --help
65*523fa7a6SAndroid Build Coastguard Worker```
66*523fa7a6SAndroid Build Coastguard Worker
67*523fa7a6SAndroid Build Coastguard Worker### Runtime
68*523fa7a6SAndroid Build Coastguard Worker
69*523fa7a6SAndroid Build Coastguard Worker**Building the MPS executor runner:**
70*523fa7a6SAndroid Build Coastguard Worker```bash
71*523fa7a6SAndroid Build Coastguard Worker# In this step, you'll be building the `mps_executor_runner` that is able to run MPS lowered modules:
72*523fa7a6SAndroid Build Coastguard Workercd executorch
73*523fa7a6SAndroid Build Coastguard Worker./examples/apple/mps/scripts/build_mps_executor_runner.sh
74*523fa7a6SAndroid Build Coastguard Worker```
75*523fa7a6SAndroid Build Coastguard Worker
76*523fa7a6SAndroid Build Coastguard Worker## Run the mv3 generated model using the mps_executor_runner
77*523fa7a6SAndroid Build Coastguard Worker
78*523fa7a6SAndroid Build Coastguard Worker```bash
79*523fa7a6SAndroid Build Coastguard Worker./cmake-out/examples/apple/mps/mps_executor_runner --model_path mv3_mps_bundled_fp16.pte --bundled_program
80*523fa7a6SAndroid Build Coastguard Worker```
81*523fa7a6SAndroid Build Coastguard Worker
82*523fa7a6SAndroid Build Coastguard Worker- You should see the following results. Note that no output file will be generated in this example:
83*523fa7a6SAndroid Build Coastguard Worker```
84*523fa7a6SAndroid Build Coastguard WorkerI 00:00:00.003290 executorch:mps_executor_runner.mm:286] Model file mv3_mps_bundled_fp16.pte is loaded.
85*523fa7a6SAndroid Build Coastguard WorkerI 00:00:00.003306 executorch:mps_executor_runner.mm:292] Program methods: 1
86*523fa7a6SAndroid Build Coastguard WorkerI 00:00:00.003308 executorch:mps_executor_runner.mm:294] Running method forward
87*523fa7a6SAndroid Build Coastguard WorkerI 00:00:00.003311 executorch:mps_executor_runner.mm:349] Setting up non-const buffer 1, size 606112.
88*523fa7a6SAndroid Build Coastguard WorkerI 00:00:00.003374 executorch:mps_executor_runner.mm:376] Setting up memory manager
89*523fa7a6SAndroid Build Coastguard WorkerI 00:00:00.003376 executorch:mps_executor_runner.mm:392] Loading method name from plan
90*523fa7a6SAndroid Build Coastguard WorkerI 00:00:00.018942 executorch:mps_executor_runner.mm:399] Method loaded.
91*523fa7a6SAndroid Build Coastguard WorkerI 00:00:00.018944 executorch:mps_executor_runner.mm:404] Loading bundled program...
92*523fa7a6SAndroid Build Coastguard WorkerI 00:00:00.018980 executorch:mps_executor_runner.mm:421] Inputs prepared.
93*523fa7a6SAndroid Build Coastguard WorkerI 00:00:00.118731 executorch:mps_executor_runner.mm:438] Model executed successfully.
94*523fa7a6SAndroid Build Coastguard WorkerI 00:00:00.122615 executorch:mps_executor_runner.mm:501] Model verified successfully.
95*523fa7a6SAndroid Build Coastguard Worker```
96*523fa7a6SAndroid Build Coastguard Worker
97*523fa7a6SAndroid Build Coastguard Worker### [Optional] Run the generated model directly using pybind
98*523fa7a6SAndroid Build Coastguard Worker1. Make sure `pybind` MPS support was installed:
99*523fa7a6SAndroid Build Coastguard Worker```bash
100*523fa7a6SAndroid Build Coastguard Worker./install_requirements.sh --pybind mps
101*523fa7a6SAndroid Build Coastguard Worker```
102*523fa7a6SAndroid Build Coastguard Worker2. Run the `mps_example` script to trace the model and run it directly from python:
103*523fa7a6SAndroid Build Coastguard Worker```bash
104*523fa7a6SAndroid Build Coastguard Workercd executorch
105*523fa7a6SAndroid Build Coastguard Worker# Check correctness between PyTorch eager forward pass and ExecuTorch MPS delegate forward pass
106*523fa7a6SAndroid Build Coastguard Workerpython3 -m examples.apple.mps.scripts.mps_example --model_name="mv3" --no-use_fp16 --check_correctness
107*523fa7a6SAndroid Build Coastguard Worker# You should see following output: `Results between ExecuTorch forward pass with MPS backend and PyTorch forward pass for mv3_mps are matching!`
108*523fa7a6SAndroid Build Coastguard Worker
109*523fa7a6SAndroid Build Coastguard Worker# Check performance between PyTorch MPS forward pass and ExecuTorch MPS forward pass
110*523fa7a6SAndroid Build Coastguard Workerpython3 -m examples.apple.mps.scripts.mps_example --model_name="mv3" --no-use_fp16 --bench_pytorch
111*523fa7a6SAndroid Build Coastguard Worker```
112*523fa7a6SAndroid Build Coastguard Worker
113*523fa7a6SAndroid Build Coastguard Worker### Profiling:
114*523fa7a6SAndroid Build Coastguard Worker1. [Optional] Generate an [ETRecord](./etrecord.rst) while you're exporting your model.
115*523fa7a6SAndroid Build Coastguard Worker```bash
116*523fa7a6SAndroid Build Coastguard Workercd executorch
117*523fa7a6SAndroid Build Coastguard Workerpython3 -m examples.apple.mps.scripts.mps_example --model_name="mv3" --generate_etrecord -b
118*523fa7a6SAndroid Build Coastguard Worker```
119*523fa7a6SAndroid Build Coastguard Worker2. Run your Program on the ExecuTorch runtime and generate an [ETDump](./etdump.md).
120*523fa7a6SAndroid Build Coastguard Worker```
121*523fa7a6SAndroid Build Coastguard Worker./cmake-out/examples/apple/mps/mps_executor_runner --model_path mv3_mps_bundled_fp16.pte --bundled_program --dump-outputs
122*523fa7a6SAndroid Build Coastguard Worker```
123*523fa7a6SAndroid Build Coastguard Worker3. Create an instance of the Inspector API by passing in the ETDump you have sourced from the runtime along with the optionally generated ETRecord from step 1.
124*523fa7a6SAndroid Build Coastguard Worker```bash
125*523fa7a6SAndroid Build Coastguard Workerpython3 -m sdk.inspector.inspector_cli --etdump_path etdump.etdp --etrecord_path etrecord.bin
126*523fa7a6SAndroid Build Coastguard Worker```
127*523fa7a6SAndroid Build Coastguard Worker
128*523fa7a6SAndroid Build Coastguard Worker## Deploying and Running on Device
129*523fa7a6SAndroid Build Coastguard Worker
130*523fa7a6SAndroid Build Coastguard Worker***Step 1***. Create the ExecuTorch core and MPS delegate frameworks to link on iOS
131*523fa7a6SAndroid Build Coastguard Worker```bash
132*523fa7a6SAndroid Build Coastguard Workercd executorch
133*523fa7a6SAndroid Build Coastguard Worker./build/build_apple_frameworks.sh --mps
134*523fa7a6SAndroid Build Coastguard Worker```
135*523fa7a6SAndroid Build Coastguard Worker
136*523fa7a6SAndroid Build Coastguard Worker`mps_delegate.xcframework` will be in `cmake-out` folder, along with `executorch.xcframework` and `portable_delegate.xcframework`:
137*523fa7a6SAndroid Build Coastguard Worker```bash
138*523fa7a6SAndroid Build Coastguard Workercd cmake-out && ls
139*523fa7a6SAndroid Build Coastguard Worker```
140*523fa7a6SAndroid Build Coastguard Worker
141*523fa7a6SAndroid Build Coastguard Worker***Step 2***. Link the frameworks into your XCode project:
142*523fa7a6SAndroid Build Coastguard WorkerGo to project Target’s  `Build Phases`  -  `Link Binaries With Libraries`, click the **+** sign and add the frameworks: files located in  `Release` folder.
143*523fa7a6SAndroid Build Coastguard Worker- `executorch.xcframework`
144*523fa7a6SAndroid Build Coastguard Worker- `portable_delegate.xcframework`
145*523fa7a6SAndroid Build Coastguard Worker- `mps_delegate.xcframework`
146*523fa7a6SAndroid Build Coastguard Worker
147*523fa7a6SAndroid Build Coastguard WorkerFrom the same page, include the needed libraries for the MPS delegate:
148*523fa7a6SAndroid Build Coastguard Worker- `MetalPerformanceShaders.framework`
149*523fa7a6SAndroid Build Coastguard Worker- `MetalPerformanceShadersGraph.framework`
150*523fa7a6SAndroid Build Coastguard Worker- `Metal.framework`
151*523fa7a6SAndroid Build Coastguard Worker
152*523fa7a6SAndroid Build Coastguard WorkerIn this tutorial, you have learned how to lower a model to the MPS delegate, build the mps_executor_runner and run a lowered model through the MPS delegate, or directly on device using the MPS delegate static library.
153*523fa7a6SAndroid Build Coastguard Worker
154*523fa7a6SAndroid Build Coastguard Worker
155*523fa7a6SAndroid Build Coastguard Worker## Frequently encountered errors and resolution.
156*523fa7a6SAndroid Build Coastguard Worker
157*523fa7a6SAndroid Build Coastguard WorkerIf you encountered any bugs or issues following this tutorial please file a bug/issue on the [ExecuTorch repository](https://github.com/pytorch/executorch/issues), with hashtag **#mps**.
158