> ## Documentation Index
> Fetch the complete documentation index at: https://dragonwingdocs.qualcomm.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 使用 QAIRT SDK 分析 AI 模型性能

> 在 Qualcomm Dragonwing IoT 平台上,使用 QNN 工具(包括 qnn-net-run、qnn-throughput-net-run 和 qnn-profile-viewer)分析 AI 模型性能。

使用 QAIRT SDK 分析您的 AI 模型,以测量模型在指定后端上执行的总运行时间,并优化性能。性能分析可提供关于执行期间延迟和硬件利用率的详细见解。

启用其他分析选项以查看不同层级的执行时间,例如按操作或按层级。使用这些分析信息来识别图执行中的瓶颈和低效之处,以便您可以优化 QNN 运行时并降低模型延迟。

## 前提条件

* 在主机上设置 QAIRT SDK。

  有关详细的安装和配置说明,请参阅[设置 Qualcomm AI Runtime SDK](/zh/AI-Developer-Workflow-Ubuntu/topic/qairt-setup)。

* 选择要进行分析的模型。

  您可以使用 QAIRT 工具转换和量化自定义模型,也可以通过 AI Hub 生成量化模型。
  有关编译和优化模型的详细指南,请参阅
  [编译并优化 AI 模型](/zh/AI-Developer-Workflow-Ubuntu/map/compile-and-optimize-model)。

  以下说明使用来自 AI Hub 的 Inception V3 模型。

