Skip to content

Commit

Permalink
Merge branch 'master' into CVS-151312_exp
Browse files Browse the repository at this point in the history
  • Loading branch information
dorloff authored Feb 21, 2025
2 parents 2c525f3 + f77ef0f commit 695db12
Show file tree
Hide file tree
Showing 32 changed files with 480 additions and 270 deletions.
2 changes: 1 addition & 1 deletion .github/dockerfiles/docker_tag
Original file line number Diff line number Diff line change
@@ -1 +1 @@
pr-28725
pr-29066
6 changes: 3 additions & 3 deletions scripts/install_dependencies/install_openvino_dependencies.sh
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ elif [ "$os" == "centos7" ] || [ "$os" == "centos8" ] || [ "$os" == "centos9" ]
pkgs_gpu+=("ocl-icd.$arch")
extra_repos+=("https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm")
elif [ "$os" == "rhel8" ] ; then
pkgs_gpu+=("http://mirror.centos.org/centos/8-stream/AppStream/$arch/os/Packages/ocl-icd-2.2.12-1.el8.$arch.rpm")
pkgs_gpu+=("http://vault.centos.org/centos/8-stream/AppStream/$arch/os/Packages/ocl-icd-2.2.12-1.el8.$arch.rpm")
pkgs_python+=(python38 python38-pip)
extra_repos+=("https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm")
elif [ "$os" == "rhel9.1" ] || [ "$os" == "rhel9.2" ] || [ "$os" == "rhel9.3" ] || [ "$os" == "rhel9.4" ] ; then
Expand Down Expand Up @@ -302,9 +302,9 @@ elif [ "$os" == "centos7" ] || [ "$os" == "centos8" ] || [ "$os" == "centos9" ]
[ -z "$interactive" ] && iopt="--assumeyes"
[ -n "$dry" ] && iopt="--downloadonly"
[ -n "$keepcache" ] && iopt="$iopt --setopt=keepcache=1"
[ -n "$extra" ] && [ ${#extra_repos[@]} -ne 0 ] && yum localinstall "$iopt" --nogpgcheck "${extra_repos[@]}"
[ -n "$extra" ] && [ ${#extra_repos[@]} -ne 0 ] && yum localinstall ${iopt:+$iopt} --nogpgcheck "${extra_repos[@]}"

yum install "$iopt" "${pkgs[@]}"
yum install ${iopt:+$iopt} "${pkgs[@]}"

elif [ "$os" == "opensuse-leap15.3" ] ; then

Expand Down
2 changes: 1 addition & 1 deletion src/bindings/python/constraints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ patchelf<=0.17.2.1
packaging>=22.0

# Frontends
h5py>=3.1.0,<3.13.0
h5py>=3.1.0,<3.14.0
docopt~=0.6.2
paddlepaddle==2.6.2
tensorflow>=1.15.5,<2.18.0
Expand Down
4 changes: 2 additions & 2 deletions src/bindings/python/src/openvino/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@
from openvino._ov_api import Op

# Import all public modules
from openvino.package_utils import lazy_import
runtime = lazy_import("openvino.runtime")
from openvino.package_utils import LazyLoader
runtime = LazyLoader("openvino.runtime")
from openvino import frontend as frontend
from openvino import helpers as helpers
from openvino import experimental as experimental
Expand Down
37 changes: 24 additions & 13 deletions src/bindings/python/src/openvino/package_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import os
import sys
from functools import wraps
from typing import Callable, Any
from typing import Callable, Any, Optional
from pathlib import Path
import importlib.util
from types import ModuleType
Expand Down Expand Up @@ -117,17 +117,28 @@ def __get__(self, obj: Any, cls: Any = None) -> Any:
return decorator


def lazy_import(module_name: str) -> ModuleType:
spec = importlib.util.find_spec(module_name)
if spec is None or spec.loader is None:
raise ImportError(f"Module {module_name} not found")
class LazyLoader:
"""A class to lazily load a module, importing it only when an attribute is accessed."""

loader = importlib.util.LazyLoader(spec.loader)
module = importlib.util.module_from_spec(spec)
sys.modules[module_name] = module
def __init__(self, module_name: str):
self.module_name = module_name
self._module: Optional[ModuleType] = None

try:
loader.exec_module(module)
except Exception as e:
raise ImportError(f"Failed to load module {module_name}") from e
return module
def _load_module(self) -> None:
if self._module is None:
# Import the module and update sys.modules with the loaded module
self._module = importlib.import_module(self.module_name)
# Update the LazyLoader instance's __dict__ with the module's __dict__
# This ensures that subsequent attribute accesses use the module's attributes directly (by __getattribute__() )
self.__dict__.update(self._module.__dict__)

def __getattr__(self, item: str) -> Any:
self._load_module()
return getattr(self._module, item)

def __dir__(self) -> list:
self._load_module()
return dir(self._module)

def __repr__(self) -> str:
return f"<LazyLoader for module '{self.module_name}'>"
4 changes: 0 additions & 4 deletions src/common/low_precision_transformations/src/mat_mul.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,10 +214,6 @@ bool MatMulTransformation::canBeTransformed(const std::shared_ptr<Node>& layer)
return false;
}
}

if (!NetworkHelper::checkZeroPoint(dequantization1.subtract)) {
return false;
}
} else {
return false;
}
Expand Down
16 changes: 16 additions & 0 deletions src/frontends/pytorch/src/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,22 @@ std::shared_ptr<Node> get_node_axes_range(const NodeContext& context, const Outp
};

Output<Node> normalize_axis(const NodeContext& context, const Output<Node>& axis, const Output<Node>& rank) {
if (const auto axis_const = ov::util::get_constant_from_source(axis)) {
// if axis is already a constant and all values are non-negative, return it
auto data = axis_const->cast_vector<int64_t>();
bool all_non_negative = std::all_of(data.begin(), data.end(), [](int64_t v) {
return v >= 0;
});
if (all_non_negative) {
Output<Node> res = axis_const;
if (axis_const->get_shape() == Shape({}) && rank.get_partial_shape() == PartialShape({1})) {
// Unsqueeze scalar const if rank is 1d
auto zero = v0::Constant::create(element::i32, Shape{}, {0});
res = std::make_shared<v0::Unsqueeze>(res, zero);
}
return res;
}
}
auto axis_rank = std::make_shared<v1::Add>(axis, rank);
auto new_axis = std::make_shared<v1::Mod>(axis_rank, rank);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,36 @@
#include <memory>

#include "openvino/core/validation_util.hpp"
#include "openvino/opsets/opset10.hpp"
#include "openvino/op/constant.hpp"
#include "openvino/op/convert.hpp"
#include "openvino/op/fake_quantize.hpp"
#include "openvino/op/multiply.hpp"
#include "openvino/op/reduce_max.hpp"
#include "openvino/op/reduce_min.hpp"
#include "openvino/op/subtract.hpp"
#include "openvino/pass/manager.hpp"
#include "openvino/pass/pattern/matcher.hpp"
#include "openvino/pass/pattern/op/optional.hpp"
#include "openvino/pass/pattern/op/wrap_type.hpp"
#include "tflite_ops/tflite_quantize.hpp"
#include "transformations/rt_info/disable_constant_folding.hpp"
#include "utils.hpp"

using namespace std;
using namespace ov::pass;
using namespace ov::opset10;
using namespace ov::op;
using namespace ov::pass::pattern;
using namespace ov::frontend::tensorflow_lite;

pass::TFLQuantizeConvert::TFLQuantizeConvert() {
auto tfl_quantize_label = wrap_type<tensorflow_lite::TFLQuantize>();
auto convert_label = wrap_type<opset10::Convert>({tfl_quantize_label});
auto convert_label = wrap_type<v0::Convert>({tfl_quantize_label});

matcher_pass_callback callback = [=](Matcher& m) {
auto pattern_map = m.get_pattern_map();
auto tfl_quantize_node = pattern_map.at(tfl_quantize_label);
auto convert_node = pattern_map.at(convert_label);
auto convert = ov::as_type_ptr<opset10::Convert>(convert_node);
auto convert = ov::as_type_ptr<v0::Convert>(convert_node);
if (!convert)
return false;
auto type = convert->get_destination_type();
Expand Down Expand Up @@ -74,14 +81,14 @@ void fuse_zp_to_weights(ov::Output<ov::Node>& output, std::vector<int64_t>& zero
vector<int64_t> axes_vec(rank);
std::iota(axes_vec.begin(), axes_vec.end(), 0);

auto axes = Constant::create(ov::element::i64, {axes_vec.size()}, axes_vec);
auto max_value = make_shared<ReduceMax>(output, axes, false)->output(0);
auto min_value = make_shared<ReduceMin>(output, axes, false)->output(0);
auto axes = v0::Constant::create(ov::element::i64, {axes_vec.size()}, axes_vec);
auto max_value = make_shared<v1::ReduceMax>(output, axes, false)->output(0);
auto min_value = make_shared<v1::ReduceMin>(output, axes, false)->output(0);

auto check_in_bounds = [&](ov::Output<ov::Node>& value) -> bool {
shared_ptr<ov::opset10::Constant> constant;
shared_ptr<v0::Constant> constant;
if (rank == 0) {
constant = ov::as_type_ptr<ov::opset10::Constant>(output.get_node_shared_ptr());
constant = ov::as_type_ptr<v0::Constant>(output.get_node_shared_ptr());
} else {
constant = ov::util::get_constant_from_source(value);
}
Expand All @@ -95,31 +102,32 @@ void fuse_zp_to_weights(ov::Output<ov::Node>& output, std::vector<int64_t>& zero
};
if (!check_in_bounds(min_value) || !check_in_bounds(max_value))
return;
output = std::make_shared<Convert>(output, ov::element::i32);
auto zp_node = ov::opset10::Constant::create(ov::element::i32, zp_shape, zero_point);
output = std::make_shared<ov::opset10::Subtract>(output, zp_node);
output = std::make_shared<ov::opset10::Convert>(output, ov::element::i8);
output = std::make_shared<v0::Convert>(output, ov::element::i32);
auto zp_node = v0::Constant::create(ov::element::i32, zp_shape, zero_point);
output = std::make_shared<v1::Subtract>(output, zp_node);
output = std::make_shared<v0::Convert>(output, ov::element::i8);
output = ov::util::get_constant_from_source(output); // TODO: Check Me
zero_point = {0};
}

pass::TFLQuantizeReplacer::TFLQuantizeReplacer() {
auto tfl_quantize_label = wrap_type<tensorflow_lite::TFLQuantize>();
const auto tfl_quantize_label = wrap_type<tensorflow_lite::TFLQuantize>();
matcher_pass_callback callback = [=](Matcher& m) {
auto pattern_map = m.get_pattern_map();
auto tfl_quantize_node = pattern_map.at(tfl_quantize_label);
auto tfl_quantize = ov::as_type_ptr<TFLQuantize>(tfl_quantize_node);
const auto& tfl_quantize_node = pattern_map.at(tfl_quantize_label);
const auto& tfl_quantize = ov::as_type_ptr<TFLQuantize>(tfl_quantize_node);
if (!tfl_quantize)
return false;
auto quantization = tfl_quantize->get_info();
const auto& quantization = tfl_quantize->get_info();
FRONT_END_GENERAL_CHECK(
quantization != nullptr,
"Internal operation TFLQuantized representing quantized tensor doesn't have quantization details");

auto in_type = tfl_quantize->get_input_element_type(0);
auto out_type = tfl_quantize->get_type();
const auto in_type = tfl_quantize->get_input_element_type(0);
const auto out_type = tfl_quantize->get_type();

auto is_constant = ov::is_type<Constant>(tfl_quantize->get_input_node_shared_ptr(0)); // for Constant case
const auto is_constant =
ov::is_type<v0::Constant>(tfl_quantize->get_input_node_shared_ptr(0)); // for Constant case

FRONT_END_GENERAL_CHECK(in_type == out_type || in_type == element::f32 || out_type == element::f32,
"TFLQuantized types do not match: in_type = ",
Expand All @@ -131,62 +139,67 @@ pass::TFLQuantizeReplacer::TFLQuantizeReplacer() {
Output<Node> output = tfl_quantize->get_input_source_output(0);

auto zp = quantization->get_zero_point();
auto scale = quantization->get_scale();
const auto& scale = quantization->get_scale();

auto zp_shape = get_quant_shape(output, quantization, zp.size());
auto scale_shape = get_quant_shape(output, quantization, scale.size());
const auto& zp_shape = get_quant_shape(output, quantization, zp.size());
const auto& scale_shape = get_quant_shape(output, quantization, scale.size());

auto zp_node = ov::opset10::Constant::create(element::f32, zp_shape, zp);
auto scale_node = ov::opset10::Constant::create(element::f32, scale_shape, scale);
const auto& zp_node = v0::Constant::create(element::f32, zp_shape, zp);
const auto& scale_node = v0::Constant::create(element::f32, scale_shape, scale);

if (is_constant) {
fuse_zp_to_weights(output, zp, zp_shape);
output = make_shared<Convert>(output, element::f32);
output = make_shared<v0::Convert>(output, element::f32);
disable_constant_folding(output.get_node_shared_ptr());
if (std::any_of(zp.begin(), zp.end(), [](const int64_t& i) {
return i != 0;
}))
output = std::make_shared<ov::opset10::Subtract>(output, zp_node);
output = std::make_shared<ov::opset10::Multiply>(output, scale_node);
output = std::make_shared<v1::Subtract>(output, zp_node);
output = std::make_shared<v1::Multiply>(output, scale_node);
tfl_quantize->output(0).replace(output);
return true;
}
if (in_type != element::f32) {
output = make_shared<Convert>(output, element::f32);
output = make_shared<v0::Convert>(output, element::f32);
}

auto levels = 1 << tfl_quantize->get_original_type().bitwidth();
auto is_signed = tfl_quantize->get_original_type().is_signed();
const auto levels = 1 << tfl_quantize->get_original_type().bitwidth();
const auto is_signed = tfl_quantize->get_original_type().is_signed();

const auto low = is_signed ? (-levels / 2) : 0;
const auto high = (is_signed ? levels / 2 : levels) - 1;

Output<Node> input_low, input_high, output_low, output_high;
output_low = std::make_shared<opset10::Multiply>(std::make_shared<opset10::Negative>(scale_node), zp_node);
output_high = std::make_shared<opset10::Multiply>(
scale_node,
std::make_shared<opset10::Subtract>(ov::opset10::Constant::create(element::f32, {}, {levels - 1}),
zp_node));
if (in_type != element::f32) {
auto low = is_signed ? (-levels / 2) : 0;
auto high = levels - low - 1;
input_low = ov::opset10::Constant::create(element::f32, {}, {low});
input_high = ov::opset10::Constant::create(element::f32, {}, {high});
} else {
input_low = output_low;
input_high = output_high;
}

if (out_type != element::f32) {
auto low = is_signed ? (-levels / 2) : 0;
auto high = levels - low - 1;
output_low = ov::opset10::Constant::create(element::f32, {}, {low});
output_high = ov::opset10::Constant::create(element::f32, {}, {high});
output_low = v0::Constant::create(element::f32, {}, {low});
output_high = v0::Constant::create(element::f32, {}, {high});
input_low = std::make_shared<v1::Multiply>(std::make_shared<v1::Subtract>(output_low, zp_node), scale_node);
input_high =
std::make_shared<v1::Multiply>(std::make_shared<v1::Subtract>(output_high, zp_node), scale_node);
} else if (in_type != element::f32) {
input_low = v0::Constant::create(element::f32, {}, {low});
input_high = v0::Constant::create(element::f32, {}, {high});
output_low = std::make_shared<v1::Multiply>(std::make_shared<v1::Subtract>(input_low, zp_node), scale_node);
output_high =
std::make_shared<v1::Multiply>(std::make_shared<v1::Subtract>(input_high, zp_node), scale_node);
} else {
output_low = v0::Constant::create(element::f32, {}, {low});
output_high = v0::Constant::create(element::f32, {}, {high});
input_low = std::make_shared<v1::Multiply>(std::make_shared<v1::Subtract>(output_low, zp_node), scale_node);
input_high =
std::make_shared<v1::Multiply>(std::make_shared<v1::Subtract>(output_high, zp_node), scale_node);
output_low = input_low;
output_high = input_high;
}

input_low = ov::util::get_constant_from_source(input_low);
input_high = ov::util::get_constant_from_source(input_high);
output_low = ov::util::get_constant_from_source(output_low);
output_high = ov::util::get_constant_from_source(output_high);
output =
std::make_shared<opset10::FakeQuantize>(output, input_low, input_high, output_low, output_high, levels);
output = std::make_shared<v0::FakeQuantize>(output, input_low, input_high, output_low, output_high, levels);
if (out_type != element::f32) {
output = make_shared<Convert>(output, out_type);
output = make_shared<v0::Convert>(output, out_type);
}
tfl_quantize->output(0).replace(output);
return true;
Expand Down
14 changes: 0 additions & 14 deletions src/frontends/tensorflow_lite/tests/convert_tricky_models.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,6 @@ static std::string s_manifest = "";
using Inputs = std::vector<std::vector<float>>;
using Outputs = std::vector<std::vector<float>>;

#if (defined OPENVINO_ARCH_ARM && defined(__linux__))
// Ticket: 153164
OPENVINO_TEST(TensorFlowLiteTrickyModels, DISABLED_tflite_dequantize) {
#else
OPENVINO_TEST(TensorFlowLiteTrickyModels, tflite_dequantize) {
#endif
auto model = convert_model("dequantize.tflite");

auto test_case = ov::test::TestCase(model, ov::test::utils::DEVICE_CPU);
test_case.add_input<float>({1, 1, 1, 1});
test_case.add_expected_output<float>(Shape{2, 2}, {2, 1.75f, 2001, 0.876f});
test_case.run_with_tolerance_as_fp(0.001f);
}

OPENVINO_TEST(TensorFlowLiteTrickyModels, tflite_densify) {
auto model = convert_model("densify.tflite");

Expand Down
Loading

0 comments on commit 695db12

Please sign in to comment.