Skip to content

[Kernel][PA] Support BF16 vectorized KV with asymmetric K/V head dim - #1065

Merged
coderfeli merged 6 commits into
ROCm:mainfrom
sammysun0711:upstream/pa-bf16-asymmetric-v
Aug 31, 2026
Merged

coderfeli merged 6 commits into
ROCm:mainfrom
sammysun0711:upstream/pa-bf16-asymmetric-v

Conversation

@sammysun0711

@sammysun0711 sammysun0711 commented Aug 24, 2026 •

Copy link
Copy Markdown
Contributor

Motivation

Based on #1064
Add BF16 vectorized-5D KV support and allow different Q/K and V/output head dimensions in pa_decode_tile kernel.

Technical Details

Extend FlyDSL PA kernel to support Models with different K/V head dim with Both FP8 and BF16 support.
E.g. MiMo-V2.5-Pro with Q/K D192 and V/O D128 does not need to physically pad V to 192.
The same tile PA path is also useful for native BF16 page-64 KV on gfx942 and gfx950.

  • Add a BF16 K16-MFMA specialization for vectorized-5D K/V caches.
  • Derive PV accumulation, partial buffers, output stores, and reduction width
    from the physical value dimension.
  • Support BF16 Q/K192 with V128/V192 and FP8 Q/K192 with V128.
  • Preserve symmetric FP8 behavior and caller-owned graph-safe workspaces.

Performance (gfx950)

Batch 32, query length 4, 16Q/1KV, Q/K D192, page 64:

Context AITER Gluon V192 FlyDSL V128 Speedup FlyDSL V192 Speedup
16K 0.648544 ms 0.103483 ms 6.267x 0.118604 ms 5.468x
64K 2.278582 ms 0.331712 ms 6.869x 0.389114 ms 5.856x

Test Plan

Extend test_pa_decode_tile.py to covers BF16 QL1/QL4 with V128/V192, asymmetric FP8, symmetric FP8 D192, multi-partition reduction.
python -m pytest -q tests/kernels/test_pa.py

Test Result

python3 -m pytest -q     tests/kernels/test_pa.py  
===================================================================== test session starts =====================================================================
platform linux -- Python 3.10.12, pytest-9.0.3, pluggy-1.6.0
rootdir: /root/workspace/mimo-opt/flydsl-upstream-prs/pr2-pa-bf16-asym/tests
configfile: pytest.ini
plugins: hypothesis-6.150.2, anyio-4.14.2
collected 2327 items                                                                                                                                          

tests/kernels/test_pa.py .............................................................................................................................. [  5%]
....................................................................................................................................................... [ 11%]
....................................................................................................................................................... [ 18%]
....................................................................................................................................................... [ 24%]
....................................................................................................................................................... [ 31%]
....................................................................................................................................................... [ 37%]
....................................................................................................................................................... [ 44%]
....................................................................................................................................................... [ 50%]
....................................................................................................................................................... [ 57%]
....................................................................................................................................................... [ 63%]
....................................................................................................................................................... [ 70%]
....................................................................................................................................................... [ 76%]
....................................................................................................................................................... [ 83%]
....................................................................................................................................................... [ 89%]
....................................................................................................................................................... [ 96%]
.......................................................................................                                                                 [100%]

====================================================================== warnings summary =======================================================================
../../../../../opt/venv/lib/python3.10/site-packages/Cython/Distutils/old_build_ext.py:15
../../../../../opt/venv/lib/python3.10/site-packages/Cython/Distutils/old_build_ext.py:15
  /opt/venv/lib/python3.10/site-packages/Cython/Distutils/old_build_ext.py:15: DeprecationWarning: dep_util is Deprecated. Use functions from setuptools instead.
    from distutils.dep_util import newer, newer_group

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
======================================================== 2327 passed, 2 warnings in 198.96s (0:03:18) =========================================================

Submission Checklist

Copilot AI lite review requested due to automatic review settings August 24, 2026 09:48
@sammysun0711 sammysun0711 changed the title [Kernel][PA] Support BF16 vectorized KV and independent value dimensions [Kernel][PA] Support BF16 vectorized KV and independent V head dim Aug 24, 2026

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

This PR extends the tile-programming paged-attention decode kernel to support (1) BF16 vectorized-5D KV caches and (2) asymmetric head dimensions where Q/K head dim can differ from V/output head dim, with accompanying correctness tests.

Changes:

  • Add a BF16 KV specialization (K16 BF16 MFMA path) alongside the existing FP8 path in pa_decode_tile.
  • Generalize PV accumulation/output/storage to use v_head_dim (derived from the physical value dimension) instead of assuming head_dim.
  • Add focused GPU correctness tests covering BF16 vectorized-5D KV (V128/V192) and FP8 asymmetric value head dim (V128).

Reviewed changes

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

File Description
kernels/attention/pa_decode_tile.py Adds BF16 KV specialization and supports independent v_head_dim across the kernel and host wrapper validation/dispatch.
tests/kernels/test_pa_decode_tile.py Adds correctness coverage for BF16 vectorized-5D KV and FP8 asymmetric value head dimensions with multi-partition reduction.
Suppressed comments (1)

