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