fp8 weight compression into 4 bit types#3501
Conversation
49c2d1e to
b29a677
Compare
|
Thanks, good to see a lot of improvements in the weight compression algorithm!
|
187c06a to
a2bf6da
Compare
Done: tests/openvino/optimized_functions/test_compression_functions.py
This was covered in tests/openvino/native/quantization/test_weights_compression.py
Done via checking that all statistics are used: tests/cross_fw/test_templates/template_test_weights_compression.py |
68b65ce to
6948773
Compare
| if weight_name in weight_names: | ||
| if i == n - 1: | ||
| is_last_layer_shared = True | ||
| is_last_layer_skipped = is_last_layer |
There was a problem hiding this comment.
I have a concern that previously this variable was named is_last_layer_shared and from that it was clear why the node is skipped. Now it is less obvious. Perhaps, some comment would help.
There was a problem hiding this comment.
Added a comment to the code.
| else: | ||
| mode = ( | ||
| CompressWeightsMode.INT8_ASYM | ||
| if self._backup_mode == BackupMode.INT8_ASYM | ||
| else CompressWeightsMode.INT8_SYM | ||
| is_last_layer_skipped = is_last_layer |
There was a problem hiding this comment.
I have difficulties matching this logic with the previous one. Where does this come from / what's the logic behind it?
There was a problem hiding this comment.
This is a fix to the previous logic. The previous logic was that if the last layer is skipped for some reason, the layer preceding the last one is also skipped. The current logic only skips the last layer.
| model: TModel, | ||
| graph: NNCFGraph, | ||
| all_weight_params: list[WeightCompressionParameters], | ||
| nodes_to_compress: list[NNCFNode], |
| def itemsize(self) -> int: | ||
| """ | ||
| Returns the size of a single item in bits for the tensor data type. | ||
|
|
||
| :return: The item size in bits. | ||
| """ | ||
| if self in [TensorDataType.nf4, TensorDataType.uint4, TensorDataType.int4]: | ||
| return 4 | ||
| if self in [TensorDataType.f8e4m3, TensorDataType.f8e5m2, TensorDataType.int8, TensorDataType.uint8]: | ||
| return 8 | ||
| if self in [TensorDataType.float16, TensorDataType.bfloat16]: | ||
| return 16 | ||
| if self in [TensorDataType.float32, TensorDataType.int32]: | ||
| return 32 | ||
| return 64 |
There was a problem hiding this comment.
| def itemsize(self) -> int: | |
| """ | |
| Returns the size of a single item in bits for the tensor data type. | |
| :return: The item size in bits. | |
| """ | |
| if self in [TensorDataType.nf4, TensorDataType.uint4, TensorDataType.int4]: | |
| return 4 | |
| if self in [TensorDataType.f8e4m3, TensorDataType.f8e5m2, TensorDataType.int8, TensorDataType.uint8]: | |
| return 8 | |
| if self in [TensorDataType.float16, TensorDataType.bfloat16]: | |
| return 16 | |
| if self in [TensorDataType.float32, TensorDataType.int32]: | |
| return 32 | |
| return 64 | |
| def itemsize(self) -> int: | |
| """ | |
| Returns the size of a single item in bits for the tensor data type. | |
| :return: The item size in bits. | |
| """ | |
| return ITEMSIZE_BITS[self] | |
| ITEMSIZE_BITS = { | |
| TensorDataType.nf4: 4, | |
| TensorDataType.uint4: 4, | |
| TensorDataType.int4: 4, | |
| TensorDataType.f8e4m3: 8, | |
| TensorDataType.f8e5m2: 8, | |
| TensorDataType.int8: 8, | |
| TensorDataType.uint8: 8, | |
| TensorDataType.float16: 16, | |
| TensorDataType.bfloat16: 16, | |
| TensorDataType.float32: 32, | |
| TensorDataType.int32: 32, | |
| TensorDataType.float64: 64, | |
| TensorDataType.int64: 64, | |
| } |
What do you think about this?
Changes
weight_dtypeinWeightCompressionParameters.WeightCompressionalgorithm to minimize number of collected statistics.AWQalgorithm by removingnodes_to_compressargument in the apply function.Convertin the compression subgraph for f8e4m3 and f8e5m2 weights.Reason for changes
Support for DeepSeek-R1
Related tickets
CVS-162315
Tests
tests/openvino/native/quantization/test_weights_compression.py
https://github.com/openvinotoolkit/nncf/actions/runs/15563432412