Skip to content

Commit e6c1f43

Browse files
committed
added support fp8 types from OpenVINO
1 parent 4d8f649 commit e6c1f43

File tree

6 files changed

+48
-11
lines changed

6 files changed

+48
-11
lines changed

nncf/openvino/graph/nncf_graph_builder.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,13 @@ def convert_to_nncf_dtype(ov_type: ov.Type) -> Dtype:
4444
"""
4545
type_name = ov_type.get_type_name()
4646
conversion_map = {
47+
"nf4": "float",
48+
"f8e4m3": "float",
49+
"f8e5m2": "float",
4750
"f16": "float",
4851
"bf16": "float",
4952
"f32": "float",
5053
"f64": "float",
51-
"nf4": "float",
5254
"i4": "int",
5355
"i8": "int",
5456
"i16": "int",

nncf/tensor/definitions.py

+3
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ class TensorDataType(Enum):
3939
bfloat16 = auto()
4040
float32 = auto()
4141
float64 = auto()
42+
f8e4m3 = auto()
43+
f8e5m2 = auto()
44+
nf4 = auto()
4245
int8 = auto()
4346
int32 = auto()
4447
int64 = auto()

nncf/tensor/functions/openvino_numeric.py

+20-5
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121
from nncf.tensor.functions import numeric
2222

2323
DTYPE_MAP: Dict[TensorDataType, ov.Type] = {
24+
TensorDataType.nf4: ov.Type.nf4,
25+
TensorDataType.f8e4m3: ov.Type.f8e4m3,
26+
TensorDataType.f8e5m2: ov.Type.f8e5m2,
2427
TensorDataType.float16: ov.Type.f16,
2528
TensorDataType.bfloat16: ov.Type.bf16,
2629
TensorDataType.float32: ov.Type.f32,
@@ -48,12 +51,17 @@ def _(a: ov.Tensor) -> TensorBackend:
4851

4952
@numeric.astype.register
5053
def _(a: ov.Tensor, dtype: TensorDataType) -> ov.Tensor:
51-
if a.get_element_type() in [ov.Type.bf16, ov.Type.i4, ov.Type.u4] or dtype in [
54+
ov_cast_types = [
5255
TensorDataType.bfloat16,
5356
TensorDataType.int4,
5457
TensorDataType.uint4,
55-
]:
56-
# Cannot cast to/from bfloat16, uint4, int4 directly
58+
TensorDataType.nf4,
59+
TensorDataType.f8e4m3,
60+
TensorDataType.f8e5m2,
61+
]
62+
a_dtype = DTYPE_MAP_REV[a.get_element_type()]
63+
if a_dtype in ov_cast_types or dtype in ov_cast_types:
64+
# Cast using OpenVINO because the target or source dtype requires special handling
5765
return _astype_ov(a, dtype)
5866
return ov.Tensor(numeric.astype(a.data, dtype).data)
5967

@@ -75,9 +83,16 @@ def _(a: ov.Tensor, shape: Union[int, Tuple[int, ...]]) -> ov.Tensor:
7583

7684
@numeric.as_numpy_tensor.register
7785
def _(a: ov.Tensor) -> NDArray[Any]:
78-
# Cannot convert bfloat16, uint4, int4 to numpy directly
86+
# Cannot convert bfloat16, uint4, int4, nf4, f8e4m3, f8e5m2 to numpy directly
7987
a_dtype = DTYPE_MAP_REV[a.get_element_type()]
80-
if a_dtype in [TensorDataType.bfloat16, TensorDataType.uint4, TensorDataType.int4]:
88+
if a_dtype in [
89+
TensorDataType.bfloat16,
90+
TensorDataType.uint4,
91+
TensorDataType.int4,
92+
TensorDataType.nf4,
93+
TensorDataType.f8e4m3,
94+
TensorDataType.f8e5m2,
95+
]:
8196
dtype = TensorDataType.float32
8297
if a_dtype == TensorDataType.uint4:
8398
dtype = TensorDataType.uint8

tests/cross_fw/test_templates/template_test_nncf_tensor.py

+6
Original file line numberDiff line numberDiff line change
@@ -1512,6 +1512,9 @@ def test_fn_zeros(self):
15121512
in [
15131513
TensorDataType.int4,
15141514
TensorDataType.uint4,
1515+
TensorDataType.nf4,
1516+
TensorDataType.f8e4m3,
1517+
TensorDataType.f8e5m2,
15151518
]
15161519
):
15171520
continue
@@ -1541,6 +1544,9 @@ def test_fn_eye(self, n, m, ref):
15411544
in [
15421545
TensorDataType.int4,
15431546
TensorDataType.uint4,
1547+
TensorDataType.nf4,
1548+
TensorDataType.f8e4m3,
1549+
TensorDataType.f8e5m2,
15441550
]
15451551
):
15461552
continue

tests/openvino/native/test_nncf_graph_builder.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ def test_compare_nncf_graph_synthetic_models(model_cls_to_test):
3939
"model,precision",
4040
[
4141
(FPModel(const_dtype=ov.Type.nf4), "nf4"),
42+
(FPModel(const_dtype=ov.Type.f8e4m3), "f8e4m3"),
43+
(FPModel(const_dtype=ov.Type.f8e5m2), "f8e5m2"),
4244
],
4345
)
4446
def test_compare_nncf_graph_precision_synthetic_models(model, precision):
@@ -112,10 +114,12 @@ def _get_default_nncf_graph_edge(from_node, to_node, input_port_id, output_port_
112114
@pytest.mark.parametrize(
113115
"ov_type,expected_nncf_dtype",
114116
[
117+
(ov.Type.nf4, Dtype.FLOAT),
118+
(ov.Type.f8e4m3, Dtype.FLOAT),
119+
(ov.Type.f8e5m2, Dtype.FLOAT),
115120
(ov.Type.f16, Dtype.FLOAT),
116121
(ov.Type.f32, Dtype.FLOAT),
117122
(ov.Type.f64, Dtype.FLOAT),
118-
(ov.Type.nf4, Dtype.FLOAT),
119123
(ov.Type.i4, Dtype.INTEGER),
120124
(ov.Type.i8, Dtype.INTEGER),
121125
(ov.Type.i16, Dtype.INTEGER),
@@ -140,8 +144,6 @@ def test_convert_to_nncf_dtype_supported_types(ov_type: ov.Type, expected_nncf_d
140144
"ov_type",
141145
[
142146
ov.Type.undefined,
143-
ov.Type.f8e4m3,
144-
ov.Type.f8e5m2,
145147
],
146148
)
147149
def test_convert_to_nncf_dtype_unsupported_types(ov_type: ov.Type):

tests/openvino/native/test_tensor.py

+11-2
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,23 @@
2626
class TestOVNNCFTensorOperators:
2727
@staticmethod
2828
def to_tensor(x, backend=TensorBackend.ov, dtype=TensorDataType.float32):
29+
no_numpy_support_dtypes = [
30+
TensorDataType.bfloat16,
31+
TensorDataType.uint4,
32+
TensorDataType.int4,
33+
TensorDataType.nf4,
34+
TensorDataType.f8e5m2,
35+
TensorDataType.f8e4m3,
36+
]
37+
2938
if backend == TensorBackend.ov:
30-
if dtype in [TensorDataType.bfloat16, TensorDataType.uint4, TensorDataType.int4]:
39+
if dtype in no_numpy_support_dtypes:
3140
ov_const = opset.constant(x, dtype=DTYPE_MAP_OV[dtype])
3241
return ov.Tensor(ov_const.data, ov_const.data.shape, DTYPE_MAP_OV[dtype])
3342
else:
3443
return ov.Tensor(np.array(x, dtype=DTYPE_MAP_NP[dtype]))
3544
elif backend == TensorBackend.numpy:
36-
if dtype in [TensorDataType.bfloat16, TensorDataType.uint4, TensorDataType.int4]:
45+
if dtype in no_numpy_support_dtypes:
3746
msg = f"Can't create NumPY tensor in dtype {dtype}"
3847
raise ValueError(msg)
3948
return np.array(x, dtype=DTYPE_MAP_NP[dtype])

0 commit comments

Comments
 (0)