ai-edge-quantizer-nightly 0.1.0.dev20250519__py3-none-any.whl → 0.1.0.dev20250520__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -58,19 +58,19 @@ def _rotate_with_diagonal_hadamard(
58
58
 
59
59
  Args:
60
60
  tensor_content: The float array to quantize.
61
- axis: The axis of the tensor to quantize.
61
+ axis: The axis of the tensor to rotate.
62
62
 
63
63
  Returns:
64
64
  A tuple containing the quantized array and the recovered array.
65
65
 
66
66
  Raises:
67
- ValueError: If the axis is not 1. To support other axes, please add
68
- support to the matrix multiplication.
67
+ ValueError: If the axis is not the last axis of tensor_content. To support
68
+ other axes, please add support to the matrix multiplication.
69
69
  """
70
- if axis != 1:
70
+ if axis != tensor_content.ndim - 1:
71
71
  raise ValueError(
72
- "Hadamard rotation is only supported for 2D tensors with quantized"
73
- " dimension 0."
72
+ "Hadamard rotation is only supported for tensors with quantized"
73
+ " dimension 0 (rotate last dimension)."
74
74
  )
75
75
 
76
76
  # Use the largest power of 2 that is a factor of the dimension and then
@@ -78,15 +78,15 @@ def _rotate_with_diagonal_hadamard(
78
78
  # of 2 to calculate this factor.
79
79
  hadamard_size = np.gcd(tensor_content.shape[axis], 2 ** 30)
80
80
  diagonal_size = tensor_content.shape[axis] // hadamard_size
81
- output_size = tensor_content.shape[1 - axis]
81
+ # Output size is the product of all dimensions except the one being rotated.
82
+ output_size = np.prod(np.delete(tensor_content.shape, axis))
82
83
  random_vector = np.ones(hadamard_size, dtype=np.int8)
83
84
 
84
85
  # Use a canonical Hadamard matrix.
85
86
  hadamard = _make_hadamard_matrix(hadamard_size)
86
87
  reshaped_tensor = tensor_content.reshape(
87
- diagonal_size, output_size, hadamard_size
88
- )
89
- w_rotated = np.einsum("jk,ilk->ilj", hadamard, reshaped_tensor)
88
+ diagonal_size * output_size, hadamard_size)
89
+ w_rotated = np.matmul(hadamard, reshaped_tensor.mT).mT
90
90
  return w_rotated.reshape(tensor_content.shape), hadamard_size, random_vector
91
91
 
92
92
 
@@ -122,8 +122,10 @@ def get_tensor_quant_params(
122
122
  "Hadamard rotation is not supported for static quantization."
123
123
  )
124
124
 
125
- if tensor_content.ndim != 2:
126
- raise ValueError("Hadamard rotation is only supported for 2D tensors.")
125
+ if tensor_content.ndim < 2:
126
+ raise ValueError(
127
+ "Hadamard rotation is only supported for tensors with rank >= 2."
128
+ )
127
129
 
128
130
  if tensor_quant_config.granularity != qtyping.QuantGranularity.CHANNELWISE:
129
131
  raise ValueError(
@@ -140,9 +142,9 @@ def get_tensor_quant_params(
140
142
  " supported."
141
143
  )
142
144
 
143
- # Reduction axis is the non-quantized dimension. Since we only support 2D
144
- # tensors and quantized_dim of 0, the reduction axis is 1.
145
- reduce_axis = 1
145
+ # Reduction axis is the last non-quantized dimension. Since we only support
146
+ # quantized_dim of 0, the reduction axis is the last axis.
147
+ reduce_axis = tensor_content.ndim - 1
146
148
 
147
149
  # Rotate the tensor with a Hadamard matrix.
148
150
  w_rotated, hadamard_size, random_vector = _rotate_with_diagonal_hadamard(
@@ -168,6 +168,36 @@ class HadamardRotationFullyConnectedTest(parameterized.TestCase):
168
168
  np.array(qparams.quantized_data), expected
169
169
  )
170
170
 
171
+ def test_get_tensor_quant_params_golden_3(self):
172
+ # test_data:
173
+ # [[[1 2 1 2 1 2]
174
+ # [3 4 3 4 3 4]
175
+ # [1 2 1 2 1 2]]
176
+ # [[3 4 3 4 3 4]
177
+ # [1 2 1 2 1 2]
178
+ # [3 4 3 4 3 4]]]
179
+ test_data = np.tile([[1, 2], [3, 4]], [3, 3])
180
+ test_data = np.reshape(test_data, (2, 3, 6))
181
+ # expected:
182
+ # [[[ 54 -18 54 -18 54 -18]
183
+ # [127 -18 127 -18 127 -18]
184
+ # [ 54 -18 54 -18 54 -18]]
185
+ # [[127 -18 127 -18 127 -18]
186
+ # [ 54 -18 54 -18 54 -18]
187
+ # [127 -18 127 -18 127 -18]]]
188
+ expected = np.tile([[54, -18], [127, -18]], [3, 3])
189
+ expected = np.reshape(expected, (2, 3, 6))
190
+ qparams = hadamard_rotation.get_tensor_quant_params(
191
+ self._op_info,
192
+ self._op_info.op_quant_config.weight_tensor_config,
193
+ test_data,
194
+ self._tensor_name_to_qsv,
195
+ )
196
+ self.assertIsNotNone(qparams.quantized_data)
197
+ np.testing.assert_array_equal(
198
+ np.array(qparams.quantized_data), expected
199
+ )
200
+
171
201
  def test_raise_missing_tensor_content(self):
172
202
  with self.assertRaisesWithPredicateMatch(
173
203
  ValueError, lambda err: "weight tensor" in str(err)
@@ -190,9 +220,9 @@ class HadamardRotationFullyConnectedTest(parameterized.TestCase):
190
220
  self._graph_info.buffers[self._fc_buffer_id],
191
221
  )
192
222
 
193
- def test_raise_non_2d_constant(self):
223
+ def test_raise_1d_constant(self):
194
224
  with self.assertRaisesWithPredicateMatch(
195
- ValueError, lambda err: "2D tensors" in str(err)
225
+ ValueError, lambda err: "rank >= 2" in str(err)
196
226
  ):
197
227
  hadamard_rotation.get_tensor_quant_params(
198
228
  self._op_info,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ai-edge-quantizer-nightly
3
- Version: 0.1.0.dev20250519
3
+ Version: 0.1.0.dev20250520
4
4
  Summary: A quantizer for advanced developers to quantize converted AI Edge models.
5
5
  Home-page: https://github.com/google-ai-edge/ai-edge-quantizer
6
6
  Keywords: On-Device ML,AI,Google,TFLite,Quantization,LLMs,GenAI
@@ -32,8 +32,8 @@ ai_edge_quantizer/algorithms/uniform_quantize/common_quantize.py,sha256=NpZ-JvZt
32
32
  ai_edge_quantizer/algorithms/uniform_quantize/common_quantize_test.py,sha256=GGf_n3wIeg3GB_eGsmyNJ0fTcxgpeMMbugTMRONK6TQ,3553
33
33
  ai_edge_quantizer/algorithms/uniform_quantize/dequantized_weight_recovery.py,sha256=BDdn_uBZakfHyzdMJPKadsOqxqyC-s6W2ZzFH99L4fE,8652
34
34
  ai_edge_quantizer/algorithms/uniform_quantize/dequantized_weight_recovery_test.py,sha256=sT5eX5TLZEHTtPfnSkCPDlS0sQxlTFWbCsbvOuj--yY,8889
35
- ai_edge_quantizer/algorithms/uniform_quantize/hadamard_rotation.py,sha256=pN4hwggrdI4eBdqvsdwnFagFxpd4D8LkWK0o4HG_xxk,12536
36
- ai_edge_quantizer/algorithms/uniform_quantize/hadamard_rotation_test.py,sha256=MajG6DqpP4HvVzcZwgiKojWL3RBxCpkU3u2mKyeB0hA,9191
35
+ ai_edge_quantizer/algorithms/uniform_quantize/hadamard_rotation.py,sha256=U3h5scCHSOdqHA-pb1C3pNgwumT4ydGbtkCSM0ORhrs,12740
36
+ ai_edge_quantizer/algorithms/uniform_quantize/hadamard_rotation_test.py,sha256=5VUxlaKP1jz4HV-LcKxXMMtmb6eWamq0A6qWJd63cR4,10179
37
37
  ai_edge_quantizer/algorithms/uniform_quantize/naive_min_max_quantize.py,sha256=8_tNLTbOWTKId4DfHBjkOR9RvELUyIpxlGxKu7tv5Ko,7556
38
38
  ai_edge_quantizer/algorithms/uniform_quantize/naive_min_max_quantize_test.py,sha256=zoF_EHjYqsKkuev8wfuutIITEmp_maa70IpJI_Df3ck,7431
39
39
  ai_edge_quantizer/algorithms/uniform_quantize/octav.py,sha256=Umxh4kJyeHddZf-Wd4aXE5MTI1XWFa5KRuM17uYU714,6922
@@ -70,8 +70,8 @@ ai_edge_quantizer/utils/tfl_interpreter_utils.py,sha256=WoewyiZpaua80oP0tpgyrw5W
70
70
  ai_edge_quantizer/utils/tfl_interpreter_utils_test.py,sha256=6fjkM-rycZ95L4yfvlr0TN6RlrhfPzxNUYrZaYO_F0A,12013
71
71
  ai_edge_quantizer/utils/validation_utils.py,sha256=oYw33Sg547AqtGw-choPUJmp9SAKkV46J_ddqSsum2Q,3950
72
72
  ai_edge_quantizer/utils/validation_utils_test.py,sha256=V_qNDikPD4OPB-siOLQCWNVWTAu87h2IgNYt7teFd-o,2934
73
- ai_edge_quantizer_nightly-0.1.0.dev20250519.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
74
- ai_edge_quantizer_nightly-0.1.0.dev20250519.dist-info/METADATA,sha256=Miou6XsSuDYRUvHBvwHgxOz3L3X3CWYcmcftB0F5cHw,1528
75
- ai_edge_quantizer_nightly-0.1.0.dev20250519.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
76
- ai_edge_quantizer_nightly-0.1.0.dev20250519.dist-info/top_level.txt,sha256=8QTfPnFXNVUhScFLaa-NWZMFWMn72M50DVPubpwWB1g,18
77
- ai_edge_quantizer_nightly-0.1.0.dev20250519.dist-info/RECORD,,
73
+ ai_edge_quantizer_nightly-0.1.0.dev20250520.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
74
+ ai_edge_quantizer_nightly-0.1.0.dev20250520.dist-info/METADATA,sha256=Ab9WYw1I2sBMaM8_rUTZZYq0Whg7yE00c808y76N_14,1528
75
+ ai_edge_quantizer_nightly-0.1.0.dev20250520.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
76
+ ai_edge_quantizer_nightly-0.1.0.dev20250520.dist-info/top_level.txt,sha256=8QTfPnFXNVUhScFLaa-NWZMFWMn72M50DVPubpwWB1g,18
77
+ ai_edge_quantizer_nightly-0.1.0.dev20250520.dist-info/RECORD,,