|
| 1 | +--- |
| 2 | +title: ML Profiling of an ExecuTorch model |
| 3 | +weight: 7 |
| 4 | + |
| 5 | +### FIXED, DO NOT MODIFY |
| 6 | +layout: learningpathall |
| 7 | +--- |
| 8 | + |
| 9 | +## ExecuTorch Profiling Tools |
| 10 | +You can use [ExecuTorch](https://pytorch.org/executorch/stable/index.html) for running PyTorch models on constrained devices like mobile. As so many models are developed in PyTorch, this is a useful way to quickly deploy them to mobile devices, without the requirement for conversion tools such as Google's [ai-edge-torch](https://github.com/google-ai-edge/ai-edge-torch) to convert them into tflite. |
| 11 | + |
| 12 | +To get started on ExecuTorch, you can follow the instructions on the [PyTorch website](https://pytorch.org/executorch/stable/getting-started-setup). To then deploy on Android, you can also find instructions on the [Pytorch website](https://pytorch.org/executorch/stable/demo-apps-android.html). If you do not already have ExecuTorch running on Android, follow these instructions first. |
| 13 | + |
| 14 | +ExecuTorch comes with a set of profiling tools, but currently they are aimed at Linux, and not Android. The instructions to profile on Linux are [here](https://pytorch.org/executorch/main/tutorials/devtools-integration-tutorial.html), and you can adapt them for use on Android. |
| 15 | + |
| 16 | +## Profiling on Android |
| 17 | + |
| 18 | +To profile on Android, the steps are the same as for [Linux](https://pytorch.org/executorch/main/tutorials/devtools-integration-tutorial.html), except that you need to generate the ETDump file on an Android device. |
| 19 | + |
| 20 | +To start, generate the ETRecord in exactly the same way as described for the Linux instructions. |
| 21 | + |
| 22 | +Next, follow the instructions to create the ExecuTorch bundled program that you will need to generate the ETDump. You will copy this to your Android device together with the runner program that you are about to compile. |
| 23 | + |
| 24 | +To compile the runner program, you will need to adapt the `build_example_runner.sh` script in the instructions that are located in the `examples/devtools` subfolder of the ExecuTorch repository to compile it for Android. Copy the script and rename the file to `build_android_example_runner.sh`, ready for editing. Remove all lines with `coreml` in them, and the options dependent on it, as these are not needed for Android. |
| 25 | + |
| 26 | +You then need to set the `ANDROID_NDK` environment variable to point to your Android NDK installation. |
| 27 | + |
| 28 | +At the top of the `main()` function add: |
| 29 | + |
| 30 | +```bash |
| 31 | + export ANDROID_NDK=~/Android/Sdk/ndk/28.0.12674087 # replace this with the correct path for your NDK installation |
| 32 | + export ANDROID_ABI=arm64-v8a |
| 33 | +``` |
| 34 | + |
| 35 | +Next, add Android options to the first `cmake` configuration line in `main()`, that configures the building of the ExecuTorch library. |
| 36 | + |
| 37 | +Change it to: |
| 38 | + |
| 39 | +```bash |
| 40 | + cmake -DCMAKE_INSTALL_PREFIX=cmake-out \ |
| 41 | + -DCMAKE_BUILD_TYPE=Release \ |
| 42 | + -DCMAKE_TOOLCHAIN_FILE="${ANDROID_NDK}/build/cmake/android.toolchain.cmake" \ |
| 43 | + -DANDROID_ABI="${ANDROID_ABI}" \ |
| 44 | + -DEXECUTORCH_BUILD_XNNPACK=ON \ |
| 45 | + -DEXECUTORCH_BUILD_EXTENSION_DATA_LOADER=ON \ |
| 46 | + -DEXECUTORCH_BUILD_EXTENSION_MODULE=ON \ |
| 47 | + -DEXECUTORCH_BUILD_EXTENSION_RUNNER_UTIL=ON \ |
| 48 | + -DEXECUTORCH_BUILD_EXTENSION_TENSOR=ON \ |
| 49 | + -DEXECUTORCH_BUILD_DEVTOOLS=ON \ |
| 50 | + -DEXECUTORCH_ENABLE_EVENT_TRACER=ON \ |
| 51 | + -Bcmake-out . |
| 52 | +``` |
| 53 | + |
| 54 | +The `cmake` build step for the ExecuTorch library stays the same, as do the next lines setting up local variables. |
| 55 | + |
| 56 | +Next you will adapt the options to Android in the second `cmake` configuration line, which is the one that configures the building of the runner. |
| 57 | + |
| 58 | +Change it to: |
| 59 | + |
| 60 | +```bash |
| 61 | + cmake -DCMAKE_PREFIX_PATH="${cmake_prefix_path}" \ |
| 62 | + -Dexecutorch_DIR="${PWD}/cmake-out/lib/cmake/ExecuTorch" -Dgflags_DIR="${PWD}/cmake-out/third-party/gflags" \ |
| 63 | + -DCMAKE_BUILD_TYPE=Release \ |
| 64 | + -DCMAKE_TOOLCHAIN_FILE="${ANDROID_NDK}/build/cmake/android.toolchain.cmake" \ |
| 65 | + -DANDROID_ABI="${ANDROID_ABI}" \ |
| 66 | + -B"${build_dir}" \ |
| 67 | + "${example_dir}" |
| 68 | +``` |
| 69 | + |
| 70 | +Once you have changed the configuration lines, you can now run the script `./build_android_example_runner.sh` to build the runner program. |
| 71 | + |
| 72 | +Once compiled, find the executable `example_runner` in `cmake-out/examples/devtools/`. |
| 73 | + |
| 74 | +Copy `example_runner` and the ExecuTorch bundled program to your Android device. |
| 75 | + |
| 76 | +Do this with adb: |
| 77 | + |
| 78 | +```bash |
| 79 | +adb push example_runner /data/local/tmp/ |
| 80 | +adb push bundled_program.bp /data/local/tmp/ |
| 81 | +adb shell |
| 82 | +chmod 777 /data/local/tmp/example_runner |
| 83 | +./example_runner --bundled_program_path="bundled_program.bp" |
| 84 | +exit |
| 85 | +adb pull /data/local/tmp/etdump.etdp . |
| 86 | +``` |
| 87 | + |
| 88 | +You now have the ETDump file ready to analyze with an ExecuTorch Inspector, in line with the Linux instructions. |
| 89 | + |
| 90 | +To get a full display of the operators and their timings, use the following: |
| 91 | + |
| 92 | +```python |
| 93 | +from executorch.devtools import Inspector |
| 94 | + |
| 95 | +etrecord_path = "etrecord.bin" |
| 96 | +etdump_path = "etdump.etdp" |
| 97 | +inspector = Inspector(etdump_path=etdump_path, etrecord=etrecord_path) |
| 98 | +inspector.print_data_tabular() |
| 99 | +``` |
| 100 | + |
| 101 | +However, as the [ExecuTorch profiling page](https://pytorch.org/executorch/main/tutorials/devtools-integration-tutorial.html) explains, there are data analysis options available. These enable you to quickly find specified criteria such as the slowest layer or group operators. Both the `EventBlock` and `DataFrame` approaches work well. However, at time of writing, the `find_total_for_module()` function has a [bug](https://github.com/pytorch/executorch/issues/7200) and returns incorrect values - hopefully this will soon be fixed. |
0 commit comments