kernels/attention/pa_decode_tile.py:1191

  • query_group_size = num_q_heads // num_kv_heads uses integer division without validating divisibility. If num_q_heads is not divisible by num_kv_heads, the kernel will silently use the truncated group size and produce incorrect indexing.
    assert context_lengths.dtype == torch.int32, f"context_lengths must be int32, got {context_lengths.dtype}"
    query_group_size = num_q_heads // num_kv_heads
    max_blocks_per_seq = block_tables.shape[1]

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread kernels/attention/pa_decode_tile.py Outdated
Comment on lines +190 to +192
pmax_ptr: fx.Tensor, # [num_seqs*query_length, num_kv_heads, num_partitions, query_group_size] row max
psum_ptr: fx.Tensor, # [num_seqs*query_length, num_kv_heads, num_partitions, query_group_size] row sum
pout_ptr: fx.Tensor, # [num_seqs*query_length, num_kv_heads, num_partitions, query_group_size, head_dim] Q_DTYPE, normalized O_p/l_p
pout_ptr: fx.Tensor, # [num_seqs*query_length, num_kv_heads, num_partitions, query_group_size, v_head_dim] Q_DTYPE, normalized O_p/l_p

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.

Fixed in ad712fb, The workspace comments now use [num_seqs, num_kv_heads, num_partitions, total_rows], with total_rows = query_length * query_group_size, matching both host allocation and flattened kernel indexing.

Besides, I also added host-side validation that num_q_heads is divisible by num_kv_heads before deriving the query group size.

@sammysun0711 sammysun0711 changed the title [Kernel][PA] Support BF16 vectorized KV and independent V head dim [Kernel][PA] Support BF16 vectorized KV and asymmetric head dim Aug 24, 2026
@sammysun0711 sammysun0711 changed the title [Kernel][PA] Support BF16 vectorized KV and asymmetric head dim [Kernel][PA] Support BF16 vectorized KV with asymmetric V head dim Aug 24, 2026
@sammysun0711 sammysun0711 changed the title [Kernel][PA] Support BF16 vectorized KV with asymmetric V head dim [Kernel][PA] Support BF16 vectorized KV with asymmetric K/V head dim Aug 24, 2026
@sammysun0711
sammysun0711 force-pushed the upstream/pa-bf16-asymmetric-v branch 2 times, most recently from 4ea457e to cc5bbdb Compare August 26, 2026 13:51
Comment thread kernels/attention/pa_decode_tile.py Outdated
per_token_kv: bool = False,
query_length: int = 1,
trans_v: bool = True,
bf16_kv: bool = False,

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.

bf16_mfma

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.

Thanks for your suggestions. In ab4e847 I've updated the compile-time API in from bf16_kv: bool to kv_dtype: str, validated as fp8 or bf16. The host derives it from the physical key-cache dtype, while the kernel uses an internal is_bf16_kv boolean for specialization branches. This describes the full KV storage/layout path rather than only the selected MFMA instruction.

@coderfeli

Copy link
Copy Markdown
Collaborator

also change pa_decode_ps_launch ?

Signed-off-by: Xiake Sun <xiake.sun@amd.com>
… test_pa.py

Signed-off-by: Xiake Sun <xiake.sun@amd.com>
Signed-off-by: Xiake Sun <xiake.sun@amd.com>
- Add docs for partition workspaces using the flattened total-row dimension
  that matches host allocation and kernel indexing.
- Reject Q-head counts that are not divisible by the number of KV heads before
  deriving the query group size.

Signed-off-by: Xiake Sun <xiake.sun@amd.com>
Signed-off-by: Xiake Sun <xiake.sun@amd.com>
Signed-off-by: Xiake Sun <xiake.sun@amd.com>
@sammysun0711
sammysun0711 force-pushed the upstream/pa-bf16-asymmetric-v branch from ad712fb to 53236d0 Compare August 29, 2026 02:37
@sammysun0711

Copy link
Copy Markdown
Contributor Author

also change pa_decode_ps_launch ?

Thanks for your suggestions. In 53236d0, I've updated pa_decode_ps_launch to dispatch non-sliding window requests (page sizes 16 and 64) to pa_decode_tile before the FP8-specific scale and metadata setup. This change enables BF16 vectorized KV and asymmetric V/output dimensions through the PS wrapper. It also supports automatic or preallocated V-sized workspaces, including CUDA graph capture and replay.

The scope of this PR is limited to BF16 asymmetric Paged Attention (PA) support for page sizes 16 and 64. Support for sliding-window and page-1024 paths requires modifications to common utilities (e.g., pa_metadata.py and pa_metadata_tuning.py), which can be addressed in a follow-up PR.

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 3 out of 3 changed files in this pull request and generated 2 comments.

Comment thread tests/kernels/test_pa.py
Comment on lines +1152 to +1156
@pytest.mark.parametrize(
"entrypoint",
["tile", "ps-allocate", "ps-preallocated"],
ids=["direct", "ps-allocate", "ps-preallocated"],
)
Comment on lines +313 to +314
if max_context_partition_num <= 0:
raise ValueError("max_context_partition_num must be positive.")
@coderfeli
coderfeli merged commit e46db60 into ROCm:main Aug 31, 2026
11 of 12 checks passed
fsx950223 added a commit to ROCm/aiter that referenced this pull request Oct 8, 2026
Port vector8 BF16 KV and K16 MFMA from ROCm/FlyDSL#1065 into the planned PA pipeline. Keep softmax and accumulation in FP32, split MTP queries to fit LDS, and distinguish KV precision in the native tuner cache.

Validation: 109 tests pass on gfx942, native eager/graph tuning and cache-hit checks pass, and BF16 addressing beyond 2 GiB passes. Black, Ruff and diff checks pass.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants