|
| 1 | +# ExecuTorch Model Fine-Tuning on Android App |
| 2 | + |
| 3 | +In this tutorial, we will be fine-tuning a CIFAR 10 model on an android app using ExecuTorch. |
| 4 | + |
| 5 | +## Environment Setup |
| 6 | + |
| 7 | +### Android Environment Setup |
| 8 | + |
| 9 | +Ensure that your development environment meets the following requirements: |
| 10 | + |
| 11 | +1. Minimum JDK version: 17 |
| 12 | +2. Target Android API level: 34 (`Android 14.0`) |
| 13 | +3. Required Android SDK components: |
| 14 | + - Android SDK Build-Tools 34 |
| 15 | + - Android SDK Platform-Tools |
| 16 | + - Android NDK (Side by side) |
| 17 | + - Android SDK Command-line Tools (latest) |
| 18 | +4. Install Android Emulator or connect an Android device |
| 19 | +5. Ensure the following environment variables are set: |
| 20 | + - `JAVA_HOME` |
| 21 | + - `ANDROID_NDK` |
| 22 | + - `ANDROID_SDK` |
| 23 | + |
| 24 | +**NOTE** For the updated steps for building the dependencies refer to the official repository over [here](https://github.com/pytorch/executorch/blob/main/extension/android/README.md). |
| 25 | + |
| 26 | +### ExecuTorch Environment Setup |
| 27 | + |
| 28 | +To ensure better management of Python environments and packages, it is recommended to use a Python environment management tool such as `conda`, `venv`, or `uv`. For this demonstration, we will use `uv` to set up the Python environment. |
| 29 | + |
| 30 | +To install ExecuTorch in a `uv` Python environment use the following commands: |
| 31 | + |
| 32 | +```bash |
| 33 | +$ git clone https://github.com/pytorch/executorch.git --recurse-submodules |
| 34 | +$ cd executorch |
| 35 | + |
| 36 | +# [optional] Setup an environment |
| 37 | +$ uv venv --seed --prompt et --python 3.10 |
| 38 | +$ source .venv/bin/activate |
| 39 | + |
| 40 | +# Install build tools and ExecuTorch pip wheel |
| 41 | +$ ./install_executorch.sh |
| 42 | + |
| 43 | +# Build ExecuTorch for Android. Output AAR: ./extension/android/executorch_android/build/outputs/aar/executorch_android-debug.aar |
| 44 | +$ ./scripts/build_android_library.sh |
| 45 | + |
| 46 | +# Fetch the examples |
| 47 | +$ git clone [email protected]:pytorch-labs/executorch-examples.git |
| 48 | + |
| 49 | +# Copy the ExecuTorch AAR into the libs directory |
| 50 | +$ mkdir -p executorch-examples/cifar/android/CifarETTrainingDemo/app/libs |
| 51 | +$ cp ./extension/android/executorch_android/build/outputs/aar/executorch_android-debug.aar executorch-examples/cifar/android/CifarETTrainingDemo/app/libs/executorch.aar |
| 52 | + |
| 53 | +# Build the data and models |
| 54 | +$ mkdir -p executorch-examples/cifar/android/CifarETTrainingDemo/app/src/main/assets/ |
| 55 | +$ python ./extension/training/examples/CIFAR/main.py --data-dir executorch-examples/cifar/android/CifarETTrainingDemo/app/src/main/assets/ --model-path executorch-examples/cifar/android/CifarETTrainingDemo/app/src/main/assets/cifar10_model.pth --pte-model-path executorch-examples/cifar/android/CifarETTrainingDemo/app/src/main/assets/cifar10_model.pte --split-pte-model-path executorch-examples/cifar/android/CifarETTrainingDemo/app/src/main/assets/cifar10_model_pte_only.pte --save-pt-json executorch-examples/cifar/android/CifarETTrainingDemo/app/src/main/assets/cifar10_pt.json --save-et-json executorch-examples/cifar/android/CifarETTrainingDemo/app/src/main/assets/cifar10_et.json --ptd-model-dir executorch-examples/cifar/android/CifarETTrainingDemo/app/src/main/assets/ --epochs 5 --fine-tune-epochs 10 |
| 56 | +``` |
| 57 | + |
| 58 | +If you run into errors for sdk path, complete the above steps in the [Trouble Shooting](#trouble-shooting) section before proceeding. |
| 59 | + |
| 60 | +## Creation of Android App |
| 61 | + |
| 62 | +1. Start with a clone of this repository and open the project in Android Studio executorch-examples/cifar/android/CifarETTrainingDemo/app/build.gradle.kts. |
| 63 | + |
| 64 | +2. Set the minimum SDK version to `API 34`. |
| 65 | + |
| 66 | +3. Wait for the Gradle sync to complete. |
| 67 | + |
| 68 | +4. Click on run to proceed:  |
| 69 | + |
| 70 | +5. Click on the fine-tune button and the training begins for `150` epochs![[Pasted image 20250709171210.png]] |
| 71 | + |
| 72 | + **Note:** The training parameters can be tweaked in `MainActivity.kt` |
| 73 | + |
| 74 | +### Summary: |
| 75 | + |
| 76 | +We trained the PyTorch model for `1 epoch` and exported the `.pte` and `.ptd` files. We started with training loss of `2.159132883071899`, training accuracy of `18%`, testing loss of `2.1072397136688235`, and testing accuracy of `29%` |
| 77 | + |
| 78 | +```log |
| 79 | +2025-07-09 17:11:46.309 13277-13277 ExecuTorchApp com.example.democifar10 D Starting Epoch 1/150 |
| 80 | +2025-07-09 17:11:46.309 13277-13277 ExecuTorchApp com.example.democifar10 D Total images to be trained: 500, Number of batches: 125 |
| 81 | +2025-07-09 17:11:47.237 13277-13428 EGL_emulation com.example.democifar10 D app_time_stats: avg=7.23ms min=2.75ms max=25.70ms count=60 |
| 82 | +2025-07-09 17:11:47.715 13277-13277 ExecuTorchApp com.example.democifar10 D Epoch [1/150] Loss: 2.159132883071899, Accuracy: 18%, Time: 1.41 s, Time per image: 2.81 ms |
| 83 | +2025-07-09 17:11:47.715 13277-13277 ExecuTorchApp com.example.democifar10 D Starting evaluation |
| 84 | +2025-07-09 17:11:47.715 13277-13277 ExecuTorchApp com.example.democifar10 D Evaluating model on 100 test images (25 batches) out of 100 total images |
| 85 | +2025-07-09 17:11:47.989 13277-13277 ExecuTorchApp com.example.democifar10 D Evaluation complete - Loss: 2.1072397136688235, Accuracy: 29.0%, Time: 0.27 s, Time per image: 2.73 ms |
| 86 | +``` |
| 87 | + |
| 88 | +We reached a training loss of `1.7837489886283875`, training accuracy of `35%`, testing loss of `2.0501016211509704`, and testing accuracy of `38%` after `150 epochs` |
| 89 | + |
| 90 | +```log |
| 91 | +2025-07-09 17:13:59.889 13277-13277 ExecuTorchApp com.example.democifar10 D Starting Epoch 150/150 |
| 92 | +2025-07-09 17:13:59.889 13277-13277 ExecuTorchApp com.example.democifar10 D Total images to be trained: 500, Number of batches: 125 |
| 93 | +2025-07-09 17:14:00.666 13277-13277 ExecuTorchApp com.example.democifar10 D Epoch [150/150] Loss: 1.7837489886283875, Accuracy: 35%, Time: 0.78 s, Time per image: 1.56 ms |
| 94 | +2025-07-09 17:14:00.666 13277-13277 ExecuTorchApp com.example.democifar10 D Starting evaluation |
| 95 | +2025-07-09 17:14:00.666 13277-13277 ExecuTorchApp com.example.democifar10 D Evaluating model on 100 test images (25 batches) out of 100 total images |
| 96 | +2025-07-09 17:14:00.809 13277-13277 ExecuTorchApp com.example.democifar10 D Evaluation complete - Loss: 1.7236163129806519, Accuracy: 38%, Time: 0.67 s, Time per image: 1.35 ms |
| 97 | +``` |
| 98 | + |
| 99 | +### Trouble Shooting |
| 100 | + |
| 101 | +Check if the `local.properties` file is present in the `extension/android` directory: |
| 102 | + |
| 103 | +```bash |
| 104 | +$ cat ./extension/android/local.properties |
| 105 | +``` |
| 106 | + |
| 107 | +**NOTE:** If this file (`local.properties`) is missing, the build process will fail because the script can't retrieve the path for the android sdk from the env variables. If you encounter this issue, please follow the following steps: |
| 108 | + |
| 109 | +```bash |
| 110 | +$ touch ./extension/android/local.properties |
| 111 | +$ vim ./extension/android/local.properties |
| 112 | +# Add the path to your sdk directory into this file like: sdk.dir=/Users/<USERNAME>/Library/Android/sdk |
| 113 | +``` |
0 commit comments