mirror of
https://github.com/saymrwulf/onnxruntime.git
synced 2026-07-29 20:14:01 +00:00
set zero point to 0 if all value are 0.0 (#12470)
* set zero point to 0 if all value are 0.0 * fix bug: lower version of numpy.finfo doesn't have smallest_subnormal * check scale to make sure it is not subnormal
This commit is contained in:
parent
ddea1e48df
commit
bdd6b00c9a
2 changed files with 45 additions and 4 deletions
|
|
@ -119,8 +119,7 @@ def quantize_nparray(qType, arr, scale, zero_point, low=None, high=None):
|
|||
|
||||
|
||||
def compute_scale_zp(rmin, rmax, qmin, qmax, symmetric=False):
|
||||
"""
|
||||
Calculate the scale s and zero point z for the quantization relation
|
||||
"""Calculate the scale s and zero point z for the quantization relation
|
||||
r = s(q-z), where r are the original values and q are the corresponding
|
||||
quantized values.
|
||||
|
||||
|
|
@ -138,6 +137,9 @@ def compute_scale_zp(rmin, rmax, qmin, qmax, symmetric=False):
|
|||
|
||||
"""
|
||||
|
||||
if qmin > 0 or qmax < 0:
|
||||
raise ValueError(f"qmin and qmax must meet requirement: qmin <= 0 <= qmax while qmin:{qmin}, qmmax:{qmax}")
|
||||
|
||||
# Adjust rmin and rmax such that 0 is included in the range. This is
|
||||
# required to make sure zero can be represented by the quantization data
|
||||
# type (i.e. to make sure qmin <= zero_point <= qmax)
|
||||
|
|
@ -149,8 +151,12 @@ def compute_scale_zp(rmin, rmax, qmin, qmax, symmetric=False):
|
|||
rmin = -absmax
|
||||
rmax = +absmax
|
||||
|
||||
scale = (rmax - rmin) / float(qmax - qmin) if rmax != rmin else 1.0
|
||||
zero_point = round(qmin - rmin / scale)
|
||||
scale = (rmax - rmin) / float(qmax - qmin)
|
||||
if scale < numpy.finfo(numpy.float32).tiny:
|
||||
scale = 1.0
|
||||
zero_point = 0
|
||||
else:
|
||||
zero_point = round(qmin - rmin / scale)
|
||||
|
||||
return [zero_point, scale]
|
||||
|
||||
|
|
|
|||
35
onnxruntime/test/python/quantization/test_quant_util.py
Normal file
35
onnxruntime/test/python/quantization/test_quant_util.py
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
#!/usr/bin/env python
|
||||
# coding: utf-8
|
||||
# -------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See License.txt in the project root for
|
||||
# license information.
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
import unittest
|
||||
|
||||
import numpy
|
||||
|
||||
from onnxruntime.quantization.quant_utils import compute_scale_zp
|
||||
|
||||
|
||||
class TestQuantUtil(unittest.TestCase):
|
||||
def test_compute_scale_zp(self):
|
||||
self.assertEqual(compute_scale_zp(0.0, 0.0, -127, 127, symmetric=True), [0, 1.0])
|
||||
self.assertEqual(compute_scale_zp(1.0, -1.0, -127, 127, symmetric=True), [0, 1.0])
|
||||
self.assertEqual(compute_scale_zp(0.0, 0.0, 0, 255, symmetric=True), [0, 1.0])
|
||||
self.assertEqual(compute_scale_zp(1.0, -1.0, 0, 255, symmetric=True), [0, 1.0])
|
||||
|
||||
self.assertEqual(compute_scale_zp(-1.0, 2.0, -127, 127, symmetric=True), [0, 2.0 / 127])
|
||||
self.assertEqual(compute_scale_zp(-1.0, 2.0, -127, 127, symmetric=False), [-42, 3.0 / 254])
|
||||
|
||||
self.assertEqual(compute_scale_zp(-1.0, 2.0, 0, 255, symmetric=True), [128, 4.0 / 255])
|
||||
self.assertEqual(compute_scale_zp(-1.0, 2.0, 0, 255, symmetric=False), [85, 3.0 / 255])
|
||||
|
||||
tiny_float = numpy.float32(numpy.finfo(numpy.float32).tiny * 0.1)
|
||||
self.assertEqual(compute_scale_zp(-tiny_float, tiny_float, 0, 255, symmetric=True), [0, 1.0])
|
||||
self.assertEqual(compute_scale_zp(-tiny_float, 0.0, 0, 255, symmetric=False), [0, 1.0])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Loading…
Reference in a new issue