diff --git a/examples/windows/onnx_ptq/genai_llm/requirements.txt b/examples/windows/onnx_ptq/genai_llm/requirements.txt index 3c90cce2de1..59b54311c08 100644 --- a/examples/windows/onnx_ptq/genai_llm/requirements.txt +++ b/examples/windows/onnx_ptq/genai_llm/requirements.txt @@ -1,4 +1,3 @@ datasets>=2.14.5 -onnx torch==2.9.0 transformers==4.57.3 diff --git a/examples/windows/onnx_ptq/whisper/requirements.txt b/examples/windows/onnx_ptq/whisper/requirements.txt index 75af41e9d42..4d375833e39 100644 --- a/examples/windows/onnx_ptq/whisper/requirements.txt +++ b/examples/windows/onnx_ptq/whisper/requirements.txt @@ -4,7 +4,6 @@ datasets==2.19.0 evaluate jiwer librosa -onnx onnxruntime-gpu==1.23.2 optimum==1.23.3 soundfile diff --git a/modelopt/onnx/__init__.py b/modelopt/onnx/__init__.py index 2dea17646a8..5a3364ac03e 100644 --- a/modelopt/onnx/__init__.py +++ b/modelopt/onnx/__init__.py @@ -18,18 +18,6 @@ import sys import warnings -import onnx.helper - -if not hasattr(onnx.helper, "float32_to_bfloat16"): - import ml_dtypes - import numpy as np - - def _float32_to_bfloat16(value): - arr = np.array(value, dtype=np.float32) - return int(arr.astype(ml_dtypes.bfloat16).view(np.uint16)) - - onnx.helper.float32_to_bfloat16 = _float32_to_bfloat16 - MIN_PYTHON_VERSION = (3, 10) try: diff --git a/pyproject.toml b/pyproject.toml index ba1eb3ea802..61708763081 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -57,8 +57,8 @@ onnx = [ "cupy-cuda12x; platform_machine != 'aarch64' and platform_system != 'Darwin'", "lief", "ml_dtypes", - "onnx-graphsurgeon", - "onnx~=1.19.0", + "onnx-graphsurgeon>=0.6.1", + "onnx~=1.21.0", "onnxconverter-common~=1.16.0", # ORT for Windows "onnxruntime-gpu==1.22.0; platform_system == 'Windows'", diff --git a/tests/unit/onnx/quantization/test_quant_utils.py b/tests/unit/onnx/quantization/test_quant_utils.py index 646d6e3eeb6..c63e0f1fdd8 100644 --- a/tests/unit/onnx/quantization/test_quant_utils.py +++ b/tests/unit/onnx/quantization/test_quant_utils.py @@ -16,7 +16,6 @@ import numpy as np import pytest import torch -from onnx.helper import pack_float32_to_4bit from modelopt.onnx.quantization.quant_utils import ( compute_e8m0, @@ -37,66 +36,50 @@ def test_pack_float32_to_4bit_utils(): input_pattern = [-123.4, 2.3, 0.23, 12345.1, -20123.4, 256.7, 0.83, -1.54] # test-case-1: Signed = True, input-length = even - test_output10 = pack_float32_to_4bit(input_pattern, True) test_output11 = pack_float32_to_4bit_optimized(input_pattern, True) test_output12 = pack_float32_to_4bit_cpp_based(input_pattern, True) - _validate_results(test_output10, test_output11) - _validate_results(test_output10, test_output12) + _validate_results(test_output11, test_output12) # test-case-2: Signed = False, input-length = even - test_output20 = pack_float32_to_4bit(input_pattern, False) test_output21 = pack_float32_to_4bit_optimized(input_pattern, False) test_output22 = pack_float32_to_4bit_cpp_based(input_pattern, False) - _validate_results(test_output20, test_output21) - _validate_results(test_output20, test_output22) + _validate_results(test_output21, test_output22) # test-case-3: Signed = True, input-length = odd - test_output30 = pack_float32_to_4bit(input_pattern[:-1], True) test_output31 = pack_float32_to_4bit_optimized(input_pattern[:-1], True) test_output32 = pack_float32_to_4bit_cpp_based(input_pattern[:-1], True) - _validate_results(test_output30, test_output31) - _validate_results(test_output30, test_output32) + _validate_results(test_output31, test_output32) # test-case-4: Signed = False, input-length = odd - test_output40 = pack_float32_to_4bit(input_pattern[:-1], False) test_output41 = pack_float32_to_4bit_optimized(input_pattern[:-1], False) test_output42 = pack_float32_to_4bit_cpp_based(input_pattern[:-1], False) - _validate_results(test_output40, test_output41) - _validate_results(test_output40, test_output42) + _validate_results(test_output41, test_output42) # test-case-5: Signed=True, input-length = 1 - test_output50 = pack_float32_to_4bit(input_pattern[0:1], True) test_output51 = pack_float32_to_4bit_optimized(input_pattern[0:1], True) test_output52 = pack_float32_to_4bit_cpp_based(input_pattern[0:1], True) - _validate_results(test_output50, test_output51) - _validate_results(test_output50, test_output52) + _validate_results(test_output51, test_output52) # test-case-6: Signed=True, input = m x n float array (i.e. 2D input) m = 4 # m rows n = 8 # n columns input_2d = [[input_pattern[i % len(input_pattern)] for i in range(n)] for i in range(m)] tensor_2d = np.array(input_2d, dtype=np.float32) - test_output60 = pack_float32_to_4bit(tensor_2d, True) test_output61 = pack_float32_to_4bit_optimized(tensor_2d, True) test_output62 = pack_float32_to_4bit_cpp_based(tensor_2d, True) - _validate_results(test_output60, test_output61) - _validate_results(test_output60, test_output62) + _validate_results(test_output61, test_output62) # test-case-7: Signed=True, input = 1D numpy array of size 8 np_array = np.array(input_pattern, dtype=np.float32) - test_output70 = pack_float32_to_4bit(np_array, True) test_output71 = pack_float32_to_4bit_optimized(np_array, True) test_output72 = pack_float32_to_4bit_cpp_based(np_array, True) - _validate_results(test_output70, test_output71) - _validate_results(test_output70, test_output72) + _validate_results(test_output71, test_output72) # test-case-8: Signed=True, input = 1D tensor of size 8 input_tensor = torch.Tensor(input_pattern) - test_output80 = pack_float32_to_4bit(input_tensor, True) test_output81 = pack_float32_to_4bit_optimized(input_tensor, True) test_output82 = pack_float32_to_4bit_cpp_based(input_tensor, True) - _validate_results(test_output80, test_output81) - _validate_results(test_output80, test_output82) + _validate_results(test_output81, test_output82) input_pattern_int8 = [123, 2, 1, -23, -3, -127, 8, 127] np8 = np.asarray(input_pattern_int8, dtype=np.int8) @@ -105,16 +88,12 @@ def test_pack_float32_to_4bit_utils(): # test-case-9: Signed=True, input = numpy array of dtype int8, size = even test_output91 = pack_float32_to_4bit_optimized(np8, True) test_output92 = pack_float32_to_4bit_cpp_based(np8, True) - test_output93 = pack_float32_to_4bit(np8, True) _validate_results(test_output91, test_output92) - _validate_results(test_output91, test_output93) # test-case-10: Signed=False, input = numpy array of dtype int8, size = odd test_output1001 = pack_float32_to_4bit_optimized(np8_odd, False) test_output1002 = pack_float32_to_4bit_cpp_based(np8_odd, False) - test_output1003 = pack_float32_to_4bit(np8_odd, False) _validate_results(test_output1001, test_output1002) - _validate_results(test_output1001, test_output1003) input_pattern_uint8 = [123, 2, 1, 56, 127, 13, 5, 15] npu8 = np.asarray(input_pattern_uint8, dtype=np.uint8) @@ -123,16 +102,12 @@ def test_pack_float32_to_4bit_utils(): # test-case-11: Signed=True, input = numpy array of dtype uint8, size = even test_output111 = pack_float32_to_4bit_optimized(npu8, True) test_output112 = pack_float32_to_4bit_cpp_based(npu8, True) - test_output113 = pack_float32_to_4bit(npu8, True) _validate_results(test_output111, test_output112) - _validate_results(test_output111, test_output113) # test-case-12: Signed=False, input = numpy array of dtype uint8, size = odd test_output121 = pack_float32_to_4bit_optimized(npu8_odd, False) test_output122 = pack_float32_to_4bit_cpp_based(npu8_odd, False) - test_output123 = pack_float32_to_4bit(npu8_odd, False) _validate_results(test_output121, test_output122) - _validate_results(test_output121, test_output123) np64 = np.asarray(input_pattern, dtype=np.float64) np64_odd = np.asarray(input_pattern[:-1], dtype=np.float64) @@ -140,16 +115,12 @@ def test_pack_float32_to_4bit_utils(): # test-case-13: Signed=True, input = numpy array of dtype float64, size = even test_output131 = pack_float32_to_4bit_optimized(np64, True) test_output132 = pack_float32_to_4bit_cpp_based(np64, True) - test_output133 = pack_float32_to_4bit(np64, True) _validate_results(test_output131, test_output132) - _validate_results(test_output131, test_output133) # test-case-14: Signed=False, input = numpy array of dtype float64, size = odd test_output141 = pack_float32_to_4bit_optimized(np64_odd, False) test_output142 = pack_float32_to_4bit_cpp_based(np64_odd, False) - test_output143 = pack_float32_to_4bit(np64_odd, False) _validate_results(test_output141, test_output142) - _validate_results(test_output141, test_output143) npf16 = np.asarray(input_pattern, dtype=np.float16) npf16_odd = np.asarray(input_pattern[:-1], dtype=np.float16) @@ -157,16 +128,12 @@ def test_pack_float32_to_4bit_utils(): # test-case-15: Signed=True, input = numpy array of dtype float16, size = even test_output151 = pack_float32_to_4bit_optimized(npf16, True) test_output152 = pack_float32_to_4bit_cpp_based(npf16, True) - test_output153 = pack_float32_to_4bit(npf16, True) _validate_results(test_output151, test_output152) - _validate_results(test_output151, test_output153) # test-case-16: Signed=False, input = numpy array of dtype float16, size = odd test_output161 = pack_float32_to_4bit_optimized(npf16_odd, False) test_output162 = pack_float32_to_4bit_cpp_based(npf16_odd, False) - test_output163 = pack_float32_to_4bit(npf16_odd, False) _validate_results(test_output161, test_output162) - _validate_results(test_output161, test_output163) input_pattern_int4_boundary = [-8, 0, 7, 0, -8, 7] np_int4_boundary = np.asarray(input_pattern_int4_boundary, dtype=np.int8) @@ -175,9 +142,7 @@ def test_pack_float32_to_4bit_utils(): # Input values are boundary values in int4 range test_output171 = pack_float32_to_4bit_optimized(np_int4_boundary, True) test_output172 = pack_float32_to_4bit_cpp_based(np_int4_boundary, True) - test_output173 = pack_float32_to_4bit(np_int4_boundary, True) _validate_results(test_output171, test_output172) - _validate_results(test_output171, test_output173) input_pattern_uint4_boundary = [15, 0, 7, 0] np_uint4_boundary = np.asarray(input_pattern_uint4_boundary, dtype=np.uint8) @@ -186,9 +151,15 @@ def test_pack_float32_to_4bit_utils(): # Input values are boundary values in uint4 range test_output181 = pack_float32_to_4bit_optimized(np_uint4_boundary, False) test_output182 = pack_float32_to_4bit_cpp_based(np_uint4_boundary, False) - test_output183 = pack_float32_to_4bit(np_uint4_boundary, False) _validate_results(test_output181, test_output182) - _validate_results(test_output181, test_output183) + + # Validate against known expected values (pre-computed from ONNX 1.19 reference) + # Signed, boundary values [-8, 0, 7, 0, -8, 7]: pairs are (-8,0), (7,0), (-8,7) + # Packing: (0 << 4) | (-8 & 0x0F) = 0x08, (0 << 4) | (7 & 0x0F) = 0x07, (7 << 4) | (-8 & 0x0F) = 0x78 + _validate_results(test_output171, np.array([0x08, 0x07, 0x78], dtype=np.uint8)) + # Unsigned, boundary values [15, 0, 7, 0]: pairs are (15,0), (7,0) + # Packing: (0 << 4) | (15 & 0x0F) = 0x0F, (0 << 4) | (7 & 0x0F) = 0x07 + _validate_results(test_output181, np.array([0x0F, 0x07], dtype=np.uint8)) @pytest.mark.parametrize(