1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311
|
# Document for Running QNN Models
## For Linux Host (Setup)
### Step 1: Install Qualcomm AI Engine Direct (QNN SDK)
1. Download the QNN SDK:
* Go to the QNN SDK product [page](https://www.qualcomm.com/developer/software/qualcomm-ai-engine-direct-sdk).
* Click **Get Software** to download the QNN SDK.
* Unzip the downloaded SDK.
2. Set Up Your Environment:
* Open a terminal.
* Navigate to `qairt/<QNN_SDK_VERSION>` inside the unzipped QNN SDK.
* Run the following commands to set up the environment:
+ `cd bin`
+ `source ./envsetup.sh`
* This will automatically set the environment variables `QNN_SDK_ROOT` and `SNPE_ROOT`.
* To save this for future bash terminals, run:
+ `echo 'export QNN_SDK_ROOT="${QNN_SDK_ROOT}"' >> ~/.bashrc`
3. Check Dependencies:
* Run:
+ `sudo ${QNN_SDK_ROOT}/bin/check-linux-dependency.sh`
* When all necessary dependencies are installed, the script will display “Done!!”.
4. Verify Toolchain Installation:
* Run:
+ `${QNN_SDK_ROOT}/bin/envcheck -c`
* This will verify that the required toolchain is installed successfully.
### Step 2: Install QNN SDK Dependencies
1. Install Python 3.10:
* Run the following commands:
+ `sudo apt-get update && sudo apt-get install python3.10 python3-distutils libpython3.10`
* Verify the installation by running:
+ `python3 --version`
2. Navigate to QNN SDK Root:
* Run:
+ `cd ${QNN_SDK_ROOT}`
3. Create and Activate a Virtual Environment:
* Run the following commands (you may rename `MY_ENV_NAME` to any name you prefer):
+ `python3 -m venv MY_ENV_NAME`
+ `source MY_ENV_NAME/bin/activate`
4. Update Dependencies:
* Run:
+ `python "${QNN_SDK_ROOT}/bin/check-python-dependency"`
### Step 3: Install Model Frameworks
1. Identify Relevant Frameworks:
* QNN supports multiple model frameworks. Install only the ones relevant for the AI model files you want to use.
* **Warning:** You do not need to install all packages listed here.
2. Note:
* You can install a package by running:
+ `pip3 install package==version`
* Example Installations:
+ `pip3 install torch==1.13.1`
+ `pip3 install tensorflow==2.10.1`
+ `pip3 install tflite==2.3.0`
+ `pip3 install torchvision==0.14.1`
+ `pip3 install onnx==1.12.0`
+ `pip3 install onnxruntime==1.17.1`
+ `pip3 install onnxsim==0.4.36`
### Step 4: Install Target Device OS-Specific Toolchain Code
#### Working with an Android Target Device:
1. Install Android NDK:
* Download the [Android NDK r26c](https://dl.google.com/android/repository/android-ndk-r26c-linux.zip).
* Unzip the file.
2. Set Up Environment Variables:
* Open a terminal.
* Replace `<path-to-your-android-ndk-root-folder>` with the path to the unzipped `android-ndk-r26c` folder, then run:
+ `echo 'export ANDROID_NDK_ROOT="<path-to-your-android-ndk-root-folder>"' >> ~/.bashrc`
* Add the location of the unzipped file to your PATH by running:
+ `echo 'export PATH="${ANDROID_NDK_ROOT}:${PATH}"' >> ~/.bashrc`
+ `source ~/.bashrc`
3. Verify Environment Variables:
* Run:
+ `${QNN_SDK_ROOT}/bin/envcheck -n`
#### Working with a Linux Target Device:
1. Verify Clang++14 Installation:
* For Linux target devices, you will likely need to use clang++14 to build models for them using the QNN SDK.
* You can verify if you have clang++14 by running:
+ `${QNN_SDK_ROOT}/bin/envcheck -c`
2. Set Up Cross Compiler (for **Linux Embedded**):
* Open a new terminal
* Follow these steps to set up the cross compiler:
+ `wget https://artifacts.codelinaro.org/artifactory/qli-ci/flashable-binaries/qimpsdk/qcm6490/x86/qcom-6.6.28-QLI.1.1-Ver.1.1_qim-product-sdk-1.1.3.zip`
+ `unzip qcom-6.6.28-QLI.1.1-Ver.1.1_qim-product-sdk-1.1.3.zip`
+ `umask a+rx`
+ `cd /path/to/unzip/target/qcm6490/sdk`
+ `sh qcom-wayland-x86_64-qcom-multimedia-image-armv8-2a-qcm6490-toolchain-ext-1.0.sh`
+ `export ESDK_ROOT=<path of installation directory>`
+ `cd $ESDK_ROOT`
+ `source environment-setup-armv8-2a-qcom-linux`
## CNN to QNN for Linux Host
### Step 1: Set Up The Example TensorFlow Model
1. Verify TensorFlow Installation:
* Run:
+ `python3 -m pip show tensorflow`
2. Set the TENSORFLOW_HOME Environment Variable:
* Run the following commands:
```
tensorflowLocation=$(python -m pip show tensorflow | grep '^Location: ' | awk '{print $2}')
export TENSORFLOW_HOME="$tensorflowLocation/tensorflow"
echo "export TENSORFLOW_HOME=$tensorflowLocation/tensorflow" >> ~/.bashrc
```
3. Verify Environment Variable:
* Run:
+ `${TENSORFLOW_HOME}`
4. Create Test Data:
* Run:
+ `python3 ${QNN_SDK_ROOT}/examples/Models/InceptionV3/scripts/setup_inceptionv3.py -a ~/tmpdir -d`
* This will create the test data for this tutorial:
+ Model file at: `${QNN_SDK_ROOT}/examples/Models/InceptionV3/tensorflow/inception_v3_2016_08_28_frozen.pb`
+ Raw images at: `${QNN_SDK_ROOT}/examples/Models/InceptionV3/data/cropped`
### Step 2: Convert the CNN Model into a QNN Model
1. Quantized Model Conversion:
* To use a quantized model, pass in the `--input_list` flag to specify the input.
* Run the following command:
```
python ${QNN_SDK_ROOT}/bin/x86_64-linux-clang/qnn-tensorflow-converter \
--input_network "${QNN_SDK_ROOT}/examples/Models/InceptionV3/tensorflow/inception_v3_2016_08_28_frozen.pb" \
--input_dim input 1,299,299,3 \
--input_list "${QNN_SDK_ROOT}/examples/Models/InceptionV3/data/cropped/raw_list.txt" \
--out_node "InceptionV3/Predictions/Reshape_1" \
--output_path "${QNN_SDK_ROOT}/examples/Models/InceptionV3/model/Inception_v3.cpp"
```
2. Flags Explanation:
* `--input_network`: Path to the source framework model.
* `--input_dim`: Input name followed by dimensions.
* `--input_list`: Absolute path to input data (required for quantization).
* `--out_node`: Name of the graph’s output Tensor Names.
* `--output_path`: Indicates where to put the output files.
3. Artifacts Produced:
* `Inception_v3.cpp`: Contains the sequence of API calls.
* `Inception_v3.bin`: Static data associated with the model.
* `Inception_v3_net.json`: Describes the model data in a standardized manner (not needed to build the QNN model later on).
4. Location of Artifacts:
* You can find the artifacts in the `${QNN_SDK_ROOT}/examples/Models/InceptionV3/model` directory.
### Other Model Types:
If you are using another type of model, you can refer to the [Tools page](https://docs.qualcomm.com/bundle/publicresource/topics/80-63442-50/tools.html) for a table of potential scripts to help convert them into QNN format. These scripts will have a similar qnn-model-type-converter naming convention.
### Step 3: Model Build on Linux Host
1. Choose Target Architecture:
* Select the most relevant supported target architecture from the following list:
+ 64-bit Linux targets: `x86_64-linux-clang`
+ 64-bit Android devices: `aarch64-android`
+ Qualcomm’s QNX OS: `aarch64-qnx` (Note: This architecture is not supported by default in the QNN SDK.)
+ OpenEmbedded Linux (GCC 11.2): `aarch64-oe-linux-gcc11.2`
+ OpenEmbedded Linux (GCC 9.3): `aarch64-oe-linux-gcc9.3`
+ OpenEmbedded Linux (GCC 8.2): `aarch64-oe-linux-gcc8.2`
+ Ubuntu Linux (GCC 9.4): `aarch64-ubuntu-gcc9.4`
+ Ubuntu Linux (GCC 7.5): `aarch64-ubuntu-gcc7.5`
2. Set Target Architecture:
* On your host machine, set the target architecture of your target device by running:
+ `export QNN_TARGET_ARCH="your-target-architecture-from-above"`
* For **Android**:
+ `export QNN_TARGET_ARCH="aarch64-android"`
* For **Linux Embedded**:
+ `export QNN_TARGET_ARCH="aarch64-oe-linux-gcc11.2"`
3. Generate Model Library:
* Run the following command on your host machine:
```
python3 "${QNN_SDK_ROOT}/bin/x86_64-linux-clang/qnn-model-lib-generator" \
-c "${QNN_SDK_ROOT}/examples/Models/InceptionV3/model/Inception_v3.cpp" \
-b "${QNN_SDK_ROOT}/examples/Models/InceptionV3/model/Inception_v3.bin" \
-o "${QNN_SDK_ROOT}/examples/Models/InceptionV3/model_libs" \
-t ${QNN_TARGET_ARCH}
```
* `-c`: Path to the `.cpp` QNN model file.
* `-b`: Path to the `.bin` QNN model file (optional but recommended).
* `-o`: Path to the output folder.
* `-t`: Target architecture to build for.
4. Verify Output File:
* Run:
+ `ls ${QNN_SDK_ROOT}/examples/Models/InceptionV3/model_libs/${QNN_TARGET_ARCH}`
* Verify that the output file `libInception_v3.so` is inside. This file will be used on the target device to execute inferences. The output `.so` file will be located in the `model_libs` directory, named according to the target architecture.
### Step 4: Model Build on Linux Host
Users can set custom options and different performance modes to the HTP Backend through the backend config. Follow these steps to create the necessary JSON files:
1. Create Backend Config File (`be.json`):
* For **Android** with the following content:
```json
{
"graphs": [
{
"graph_names": [
"Inception_v3"
],
"vtcm_mb": 8
}
],
"devices": [
{
"htp_arch": "v79"
}
]
}
```
* For **Linux Embedded** with the following content:
```json
{
"graphs": [
{
"graph_names": [
"Inception_v3"
],
"vtcm_mb": 8
}
],
"devices": [
{
"htp_arch": "v73"
}
]
}
```
2. Create Backend Extensions Config File (`config.json`):
* The config file with minimum parameters specified through JSON is given below:
```json
{
"backend_extensions": {
"shared_library_path": "./libQnnHtpNetRunExtensions.so",
"config_file_path": "./be.json"
}
}
```
3. Place JSON Files in the Model Libraries Path:
* Ensure that the `be.json` and `config.json` files are located in the following path:
+ `${QNN_SDK_ROOT}/examples/Models/InceptionV3/model_libs/${QNN_TARGET_ARCH}`
### Step 5: Prepare the Target Device
1. Open a Terminal on the Target Device:
* Run the following commands to create a destination folder and set the necessary permissions:
```
adb shell "mkdir -p /data/local/tmp"
adb shell "ln -s /etc/ /data/local/tmp"
adb shell "chmod -R 777 /data/local/tmp"
adb shell "mkdir -p /data/local/tmp/inception_v3"
```
2. Push Necessary Files:
* Push `libQnnHtp.so` and other necessary executables, input data, and input list from your host machine to `/data/local/tmp/inception_v3` on the target device:
```
adb push \path\to\qairt\2.32.0.250228\lib\${QNN_TARGET_ARCH} /data/local/tmp/inception_v3
adb shell "cd /data/local/tmp/inception_v3; mv ./${QNN_TARGET_ARCH}/* ./; rmdir ${QNN_TARGET_ARCH}"
```
* For **Android**:
+ `adb push \path\to\qairt\2.32.0.250228\lib\hexagon-v79\unsigned /data/local/tmp/inception_v3`
* For **Linux Embedded**:
+ `adb push \path\to\qairt\2.32.0.250228\lib\hexagon-v73\unsigned /data/local/tmp/inception_v3`
* Continue remaining steps on the target device:
```
adb shell "cd /data/local/tmp/inception_v3; mv ./unsigned/* ./; rmdir unsigned"
adb push \path\to\qairt\2.32.0.250228\examples\Models\InceptionV3\model_libs\${QNN_TARGET_ARCH}\ /data/local/tmp/inception_v3
adb shell "cd /data/local/tmp/inception_v3; mv ./${QNN_TARGET_ARCH}/* ./; rmdir ${QNN_TARGET_ARCH}"
```
```
adb push \path\to\qairt\2.32.0.250228\examples\Models\InceptionV3\data\cropped /data/local/tmp/inception_v3
adb push \path\to\qairt\2.32.0.250228\examples\Models\InceptionV3\data\target_raw_list.txt /data/local/tmp/inception_v3
adb push \path\to\qairt\2.32.0.250228\bin\${QNN_TARGET_ARCH}\qnn-net-run /data/local/tmp/inception_v3
adb shell "chmod 777 /data/local/tmp/inception_v3/qnn-net-run"
```
3. Run the Model & Pull Output Directory to Host Machine:
* On the target device, run the following command to execute the model:
```
adb shell "LD_LIBRARY_PATH=/data/local/tmp/inception_v3 DSP_LIBRARY_PATH=/data/local/tmp/inception_v3; cd /data/local/tmp/inception_v3; ./qnn-net-run --model ./libInception_v3.so --input_list ./target_raw_list.txt --backend ./libQnnHtp.so --output_dir ./output --config_file ./config.json"
```
* Run the following command to pull the output directory from the target device to your host machine:
+ `adb pull /data/local/tmp/inception_v3/output \path\to\qairt\2.32.0.250228\examples\Models\InceptionV3`
### Step 6: View Classification Result
1. Navigate to the Example Directory on Host Machine:
* Run:
+ `cd ${QNN_SDK_ROOT}/examples/Models/InceptionV3`
2. Run the Script to View Classification Results:
* Execute the following command to view the classification results:
```
python3 "./scripts/show_inceptionv3_classifications.py" \
-i "./data/cropped/raw_list.txt" \
-o "./output" \
-l "./data/imagenet_slim_labels.txt"
```
* Ensure that the classification results in the output match the following:
```
${QNN_SDK_ROOT}/examples/Models/InceptionV3/data/cropped/notice_sign.raw 0.152344 459 brass
${QNN_SDK_ROOT}/examples/Models/InceptionV3/data/cropped/chairs.raw 0.281250 832 studio couch
${QNN_SDK_ROOT}/examples/Models/InceptionV3/data/cropped/trash_bin.raw 0.800781 413 ashcan
${QNN_SDK_ROOT}/examples/Models/InceptionV3/data/cropped/plastic_cup.raw 0.988281 648 measuring cup
```
### References
* [Linux Setup](https://docs.qualcomm.com/bundle/publicresource/topics/80-63442-50/linux_setup.html)
* [CNN to QNN for Linux Host](https://docs.qualcomm.com/bundle/publicresource/topics/80-63442-50/qnn_tutorial_linux_host.html)
* [CNN to QNN for Linux Host on Linux Target](https://docs.qualcomm.com/bundle/publicresource/topics/80-63442-50/qnn_tutorial_linux_host_linux_target.html)
|