Skip to content

Commit 00576e0

Browse files
Fix QuantizationConstraints (#4046)
### Changes Update `QuantizationConstraints.from_config_dict` to avoid unexpected behavior on using `from_config_dict` ### Reason for changes https://github.com/openvinotoolkit/nncf/blob/f12f4ca93195f342825e30127b4a96ccf9d0a9e2/src/nncf/quantization/algorithms/min_max/algorithm.py#L658-L659 Overriding unexpected attributes by using QuantizationConstraints https://github.com/openvinotoolkit/nncf/blob/f12f4ca93195f342825e30127b4a96ccf9d0a9e2/src/nncf/common/quantization/quantizer_propagation/solver.py#L1041-L1045 Before ```python local = QuantizationConstraints(num_bits=8) # {'num_bits': 8} scope_constraints = QuantizationConstraints.from_config_dict({"mode": "symmetric"}) # {'num_bits': None, 'mode': 'symmetric', 'per_channel': None, 'signedness_to_force': None} new = local.get_updated_constraints(scope_constraints) # {'num_bits': None, 'mode': 'symmetric', 'per_channel': None, 'signedness_to_force': None} ``` After ```python local = QuantizationConstraints(num_bits=8) # {'num_bits': 8} scope_constraints = QuantizationConstraints.from_config_dict({"mode": "symmetric"}) # {'mode': 'symmetric'} new = local.get_updated_constraints(scope_constraints) # {'num_bits': 8, 'mode': 'symmetric'} ``` ### Related tickets CVS-183279 #4002 ### Tests https://github.com/openvinotoolkit/nncf/actions/runs/24669694021 https://github.com/openvinotoolkit/nncf/actions/runs/24669719478 PTQ-848
1 parent e452dcd commit 00576e0

2 files changed

Lines changed: 34 additions & 6 deletions

File tree

src/nncf/common/quantization/structs.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@ def from_config(cls, qconfig: QuantizerConfig, narrow_range: bool, half_range: b
265265

266266

267267
class QuantizationConstraints:
268+
# TODO(AlexanderDokuchaev): Refactor this class. Ticket-185344
268269
REF_QCONF_OBJ = QuantizerConfig()
269270

270271
def __init__(self, **kwargs: Any) -> None:
@@ -302,12 +303,12 @@ def get_updated_constraints(self, overriding_constraints: "QuantizationConstrain
302303

303304
@classmethod
304305
def from_config_dict(cls, config_dict: dict[str, Any]) -> "QuantizationConstraints":
305-
return cls(
306-
num_bits=config_dict.get("bits"),
307-
mode=config_dict.get("mode"),
308-
per_channel=config_dict.get("per_channel"),
309-
signedness_to_force=config_dict.get("signed"),
310-
)
306+
renamed_keys = {
307+
"bits": "num_bits",
308+
"signed": "signedness_to_force",
309+
}
310+
new_dict = {renamed_keys.get(k, k): v for k, v in config_dict.items()}
311+
return cls(**new_dict)
311312

312313
def constrain_qconfig_list(
313314
self,

tests/openvino/native/quantization/test_quantization_pipeline.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
from tests.openvino.native.models import ConvModel
2727
from tests.openvino.native.models import LinearModel
2828
from tests.openvino.native.models import MatMul2DModel
29+
from tests.openvino.native.models import ScaledDotProductAttentionModel
2930
from tests.openvino.native.models import WeightsModel
3031
from tests.openvino.native.test_model_transformer import get_nodes_by_type
3132

@@ -269,3 +270,29 @@ def test_ignored_scope_dump(ignored_options, expected_dump, tmp_path):
269270
assert dumped_model.get_rt_info(rt_path) == value
270271
else:
271272
assert dumped_model.has_rt_info(rt_path) is False
273+
274+
275+
@pytest.mark.parametrize("target_device", [TargetDevice.CPU, TargetDevice.GPU, TargetDevice.NPU])
276+
@pytest.mark.parametrize("num_bits", [None, 8, 16])
277+
def test_sdpa_quantize_activations_with_8_16_bits(num_bits: int | None, target_device: TargetDevice):
278+
model = ScaledDotProductAttentionModel(with_weights=True).ov_model
279+
dataset = get_dataset_for_test(model)
280+
281+
compressed_model = nncf.compress_weights(model, mode=nncf.CompressWeightsMode.INT8_SYM)
282+
quantized_model = quantize_impl(
283+
compressed_model,
284+
dataset,
285+
preset=QuantizationPreset.MIXED,
286+
target_device=target_device,
287+
subset_size=1,
288+
advanced_parameters=AdvancedQuantizationParameters(
289+
disable_bias_correction=True,
290+
activations_quantization_params=QuantizationParameters(num_bits=num_bits),
291+
),
292+
)
293+
expected_levels = 2**num_bits if num_bits is not None else 256
294+
fq_nodes = get_nodes_by_type(quantized_model, type_name="FakeQuantize")
295+
296+
for node in fq_nodes:
297+
levels = node.get_attributes()["levels"]
298+
assert levels in [expected_levels, expected_levels - 1]

0 commit comments

Comments
 (0)