[ONNX] Enhance GroupQueryAttention to handle null inputs and improve …#36842
[ONNX] Enhance GroupQueryAttention to handle null inputs and improve …#36842sgbihu wants to merge 10 commits into
Conversation
There was a problem hiding this comment.
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
NullNodeinputs during ONNX import and record their original ONNX positions. - Extend
internal::GroupQueryAttentionto storenull_onnx_input_positionsand 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. |
There was a problem hiding this comment.
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_nulllambda is now unused (no remaining call sites), which is likely to trigger-Wunused-variableunder 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";
};
…g and improve clarity
…l input positions and improve type checks
…d error handling for missing inputs
…nd enhance input checks for non-null tensors
…index type conversion
…o validate_and_infer_types for improved consistency and error handling
3551fc7 to
7d6698a
Compare
|
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. |
There was a problem hiding this comment.
Remove this comment.
| // 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. |
There was a problem hiding this comment.
Remove this comment.
| // 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 { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
I wanna hear other people opinions. I don't really like the suggested solution, but I cannot come with a better one myself.
|
@CuriousPanCake fyi for the latest GQA spec doc - https://github.com/microsoft/onnxruntime/blob/main/docs/ContribOperators.md#com.microsoft.GroupQueryAttention |
Details:
NullNodeto take the input position and let the user to get input node with index.NullNode, that makes the compile error.Solution:
Tickets:
AI Assistance: