Skip to content

[GPU] Add UINT2 (2-bit) weight compression support via oneDNN fully_connected - #37212

Merged
isanghao merged 25 commits into
openvinotoolkit:masterfrom
vmadananth:u2-onednn-support
Nov 2, 2026
Merged

isanghao merged 25 commits into
openvinotoolkit:masterfrom
vmadananth:u2-onednn-support

Conversation

@vmadananth

@vmadananth vmadananth commented Aug 3, 2026 •

Copy link
Copy Markdown
Contributor

Details:

This PR enables 2-bit unsigned integer (UINT2) compressed weight support for the GPU plugin's oneDNN fully_connected implementation

UINT2 packs 4 weight values per byte, enabling extreme weight compression for LLM inference (e.g., Phi/Orca 2-bit quantized models).

oneDNN fully_connected enablement:

  • Add data_types::u2 to compressed weight dtype validation and allow bitwidth==2 in assertions
  • Map cldnn::data_types::u2 → dnnl::memory::data_type::u2 in oneDNN utils
  • Handle u2 offset calculation (÷4) in get_offset() and weight padding/strides for memory descriptor creation
  • Support u2 as a decompression zero-point dtype
  • Add u2 memory dump support in debug_helper (4 values per byte)

Horizontal FC fusion:

  • Update concat reference kernel to handle u2 in the horizontal FC fusion pass

Tickets:

AI Assistance:

  • yes

@vmadananth
vmadananth requested review from a team as code owners August 3, 2026 21:59
@github-actions github-actions Bot added category: Core OpenVINO Core (aka ngraph) category: GPU OpenVINO GPU plugin labels Aug 3, 2026
@sys-openvino-ci sys-openvino-ci added the ExternalPR External contributor label Aug 3, 2026
@vmadananth

Copy link
Copy Markdown
Contributor Author

The oneDNN submodule is temporarily pointing to mdvoretc/u2 for CI and review. Will update it once the changes make it to oneDNN.

@p-durandin

Copy link
Copy Markdown
Contributor

build_jenkins

@vmadananth vmadananth changed the title [GPU] Add UINT2 (2-bit) weight compression support via oneDNN fully_connected and reorder kernels [GPU] Add UINT2 (2-bit) weight compression support via oneDNN fully_connected Aug 4, 2026
- Add data_types::u2 to compressed_case weight dtype validation
- Allow bitwidth==2 in compressed weights assertion
- Add u2 to weights padding/strides path for memory descriptor creation
- Map cldnn::data_types::u2 to dnnl::memory::data_type::u2 in utils
- Handle u2 offset calculation (divide by 4) in get_offset()
- Add u2 to decompression zero-point dtype validation
- Add GPU_DEBUG_TRACE logging for FC implementation selection
- Add U2 memory dump support in debug_helper (4 values per byte)"
@vmadananth

vmadananth commented Aug 13, 2026 •

Copy link
Copy Markdown
Contributor Author

@Lyamin-Roman @v-Golubev : Could you please review this PR (complementary OV support needed for U2 support needed for oneDNN). The oneDNN submodule in this PR is temporarily pointing to mdvoretc/u2 for CI and review. . I will change this eventually once the PR in oneDNN is merged.

@vmadananth

Copy link
Copy Markdown
Contributor Author

build_jenkins

1 similar comment
@vmadananth

Copy link
Copy Markdown
Contributor Author

build_jenkins

@vmadananth

Copy link
Copy Markdown
Contributor Author

@p-durandin Could you pls review this?

@vmadananth

Copy link
Copy Markdown
Contributor Author

build_jenkins

vmadananth and others added 3 commits September 18, 2026 10:48
# Conflicts:
#	src/core/reference/src/op/concat.cpp
#	src/plugins/intel_gpu/src/graph/debug_helper.cpp
#	src/plugins/intel_gpu/src/graph/impls/onednn/utils.cpp
#	src/plugins/intel_gpu/thirdparty/onednn_gpu
@github-actions github-actions Bot added the category: transformations OpenVINO Runtime library - Transformations label Oct 19, 2026
vmadananth added a commit to vmadananth/openvino that referenced this pull request Oct 19, 2026
u2 weight-only-quantized FCs require f16 activations on both the CM and oneDNN kernels; skip per-token INT8 dynamic quantization for them so the u2 path is taken. Carried from openvinotoolkit#37212.
vmadananth added a commit to vmadananth/openvino that referenced this pull request Oct 21, 2026
u2 weight-only-quantized FCs require f16 activations on both the CM and oneDNN kernels; skip per-token INT8 dynamic quantization for them so the u2 path is taken. Carried from openvinotoolkit#37212.
@vmadananth

Copy link
Copy Markdown
Contributor Author

