[CPU] Fix output saturation in int8 QLinearSoftmax - #29728
Conversation
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
There was a problem hiding this comment.
Pull request overview
This PR fixes incorrect output clamping in the CPU contrib com.microsoft.QLinearSoftmax kernel for int8 outputs, preventing values that should saturate at 127 from instead wrapping around to -128. It also adds a regression unit test that reproduces the saturation scenario reported in #29727.
Changes:
- Fix int8 output saturation in
QlinearSoftmaxCPU<int8_t>by clamping to the proper int8 range ([-128, 127]) instead of using the uint8-style255upper bound. - Add a unit test that exercises the saturation edge case with
Y_scale=1/256andY_zero_point=-128.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
onnxruntime/contrib_ops/cpu/quantization/qlinear_softmax.cc |
Corrects int8 output clamping to saturate to int8_t min/max instead of uint8 max. |
onnxruntime/test/contrib_ops/qlinear_lookup_table_test.cc |
Adds a regression test to validate correct saturation behavior for int8 QLinearSoftmax. |
Review: PR #29728 —
|
|
Can you please fix the failing lint checks ? |
|
Followed up in #29750 |
|
And following up on the "Windows x64 QNN CI Pipeline" failure in #29753 |
### Description Copies the Java setup step from sibling files `windows_webgpu.yml`, `windows_x64_release_xnnpack.yml`, `windows_x64_release_build_x64_release.yml` to `windows_qnn_x64.yml`. This explicitly ensures a compatible Java version, rather than relying on the JDK already installed on the self-hosted runner. Otherwise there may be breakages when switching the runner. ### Motivation and Context I believe this will fix the failures in CI for the Windows x64 QNN CI Pipeline. I'm seeing it fail in both an unrelated PR: #29728 https://github.com/microsoft/onnxruntime/actions/runs/29509983398/job/87780661649?pr=29728 and in commits to main: https://github.com/microsoft/onnxruntime/actions/runs/29546572913/job/87780090142 https://github.com/microsoft/onnxruntime/actions/runs/29499730505/job/87625355397 This is assuming the chain of causation: 1. #29731 switches the runner pool 2. The `windows_qnn_x64.yml` pipeline finds JDK 8 already on the runner (previous runner pool had JDK 11) 3. The Spotless Gradle plugin v7.2.1 isn't compatible with JDK 8 4. onnxruntime Java project can't be configured 5. Build fails This new workflow action hopefully installs a compatible JDK & all will be well. #29753
|
Can you please rebase ? Maybe the checks will all pass now |
|
If you do hit genuine linting errors again, here are the steps to mitigate: |
Adds a test case that checks the output saturation behavior of QLinearSoftmax. There's currently a bug: https://gist.github.com/mcollinswisc/b3c9a2d9cf50b7bf289ced1d6be2c709 and this test is expected to fail with message: [ RUN ] QLinearLookupTableBasedOperatorTests.QLinearSoftmax_Int8_Saturate /mnt/themis/artevelde/research/onnxruntime/onnxruntime/test/unittest_util/checkers.cc:393: Failure Expected equality of these values: cur_expected[i] Which is: '\x7F' (127) cur_actual[i] Which is: '\x80' (-128) i:0
Old code copied the saturation from the uint8 kernel, which caused int8 outputs to wrap instead.
Head branch was pushed to by a user without write access
adf13a7 to
dfbf9c7
Compare
Certainly, I have rebased it |
Copies the Java setup step from sibling files `windows_webgpu.yml`, `windows_x64_release_xnnpack.yml`, `windows_x64_release_build_x64_release.yml` to `windows_qnn_x64.yml`. This explicitly ensures a compatible Java version, rather than relying on the JDK already installed on the self-hosted runner. Otherwise there may be breakages when switching the runner. I believe this will fix the failures in CI for the Windows x64 QNN CI Pipeline. I'm seeing it fail in both an unrelated PR: #29728 https://github.com/microsoft/onnxruntime/actions/runs/29509983398/job/87780661649?pr=29728 and in commits to main: https://github.com/microsoft/onnxruntime/actions/runs/29546572913/job/87780090142 https://github.com/microsoft/onnxruntime/actions/runs/29499730505/job/87625355397 This is assuming the chain of causation: 1. #29731 switches the runner pool 2. The `windows_qnn_x64.yml` pipeline finds JDK 8 already on the runner (previous runner pool had JDK 11) 3. The Spotless Gradle plugin v7.2.1 isn't compatible with JDK 8 4. onnxruntime Java project can't be configured 5. Build fails This new workflow action hopefully installs a compatible JDK & all will be well. #29753

Description
Uses the correct int8 range to clamp/saturate the output of the int8 specialization of the QLinearSoftmax kernel.
Previously there was a copy-paste error, and it was saturating to 255 like in the uint8 specialization.
https://github.com/microsoft/onnxruntime/blob/main/docs/ContribOperators.md#com.microsoft.QLinearSoftmax
This change also adds a unit test case that causes output saturation, and reproduced the bug.
Motivation and Context
When there are:
then the output of int8 QLinearSoftmax will saturate. Incorrect clamping is causing this to wrap around to -128 instead, producing incorrect results.
#29727