Skip to content

Commit

Permalink
[ONNX] Update DequantizeLinear21 converter (#27351)
Browse files Browse the repository at this point in the history
### Details:
Aligned with the canonical form of the dequantization subgraph.

Reshape op has been moved up right after the Constant, it will be const
folded in MOC, this is ok, Reshape const folding doesn't copy a
constant, just copies a pointer.

And ConvertLike were replaced with Convert. Perhaps that's a pretty
rough change and we need to add a check here that the scale is a
contant. And in that case use Convert instead of ConvertLike, if scale
is not a constant, maybe we should leave ConvertLike.

### Tickets:
 - *https://jira.devtools.intel.com/browse/CVS-156329*
  • Loading branch information
itikhono authored Oct 31, 2024
1 parent a0b73e0 commit b9a94c3
Showing 1 changed file with 18 additions and 15 deletions.
33 changes: 18 additions & 15 deletions src/frontends/onnx/frontend/src/op/dequantize_linear.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,36 +221,39 @@ ov::OutputVector dequantize_linear(const ov::frontend::onnx::Node& node) {
FRONT_END_GENERAL_CHECK(src_x.get_partial_shape().is_static(),
"DequantizeLinear cannot operate with dynamic shapes of input X");

const auto& unsqueezed_axes = std::make_shared<v0::Constant>(ov::element::i64, Shape{1}, std::vector<int64_t>{1});

if (inputs.size() > 2) {
zp = inputs[2];
if (zp.get_element_type() != scale.get_element_type()) {
zp = std::make_shared<v1::ConvertLike>(zp, scale);
}
zp = std::make_shared<v0::Unsqueeze>(zp, unsqueezed_axes);
}

const auto axis = node.get_attribute_value<int64_t>("axis", 1);
const auto block_size = static_cast<size_t>(node.get_attribute_value<int64_t>("block_size", 0));
const auto scale_type = scale.get_element_type();

FRONT_END_GENERAL_CHECK(axis == 0, "Axis != 0 isn't supported");
FRONT_END_GENERAL_CHECK(block_size > 0, "block_size must be greater than zero");
FRONT_END_GENERAL_CHECK(
src_x.get_shape()[0] % block_size == 0,
"DequantizeLinear doesn't support case when first dimension of X cannot be divided by block_size");

const auto& x = src_x.get_element_type() == scale_type ? src_x : std::make_shared<v1::ConvertLike>(src_x, scale);
ov::Output<ov::Node> broadcastable_x = op::util::reshape(
src_x,
Shape{static_cast<size_t>(src_x.get_shape()[0]) / block_size, block_size, src_x.get_shape()[1]});

const auto& unsqueezed_axes = std::make_shared<v0::Constant>(ov::element::i64, Shape{1}, std::vector<int64_t>{1});

const auto scale_type = scale.get_element_type();
if (inputs.size() > 2) {
zp = inputs[2];
if (zp.get_element_type() != scale.get_element_type()) {
zp = std::make_shared<v0::Convert>(zp, scale_type);
}
zp = std::make_shared<v0::Unsqueeze>(zp, unsqueezed_axes);
}

const auto& x = src_x.get_element_type() == scale_type ? broadcastable_x
: std::make_shared<v0::Convert>(broadcastable_x, scale_type);
// For further broadcasting scales and zp - reshape input to a shape [x.shape[0]/block_size, block_size, x.shape[1]]
ov::Output<ov::Node> broadcastable_x =
op::util::reshape(x, Shape{static_cast<size_t>(x.get_shape()[0]) / block_size, block_size, x.get_shape()[1]});

// Adding additional dimension for broadcasting
scale = std::make_shared<v0::Unsqueeze>(scale, unsqueezed_axes);

if (zp.get_node_shared_ptr()) {
broadcastable_x = std::make_shared<v1::Subtract>(broadcastable_x, zp);
broadcastable_x = std::make_shared<v1::Subtract>(x, zp);
}

const auto& scaled_x = std::make_shared<v1::Multiply>(broadcastable_x, scale);
Expand Down

0 comments on commit b9a94c3

Please sign in to comment.