* 在设备上启用 Wi-Fi 和 SSH。

  设备需要联网,以下载运行示例应用所需的工件。如果已经配置了 SSH 和 Wi-Fi,请跳过此步骤。

  按照[设置 SSH 连接](https://dragonwingdocs.qualcomm.com/Technologies/Ethernet/get-started-with-ethernet#set-up-an-ssh-connection)的说明,在设备上启用 Wi-Fi 和 SSH。

* 确保已在目标设备上安装以下 QNN 工具作为构建的一部分。

  * qnn-net-run
  * qnn-throughput-net-run
  * qnn-context-binary-generator
  * qnn-profile-viewer

## HTP 上的分析级别

下表列出了各分析级别、其描述及配置方式:

| 分析级别     | 描述                                                                           | 配置                                                                                                                   |
| -------- | ---------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| Basic    | • 模型执行总时间(单位:微秒)<br />• 用于延迟测量                                               | 在 `qnn-net-run` 中使用 `--profiling_level=basic`                                                                        |
| Detailed | 提供基本信息以及以周期数计的每个操作的执行时间。                                                     | 在 `qnn-net-run` 中使用 `--profiling_level=detailed`                                                                     |
| Lint     | • 提供主线程上每个操作的周期计数以及后台执行信息。<br />• 启用 chrometrace 以进行更深入的分析。                  | 在 `qnn-net-run` 中使用 `--profiling_level=backend`,并在 `backend_extension_config.json` 文件内使用 `--profiling_level=linting` |
| Opttrace | • 提供极其详细的操作级 HTP 执行状态。<br />• 提供 HVX/HMX 利用率和 VTCM 使用情况。<br />• 用于深入的性能瓶颈分析。 | 在 `qnn-net-run` 中使用 `--profiling_level=detailed` 和 `--profiling_options=optrace`                                     |

下图显示了 HTP 的主要执行分析事件,以及推理期间如何测量这些事件:

<img src="https://mintlify.s3.us-west-1.amazonaws.com/qualcomm-prod/zh/AI-Developer-Workflow-Ubuntu/_images/htp-basic-profiling-events.png" alt="HTP 基本分析事件示意图" />

**图:HTP 基本分析事件**

## 使用 `qnn-net-run` 进行 Lint 分析

Lint 分析可提供主线程上每个操作的详细周期计数以及后台执行信息。以下步骤在 Inception-v3 AI Hub 模型上执行 lint 分析。请按照这些步骤操作,并将模型替换为您的自定义模型。

<Steps>
  <Step title="通过 SSH 连接到目标设备">
    ```shell theme={null}
    ssh ubuntu@<IP ADDRESS OF THE TARGET DEVICE>
    ```

    出现提示时,输入密码。
  </Step>

  <Step title="在目标设备上从 AI Hub 下载已量化(w8a8)的 inception_v3 dlc 模型以进行分析">
    ```shell theme={null}
    curl -L https://huggingface.co/qualcomm/Inception-v3/resolve/v0.42.0/Inception-v3_w8a8.dlc -o /etc/models/inception_v3_quantized.dlc 
    ```
  </Step>

  <Step title="使用生成的输入文件对模型进行分析">
    出于演示目的,您可以使用生成的输入文件对模型进行分析。

    使用以下针对 `inception_v3_quantized.dlc` 模型定制的 Python 脚本生成这些输入文件。

    <Steps>
      <Step title="将以下脚本另存为 /etc/models 目录中的 generate_random_input.py">
        ```python theme={null}
        import os
        import numpy as np

        input_path_list =[]
        BASE_PATH = "/tmp/RandomInputsForInceptionV3Profiling/"

        if not os.path.exists(BASE_PATH):
           os.mkdir(BASE_PATH)

        # generate 10 random inputs and save as raw
        NUM_IMAGES = 10

        #binary files
        for img in range(NUM_IMAGES):
           filename = "input_{}.raw".format(img)
           randomTensor = np.random.random((1, 224, 224, 3)).astype(np.float32)
           filename = os.path.join(BASE_PATH, filename)
           randomTensor.tofile(filename)
           input_path_list.append(filename)

        #for saving as input_list text
              with open("input_list_profiling.txt", "w") as f:
                 for path in input_path_list:
                    f.write(path)
                    f.write("\n")
        ```

        此脚本会生成 10 个示例输入文件,保存在 `/tmp/RandomInputsForInceptionV3Profiling/`
        目录中,并生成一个 `input_list_profiling.txt` 文件,其中包含每个生成样本的路径。
      </Step>

      <Step title="在目标设备上运行脚本">
        ```shell theme={null}
        python3 /etc/models/generate_random_input.py
        ```
      </Step>
    </Steps>
  </Step>

  <Step title="创建 backend_extension_config_file.json 和 htp_config.json 文件">
    在目标设备的 `/etc/models` 目录中创建 `backend_extension_config_file.json` 和 `htp_config.json` 文件,
    以便使用 HTP 运行时对模型进行分析。

    * `backend_extension_config_file.json`

      ```json theme={null}
      {
         "backend_extensions": {
            "shared_library_path" : "libQnnHtpNetRunExtensions.so",
            "config_file_path" : "./htp_config.json"
         }
      }
      ```

    * `htp_config.json`

      ```json theme={null}
      {
      "graphs": [
            {
                  "vtcm_mb": 2,
                  "fp16_relaxed_precision": 0,
                  "graph_names": [
                     "graph_name_1"
                  ],
                  "O": 3.0
            }
         ],
         "devices": [
            {
                  "dsp_arch": "v68",
                  "profiling_level": "linting",
                  "cores": [
                     {
                        "perf_profile": "burst"
                     }
                  ]
            }
         ]
      }
      ```

          <Note>
            * 对于 Qualcomm Dragonwing™ RB3 Gen 2,使用 `"dsp_arch": "v68"`
            * 对于 Dragonwing IQ-8275,使用 `"dsp_arch": "v75"`
            * 对于 Dragonwing IQ-9075,使用 `"dsp_arch": "v73"`
          </Note>
  </Step>

  <Step title="进入 /etc/models 目录并在目标设备上运行 qnn-net-run 命令">
    ```shell theme={null}
    qnn-net-run --model libQnnModelDlc.so \
                --backend libQnnHtp.so \
                --input_list input_list_profiling.txt \
                --config_file backend_extension_config_file.json \
                --output_dir output_htp \
                --profiling_level backend \
                --dlc_path /etc/models/inception_v3_quantized.dlc
    ```
  </Step>

  <Step title="通过指定 --profiling_level=backend 启用 Lint 分析">
    此步骤确保应用后端特定配置文件中定义的分析级别。

    应该会在 `/etc/models/output_htp` 目录中创建 `execution_metadata.yaml` 和 `qnn-profiling-data_0.log` 文件。

    要查看 qnn-profiling-data\_0.log 文件中的日志,请使用 qnn-profile-viewer。

    <img src="https://mintlify.s3.us-west-1.amazonaws.com/qualcomm-prod/zh/AI-Developer-Workflow-Ubuntu/_images/lint-profling.png" alt="输出目录中的 Lint 分析输出文件" />
  </Step>
</Steps>

## 使用 qnn-profile-viewer 查看 lint 分析日志

通过将 qnn-profile-viewer 工具与以下插件配合使用,查看在后端分析级别生成的分析输出:

<Tabs>
  <Tab title="libQnnHtpProfilingReader.so">
    要从推理中检索 linting 信息,请使用 `libQnnHtpProfilingReader.so` 插件运行 qnn-profile-viewer。此插件提供每次单独运行的原始输出。

    ```shell theme={null}
    qnn-profile-viewer --reader libQnnHtpProfilingReader.so --input_log /etc/models/output_htp/qnn-profiling-data_0.log --output /etc/models/output_htp/profile_htp.csv
    ```

    以下是示例输出:

    <img src="https://mintlify.s3.us-west-1.amazonaws.com/qualcomm-prod/zh/AI-Developer-Workflow-Ubuntu/_images/lint-profling-output.png" />

    **图:使用 libQnnHtpProfilingReader.so 进行 Lint 分析的示例输出**

    在 linting 分析报告中,每个操作都有:

    * **Cycle count(周期计数)**:在主线程上执行所花费的时间。
    * **Wait entry(等待项)**:在开始执行之前所花费的等待周期数。
    * **Overlap(重叠)**:在主线程执行当前操作时,至少一个后台操作所花费的周期数。
    * **Overlap (wait)(等待期间的重叠)**:在主线程等待期间,至少一个后台操作所花费的周期数。

    <Note>
      主线程上的每个操作在执行之前都有一段等待期,该等待期仅在前一个操作结束后才开始。这种延迟可能由调度问题或等待 HVX 或 DMA 等后台活动完成引起。
    </Note>
  </Tab>

  <Tab title="libQnnChrometraceProfilingReader.so">
    `libQnnChrometraceProfilingReader.so` 插件提供所有运行的平均输出。
    此外,如果使用 `--output` 选项指定了输出文件,还会生成一个
    包含 chrometrace 格式分析数据的文件。

    ```
    qnn-profile-viewer --reader libQnnChrometraceProfilingReader.so --input_log /etc/models/output_htp/qnn-profiling-data_0.log --output /etc/models/output_htp/chromeTrace.json
    ```

    下图显示了示例输出:

    <img src="https://mintlify.s3.us-west-1.amazonaws.com/qualcomm-prod/zh/AI-Developer-Workflow-Ubuntu/_images/lint-libQnnChrometraceProfilingReader.png" />

    **图:使用 libQnnChrometraceProfilingReader.so 进行 Lint 分析的示例输出**

    <Note>
      要查看 chrome trace,请使用 Google Chrome。
    </Note>
  </Tab>
</Tabs>

## 使用 QNN HTP Optrace 进行高级分析

使用 QNN optrace 分析来了解 QNN HTP 硬件模块的详细内部操作。此功能可帮助您:

* 识别可能未很好并行化的问题操作。
* 查看操作在整个执行过程中的调度方式。
* 观察各操作符之间的交互。
* 评估 HVX 并行性对每个操作的工作效率。

要进一步了解 QNN HTP optrace 分析,请参阅 [QNN HTP Optrace Profiling](https://docs.qualcomm.com/nav/home/htp_backend.html?product=1601111740009302#qnn-htp-optrace-profiling)。

## 使用 `qnn-throughput-net-run` 进行分析

使用 qnn-throughput-net-run 在一个或多个 QNN 后端上进行多线程执行。此分析支持多线程执行,并允许您在指定的持续时间或设定的迭代次数内重复运行模型。此分析适用于需要对多个模型进行并发或重复执行以进行性能基准测试的场景。

<Steps>
  <Step title="通过 SSH 连接到目标设备">
    ```shell theme={null}
    ssh ubuntu@<IP ADDRESS OF THE TARGET DEVICE>
    ```

    出现提示时,输入密码。
  </Step>

  <Step title="在目标设备上创建工作目录">
    ```shell theme={null}
    mkdir -p /etc/models
    ```
  </Step>

  <Step title="在目标设备上从 AI Hub 下载已量化(w8a8)的 inception_v3 dlc 模型">
    ```shell theme={null}
    curl -L https://huggingface.co/qualcomm/Inception-v3/resolve/v0.42.0/Inception-v3_w8a8.dlc -o /etc/models/inception_v3_quantized.dlc
    ```
  </Step>

  <Step title="在目标设备上创建 backend_extension_config.json 和 htp_config.json 文件">
    在 `/etc/models` 目录中创建这些文件。

    在下一步中生成上下文二进制文件时需要用到这些文件。

    * **backend\_extension\_config.json**

      ```json theme={null}
      {
         "backend_extensions": {
            "shared_library_path": "libQnnHtpNetRunExtensions.so",
            "config_file_path": "./htp_config.json"
         }
      }
      ```

    * **htp\_config.json**

      ```json theme={null}
      {
      "graphs": [
            {
                  "vtcm_mb": 2,
                  "fp16_relaxed_precision": 0,
                  "graph_names": [
                     "graph_name_2"
                  ],
                  "O": 3.0
            }
         ],
         "devices": [
            {
                  "dsp_arch": "v68",
                  "profiling_level": "linting",
                  "cores": [
                     {
                        "perf_profile": "burst"
                     }
                  ]
            }
         ]
      }
      ```

    <Note>
      - 对于 Qualcomm Dragonwing™ RB3 Gen 2,使用 `"dsp_arch": "v68"`。
      - 对于 Dragonwing IQ-8275,使用 `"dsp_arch": "v75"`。
      - 对于 Dragonwing IQ-9075,使用 `"dsp_arch": "v73"`。
    </Note>
  </Step>

  <Step title="在目标设备上,使用 qnn-context-binary-generator 工具生成上下文二进制文件(.bin 文件)">
    ```shell theme={null}
    qnn-context-binary-generator --log_level=info --backend libQnnHtp.so --model libQnnModelDlc.so --config_file /etc/models/backend_extension_config.json --output_dir context_bin_dir --dlc_path /etc/models/inception_v3_quantized.dlc --binary_file inception_v3
    ```

    `qnn-throughput-net-run` 命令将摄取生成的上下文二进制文件。
  </Step>

  <Step title="要使用 qnn-throughput-net-run 对模型进行分析,请创建 qtnr_config.json 和 htp_backend.json 文件">
    在目标设备的 `/etc/models/` 目录中创建这些文件。

    * `htp_backend.json`:

      ```json theme={null}
      {
         "devices": [
            {
            "dsp_arch": "v68",
            "device_id" : 0
            }
         ]
      }
      ```
    * `qtnr_config.json`:

      ```json theme={null}
      {
      "backends": [
         {
         "backendName": "htp_backend",
         "backendPath": "libQnnHtp.so",
         "profilingLevel": "BASIC",
         "backendExtensions": "libQnnHtpNetRunExtensions.so",
         "perfProfile": "burst"
         }
      ],
      "models": [
         {
         "modelName": "inception_v3",
         "modelPath": "/etc/models/context_bin_dir/inception_v3.bin",
         "loadFromCachedBinary": true,
         "outputPath": "output_original"
         }
      ],
      "contexts": [
         {
         "contextName": "htp_context_1",
         "priority": "HIGH"
         }
      ],
      "testCase": {
         "iteration": 1,
         "logLevel": "info",
         "threads": [
            {
               "threadName": "htp_thread_1",
               "backend": "htp_backend",
               "context": "htp_context_1",
               "model": "inception_v3",
               "interval": 0,
               "loopUnit": "second",
               "loop": 10,
               "backendConfig": "htp_backend.json"
            }
         ]
         }
      }
      ```

    <Note>
      - 对于 Qualcomm Dragonwing™ RB3 Gen 2,使用 `"dsp_arch"`: `"v68"`
      - 对于 Dragonwing IQ-8275,使用 `"dsp_arch"`: `"v75"`
      - 对于 Dragonwing IQ-9075,使用 `"dsp_arch"`: `"v73"`
    </Note>
  </Step>

  <Step title="要执行分析,请在目标设备上运行以下命令">
    ```shell theme={null}
    cd /etc/models
    ```

    ```shell theme={null}
    qnn-throughput-net-run --config /etc/models/qtnr_config.json --output /etc/models/output_qtnr.json
    ```

    分析信息将在 `/etc/models` 目录中生成。

    <img src="https://mintlify.s3.us-west-1.amazonaws.com/qualcomm-prod/zh/AI-Developer-Workflow-Ubuntu/_images/qnn-throughput-net-run-profiling-output.png" alt="qnn-throughput-net-run 分析的示例输出" />

    **图:qnn-throughput-net-run 分析的示例输出**
  </Step>
</Steps>
