[QNN EP] Update QNN SDK to 2.21 (#20534)

### Description
- Updates QNN pipelines to use QNN SDK 2.21
- Downloads QNN SDK from Azure storage to avoid having to rebuild images
when a new version is released.


### Motivation and Context
Test with the latest QNN SDK.
This commit is contained in:
Adrian Lizarraga 2024-05-01 20:17:35 -07:00 committed by GitHub
parent 87076553b0
commit 0dda8b0c44
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 105 additions and 51 deletions

View file

@ -169,10 +169,10 @@ Status ResizeOpBuilder::IsOpSupported(QnnModelWrapper& qnn_model_wrapper,
// nearest_mode:
// coordinate_transformation_mode: | round_prefer_floor round_prefer_ceil floor ceil
// -----------------------------------------------------------------------------------------
// half_pixel | Resize X RNN X
// pytorch_half_pixel | Resize X X X
// align_corners | Resize X RNN X
// asymmetric | Resize X RNN X
// half_pixel | Resize(QNN < 2.20) X RNN X
// pytorch_half_pixel | Resize(QNN < 2.20) X X X
// align_corners | Resize(QNN < 2.20) Resize(QNN 2.20) RNN X
// asymmetric | Resize(QNN < 2.20) X RNN X
if (interp_mode == "nearest") {
const std::string nearest_mode = GetOnnxAttr(node_helper, onnx_nearest_mode_attr);
@ -181,13 +181,16 @@ Status ResizeOpBuilder::IsOpSupported(QnnModelWrapper& qnn_model_wrapper,
if (is_npu_backend) {
// QNN only supports the following nearest_mode values on HTP:
// - "round_prefer_floor" via QNN's Resize operator
// - QNN 2.19: "round_prefer_floor" via QNN's Resize operator
// - QNN 2.20 (API version 2.14): "round_prefer_ceil" via QNN's Resize operator
// - "floor" via QNN's ResizeNearestNeighbor operator
//
// QNN validation does not throw an error if unsupported nearest_mode values are used, so we have to
// catch them here. Otherwise, accuracy is significantly degraded.
#if QNN_API_VERSION_MAJOR >= 2 && QNN_API_VERSION_MINOR >= 14
ORT_RETURN_IF_NOT(nearest_mode == "round_prefer_ceil" || nearest_mode == "floor",
"QNN EP: Resize on the NPU does not support nearest_mode ", nearest_mode.c_str());
#else
ORT_RETURN_IF_NOT(nearest_mode == "round_prefer_floor" || nearest_mode == "floor",
"QNN EP: Resize on the NPU does not support nearest_mode ", nearest_mode.c_str());
#endif
const bool use_resize_nn_op = nearest_mode == "floor";
@ -200,6 +203,13 @@ Status ResizeOpBuilder::IsOpSupported(QnnModelWrapper& qnn_model_wrapper,
// QNN's ResizeNearestNeighbor requires rank 4 inputs.
ORT_RETURN_IF(use_resize_nn_op && input_rank != 4,
"QNN EP: Resize on the NPU with nearest_mode == 'floor' requires an input with rank 4.");
#if QNN_API_VERSION_MAJOR >= 2 && QNN_API_VERSION_MINOR >= 14
// QNN's Resize only supports "round_prefer_ceil" if transformation_mode is "align_corners".
ORT_RETURN_IF(!use_resize_nn_op && transformation_mode != "align_corners",
"QNN EP: Resize on the NPU only supports 'round_prefer_ceil' if "
"transformation mode is 'align_corners'");
#endif
}
}

View file

@ -394,10 +394,21 @@ TEST_F(QnnHTPBackendTests, ResizeU8_2xLinearAsymmetric) {
// Test 2x QDQ Resize mode: "nearest", coordinate_transformation_mode: "half_pixel", nearest_mode: "round_prefer_floor"
// Maps to QNN's Resize operator.
TEST_F(QnnHTPBackendTests, ResizeU8_2xNearestHalfPixelRoundPreferFloor) {
// UPDATE: "round_prefer_floor" no longer supported in QNN SDK 2.21 (supported in QNN SDK 2.19)
TEST_F(QnnHTPBackendTests, ResizeU8_2xNearestHalfPixelRoundPreferFloor_Unsupported) {
std::vector<float> input_data = GetFloatDataInRange(-10.0f, 10.0f, 48);
RunQDQResizeOpTest<uint8_t>(TestInputDef<float>({1, 3, 4, 4}, false, input_data),
{1, 3, 8, 8}, "nearest", "half_pixel", "round_prefer_floor",
ExpectedEPNodeAssignment::None); // No longer supported as of QNN SDK 2.21
}
// Test 2x QDQ Resize mode: "nearest", coordinate_transformation_mode: "align_corners", nearest_mode: "round_prefer_ceil"
// Maps to QNN's Resize operator.
// UPDATE: "round_prefer_ceil" is supported as of QNN SDK 2.21 if using "align_corners". (Unsupported in QNN SDK 2.19).
TEST_F(QnnHTPBackendTests, ResizeU8_2xNearestAlignCornersRoundPreferCeil) {
std::vector<float> input_data = GetFloatDataInRange(-10.0f, 10.0f, 48);
RunQDQResizeOpTest<uint8_t>(TestInputDef<float>({1, 3, 4, 4}, false, input_data),
{1, 3, 8, 8}, "nearest", "align_corners", "round_prefer_ceil",
ExpectedEPNodeAssignment::All);
}
@ -420,11 +431,12 @@ TEST_F(QnnHTPBackendTests, ResizeU8_3xNearestAsymmetricFloor) {
// Test 2x QDQ Resize mode: "nearest", coordinate_transformation_mode: "asymmetric", nearest_mode: "round_prefer_floor"
// Maps to QNN's Resize operator.
TEST_F(QnnHTPBackendTests, ResizeU8_2xNearestAsymmetricRoundPreferFloor) {
// UPDATE: "round_prefer_floor" no longer supported in QNN SDK 2.21 (supported in QNN SDK 2.19)
TEST_F(QnnHTPBackendTests, ResizeU8_2xNearestAsymmetricRoundPreferFloor_Unsupported) {
std::vector<float> input_data = GetFloatDataInRange(-10.0f, 10.0f, 8);
RunQDQResizeOpTest<uint8_t>(TestInputDef<float>({1, 2, 2, 2}, false, input_data),
{1, 2, 4, 4}, "nearest", "asymmetric", "round_prefer_floor",
ExpectedEPNodeAssignment::All);
ExpectedEPNodeAssignment::None); // No longer supported as of QNN SDK 2.21
}
// Test 3x QDQ Resize mode: "nearest", coordinate_transformation_mode: "asymmetric", nearest_mode: "round_prefer_floor"

View file

@ -616,7 +616,13 @@ TEST_F(QnnHTPBackendTests, UnaryOp_Ceil) {
}
// Test accuracy of 16-bit QDQ Ceil op.
TEST_F(QnnHTPBackendTests, UnaryOp_Ceil_U16) {
// TODO(adrianlizarraga): Fails in QNN SDK 2.21 (linux). On Windows ARM64, fails in QNN SDK 2.19.
//
// input: [-12.0, -7.199, -2.399, 2.4, 7.2, 12.0]
// CPU EP f32 model output: [-12.0, -7.0, -2.0, 3.0, 8.0, 12.0]
// CPU EP qdq model output: [-12.0, -6.99, -1.99, 3.0, 8.0, 11.99]
// QNN EP qdq model output: [-11.0 (WRONG), -7.0, -2.0, 2.99, 8.0, 11.99]
TEST_F(QnnHTPBackendTests, DISABLED_UnaryOp_Ceil_U16) {
const std::vector<float> input_data = GetFloatDataInRange(-12.0f, 12.0f, 6);
RunQDQOpTest<uint16_t>("Ceil",
{TestInputDef<float>({1, 2, 3}, false, input_data)},

View file

@ -31,7 +31,7 @@ parameters:
- name: QnnSdk
displayName: QNN SDK version
type: string
default: qnn-v2.19.2.240210
default: 2.21.0.240401
jobs:
- job: Build_QNN_EP
@ -40,10 +40,6 @@ jobs:
workspace:
clean: all
variables:
- name: QNN_SDK_ROOT
value: /data/qnnsdk/${{parameters.QnnSdk}}
steps:
- task: UsePythonVersion@0
displayName: Use Python $(pythonVersion)
@ -56,6 +52,10 @@ jobs:
- script: sudo chmod go+rw /dev/kvm
displayName: Update permissions to KVM
- template: templates/jobs/download_linux_qnn_sdk.yml
parameters:
QnnSDKVersion: ${{ parameters.QnnSdk }}
- script: |
export ANDROID_SDK_ROOT=/usr/local/lib/android/sdk
export ANDROID_HOME=/usr/local/lib/android/sdk
@ -78,7 +78,7 @@ jobs:
--android_api=31 \
--parallel \
--use_qnn \
--qnn_home $(QNN_SDK_ROOT) \
--qnn_home $(QnnSDKRootDir) \
--cmake_generator=Ninja \
--skip_tests --path_to_protoc_exe $(Build.BinariesDirectory)/installed/bin/protoc
displayName: Build QNN EP

View file

@ -32,7 +32,7 @@ parameters:
- name: QnnSdk
displayName: QNN SDK version
type: string
default: qnn-v2.19.2.240210
default: 2.21.0.240401
jobs:
- job: Build_QNN_EP
@ -41,13 +41,8 @@ jobs:
workspace:
clean: all
variables:
- name: QNN_SDK_ROOT
value: /data/qnnsdk/${{parameters.QnnSdk}}
steps:
- script: |
ls /data/qnnsdk
ls -R /data/qnn_test_data
displayName: Check QNN test data
@ -59,13 +54,17 @@ jobs:
- script: sudo apt-get update -y && sudo apt-get install -y coreutils ninja-build
displayName: Install coreutils and ninja
- template: templates/jobs/download_linux_qnn_sdk.yml
parameters:
QnnSDKVersion: ${{ parameters.QnnSdk }}
- script: |
python3 tools/ci_build/build.py \
--build_dir build \
--config Release \
--parallel --use_binskim_compliant_compile_flags \
--use_qnn \
--qnn_home $(QNN_SDK_ROOT) \
--qnn_home $(QnnSDKRootDir) \
--cmake_generator=Ninja \
--skip_tests
displayName: Build QNN EP
@ -75,7 +74,7 @@ jobs:
--build_dir build \
--config Release --use_binskim_compliant_compile_flags \
--test \
--qnn_home $(QNN_SDK_ROOT) \
--qnn_home $(QnnSDKRootDir) \
--cmake_generator=Ninja \
--skip_submodule_sync \
--ctest_path ""
@ -86,7 +85,7 @@ jobs:
inputs:
script: |
./build/Release/onnx_test_runner -e qnn \
-v -j 1 -i "backend_path|$(QNN_SDK_ROOT)/lib/x86_64-linux-clang/libQnnCpu.so" \
-v -j 1 -i "backend_path|$(QnnSDKRootDir)/lib/x86_64-linux-clang/libQnnCpu.so" \
cmake/external/onnx/onnx/backend/test/data/node
- task: CmdLine@2
@ -94,7 +93,7 @@ jobs:
inputs:
script: |
./build/Release/onnx_test_runner -e qnn \
-v -j 1 -i "backend_path|$(QNN_SDK_ROOT)/lib/x86_64-linux-clang/libQnnCpu.so" \
-v -j 1 -i "backend_path|$(QnnSDKRootDir)/lib/x86_64-linux-clang/libQnnCpu.so" \
/data/float32_models
- task: CmdLine@2
@ -102,7 +101,7 @@ jobs:
inputs:
script: |
./build/Release/onnx_test_runner -e qnn \
-v -j 1 -i "backend_path|$(QNN_SDK_ROOT)/lib/x86_64-linux-clang/libQnnHtp.so" \
-v -j 1 -i "backend_path|$(QnnSDKRootDir)/lib/x86_64-linux-clang/libQnnHtp.so" \
/data/qdq_models
- task: CmdLine@2
@ -110,5 +109,5 @@ jobs:
inputs:
script: |
./build/Release/onnx_test_runner -e qnn \
-v -f -j 1 -i "backend_path|$(QNN_SDK_ROOT)/lib/x86_64-linux-clang/libQnnHtp.so" \
-v -f -j 1 -i "backend_path|$(QnnSDKRootDir)/lib/x86_64-linux-clang/libQnnHtp.so" \
/data/qdq_models/mobilenetv2-1.0_add_transpose_quant

View file

@ -59,7 +59,7 @@ parameters:
- name: qnn_sdk_version
type: string
displayName: 'QNN SDK version. Only for QNN packages.'
default: 2.19.2.240210
default: 2.21.0.240401
trigger: none

View file

@ -2,7 +2,7 @@ parameters:
- name: QnnSdk
displayName: QNN SDK Version
type: string
default: 2.19.2.240210
default: 2.21.0.240401
- name: build_config
displayName: Build Configuration

View file

@ -0,0 +1,25 @@
parameters:
- name: QnnSDKVersion
type: string
default: '2.21.0.240401'
steps:
- script: |
azcopy cp --recursive https://lotusscus.blob.core.windows.net/models/qnnsdk/qnn-v${{ parameters.QnnSDKVersion }} $(Agent.TempDirectory)
displayName: 'Download QNN SDK v${{ parameters.QnnSDKVersion }}'
- bash: |
echo "##vso[task.setvariable variable=QnnSDKRootDir]$(Agent.TempDirectory)/qnn-v${{ parameters.QnnSDKVersion }}"
displayName: Set QnnSDKRootDir
- script: |
echo $(QnnSDKRootDir)
displayName: 'Print QnnSDKRootDir after downloading QNN SDK'
- script: |
azcopy cp --recursive 'https://lotusscus.blob.core.windows.net/models/qnnsdk/Qualcomm AI Hub Proprietary License.pdf' $(QnnSDKRootDir)
displayName: 'Download Qualcomm AI Hub license'
- script: |
ls -al $(QnnSDKRootDir)
displayName: 'Print contents of QNN SDK'

View file

@ -1,7 +1,7 @@
parameters:
- name: QnnSDKVersion
type: string
default: '2.19.2.240210'
default: '2.21.0.240401'
steps:
- powershell: |

View file

@ -60,7 +60,7 @@ parameters:
- name: qnn_sdk_version
type: string
displayName: 'QNN SDK version. Only for QNN packages.'
default: 2.19.2.240210
default: 2.21.0.240401
stages:
- ${{ if eq(parameters.enable_windows_cpu, true) }}:

View file

@ -7,7 +7,7 @@ parameters:
- name: QNN_SDK
displayName: QNN SDK Version
type: string
default: 2.19.2.240210
default: 2.21.0.240401
- name: PYTHON_VERSION
type: string

View file

@ -7,7 +7,7 @@ parameters:
- name: QNN_SDK
displayName: QNN SDK Version
type: string
default: 2.19.2.240210
default: 2.21.0.240401
- name: ENV_SETUP_SCRIPT
type: string

View file

@ -32,7 +32,7 @@ parameters:
- name: QnnSdk
displayName: QNN SDK version
type: string
default: qnn-v2.19.2.240210_win
default: 2.21.0.240401
jobs:
- job: 'build'
@ -42,7 +42,6 @@ jobs:
buildArch: arm64
BuildConfig: 'RelWithDebInfo'
ALLOW_RELEASED_ONNX_OPSET_ONLY: '1'
QNN_SDK_ROOT: 'C:\data\qnnsdk\${{parameters.QnnSdk}}'
timeoutInMinutes: 240
workspace:
clean: all
@ -57,10 +56,6 @@ jobs:
DIR $(Agent.ToolsDirectory)\Python\3.11.0\arm64
displayName: Copy python 3.11.0 version to agent tools directory
- script: |
DIR C:\data\qnnsdk
displayName: Check available QNN SDKs
- task: UsePythonVersion@0
inputs:
versionSpec: '3.x'
@ -71,11 +66,15 @@ jobs:
inputs:
versionSpec: 6.4.x
- template: templates/jobs/download_win_qnn_sdk.yml
parameters:
QnnSDKVersion: ${{ parameters.QnnSdk }}
- task: PythonScript@0
displayName: 'Build'
inputs:
scriptPath: '$(Build.SourcesDirectory)\tools\ci_build\build.py'
arguments: '--config $(BuildConfig) --build_dir $(Build.BinariesDirectory) --skip_tests --cmake_generator "Visual Studio 17 2022" --use_qnn --qnn_home $(QNN_SDK_ROOT) --parallel'
arguments: '--config $(BuildConfig) --build_dir $(Build.BinariesDirectory) --skip_tests --cmake_generator "Visual Studio 17 2022" --use_qnn --qnn_home $(QnnSDKRootDir) --parallel'
workingDirectory: '$(Build.BinariesDirectory)'
- powershell: |
@ -84,17 +83,17 @@ jobs:
displayName: 'Run unit tests'
- script: |
.\$(BuildConfig)\onnx_test_runner -j 1 -v -e qnn -i "backend_path|$(QNN_SDK_ROOT)\lib\aarch64-windows-msvc\QnnCpu.dll" $(Build.SourcesDirectory)\cmake\external\onnx\onnx\backend\test\data\node
.\$(BuildConfig)\onnx_test_runner -j 1 -v -e qnn -i "backend_path|$(QnnSDKRootDir)\lib\aarch64-windows-msvc\QnnCpu.dll" $(Build.SourcesDirectory)\cmake\external\onnx\onnx\backend\test\data\node
workingDirectory: '$(Build.BinariesDirectory)\$(BuildConfig)'
displayName: 'Run ONNX Tests'
- script: |
.\$(BuildConfig)\onnx_test_runner -j 1 -v -e qnn -i "backend_path|$(QNN_SDK_ROOT)\lib\aarch64-windows-msvc\QnnCpu.dll" C:\data\float32_models
.\$(BuildConfig)\onnx_test_runner -j 1 -v -e qnn -i "backend_path|$(QnnSDKRootDir)\lib\aarch64-windows-msvc\QnnCpu.dll" C:\data\float32_models
workingDirectory: '$(Build.BinariesDirectory)\$(BuildConfig)'
displayName: 'Run float32 model tests'
- script: |
.\$(BuildConfig)\onnx_test_runner -j 1 -v -e qnn -i "backend_path|$(QNN_SDK_ROOT)\lib\aarch64-windows-msvc\QnnHtp.dll" C:\data\qdq_models
.\$(BuildConfig)\onnx_test_runner -j 1 -v -e qnn -i "backend_path|$(QnnSDKRootDir)\lib\aarch64-windows-msvc\QnnHtp.dll" C:\data\qdq_models
workingDirectory: '$(Build.BinariesDirectory)\$(BuildConfig)'
displayName: 'Run QDQ model tests'
enabled: false

View file

@ -32,7 +32,7 @@ parameters:
- name: QnnSdk
displayName: QNN SDK version
type: string
default: qnn-v2.19.2.240210_win
default: 2.21.0.240401
jobs:
- job: 'build'
@ -45,7 +45,6 @@ jobs:
setVcvars: true
BuildConfig: 'RelWithDebInfo'
ALLOW_RELEASED_ONNX_OPSET_ONLY: '1'
QNN_SDK_ROOT: 'C:\data\qnnsdk\${{parameters.QnnSdk}}'
TODAY: $[format('{0:dd}{0:MM}{0:yyyy}', pipeline.startTime)]
timeoutInMinutes: 120
workspace:
@ -58,6 +57,10 @@ jobs:
addToPath: true
architecture: $(buildArch)
- template: templates/jobs/download_win_qnn_sdk.yml
parameters:
QnnSDKVersion: ${{ parameters.QnnSdk }}
# TODO: Remove --compile_no_warning_as_error once we update from MSVC Runtime library version 14.32 or we
# fix/silence the following warning from the <variant> STL header. This warning halts compilation due to
# the /external:templates- option, which allows warnings from external libs for template instantiations.
@ -76,7 +79,7 @@ jobs:
WithCache: True
Today: $(TODAY)
AdditionalKey: "win-qnn | $(BuildConfig)"
BuildPyArguments: '--config $(BuildConfig) --build_dir $(Build.BinariesDirectory) --compile_no_warning_as_error --update --cmake_generator "Visual Studio 17 2022" --use_qnn --qnn_home $(QNN_SDK_ROOT) --parallel --use_binskim_compliant_compile_flags'
BuildPyArguments: '--config $(BuildConfig) --build_dir $(Build.BinariesDirectory) --compile_no_warning_as_error --update --cmake_generator "Visual Studio 17 2022" --use_qnn --qnn_home $(QnnSDKRootDir) --parallel --use_binskim_compliant_compile_flags'
MsbuildArguments: $(MsbuildArguments)
BuildArch: $(buildArch)
Platform: 'x64'
@ -88,11 +91,11 @@ jobs:
displayName: 'Run unit tests'
- script: |
.\$(BuildConfig)\onnx_test_runner -j 1 -v -e qnn -i "backend_path|$(QNN_SDK_ROOT)\lib\x86_64-windows-msvc\QnnCpu.dll" $(Build.SourcesDirectory)\cmake\external\onnx\onnx\backend\test\data\node
.\$(BuildConfig)\onnx_test_runner -j 1 -v -e qnn -i "backend_path|$(QnnSDKRootDir)\lib\x86_64-windows-msvc\QnnCpu.dll" $(Build.SourcesDirectory)\cmake\external\onnx\onnx\backend\test\data\node
workingDirectory: '$(Build.BinariesDirectory)\$(BuildConfig)'
displayName: 'Run ONNX Tests'
- script: |
.\$(BuildConfig)\onnx_test_runner -j 1 -v -e qnn -i "backend_path|$(QNN_SDK_ROOT)\lib\x86_64-windows-msvc\QnnCpu.dll" C:\data\float32_models
.\$(BuildConfig)\onnx_test_runner -j 1 -v -e qnn -i "backend_path|$(QnnSDKRootDir)\lib\x86_64-windows-msvc\QnnCpu.dll" C:\data\float32_models
workingDirectory: '$(Build.BinariesDirectory)\$(BuildConfig)'
displayName: 'Run float32 model tests'