Skip to content

[ONNX] Enhance GroupQueryAttention to handle null inputs and improve …#36842

Open
sgbihu wants to merge 10 commits into
openvinotoolkit:masterfrom
sgbihu:gqa_avoid_nullnode
Open

[ONNX] Enhance GroupQueryAttention to handle null inputs and improve …#36842
sgbihu wants to merge 10 commits into
openvinotoolkit:masterfrom
sgbihu:gqa_avoid_nullnode

Conversation

@sgbihu

@sgbihu sgbihu commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Details:

  • The ONNX's default unused input is NullNode to take the input position and let the user to get input node with index.
  • But the OV doesn't support NullNode, that makes the compile error.

Solution:

  • Add the missing input index in the operator
  • Check the index before using it.

Tickets:

AI Assistance:

  • AI assistance used: no / yes
  • If yes, summarize how AI was used and what human validation was performed (build/tests/manual checks).

@sgbihu
sgbihu requested a review from Copilot July 13, 2026 08:35

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot couldn't run its full agentic review because no GitHub Actions runner was available. Make sure your repository has a runner available to run Copilot's review, or add a copilot-setup-steps.yml file specifying one with the runs-on attribute. See the docs for more details.

This PR updates the ONNX com.microsoft.GroupQueryAttention frontend import and the internal OpenVINO GroupQueryAttention op to handle ONNX NullNode optional inputs by filtering them out while preserving enough positional information to map ONNX input positions to actual OpenVINO input indices.

Changes:

  • Filter NullNode inputs during ONNX import and record their original ONNX positions.
  • Extend internal::GroupQueryAttention to store null_onnx_input_positions and expose helpers to map ONNX positions to OV indices.
  • Update the GQA decomposition pass to use mapped indices for several optional inputs (scales, RoPE caches, position ids, mask).

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
src/frontends/onnx/frontend/src/op/com.microsoft/group_query_attention.cpp Filters out NullNode inputs and passes null-position metadata into the internal op.
src/core/src/op/group_query_attention.cpp Stores null-position metadata and uses it to validate quantization scale inputs.
src/core/dev_api/openvino/op/group_query_attention.hpp Adds ONNX input position enum + helpers (has_input, get_input_index) and persists null-position metadata.
src/common/transformations/src/transformations/op_conversions/group_query_attention_decomposition.cpp Uses mapped indices for some optional inputs rather than hard-coded indices.

Comment thread src/core/dev_api/openvino/op/group_query_attention.hpp Outdated
@github-actions github-actions Bot added category: Core OpenVINO Core (aka ngraph) category: transformations OpenVINO Runtime library - Transformations category: ONNX FE OpenVINO ONNX FrontEnd labels Jul 13, 2026
@sgbihu
sgbihu requested a review from Copilot July 14, 2026 01:17
@sgbihu
sgbihu marked this pull request as ready for review July 14, 2026 01:20
@sgbihu
sgbihu requested review from a team as code owners July 14, 2026 01:20

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

Comment thread src/core/dev_api/openvino/op/group_query_attention.hpp

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

src/common/transformations/src/transformations/op_conversions/group_query_attention_decomposition.cpp:115

  • [BLOCKER] is_null lambda is now unused (no remaining call sites), which is likely to trigger -Wunused-variable under the project’s warning settings and break the build. Please remove it (or use it).
    auto is_null = [](const ov::Output<ov::Node>& output) {
        return output.get_node_shared_ptr()->description() == "NullNode";
    };

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

Comment thread src/core/src/op/group_query_attention.cpp

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

Comment thread src/core/dev_api/openvino/op/group_query_attention.hpp Outdated
Comment thread src/frontends/onnx/frontend/src/op/com.microsoft/group_query_attention.cpp Outdated
Comment thread src/core/src/op/group_query_attention.cpp Outdated
@sgbihu
sgbihu requested a review from a team as a code owner July 14, 2026 04:55

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Comment thread src/plugins/intel_npu/src/plugin/npuw/npuw_transformations/decompose_gqa.cpp Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Comment thread src/core/dev_api/openvino/op/group_query_attention.hpp

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Comment thread src/core/src/op/group_query_attention.cpp

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.

@CuriousPanCake

Copy link
Copy Markdown
Contributor

I guess, it would've been good to add some tests

return m_kv_cache_bit_width != 0 && m_k_quant_type != "NONE";
}

// Get original input positions that are null/missing and therefore omitted from OV inputs.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this comment.

Suggested change
// Get original input positions that are null/missing and therefore omitted from OV inputs.

return static_cast<int64_t>(get_input_size() + m_null_input_positions.size());
}

// Check if a specific original input position exists and was not filtered as NullNode.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this comment.

Suggested change
// Check if a specific original input position exists and was not filtered as NullNode.

}

// Get original input positions that are null/missing and therefore omitted from OV inputs.
const std::vector<int64_t>& get_null_input_positions() const {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a afraid the new functionality introduces a risk of getting silent and non-silent errors when using the traditional ov::Node's API for inputs acquisition.

Say, we've compacted from a following ONNX representation:
0:Q 1:K 2:V 3:past_key 4:past_value 5:seqlens_k 6:total_seq_len 7:NULL 8:NULL 9:position_ids 10:attention_mask into
0:Q 1:K 2:V 3:past_key 4:past_value 5:seqlens_k 6:total_seq_len 7:position_ids 8:attention_mask
It's okay, if we use new functions for obtaining indices and getters for inputs as indices will be translated, but it's not clear what input is at what index. In the example above attention_mask has input 10, but for ONNX's
0:Q 1:K 2:V 3:past_key 4:past_value 5:seqlens_k 6:total_seq_len 7:cos_cache 8:sin_cache 9:NULL 10:attention_mask
translated into OV's
0:Q 1:K 2:V 3:past_key 4:past_value 5:seqlens_k 6:total_seq_len 7:cos_cache 8:sin_cache 9:attention_mask
it's index 9 now. So there's no clarity when we use ov::Node::input_value() and I'm pretty sure it's gonna cause a bug at some point. More than that, handling ops. with variable number of inputs is really complicated.

@mitruska @praasz what do you think?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand your concern. But we don't have an operator to keep the index aligned. The NullNode only for frontend. The OV core doesn't has it. If we want to keep the order, we need to add an operator like NullNode. I can change the code if OV has a better way to do this.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanna hear other people opinions. I don't really like the suggested solution, but I cannot come with a better one myself.

@ankitm3k

Copy link
Copy Markdown
Contributor

@sgbihu
sgbihu requested a review from CuriousPanCake July 16, 2026 02:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

category: Core OpenVINO Core (aka ngraph) category: NPU OpenVINO NPU plugin category: NPUW NPUW plugin category: ONNX FE OpenVINO ONNX FrontEnd category: transformations OpenVINO Runtime library - Transformations

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants