Repository navigation
Conversation
Contributor
|
/ci-doctor |
# Conflicts: # src/plugins/intel_gpu/src/plugin/transformations_pipeline.cpp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Details:
Depends on #39118
FullyConnectedGGUF, a GPU primitive that performs MatMul directly on GGUF Q5_K/Q6_K weight blocks without converting them to 8-bit weights.Addis fused into the kernels.ConvertMatMulToFullyConnectedGGUFrecognizesMatMul(A, GGUFDequantize(Constant))and replaces it withFullyConnectedGGUF.Only models containing
GGUFDequantizeare affected; the GGUF frontend changes are a follow-up.Why a new primitive
GGUF weights are stored as byte blocks,
[N, K / 256 * block_bytes], rather than[N, K]values. ExistingFullyConnectedand its transformations assume decoded weights with separate scales and zero points, so a dedicated primitive keeps those paths unchanged.Transformation
The transformation runs after
TransposeMatMuland before constant folding, when:GGUFDequantizehas no other consumer.Q5_K blocks are passed in their original layout. Q6_K blocks are regrouped once at compile time into aligned planes,
QL [nblk][128] | QH [nblk][64] | SC [nblk][16] | D [nblk]. This does not change their size or contents.Implementation
FullyConnectedGGUFselects the execution path from the number of activation rows, so the same primitive can switch between decode and prefill:< 8or f32>= 8, f16, Xe2+>= 8, f16, other devicesN,K), allowing layers with matching shapes to share them.Addis fused into the output store; on the scratch path it becomes a oneDNN binary post-op.Internal option
GPU_GGUF_PREFILL_PATHcan force thescratchorgemvpath for testing.Tests
fully_connected_gguf_gpu_test: 22 tests covering Q5_K/Q6_K, different row counts and input ranks, dynamic shapes, all execution paths and prefill tiles, model caching,compile_model, and fused residualAdd.convert_matmul_to_fc_gguf_test: 7 tests covering both formats, Q6_K plane layout, successful conversion, and cases that must not match.Expected values are generated from
GGUFDequantize::evaluate()and compared in float.Performance
Decode on Panther Lake with Phi-3.5-mini through llama.cpp's OpenVINO backend, as a share of llama.cpp Vulkan on the same iGPU:
Phi-3.5-mini-instruct on a Panther Lake iGPU through llama.cpp's OpenVINO backend, which emits
GGUFDequantizefor Q5_K/Q6_K weights. Both OpenVINO columns run master with our pending GPU PRs (#38696, #38995, #38996); Vulkan is llama.cpp b11236 on the same iGPU. llama-bench-fa 1; decode in tok/s at depth 0 / 4K / 8K:Peak GPU memory drops from 5.46 GB to 4.54 GB for Q5_K_M and 5.46 GB to 4.82 GB for Q6_K.
Q4_K_M also benefits because its Q5_K/Q6_K weights use this path; its Q4_K weights remain on the converted path.
The main tradeoff is prefill: at 8K tokens, this PR reaches 89–94% of the converted path because the converted weights use oneDNN's tuned GEMM, while this implementation decodes GGUF blocks in the kernel.
Short prompts are also slower, with Q5_K_M reaching about 70% of the converted path around 96–128 tokens.
Limitations
Tickets:
AI Assistance:
ov_gpu_unit_tests --gtest_filter=*gguf*(29 tests) and all fully connected unit tests pass on Arc B580 (Xe2, this branch on master 1c169aa) and on Panther Lake (Xe3, the same code on master 38ff87c); on Panther Lake, llama.cpptest-backend-ops -o MUL_MATpasses 964/964 with the native path, and the benchmarks above.