Merged latest master (resolved the conflict with #38934 by dropping get_grouped_mask()) and updated oneDNN to uxlfoundation/oneDNN#6296

@@ -23,22 +23,6 @@ struct fully_connected_onednn : typed_primitive_onednn_impl<fully_connected> {
static constexpr int COMMON = 0;

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.

random spot)

  • onednn update requires broad validation. Let's separate that.
  • Please attach a ticket and upload performance/accuracy result there.

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.

# Conflicts:
#	src/plugins/intel_gpu/thirdparty/onednn_gpu
# Conflicts:
#	src/plugins/intel_gpu/src/graph/impls/onednn/fully_connected_onednn.cpp
#	src/plugins/intel_gpu/src/graph/impls/onednn/fully_connected_onednn.hpp
#	src/plugins/intel_gpu/src/graph/impls/onednn/utils.cpp

@isanghao isanghao 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.

lgtm

@isanghao
isanghao added this pull request to the merge queue Nov 2, 2026
Merged via the queue into openvinotoolkit:master with commit 23ea61f Nov 2, 2026
231 of 233 checks passed
akazakov-github pushed a commit to akazakov-github/openvino that referenced this pull request Nov 2, 2026
…kit#39316)

### This PR fixes micro SDPA config selection on integrated GPUs, which
picked a decode (second-token) config for every prefill chunk.

### Tickets:
 - [CVS-197466](https://jira.devtools.intel.com/browse/CVS-197466)

This PR is one part of a set of TTFT optimizations for 2-bit LLMs on
Panther Lake. The other parts are openvinotoolkit#39317 (L2
normalization into RMS), openvinotoolkit#39320 (int8
activations for u2 FullyConnected) and uxlfoundation/oneDNN#6381 (u2
weights with int8 activations).

---

### Changes

Xe2/Xe3 reach `choose_config_xehpc` for head size <= 128. There were two
problems:
- **Check order:** the `is_integrated` check returned
`xehpc_q_h128_2nd_integrated`, a second-token config, before `thin_q`
was checked. With an f16 KV cache, every prefill chunk ran a
decode-shaped kernel.
- **Unknown key count:** a dynamic key count (StatelessKV) arrives as
`seq = 0`, so a prefill over thousands of keys was sized as a short
sequence.

After the fix:
- the integrated decode config is used for `thin_q` only;
- a multi-token call with an unknown key count on an integrated GPU is
sized as a long sequence. With a quantized KV cache this selects
`xehpc_q_h128`, the config that a known long sequence already gets.

Discrete GPUs, PagedAttention and decode (`thin_q`) take the same paths
as before.

---

### Before / after

LLM (2-bit weights, f16 KV cache), PTL 4Xe, ~8200-token prompt in
512-token chunks, TTFT median of 3 runs:

| | TTFT | |
|---|---|---|
| before | 28.92 s | |
| after | 24.21 s | **1.19x** |

Greedy output is identical and decode speed is unchanged. Running a
2-bit model needs u2 FullyConnected support (openvinotoolkit#37212), so this was
measured on a branch that has it. This change does not depend on it.

---

### Validation

- The existing SDPA unit tests give the same results with and without
this PR.
- End to end on PTL 4Xe: greedy output identical to before on all
prompts.

> [!NOTE]
> AI assistance was used. All changes were reviewed, built, tested and
measured on hardware.
mvafin pushed a commit to mvafin/openvino that referenced this pull request Nov 5, 2026
…oolkit#39469)

### Details:
- **Issue 1.** In file
_src/plugins/intel_gpu/src/graph/impls/onednn/fully_connected_onednn.cpp_
function _get_ifm_dim_idx()_ guessed which axis of the scale/zero-point
tensor holds the number of groups. It derived the axis from the rank of
the weights, after a heuristic squeeze.
The guess is wrong when the scale or zero-point tensor keeps an extra
group-size axis of length 1 that the weights don't have. The
extra_multiply cases and 3D weights are examples. The code then picked
the OC axis and got a bogus ngroups, for example 32 instead of 1. That
made group_size = ifm / ngroups meaningless. oneDNN rejected it.
- **Fix 1**. _get_ngroups()_ replaces the axis guess. It computes the
group count from element counts, scale_total_count / (OC * batch). It
uses the IFM and OC positions from the weights layout, which are
reliable. create() and load() both use it, for scales and zero points.
This fixes the 4 tests.

- **Issue 2.** The tests failed with clWaitForEvents ...
CL_INVALID_EVENT, later clEnqueueMemFillINTEL ... CL_OUT_OF_RESOURCES.
These are only downstream symptoms. dmesg shows a GPU memory fault:
Faulted Address, Engine memory CAT error, Engine reset. The engine reset
kills the OpenCL queue, so the next command fails.
Cause is OOB read in oneDNN.
- **Fix 2.** In separate PR
[oneDNN-6417](uxlfoundation/oneDNN#6417. This
fixes other 23 tests.

- **Issue 3.** The new one came from openvinotoolkit#37212.
smoke_MatMulCompressedWeights_basic with u2 weights, shape [377,335],
f16 activations and constant weights, one per transpose_weights value.
The oneDNN rejecting the weights descriptor with bad dimension strides.
In the vendored oneDNN, memory_desc_strides_check (the "generalize
strides check for subbyte dts" commit) requires every non-unit stride of
a sub-byte descriptor to be a whole number of bytes. For u2 that means a
multiple of 4 elements. The weights row stride is the innermost weights
dimension. Here it is 335 or 377, so oneDNN refuses the descriptor.
- **Fix 3.** In _fully_connected_onednn.hpp_, _validate_impl()_ now
rejects the oneDNN FC implementation for compressed weights narrower
than 8 bits when the innermost weights dimension isn't a whole number of
bytes. It then picks another FC implementation, as it already does for
unsupported u2 scale grouping.
This fixes the 2 tests.

### Tickets:
 - *[CVS-199121](https://jira.devtools.intel.com/browse/CVS-199121)*

### AI Assistance:
 - *AI assistance used: yes*
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

category: GPU OpenVINO GPU plugin category: transformations OpenVINO Runtime library - Transformations Code Freeze ExternalPR External contributor orca_CF

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants